nagios-2.6/0000775000076500007650000000000010532717611012202 5ustar nagiosnagiosnagios-2.6/base/0000775000076500007650000000000010532717537013123 5ustar nagiosnagiosnagios-2.6/base/Makefile.in0000664000076500007650000001253410437071560015166 0ustar nagiosnagios############################ # Makefile for Nagios # # Last Modified: 05-30-2006 ############################ # Source code directories SRC_COMMON=../common SRC_INCLUDE=../include SRC_XDATA=../xdata CC=@CC@ CFLAGS=@CFLAGS@ @DEFS@ -DNSCORE # Compiler flags for optimization (overrides default) #CFLAGS=-O3 -Wall -Wshadow -Wpointer-arith -Wcast-qual -Wcast-align -Wstrict-prototypes -Wmissing-prototypes -Wnested-externs -DHAVE_CONFIG_H -DNSCORE # Compiler flags for optimization (complements default) #CFLAGS_WARN=-Wall -Wshadow -Wpointer-arith -Wcast-qual -Wcast-align -Wstrict-prototypes -Wmissing-prototypes -Wnested-externs #CFLAGS_DEBUG=-ggdb3 -g3 #CFLAGS+=$(CFLAGS_WARN) $(CFLAGS_DEBUG) LDFLAGS=@LDFLAGS@ LIBS=@LIBS@ prefix=@prefix@ exec_prefix=@exec_prefix@ LOGDIR=@localstatedir@ CFGDIR=@sysconfdir@ BINDIR=@bindir@ CGIDIR=@sbindir@ HTMLDIR=@datadir@ INSTALL=@INSTALL@ INSTALL_OPTS=@INSTALL_OPTS@ COMMAND_OPTS=@COMMAND_OPTS@ STRIP=@STRIP@ CGIURL=@cgiurl@ HTMURL=@htmurl@ MATHLIBS=-lm PERLLIBS=@PERLLIBS@ PERLXSI_O=@PERLXSI_O@ SOCKETLIBS=@SOCKETLIBS@ THREADLIBS=@THREADLIBS@ BROKERLIBS=@BROKERLIBS@ BROKER_LDFLAGS=@BROKER_LDFLAGS@ CP=@CP@ # External data I/O code and headers XSDC=@XSDC@ XSDH=@XSDH@ XCDC=@XCDC@ XCDH=@XCDH@ XRDC=@XRDC@ XRDH=@XRDH@ XODC=@XODC@ XODH=@XODH@ XPDC=@XPDC@ XPDH=@XPDH@ XDDC=@XDDC@ XDDH=@XDDH@ # Extra base code BASEEXTRALIBS=@BASEEXTRALIBS@ # Generated automatically from configure script SNPRINTF_O=@SNPRINTF_O@ BROKER_O=@BROKER_O@ BROKER_H=@BROKER_H@ # Object data #ODATALIBS=$(SRC_COMMON)/objects.c $(SRC_XDATA)/$(XODC) #ODATAHDRS=$(SRC_INCLUDE)/objects.h $(SRC_XDATA)/$(XODH) ODATALIBS=objects-base.o xobjects-base.o ODATAHDRS= ODATADEPS=$(ODATALIBS) # Retention data #RDATALIBS=sretention.o $(SRC_XDATA)/$(XRDC) #RDATAHDRS=$(SRC_INCLUDE)/sretention.h $(SRC_XDATA)/$(XRDH) RDATALIBS=retention-base.o xretention-base.o RDATAHDRS= RDATADEPS=$(RDATALIBS) # Comment data #CDATALIBS=$(SRC_COMMON)/comments.c $(SRC_XDATA)/$(XCDC) #CDATAHDRS=$(SRC_INCLUDE)/comments.h $(SRC_XDATA)/$(XCDH) CDATALIBS=comments-base.o xcomments-base.o CDATAHDRS= CDATADEPS=$(CDATALIBS) # Status data #SDATALIBS=$(SRC_COMMON)/statusdata.c $(SRC_XDATA)/$(XSDC) #SDATAHDRS=$(SRC_INCLUDE)/statusdata.h $(SRC_XDATA)/$(XSDH) SDATALIBS=statusdata-base.o xstatusdata-base.o SDATAHDRS= SDATADEPS=$(SDATALIBS) # Performance data #PDATALIBS=perfdata.o $(SRC_XDATA)/$(XPDC) #PDATAHDRS=$(SRC_INCLUDE)/perfdata.h $(SRC_XDATA)/$(XPDH) PDATALIBS=perfdata-base.o xperfdata-base.o PDATAHDRS= PDATADEPS=$(PDATALIBS) # Downtime data #DDATALIBS=$(SRC_COMMON)/downtime.c $(SRC_XDATA)/$(XDDC) #DDATAHDRS=$(SRC_INCLUDE)/downtime.h $(SRC_XDATA)/$(XDDH) DDATALIBS=downtime-base.o xdowntime-base.o DDATAHDRS= DDATADEPS=$(DDATALIBS) OBJS=$(BROKER_O) checks.o config.o commands.o events.o flapping.o logging.o notifications.o sehandlers.o utils.o $(RDATALIBS) $(CDATALIBS) $(ODATALIBS) $(SDATALIBS) $(PDATALIBS) $(DDATALIBS) $(BASEEXTRALIBS) $(SNPRINTF_O) $(PERLXSI_O) OBJDEPS=$(ODATADEPS) $(ODATADEPS) $(RDATADEPS) $(CDATADEPS) $(SDATADEPS) $(PDATADEPS) $(DDATADEPS) $(BROKER_H) all: nagios nagiostats ######## REQUIRED LIBRARIES ########## objects-base.o: $(SRC_COMMON)/objects.c $(SRC_INCLUDE)/objects.h $(CC) $(CFLAGS) -c -o $@ $(SRC_COMMON)/objects.c xobjects-base.o: $(SRC_XDATA)/$(XODC) $(SRC_XDATA)/$(XODH) $(CC) $(CFLAGS) -c -o $@ $(SRC_XDATA)/$(XODC) statusdata-base.o: $(SRC_COMMON)/statusdata.c $(SRC_INCLUDE)/statusdata.h $(CC) $(CFLAGS) -c -o $@ $(SRC_COMMON)/statusdata.c xstatusdata-base.o: $(SRC_XDATA)/$(XSDC) $(SRC_XDATA)/$(XSDH) $(CC) $(CFLAGS) -c -o $@ $(SRC_XDATA)/$(XSDC) comments-base.o: $(SRC_COMMON)/comments.c $(SRC_INCLUDE)/comments.h $(CC) $(CFLAGS) -c -o $@ $(SRC_COMMON)/comments.c xcomments-base.o: $(SRC_XDATA)/$(XCDC) $(SRC_XDATA)/$(XCDH) $(CC) $(CFLAGS) -c -o $@ $(SRC_XDATA)/$(XCDC) downtime-base.o: $(SRC_COMMON)/downtime.c $(SRC_INCLUDE)/downtime.h $(CC) $(CFLAGS) -c -o $@ $(SRC_COMMON)/downtime.c xdowntime-base.o: $(SRC_XDATA)/$(XDDC) $(SRC_XDATA)/$(XDDH) $(CC) $(CFLAGS) -c -o $@ $(SRC_XDATA)/$(XDDC) perfdata-base.o: perfdata.c $(SRC_INCLUDE)/perfdata.h $(CC) $(CFLAGS) -c -o $@ perfdata.c xperfdata-base.o: $(SRC_XDATA)/$(XPDC) $(SRC_XDATA)/$(XPDH) $(CC) $(CFLAGS) -c -o $@ $(SRC_XDATA)/$(XPDC) retention-base.o: sretention.c $(SRC_INCLUDE)/sretention.h $(CC) $(CFLAGS) -c -o $@ sretention.c xretention-base.o: $(SRC_XDATA)/$(XRDC) $(SRC_XDATA)/$(XRDH) $(CC) $(CFLAGS) -c -o $@ $(SRC_XDATA)/$(XRDC) ########## CGIS ########## nagios: nagios.c $(OBJS) $(OBJDEPS) $(SRC_INCLUDE)/nagios.h $(SRC_INCLUDE)/locations.h $(CC) $(CFLAGS) -o $@ nagios.c $(OBJS) $(BROKER_LDFLAGS) $(LDFLAGS) $(PERLLIBS) $(MATHLIBS) $(SOCKETLIBS) $(THREADLIBS) $(BROKERLIBS) $(LIBS) nagiostats: nagiostats.c $(SRC_INCLUDE)/locations.h $(CC) $(CFLAGS) -o $@ nagiostats.c $(LDFLAGS) $(MATHLIBS) $(LIBS) $(OBJS): $(SRC_INCLUDE)/locations.h clean: rm -f nagios nagiostats core *.o gmon.out rm -f *~ *.*~ distclean: clean rm -f perlxsi.c rm -f Makefile devclean: distclean install: $(MAKE) install-basic $(MAKE) strip-post-install install-unstripped: $(MAKE) install-basic install-basic: $(INSTALL) -m 775 $(INSTALL_OPTS) -d $(DESTDIR)$(BINDIR) $(INSTALL) -m 774 $(INSTALL_OPTS) @nagios_name@ $(DESTDIR)$(BINDIR) $(INSTALL) -m 774 $(INSTALL_OPTS) @nagiostats_name@ $(DESTDIR)$(BINDIR) strip-post-install: $(STRIP) $(DESTDIR)$(BINDIR)/@nagios_name@ $(STRIP) $(DESTDIR)$(BINDIR)/@nagiostats_name@ nagios-2.6/base/broker.c0000664000076500007650000006351110353050227014544 0ustar nagiosnagios/***************************************************************************** * * BROKER.C - Event broker routines for Nagios * * Copyright (c) 2002-2005 Ethan Galstad (nagios@nagios.org) * Last Modified: 12-16-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. * *****************************************************************************/ #include "../include/config.h" #include "../include/common.h" #include "../include/nagios.h" #include "../include/broker.h" #include "../include/nebcallbacks.h" #include "../include/nebstructs.h" #include "../include/nebmods.h" extern unsigned long event_broker_options; extern time_t program_start; extern int nagios_pid; extern int daemon_mode; extern time_t last_command_check; extern time_t last_log_rotation; extern int enable_notifications; extern int execute_service_checks; extern int accept_passive_service_checks; extern int execute_host_checks; extern int accept_passive_host_checks; extern int enable_event_handlers; extern int obsess_over_services; extern int obsess_over_hosts; extern int enable_flap_detection; extern int enable_failure_prediction; extern int process_performance_data; extern int aggregate_status_updates; extern unsigned long modified_host_process_attributes; extern unsigned long modified_service_process_attributes; extern char *global_host_event_handler; extern char *global_service_event_handler; #ifdef USE_EVENT_BROKER /******************************************************************/ /************************* EVENT FUNCTIONS ************************/ /******************************************************************/ /* sends program data (starts, restarts, stops, etc.) to broker */ void broker_program_state(int type, int flags, int attr, struct timeval *timestamp){ nebstruct_process_data ds; if(!(event_broker_options & BROKER_PROGRAM_STATE)) return; /* fill struct with relevant data */ ds.type=type; ds.flags=flags; ds.attr=attr; ds.timestamp=get_broker_timestamp(timestamp); /* make callbacks */ neb_make_callbacks(NEBCALLBACK_PROCESS_DATA,(void *)&ds); return; } /* send timed event data to broker */ void broker_timed_event(int type, int flags, int attr, timed_event *event, struct timeval *timestamp){ nebstruct_timed_event_data ds; if(!(event_broker_options & BROKER_TIMED_EVENTS)) return; if(event==NULL) return; /* fill struct with relevant data */ ds.type=type; ds.flags=flags; ds.attr=attr; ds.timestamp=get_broker_timestamp(timestamp); ds.event_type=event->event_type; ds.recurring=event->recurring; ds.run_time=event->run_time; ds.event_data=event->event_data; /* make callbacks */ neb_make_callbacks(NEBCALLBACK_TIMED_EVENT_DATA,(void *)&ds); return; } /* send log data to broker */ void broker_log_data(int type, int flags, int attr, char *data, unsigned long data_type, time_t entry_time, struct timeval *timestamp){ nebstruct_log_data ds; if(!(event_broker_options & BROKER_LOGGED_DATA)) return; /* fill struct with relevant data */ ds.type=type; ds.flags=flags; ds.attr=attr; ds.timestamp=get_broker_timestamp(timestamp); ds.entry_time=entry_time; ds.data_type=data_type; ds.data=data; /* make callbacks */ neb_make_callbacks(NEBCALLBACK_LOG_DATA,(void *)&ds); return; } /* send system command data to broker */ void broker_system_command(int type, int flags, int attr, struct timeval start_time, struct timeval end_time, double exectime, int timeout, int early_timeout, int retcode, char *cmd, char *output, struct timeval *timestamp){ nebstruct_system_command_data ds; if(!(event_broker_options & BROKER_SYSTEM_COMMANDS)) return; if(cmd==NULL) return; /* fill struct with relevant data */ ds.type=type; ds.flags=flags; ds.attr=attr; ds.timestamp=get_broker_timestamp(timestamp); ds.start_time=start_time; ds.end_time=end_time; ds.timeout=timeout; ds.command_line=cmd; ds.early_timeout=early_timeout; ds.execution_time=exectime; ds.return_code=retcode; ds.output=output; /* make callbacks */ neb_make_callbacks(NEBCALLBACK_SYSTEM_COMMAND_DATA,(void *)&ds); return; } /* send event handler data to broker */ void broker_event_handler(int type, int flags, int attr, int eventhandler_type, void *data, int state, int state_type, struct timeval start_time, struct timeval end_time, double exectime, int timeout, int early_timeout, int retcode, char *command, char *cmdline, char *output, struct timeval *timestamp){ service *temp_service=NULL; host *temp_host=NULL; char *command_buf=NULL; char *command_name=NULL; char *command_args=NULL; nebstruct_event_handler_data ds; if(!(event_broker_options & BROKER_EVENT_HANDLERS)) return; if(data==NULL) return; /* get command name/args */ if(command!=NULL){ command_buf=strdup(command); command_name=strtok(command_buf,"!"); command_args=strtok(NULL,"\x0"); } /* fill struct with relevant data */ ds.type=type; ds.flags=flags; ds.attr=attr; ds.timestamp=get_broker_timestamp(timestamp); ds.eventhandler_type=eventhandler_type; if(eventhandler_type==SERVICE_EVENTHANDLER || eventhandler_type==GLOBAL_SERVICE_EVENTHANDLER){ temp_service=(service *)data; ds.host_name=temp_service->host_name; ds.service_description=temp_service->description; } else{ temp_host=(host *)data; ds.host_name=temp_host->name; ds.service_description=NULL; } ds.state=state; ds.state_type=state_type; ds.start_time=start_time; ds.end_time=end_time; ds.timeout=timeout; ds.command_name=command_name; ds.command_args=command_args; ds.command_line=cmdline; ds.early_timeout=early_timeout; ds.execution_time=exectime; ds.return_code=retcode; ds.output=output; /* make callbacks */ neb_make_callbacks(NEBCALLBACK_EVENT_HANDLER_DATA,(void *)&ds); /* free memory */ free(command_buf); return; } /* send host check data to broker */ void broker_host_check(int type, int flags, int attr, host *hst, int check_type, int state, int state_type, struct timeval start_time, struct timeval end_time, char *command, double latency, double exectime, int timeout, int early_timeout, int retcode, char *cmdline, char *output, char *perfdata, struct timeval *timestamp){ char *command_buf=NULL; char *command_name=NULL; char *command_args=NULL; nebstruct_host_check_data ds; if(!(event_broker_options & BROKER_HOST_CHECKS)) return; if(hst==NULL) return; /* get command name/args */ if(command!=NULL){ command_buf=strdup(command); command_name=strtok(command_buf,"!"); command_args=strtok(NULL,"\x0"); } /* fill struct with relevant data */ ds.type=type; ds.flags=flags; ds.attr=attr; ds.timestamp=get_broker_timestamp(timestamp); ds.host_name=hst->name; ds.check_type=check_type; ds.current_attempt=hst->current_attempt; ds.max_attempts=hst->max_attempts; ds.state=state; ds.state_type=state_type; ds.timeout=timeout; ds.command_name=command_name; ds.command_args=command_args; ds.command_line=cmdline; ds.start_time=start_time; ds.end_time=end_time; ds.early_timeout=early_timeout; ds.execution_time=exectime; ds.latency=latency; ds.return_code=retcode; ds.output=output; ds.perf_data=perfdata; /* make callbacks */ neb_make_callbacks(NEBCALLBACK_HOST_CHECK_DATA,(void *)&ds); /* free data */ free(command_buf); return; } /* send service check data to broker */ void broker_service_check(int type, int flags, int attr, service *svc, int check_type, struct timeval start_time, struct timeval end_time, char *command, double latency, double exectime, int timeout, int early_timeout, int retcode, char *cmdline, struct timeval *timestamp){ char *command_buf=NULL; char *command_name=NULL; char *command_args=NULL; nebstruct_service_check_data ds; if(!(event_broker_options & BROKER_SERVICE_CHECKS)) return; if(svc==NULL) return; /* get command name/args */ if(command!=NULL){ command_buf=strdup(command); command_name=strtok(command_buf,"!"); command_args=strtok(NULL,"\x0"); } /* fill struct with relevant data */ ds.type=type; ds.flags=flags; ds.attr=attr; ds.timestamp=get_broker_timestamp(timestamp); ds.host_name=svc->host_name; ds.service_description=svc->description; ds.check_type=check_type; ds.current_attempt=svc->current_attempt; ds.max_attempts=svc->max_attempts; ds.state=svc->current_state; ds.state_type=svc->state_type; ds.timeout=timeout; ds.command_name=command_name; ds.command_args=command_args; ds.command_line=cmdline; ds.start_time=start_time; ds.end_time=end_time; ds.early_timeout=early_timeout; ds.execution_time=exectime; ds.latency=latency; ds.return_code=retcode; ds.output=svc->plugin_output; ds.perf_data=svc->perf_data; /* make callbacks */ neb_make_callbacks(NEBCALLBACK_SERVICE_CHECK_DATA,(void *)&ds); /* free data */ free(command_buf); return; } /* send comment data to broker */ void broker_comment_data(int type, int flags, int attr, int comment_type, int entry_type, char *host_name, char *svc_description, time_t entry_time, char *author_name, char *comment_data, int persistent, int source, int expires, time_t expire_time, unsigned long comment_id, struct timeval *timestamp){ nebstruct_comment_data ds; if(!(event_broker_options & BROKER_COMMENT_DATA)) return; /* fill struct with relevant data */ ds.type=type; ds.flags=flags; ds.attr=attr; ds.timestamp=get_broker_timestamp(timestamp); ds.comment_type=comment_type; ds.entry_type=entry_type; ds.host_name=host_name; ds.service_description=svc_description; ds.entry_time=entry_time; ds.author_name=author_name; ds.comment_data=comment_data; ds.persistent=persistent; ds.source=source; ds.expires=expires; ds.expire_time=expire_time; ds.comment_id=comment_id; /* make callbacks */ neb_make_callbacks(NEBCALLBACK_COMMENT_DATA,(void *)&ds); return; } /* send downtime data to broker */ void broker_downtime_data(int type, int flags, int attr, int downtime_type, char *host_name, char *svc_description, time_t entry_time, char *author_name, char *comment_data, time_t start_time, time_t end_time, int fixed, unsigned long triggered_by, unsigned long duration, unsigned long downtime_id, struct timeval *timestamp){ nebstruct_downtime_data ds; if(!(event_broker_options & BROKER_DOWNTIME_DATA)) return; /* fill struct with relevant data */ ds.type=type; ds.flags=flags; ds.attr=attr; ds.timestamp=get_broker_timestamp(timestamp); ds.downtime_type=downtime_type; ds.host_name=host_name; ds.service_description=svc_description; ds.entry_time=entry_time; ds.author_name=author_name; ds.comment_data=comment_data; ds.start_time=start_time; ds.end_time=end_time; ds.fixed=fixed; ds.duration=duration; ds.triggered_by=triggered_by; ds.downtime_id=downtime_id; /* make callbacks */ neb_make_callbacks(NEBCALLBACK_DOWNTIME_DATA,(void *)&ds); return; } /* send flapping data to broker */ void broker_flapping_data(int type, int flags, int attr, int flapping_type, void *data, double percent_change, double high_threshold, double low_threshold, struct timeval *timestamp){ nebstruct_flapping_data ds; host *temp_host=NULL; service *temp_service=NULL; if(!(event_broker_options & BROKER_FLAPPING_DATA)) return; if(data==NULL) return; /* fill struct with relevant data */ ds.type=type; ds.flags=flags; ds.attr=attr; ds.timestamp=get_broker_timestamp(timestamp); ds.flapping_type=flapping_type; if(flapping_type==SERVICE_FLAPPING){ temp_service=(service *)data; ds.host_name=temp_service->host_name; ds.service_description=temp_service->description; ds.comment_id=temp_service->flapping_comment_id; } else{ temp_host=(host *)data; ds.host_name=temp_host->name; ds.service_description=NULL; ds.comment_id=temp_host->flapping_comment_id; } ds.percent_change=percent_change; ds.high_threshold=high_threshold; ds.low_threshold=low_threshold; /* make callbacks */ neb_make_callbacks(NEBCALLBACK_FLAPPING_DATA,(void *)&ds); return; } /* sends program status updates to broker */ void broker_program_status(int type, int flags, int attr, struct timeval *timestamp){ nebstruct_program_status_data ds; if(!(event_broker_options & BROKER_STATUS_DATA)) return; /* fill struct with relevant data */ ds.type=type; ds.flags=flags; ds.attr=attr; ds.timestamp=get_broker_timestamp(timestamp); ds.program_start=program_start; ds.pid=nagios_pid; ds.daemon_mode=daemon_mode; ds.last_command_check=last_command_check; ds.last_log_rotation=last_log_rotation; ds.notifications_enabled=enable_notifications; ds.active_service_checks_enabled=execute_service_checks; ds.passive_service_checks_enabled=accept_passive_service_checks; ds.active_host_checks_enabled=execute_host_checks; ds.passive_host_checks_enabled=accept_passive_host_checks; ds.event_handlers_enabled=enable_event_handlers; ds.flap_detection_enabled=enable_flap_detection; ds.failure_prediction_enabled=enable_failure_prediction; ds.process_performance_data=process_performance_data; ds.obsess_over_hosts=obsess_over_hosts; ds.obsess_over_services=obsess_over_services; ds.modified_host_attributes=modified_host_process_attributes; ds.modified_service_attributes=modified_service_process_attributes; ds.global_host_event_handler=global_host_event_handler; ds.global_service_event_handler=global_service_event_handler; /* make callbacks */ neb_make_callbacks(NEBCALLBACK_PROGRAM_STATUS_DATA,(void *)&ds); return; } /* sends host status updates to broker */ void broker_host_status(int type, int flags, int attr, host *hst, struct timeval *timestamp){ nebstruct_host_status_data ds; if(!(event_broker_options & BROKER_STATUS_DATA)) return; /* fill struct with relevant data */ ds.type=type; ds.flags=flags; ds.attr=attr; ds.timestamp=get_broker_timestamp(timestamp); ds.object_ptr=(void *)hst; /* make callbacks */ neb_make_callbacks(NEBCALLBACK_HOST_STATUS_DATA,(void *)&ds); return; } /* sends service status updates to broker */ void broker_service_status(int type, int flags, int attr, service *svc, struct timeval *timestamp){ nebstruct_service_status_data ds; if(!(event_broker_options & BROKER_STATUS_DATA)) return; /* fill struct with relevant data */ ds.type=type; ds.flags=flags; ds.attr=attr; ds.timestamp=get_broker_timestamp(timestamp); ds.object_ptr=(void *)svc; /* make callbacks */ neb_make_callbacks(NEBCALLBACK_SERVICE_STATUS_DATA,(void *)&ds); return; } /* send notification data to broker */ void broker_notification_data(int type, int flags, int attr, int notification_type, int reason_type, struct timeval start_time, struct timeval end_time, void *data, char *ack_author, char *ack_data, int escalated, int contacts_notified, struct timeval *timestamp){ nebstruct_notification_data ds; host *temp_host=NULL; service *temp_service=NULL; if(!(event_broker_options & BROKER_NOTIFICATIONS)) return; /* fill struct with relevant data */ ds.type=type; ds.flags=flags; ds.attr=attr; ds.timestamp=get_broker_timestamp(timestamp); ds.notification_type=notification_type; ds.start_time=start_time; ds.end_time=end_time; ds.reason_type=reason_type; if(notification_type==SERVICE_NOTIFICATION){ temp_service=(service *)data; ds.host_name=temp_service->host_name; ds.service_description=temp_service->description; ds.state=temp_service->current_state; ds.output=temp_service->plugin_output; } else{ temp_host=(host *)data; ds.host_name=temp_host->name; ds.service_description=NULL; ds.state=temp_host->current_state; ds.output=temp_host->plugin_output; } ds.ack_author=ack_author; ds.ack_data=ack_data; ds.escalated=escalated; ds.contacts_notified=contacts_notified; /* make callbacks */ neb_make_callbacks(NEBCALLBACK_NOTIFICATION_DATA,(void *)&ds); return; } /* send contact notification data to broker */ void broker_contact_notification_data(int type, int flags, int attr, int notification_type, int reason_type, struct timeval start_time, struct timeval end_time, void *data, contact *cntct, char *ack_author, char *ack_data, int escalated, struct timeval *timestamp){ nebstruct_contact_notification_data ds; host *temp_host=NULL; service *temp_service=NULL; if(!(event_broker_options & BROKER_NOTIFICATIONS)) return; /* fill struct with relevant data */ ds.type=type; ds.flags=flags; ds.attr=attr; ds.timestamp=get_broker_timestamp(timestamp); ds.notification_type=notification_type; ds.start_time=start_time; ds.end_time=end_time; ds.reason_type=reason_type; ds.contact_name=cntct->name; if(notification_type==SERVICE_NOTIFICATION){ temp_service=(service *)data; ds.host_name=temp_service->host_name; ds.service_description=temp_service->description; ds.state=temp_service->current_state; ds.output=temp_service->plugin_output; } else{ temp_host=(host *)data; ds.host_name=temp_host->name; ds.service_description=NULL; ds.state=temp_host->current_state; ds.output=temp_host->plugin_output; } ds.ack_author=ack_author; ds.ack_data=ack_data; ds.escalated=escalated; /* make callbacks */ neb_make_callbacks(NEBCALLBACK_CONTACT_NOTIFICATION_DATA,(void *)&ds); return; } /* send contact notification data to broker */ void broker_contact_notification_method_data(int type, int flags, int attr, int notification_type, int reason_type, struct timeval start_time, struct timeval end_time, void *data, contact *cntct, char *command, char *ack_author, char *ack_data, int escalated, struct timeval *timestamp){ nebstruct_contact_notification_method_data ds; host *temp_host=NULL; service *temp_service=NULL; char *command_buf=NULL; char *command_name=NULL; char *command_args=NULL; if(!(event_broker_options & BROKER_NOTIFICATIONS)) return; /* get command name/args */ if(command!=NULL){ command_buf=strdup(command); command_name=strtok(command_buf,"!"); command_args=strtok(NULL,"\x0"); } /* fill struct with relevant data */ ds.type=type; ds.flags=flags; ds.attr=attr; ds.timestamp=get_broker_timestamp(timestamp); ds.notification_type=notification_type; ds.start_time=start_time; ds.end_time=end_time; ds.reason_type=reason_type; ds.contact_name=cntct->name; ds.command_name=command_name; ds.command_args=command_args; if(notification_type==SERVICE_NOTIFICATION){ temp_service=(service *)data; ds.host_name=temp_service->host_name; ds.service_description=temp_service->description; ds.state=temp_service->current_state; ds.output=temp_service->plugin_output; } else{ temp_host=(host *)data; ds.host_name=temp_host->name; ds.service_description=NULL; ds.state=temp_host->current_state; ds.output=temp_host->plugin_output; } ds.ack_author=ack_author; ds.ack_data=ack_data; ds.escalated=escalated; /* make callbacks */ neb_make_callbacks(NEBCALLBACK_CONTACT_NOTIFICATION_METHOD_DATA,(void *)&ds); /* free memory */ free(command_buf); return; } /* sends adaptive programs updates to broker */ void broker_adaptive_program_data(int type, int flags, int attr, int command_type, unsigned long modhattr, unsigned long modhattrs, unsigned long modsattr, unsigned long modsattrs, char *gheh, char *gseh, struct timeval *timestamp){ nebstruct_adaptive_program_data ds; if(!(event_broker_options & BROKER_ADAPTIVE_DATA)) return; /* fill struct with relevant data */ ds.type=type; ds.flags=flags; ds.attr=attr; ds.timestamp=get_broker_timestamp(timestamp); ds.command_type=command_type; ds.modified_host_attribute=modhattr; ds.modified_host_attributes=modhattrs; ds.modified_service_attribute=modsattr; ds.modified_service_attributes=modsattrs; ds.global_host_event_handler=gheh; ds.global_service_event_handler=gseh; /* make callbacks */ neb_make_callbacks(NEBCALLBACK_ADAPTIVE_PROGRAM_DATA,(void *)&ds); return; } /* sends adaptive host updates to broker */ void broker_adaptive_host_data(int type, int flags, int attr, host *hst, int command_type, unsigned long modattr, unsigned long modattrs, struct timeval *timestamp){ nebstruct_adaptive_host_data ds; if(!(event_broker_options & BROKER_ADAPTIVE_DATA)) return; /* fill struct with relevant data */ ds.type=type; ds.flags=flags; ds.attr=attr; ds.timestamp=get_broker_timestamp(timestamp); ds.command_type=command_type; ds.modified_attribute=modattr; ds.modified_attributes=modattrs; ds.object_ptr=(void *)hst; /* make callbacks */ neb_make_callbacks(NEBCALLBACK_ADAPTIVE_HOST_DATA,(void *)&ds); return; } /* sends adaptive service updates to broker */ void broker_adaptive_service_data(int type, int flags, int attr, service *svc, int command_type, unsigned long modattr, unsigned long modattrs, struct timeval *timestamp){ nebstruct_adaptive_service_data ds; if(!(event_broker_options & BROKER_ADAPTIVE_DATA)) return; /* fill struct with relevant data */ ds.type=type; ds.flags=flags; ds.attr=attr; ds.timestamp=get_broker_timestamp(timestamp); ds.command_type=command_type; ds.modified_attribute=modattr; ds.modified_attributes=modattrs; ds.object_ptr=(void *)svc; /* make callbacks */ neb_make_callbacks(NEBCALLBACK_ADAPTIVE_SERVICE_DATA,(void *)&ds); return; } /* sends external commands to broker */ void broker_external_command(int type, int flags, int attr, int command_type, time_t entry_time, char *command_string, char *command_args, struct timeval *timestamp){ nebstruct_external_command_data ds; if(!(event_broker_options & BROKER_EXTERNALCOMMAND_DATA)) return; /* fill struct with relevant data */ ds.type=type; ds.flags=flags; ds.attr=attr; ds.timestamp=get_broker_timestamp(timestamp); ds.command_type=command_type; ds.entry_time=entry_time; ds.command_string=command_string; ds.command_args=command_args; /* make callbacks */ neb_make_callbacks(NEBCALLBACK_EXTERNAL_COMMAND_DATA,(void *)&ds); return; } /* brokers aggregated status dumps */ void broker_aggregated_status_data(int type, int flags, int attr, struct timeval *timestamp){ nebstruct_aggregated_status_data ds; if(!(event_broker_options & BROKER_STATUS_DATA)) return; /* fill struct with relevant data */ ds.type=type; ds.flags=flags; ds.attr=attr; ds.timestamp=get_broker_timestamp(timestamp); /* make callbacks */ neb_make_callbacks(NEBCALLBACK_AGGREGATED_STATUS_DATA,(void *)&ds); return; } /* brokers retention data */ void broker_retention_data(int type, int flags, int attr, struct timeval *timestamp){ nebstruct_retention_data ds; if(!(event_broker_options & BROKER_RETENTION_DATA)) return; /* fill struct with relevant data */ ds.type=type; ds.flags=flags; ds.attr=attr; ds.timestamp=get_broker_timestamp(timestamp); /* make callbacks */ neb_make_callbacks(NEBCALLBACK_RETENTION_DATA,(void *)&ds); return; } /* send acknowledgement data to broker */ void broker_acknowledgement_data(int type, int flags, int attr, int acknowledgement_type, void *data, char *ack_author, char *ack_data, int subtype, int notify_contacts, int persistent_comment, struct timeval *timestamp){ nebstruct_acknowledgement_data ds; host *temp_host=NULL; service *temp_service=NULL; if(!(event_broker_options & BROKER_ACKNOWLEDGEMENT_DATA)) return; /* fill struct with relevant data */ ds.type=type; ds.flags=flags; ds.attr=attr; ds.timestamp=get_broker_timestamp(timestamp); ds.acknowledgement_type=acknowledgement_type; if(acknowledgement_type==SERVICE_ACKNOWLEDGEMENT){ temp_service=(service *)data; ds.host_name=temp_service->host_name; ds.service_description=temp_service->description; ds.state=temp_service->current_state; } else{ temp_host=(host *)data; ds.host_name=temp_host->name; ds.service_description=NULL; ds.state=temp_host->current_state; } ds.author_name=ack_author; ds.comment_data=ack_data; ds.is_sticky=(subtype==ACKNOWLEDGEMENT_STICKY)?TRUE:FALSE; ds.notify_contacts=notify_contacts; ds.persistent_comment=persistent_comment; /* make callbacks */ neb_make_callbacks(NEBCALLBACK_ACKNOWLEDGEMENT_DATA,(void *)&ds); return; } /* send state change data to broker */ void broker_statechange_data(int type, int flags, int attr, int statechange_type, void *data, int state, int state_type, int current_attempt, int max_attempts, struct timeval *timestamp){ nebstruct_statechange_data ds; host *temp_host=NULL; service *temp_service=NULL; if(!(event_broker_options & BROKER_STATECHANGE_DATA)) return; /* fill struct with relevant data */ ds.type=type; ds.flags=flags; ds.attr=attr; ds.timestamp=get_broker_timestamp(timestamp); ds.statechange_type=statechange_type; if(statechange_type==SERVICE_STATECHANGE){ temp_service=(service *)data; ds.host_name=temp_service->host_name; ds.service_description=temp_service->description; ds.output=temp_service->plugin_output; } else{ temp_host=(host *)data; ds.host_name=temp_host->name; ds.service_description=NULL; ds.output=temp_host->plugin_output; } ds.state=state; ds.state_type=state_type; ds.current_attempt=current_attempt; ds.max_attempts=max_attempts; /* make callbacks */ neb_make_callbacks(NEBCALLBACK_STATE_CHANGE_DATA,(void *)&ds); return; } /******************************************************************/ /************************ UTILITY FUNCTIONS ***********************/ /******************************************************************/ /* gets timestamp for use by broker */ struct timeval get_broker_timestamp(struct timeval *timestamp){ struct timeval tv; if(timestamp==NULL) gettimeofday(&tv,NULL); else tv=*timestamp; return tv; } #endif nagios-2.6/base/checks.c0000664000076500007650000025442310446114747014537 0ustar nagiosnagios/***************************************************************************** * * CHECKS.C - Service and host check functions for Nagios * * Copyright (c) 1999-2006 Ethan Galstad (nagios@nagios.org) * Last Modified: 06-20-2006 * * 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. * *****************************************************************************/ #include "../include/config.h" #include "../include/common.h" #include "../include/statusdata.h" #include "../include/downtime.h" #include "../include/nagios.h" #include "../include/broker.h" #include "../include/perfdata.h" /*#define DEBUG_CHECKS*/ #ifdef EMBEDDEDPERL #include "../include/epn_nagios.h" #endif extern int sigshutdown; extern int sigrestart; extern char *temp_file; extern int interval_length; extern int command_check_interval; extern int ipc_pipe[2]; extern int log_initial_states; extern int service_check_timeout; extern int host_check_timeout; extern int service_check_reaper_interval; extern int max_check_reaper_time; extern int use_aggressive_host_checking; extern int soft_state_dependencies; extern int currently_running_service_checks; extern int non_parallelized_check_running; extern int accept_passive_service_checks; extern int execute_service_checks; extern int execute_host_checks; extern int obsess_over_services; extern int obsess_over_hosts; extern int check_service_freshness; extern int check_host_freshness; extern time_t program_start; extern timed_event *event_list_low; extern host *host_list; extern service *service_list; extern servicedependency *servicedependency_list; extern hostdependency *hostdependency_list; extern service_message svc_msg; extern pthread_t worker_threads[TOTAL_WORKER_THREADS]; extern circular_buffer service_result_buffer; #ifdef EMBEDDEDPERL extern int use_embedded_perl; #endif /******************************************************************/ /****************** SERVICE MONITORING FUNCTIONS ******************/ /******************************************************************/ /* forks a child process to run a service check, but does not wait for the service check result */ void run_service_check(service *svc){ char raw_command[MAX_COMMAND_BUFFER]; char processed_command[MAX_COMMAND_BUFFER]; char plugin_output[MAX_PLUGINOUTPUT_LENGTH]; char temp_buffer[MAX_INPUT_BUFFER]; int check_service=TRUE; struct timeval start_time,end_time; time_t current_time; time_t preferred_time=0L; time_t next_valid_time; pid_t pid; int fork_error=FALSE; int wait_result=0; host *temp_host=NULL; FILE *fp; int pclose_result=0; int time_is_valid=TRUE; #ifdef EMBEDDEDPERL char fname[512]; char *args[5] = {"",DO_CLEAN, "", "", NULL }; char *perl_plugin_output ; int isperl; SV *plugin_hndlr_cr; STRLEN n_a ; #ifdef aTHX dTHX; #endif dSP; #endif /* get the current time */ time(¤t_time); /* if the service check is currently disabled... */ if(svc->checks_enabled==FALSE){ /* don't check the service if we're not forcing it through */ if(!(svc->check_options & CHECK_OPTION_FORCE_EXECUTION)) check_service=FALSE; /* reschedule the service check */ preferred_time=current_time+(svc->check_interval*interval_length); } /* if the service check should not be checked on a regular interval... */ if(svc->check_interval==0){ /* don't check the service if we're not forcing it through */ if(!(svc->check_options & CHECK_OPTION_FORCE_EXECUTION)) check_service=FALSE; /* don't reschedule the service check */ svc->should_be_scheduled=FALSE; } /* make sure this is a valid time to check the service */ if(check_time_against_period((unsigned long)current_time,svc->check_period)==ERROR){ /* don't check the service if we're not forcing it through */ if(!(svc->check_options & CHECK_OPTION_FORCE_EXECUTION)) check_service=FALSE; /* get the next valid time we can run the check */ preferred_time=current_time; /* set the invalid time flag */ time_is_valid=FALSE; } /* check service dependencies for execution */ if(check_service_dependencies(svc,EXECUTION_DEPENDENCY)==DEPENDENCIES_FAILED){ /* don't check the service if we're not forcing it through */ if(!(svc->check_options & CHECK_OPTION_FORCE_EXECUTION)) check_service=FALSE; /* reschedule the service check */ preferred_time=current_time+(svc->check_interval*interval_length); } /* clear the force execution flag */ if(svc->check_options & CHECK_OPTION_FORCE_EXECUTION) svc->check_options-=CHECK_OPTION_FORCE_EXECUTION; /* find the host associated with this service */ temp_host=find_host(svc->host_name); /* don't check the service if we couldn't find the associated host */ if(temp_host==NULL) check_service=FALSE; /* if we shouldn't check the service, just reschedule it and leave... */ if(check_service==FALSE){ /* only attempt to (re)schedule checks that should get checked... */ if(svc->should_be_scheduled==TRUE){ /* make sure we rescheduled the next service check at a valid time */ get_next_valid_time(preferred_time,&next_valid_time,svc->check_period); /* the service could not be rescheduled properly - set the next check time for next year, but don't actually reschedule it */ if(time_is_valid==FALSE && next_valid_time==preferred_time){ svc->next_check=(time_t)(next_valid_time+(60*60*24*365)); svc->should_be_scheduled=FALSE; #ifdef DEBUG1 printf("Warning: Could not find any valid times to reschedule a check of service '%s' on host '%s'!\n",svc->description,svc->host_name); #endif } /* this service could be rescheduled... */ else{ svc->next_check=next_valid_time; svc->should_be_scheduled=TRUE; } } /* update the status log with the current service */ update_service_status(svc,FALSE); /* reschedule the next service check - unless we couldn't find a valid next check time */ if(svc->should_be_scheduled==TRUE) schedule_service_check(svc,svc->next_check,FALSE); return; } /**** ELSE RUN THE SERVICE CHECK ****/ #ifdef DEBUG3 printf("\tChecking service '%s' on host '%s'...\n",svc->description,svc->host_name); #endif /* increment number of parallel service checks currently out there... */ currently_running_service_checks++; /* set a flag if this service check shouldn't be parallelized with others... */ if(svc->parallelize==FALSE) non_parallelized_check_running=TRUE; /* set the execution flag */ svc->is_executing=TRUE; /* grab the host and service macro variables */ clear_volatile_macros(); grab_host_macros(temp_host); grab_service_macros(svc); grab_summary_macros(NULL); /* get the raw command line */ get_raw_command_line(svc->service_check_command,raw_command,sizeof(raw_command),0); strip(raw_command); /* process any macros contained in the argument */ process_macros(raw_command,processed_command,sizeof(processed_command),0); strip(processed_command); /* get the command start time */ gettimeofday(&start_time,NULL); /* save service info */ strncpy(svc_msg.host_name,svc->host_name,sizeof(svc_msg.host_name)-1); svc_msg.host_name[sizeof(svc_msg.host_name)-1]='\x0'; strncpy(svc_msg.description,svc->description,sizeof(svc_msg.description)-1); svc_msg.description[sizeof(svc_msg.description)-1]='\x0'; svc_msg.parallelized=svc->parallelize; svc_msg.start_time=start_time; svc_msg.finish_time=start_time; svc_msg.early_timeout=FALSE; #ifdef USE_EVENT_BROKER /* send data to event broker */ end_time.tv_sec=0L; end_time.tv_usec=0L; broker_service_check(NEBTYPE_SERVICECHECK_INITIATE,NEBFLAG_NONE,NEBATTR_NONE,svc,SERVICE_CHECK_ACTIVE,start_time,end_time,svc->service_check_command,svc->latency,0.0,0,FALSE,0,processed_command,NULL); #endif #ifdef EMBEDDEDPERL strncpy(fname,processed_command,strcspn(processed_command," ")); fname[strcspn(processed_command," ")] = '\x0'; /* have "filename" component of command. Check for PERL */ fp=fopen(fname, "r"); if(fp==NULL) strcpy(raw_command,""); else{ fgets(raw_command,80,fp); fclose(fp); } isperl=FALSE; if(strstr(raw_command,"/bin/perl")!=NULL){ isperl = TRUE; args[0] = fname; args[2] = ""; if(strchr(processed_command,' ')==NULL) args[3]=""; else args[3]=processed_command+strlen(fname)+1; ENTER; SAVETMPS; PUSHMARK(SP); XPUSHs(sv_2mortal(newSVpv(args[0],0))); XPUSHs(sv_2mortal(newSVpv(args[1],0))); XPUSHs(sv_2mortal(newSVpv(args[2],0))); XPUSHs(sv_2mortal(newSVpv(args[3],0))); PUTBACK; /* call our perl interpreter to compile and optionally cache the command */ call_pv("Embed::Persistent::eval_file", G_SCALAR | G_EVAL); SPAGAIN ; if ( SvTRUE(ERRSV) ) { /* * if SvTRUE(ERRSV) * write failure to IPC pipe * return */ /* remove the top element of the Perl stack (undef) */ (void) POPs ; pclose_result=STATE_UNKNOWN; perl_plugin_output=SvPVX(ERRSV); strip(perl_plugin_output); #ifdef DEBUG1 printf("embedded perl failed to compile %s, compile error %s - skipping plugin\n",fname,perl_plugin_output); #endif /* get the check finish time */ gettimeofday(&end_time,NULL); /* record check result info */ strncpy(svc_msg.output,perl_plugin_output,sizeof(svc_msg.output)-1); svc_msg.output[sizeof(svc_msg.output)-1]='\x0'; svc_msg.return_code=pclose_result; svc_msg.exited_ok=TRUE; svc_msg.check_type=SERVICE_CHECK_ACTIVE; svc_msg.finish_time=end_time; svc_msg.early_timeout=FALSE; /* write check results to message queue */ write_svc_message(&svc_msg); return ; } else{ plugin_hndlr_cr=newSVsv(POPs); #ifdef DEBUG1 printf("embedded perl successfully compiled %s and returned code ref to plugin handler\n",fname); #endif PUTBACK ; FREETMPS ; LEAVE ; } } #endif /* plugin is a C plugin or a Perl plugin _without_ compilation errors */ /* fork a child process */ pid=fork(); /* an error occurred while trying to fork */ if(pid==-1) fork_error=TRUE; /* if we are in the child process... */ else if(pid==0){ /* set environment variables */ set_all_macro_environment_vars(TRUE); #ifndef USE_MEMORY_PERFORMANCE_TWEAKS /* free allocated memory */ free_memory(); #endif /* fork again... */ pid=fork(); /* an error occurred while trying to fork again */ if(pid==-1) exit(STATE_UNKNOWN); /* the grandchild process should run the service check... */ if(pid==0){ /* reset signal handling */ reset_sighandler(); /* become the process group leader */ setpgid(0,0); /* close read end of IPC pipe */ close(ipc_pipe[0]); /* catch plugins that don't finish in a timely manner */ signal(SIGALRM,service_check_sighandler); alarm(service_check_timeout); /******** BEGIN EMBEDDED PERL INTERPRETER EXECUTION ********/ #ifdef EMBEDDEDPERL if(isperl){ int count ; /* execute our previously compiled script - from call_pv("Embed::Persistent::eval_file",..) */ /* NB. args[2] is _now_ a code ref (to the Perl subroutine corresp to the plugin) returned by eval_file() */ ENTER; SAVETMPS; PUSHMARK(SP); XPUSHs(sv_2mortal(newSVpv(args[0],0))); XPUSHs(sv_2mortal(newSVpv(args[1],0))); XPUSHs(plugin_hndlr_cr); XPUSHs(sv_2mortal(newSVpv(args[3],0))); PUTBACK; count=call_pv("Embed::Persistent::run_package", G_ARRAY); SPAGAIN; perl_plugin_output=POPpx; strip(perl_plugin_output); strncpy(plugin_output, perl_plugin_output, sizeof(plugin_output)); perl_plugin_output[sizeof(perl_plugin_output)-1]='\x0'; pclose_result=POPi; PUTBACK; FREETMPS; LEAVE; #ifdef DEBUG1 printf("embedded perl ran %s, plugin output was %d, %s\n",fname, pclose_result, plugin_output); #endif /* reset the alarm */ alarm(0); /* get the check finish time */ gettimeofday(&end_time,NULL); /* record check result info */ strncpy(svc_msg.output,plugin_output,sizeof(svc_msg.output)-1); svc_msg.output[sizeof(svc_msg.output)-1]='\x0'; svc_msg.return_code=pclose_result; svc_msg.exited_ok=TRUE; svc_msg.check_type=SERVICE_CHECK_ACTIVE; svc_msg.finish_time=end_time; svc_msg.early_timeout=FALSE; /* write check results to message queue */ write_svc_message(&svc_msg); /* close write end of IPC pipe */ close(ipc_pipe[1]); /* return with plugin exit status - not really necessary... */ _exit(pclose_result); } /* Not a perl command. Use popen... */ #endif /******** END EMBEDDED PERL INTERPRETER EXECUTION ********/ /* run the plugin check command */ fp=popen(processed_command,"r"); if(fp==NULL) _exit(STATE_UNKNOWN); /* default return string in case nothing was returned */ strcpy(plugin_output,"(No output!)"); /* grab the plugin output and clean it */ fgets(plugin_output,sizeof(plugin_output)-1,fp); strip(plugin_output); /* ADDED 01/04/2004 */ /* ignore any additional lines of output */ while(fgets(temp_buffer,sizeof(temp_buffer)-1,fp)); /* close the process */ pclose_result=pclose(fp); /* reset the alarm */ alarm(0); /* get the check finish time */ gettimeofday(&end_time,NULL); /* record check result info */ strncpy(svc_msg.output,plugin_output,sizeof(svc_msg.output)-1); svc_msg.output[sizeof(svc_msg.output)-1]='\x0'; svc_msg.return_code=WEXITSTATUS(pclose_result); svc_msg.exited_ok=TRUE; svc_msg.check_type=SERVICE_CHECK_ACTIVE; svc_msg.finish_time=end_time; svc_msg.early_timeout=FALSE; /* test for execution error */ if(pclose_result==-1){ pclose_result=STATE_UNKNOWN; strncpy(svc_msg.output,"(Error returned by call to pclose() function)",sizeof(svc_msg.output)-1); svc_msg.output[sizeof(svc_msg.output)-1]='\x0'; svc_msg.return_code=STATE_CRITICAL; svc_msg.exited_ok=FALSE; svc_msg.early_timeout=FALSE; } /* write check result to message queue */ write_svc_message(&svc_msg); /* close write end of IPC pipe */ close(ipc_pipe[1]); /* return with plugin exit status - not really necessary... */ _exit(pclose_result); } /* close write end of IPC pipe */ close(ipc_pipe[1]); /* unset environment variables */ set_all_macro_environment_vars(FALSE); /* parent exits immediately - grandchild process is inherited by the INIT process, so we have no zombie problem... */ _exit(STATE_OK); } /* else the parent should wait for the first child to return... */ else if(pid>0){ wait_result=waitpid(pid,NULL,0); /* removed 06/28/2000 - caused problems under AIX */ /* result=WEXITSTATUS(wait_result); if(result==STATE_UNKNOWN) fork_error=TRUE; */ } /* see if we could run the check... */ if(fork_error==TRUE){ /* log an error */ snprintf(temp_buffer,sizeof(temp_buffer),"Warning: The check of service '%s' on host '%s' could not be performed due to a fork() error. The check will be rescheduled.\n",svc_msg.description,svc_msg.host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_RUNTIME_WARNING,TRUE); /* make sure we rescheduled the next service check at a valid time */ preferred_time=current_time; get_next_valid_time(preferred_time,&next_valid_time,svc->check_period); /* the service could not be rescheduled properly - set the next check time for next year, but don't actually reschedule it */ if(time_is_valid==FALSE && next_valid_time==preferred_time){ svc->next_check=(time_t)(next_valid_time+(60*60*24*365)); svc->should_be_scheduled=FALSE; #ifdef DEBUG1 printf("Warning: Could not find any valid times to reschedule a check of service '%s' on host '%s'!\n",svc->description,svc->host_name); #endif } /* this service could be rescheduled... */ else{ svc->next_check=next_valid_time; /* only reschedule checks with recurring intervals */ if(svc->check_interval==0) svc->should_be_scheduled=FALSE; else svc->should_be_scheduled=TRUE; } /* update the status log with the current service */ update_service_status(svc,FALSE); /* reschedule the next service check - unless we couldn't find a valid next check time */ if(svc->should_be_scheduled==TRUE) schedule_service_check(svc,svc->next_check,FALSE); } return; } /* reaps service check results */ void reap_service_checks(void){ service_message queued_svc_msg; service *temp_service=NULL; host *temp_host=NULL; time_t preferred_time; time_t next_valid_time; char temp_buffer[MAX_INPUT_BUFFER]; int state_change=FALSE; int hard_state_change=FALSE; int route_result=HOST_UP; int dependency_result=DEPENDENCIES_OK; time_t current_time; int first_check=FALSE; int state_was_logged=FALSE; char old_plugin_output[MAX_PLUGINOUTPUT_LENGTH]=""; char temp_plugin_output[MAX_PLUGINOUTPUT_LENGTH]=""; char *temp_ptr; time_t reaper_start_time; struct timeval tv; #ifdef DEBUG0 printf("reap_service_checks() start\n"); #endif #ifdef DEBUG3 printf("Starting to reap service check results...\n"); #endif time(&reaper_start_time); /* read all service checks results that have come in... */ while(read_svc_message(&queued_svc_msg)!=-1){ /* make sure we really have something... */ if(!strcmp(queued_svc_msg.description,"") && !strcmp(queued_svc_msg.host_name,"")){ #ifdef DEBUG1 printf("Found an empty message in service result pipe!\n"); #endif continue; } /* get the current time */ time(¤t_time); /* skip this service check results if its passive and we aren't accepting passive check results */ if(accept_passive_service_checks==FALSE && queued_svc_msg.check_type==SERVICE_CHECK_PASSIVE) continue; /* because of my idiotic idea of having UNKNOWN states be equivalent to -1, I must hack things a bit... */ if(queued_svc_msg.return_code==255 || queued_svc_msg.return_code==-1) queued_svc_msg.return_code=STATE_UNKNOWN; /* find the service */ temp_service=find_service(queued_svc_msg.host_name,queued_svc_msg.description); if(temp_service==NULL){ snprintf(temp_buffer,sizeof(temp_buffer),"Warning: Message queue contained results for service '%s' on host '%s'. The service could not be found!\n",queued_svc_msg.description,queued_svc_msg.host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_RUNTIME_WARNING,TRUE); continue; } /* calculate passive check latency */ if(queued_svc_msg.check_type==SERVICE_CHECK_PASSIVE){ gettimeofday(&tv,NULL); temp_service->latency=(double)((double)(tv.tv_sec-queued_svc_msg.finish_time.tv_sec)+(double)((tv.tv_usec-queued_svc_msg.finish_time.tv_usec)/1000.0)); if(temp_service->latency<0.0) temp_service->latency=0.0; } /* update the execution time for this check (millisecond resolution) */ temp_service->execution_time=(double)((double)(queued_svc_msg.finish_time.tv_sec-queued_svc_msg.start_time.tv_sec)+(double)((queued_svc_msg.finish_time.tv_usec-queued_svc_msg.start_time.tv_usec)/1000)/1000.0); #ifdef REMOVED_050803 if(queued_svc_msg.start_time.time>current_time || queued_svc_msg.finish_time.time>current_time || (queued_svc_msg.finish_time.timeexecution_time=0.0; else temp_service->execution_time=(double)((double)(queued_svc_msg.finish_time.time-queued_svc_msg.start_time.time)+(double)((queued_svc_msg.finish_time.millitm-queued_svc_msg.start_time.millitm)/1000.0)); #endif /* clear the freshening flag (it would have been set if this service was determined to be stale) */ temp_service->is_being_freshened=FALSE; /* ignore passive service check results if we're not accepting them for this service */ if(temp_service->accept_passive_service_checks==FALSE && queued_svc_msg.check_type==SERVICE_CHECK_PASSIVE) continue; #ifdef DEBUG3 printf("\n\tFound check result for service '%s' on host '%s'\n",temp_service->description,temp_service->host_name); printf("\t\tCheck Type: %s\n",(queued_svc_msg.check_type==SERVICE_CHECK_ACTIVE)?"ACTIVE":"PASSIVE"); printf("\t\tParallelized?: %s\n",(queued_svc_msg.parallelized==TRUE)?"Yes":"No"); printf("\t\tExited OK?: %s\n",(queued_svc_msg.exited_ok==TRUE)?"Yes":"No"); printf("\t\tReturn Status: %d\n",queued_svc_msg.return_code); printf("\t\tPlugin Output: '%s'\n",queued_svc_msg.output); #endif /* decrement the number of service checks still out there... */ if(queued_svc_msg.check_type==SERVICE_CHECK_ACTIVE && currently_running_service_checks>0) currently_running_service_checks--; /* if this check was not parallelized, clear the flag */ if(queued_svc_msg.parallelized==FALSE && queued_svc_msg.check_type==SERVICE_CHECK_ACTIVE) non_parallelized_check_running=FALSE; /* clear the execution flag if this was an active check */ if(queued_svc_msg.check_type==SERVICE_CHECK_ACTIVE) temp_service->is_executing=FALSE; /* get the last check time */ temp_service->last_check=queued_svc_msg.start_time.tv_sec; #ifdef REMOVED_050803 temp_service->last_check=queued_svc_msg.start_time.time; #endif /* was this check passive or active? */ temp_service->check_type=(queued_svc_msg.check_type==SERVICE_CHECK_ACTIVE)?SERVICE_CHECK_ACTIVE:SERVICE_CHECK_PASSIVE; /* INITIALIZE VARIABLES FOR THIS SERVICE */ state_change=FALSE; hard_state_change=FALSE; route_result=HOST_UP; dependency_result=DEPENDENCIES_OK; first_check=FALSE; state_was_logged=FALSE; strcpy(old_plugin_output,""); strcpy(temp_plugin_output,""); /* save the old service status info */ temp_service->last_state=temp_service->current_state; /* save old plugin output */ strncpy(old_plugin_output,(temp_service->plugin_output==NULL)?"":temp_service->plugin_output,sizeof(old_plugin_output)-1); old_plugin_output[sizeof(old_plugin_output)-1]='\x0'; /* clear the old plugin output and perf data buffers */ strcpy(temp_service->plugin_output,""); strcpy(temp_service->perf_data,""); /* check for empty plugin output */ if(!strcmp(temp_plugin_output,"")) strcpy(temp_plugin_output,"(No output returned from plugin)"); /* get performance data (if it exists) */ strncpy(temp_plugin_output,queued_svc_msg.output,sizeof(temp_plugin_output)-1); temp_plugin_output[sizeof(temp_plugin_output)-1]='\x0'; temp_ptr=strtok(temp_plugin_output,"|\n"); temp_ptr=strtok(NULL,"\n"); if(temp_ptr!=NULL){ strip(temp_ptr); strncpy(temp_service->perf_data,temp_ptr,MAX_PLUGINOUTPUT_LENGTH-1); temp_service->perf_data[MAX_PLUGINOUTPUT_LENGTH-1]='\x0'; } /* get status data - everything before pipe sign */ strncpy(temp_plugin_output,queued_svc_msg.output,sizeof(temp_plugin_output)-1); temp_plugin_output[sizeof(temp_plugin_output)-1]='\x0'; temp_ptr=strtok(temp_plugin_output,"|\n"); /* if there was some error running the command, just skip it (this shouldn't be happening) */ if(queued_svc_msg.exited_ok==FALSE){ snprintf(temp_buffer,sizeof(temp_buffer),"Warning: Check of service '%s' on host '%s' did not exit properly!\n",temp_service->description,temp_service->host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_RUNTIME_WARNING,TRUE); snprintf(temp_service->plugin_output,MAX_PLUGINOUTPUT_LENGTH-1,"(Service check did not exit properly)"); temp_service->plugin_output[MAX_PLUGINOUTPUT_LENGTH-1]='\x0'; temp_service->current_state=STATE_CRITICAL; } /* make sure the return code is within bounds */ else if(queued_svc_msg.return_code<0 || queued_svc_msg.return_code>3){ snprintf(temp_buffer,sizeof(temp_buffer),"Warning: Return code of %d for check of service '%s' on host '%s' was out of bounds.%s\n",queued_svc_msg.return_code,temp_service->description,temp_service->host_name,(queued_svc_msg.return_code==126 || queued_svc_msg.return_code==127)?" Make sure the plugin you're trying to run actually exists.":""); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_RUNTIME_WARNING,TRUE); snprintf(temp_service->plugin_output,MAX_PLUGINOUTPUT_LENGTH-1,"(Return code of %d is out of bounds%s)",queued_svc_msg.return_code,(queued_svc_msg.return_code==126 || queued_svc_msg.return_code==127)?" - plugin may be missing":""); temp_service->plugin_output[MAX_PLUGINOUTPUT_LENGTH-1]='\x0'; temp_service->current_state=STATE_CRITICAL; } /* else the return code is okay... */ else{ /* make sure the plugin output isn't null */ if(temp_ptr==NULL){ strncpy(temp_service->plugin_output,"(No output returned from plugin)",MAX_PLUGINOUTPUT_LENGTH-1); temp_service->plugin_output[MAX_PLUGINOUTPUT_LENGTH-1]='\x0'; } /* grab the plugin output */ else{ strip(temp_ptr); if(!strcmp(temp_ptr,"")) strncpy(temp_service->plugin_output,"(No output returned from plugin)",MAX_PLUGINOUTPUT_LENGTH-1); else strncpy(temp_service->plugin_output,temp_ptr,MAX_PLUGINOUTPUT_LENGTH-1); temp_service->plugin_output[MAX_PLUGINOUTPUT_LENGTH-1]='\x0'; } /* replace semicolons in plugin output (but not performance data) with colons */ temp_ptr=temp_service->plugin_output; while((temp_ptr=strchr(temp_ptr,';'))) *temp_ptr=':'; /* grab the return code */ temp_service->current_state=queued_svc_msg.return_code; } /* record the last state time */ switch(temp_service->current_state){ case STATE_OK: temp_service->last_time_ok=temp_service->last_check; break; case STATE_WARNING: temp_service->last_time_warning=temp_service->last_check; break; case STATE_UNKNOWN: temp_service->last_time_unknown=temp_service->last_check; break; case STATE_CRITICAL: temp_service->last_time_critical=temp_service->last_check; break; default: break; } /* get the host that this service runs on */ temp_host=find_host(temp_service->host_name); /* if the service check was okay... */ if(temp_service->current_state==STATE_OK){ /* if the host has never been checked before... */ if(temp_host->has_been_checked==FALSE){ /* verify the host status */ verify_route_to_host(temp_host,CHECK_OPTION_NONE); #ifdef REMOVED_080303 /* really check the host status if we're using aggressive host checking */ if(use_aggressive_host_checking==TRUE) verify_route_to_host(temp_host,CHECK_OPTION_NONE); /* else let's just assume the host is up... */ else{ /* set the checked flag */ temp_host->has_been_checked=TRUE; /* update the last check time */ temp_host->last_check=temp_service->last_check; /* set the host state and check types */ temp_host->current_state=HOST_UP; temp_host->current_attempt=1; temp_host->state_type=HARD_STATE; temp_host->check_type=HOST_CHECK_ACTIVE; /* plugin output should reflect our guess at the current host state */ strncpy(temp_host->plugin_output,"(Host assumed to be up)",MAX_PLUGINOUTPUT_LENGTH); temp_host->plugin_output[MAX_PLUGINOUTPUT_LENGTH-1]='\x0'; /* should we be calling handle_host_state() here? probably not, but i'm not sure at the present time - 02/18/03 */ /* update the status log with the host status */ update_host_status(temp_host,FALSE); #ifdef REMOVED_042903 /* log the initial state if the user wants */ if(log_initial_states==TRUE) log_host_event(temp_host); #endif } #endif } #ifdef REMOVED_042903 /* log the initial state if the user wants */ if(temp_service->has_been_checked==FALSE && log_initial_states==TRUE){ log_service_event(temp_service); state_was_logged=TRUE; } #endif } /**** NOTE - THIS WAS MOVED UP FROM LINE 1049 BELOW TO FIX PROBLEMS WHERE CURRENT ATTEMPT VALUE WAS ACTUALLY "LEADING" REAL VALUE ****/ /* increment the current attempt number if this is a soft state (service was rechecked) */ if(temp_service->state_type==SOFT_STATE && (temp_service->current_attempt < temp_service->max_attempts)) temp_service->current_attempt=temp_service->current_attempt+1; #ifdef DEBUG_CHECKS printf("SERVICE '%s' on HOST '%s'\n",temp_service->description,temp_service->host_name); printf("%s",ctime(&temp_service->last_check)); printf("\tST: %s CA: %d MA: %d CS: %d LS: %d LHS: %d\n",(temp_service->state_type==SOFT_STATE)?"SOFT":"HARD",temp_service->current_attempt,temp_service->max_attempts,temp_service->current_state,temp_service->last_state,temp_service->last_hard_state); #endif /* check for a state change (either soft or hard) */ if(temp_service->current_state!=temp_service->last_state){ #ifdef DEBUG3 printf("\t\tService '%s' on host '%s' has changed state since last check!\n",temp_service->description,temp_service->host_name); #endif state_change=TRUE; #ifdef DEBUG_CHECKS printf("\tSTATE CHANGE\n"); #endif } /* checks for a hard state change where host was down at last service check */ /* this occurs in the case where host goes down and service current attempt gets reset to 1 */ /* if this check is not made, the service recovery looks like a soft recovery instead of a hard one */ if(temp_service->host_problem_at_last_check==TRUE && temp_service->current_state==STATE_OK){ #ifdef DEBUG3 printf("\t\tService '%s' on host '%s' has had a HARD STATE CHANGE!!\n",temp_service->description,temp_service->host_name); #endif hard_state_change=TRUE; #ifdef DEBUG_CHECKS printf("\tHARD STATE CHANGE A\n"); #endif } /* check for a "normal" hard state change where max check attempts is reached */ if(temp_service->current_attempt>=temp_service->max_attempts && temp_service->current_state!=temp_service->last_hard_state){ #ifdef DEBUG3 printf("\t\tService '%s' on host '%s' has had a HARD STATE CHANGE!!\n",temp_service->description,temp_service->host_name); #endif hard_state_change=TRUE; #ifdef DEBUG_CHECKS printf("\tHARD STATE CHANGE B\n"); #endif } /* reset last and next notification times and acknowledgement flag if necessary */ if(state_change==TRUE || hard_state_change==TRUE){ /* reset notification times */ temp_service->last_notification=(time_t)0; temp_service->next_notification=(time_t)0; /* reset notification suppression option */ temp_service->no_more_notifications=FALSE; if(temp_service->acknowledgement_type==ACKNOWLEDGEMENT_NORMAL){ temp_service->problem_has_been_acknowledged=FALSE; temp_service->acknowledgement_type=ACKNOWLEDGEMENT_NONE; } else if(temp_service->acknowledgement_type==ACKNOWLEDGEMENT_STICKY && temp_service->current_state==STATE_OK){ temp_service->problem_has_been_acknowledged=FALSE; temp_service->acknowledgement_type=ACKNOWLEDGEMENT_NONE; } /* do NOT reset current notification number!!! */ /* hard changes between non-OK states should continue to be escalated, so don't reset current notification number */ /*temp_service->current_notification_number=0;*/ } /* initialize the last host and service state change times if necessary */ if(temp_service->last_state_change==(time_t)0) temp_service->last_state_change=temp_service->last_check; if(temp_service->last_hard_state_change==(time_t)0) temp_service->last_hard_state_change=temp_service->last_check; if(temp_host->last_state_change==(time_t)0) temp_host->last_state_change=temp_service->last_check; if(temp_host->last_hard_state_change==(time_t)0) temp_host->last_hard_state_change=temp_service->last_check; /* update last service state change times */ if(state_change==TRUE) temp_service->last_state_change=temp_service->last_check; if(hard_state_change==TRUE) temp_service->last_hard_state_change=temp_service->last_check; /**************************************/ /******* SERVICE CHECK OK LOGIC *******/ /**************************************/ /* if the service is up and running OK... */ if(temp_service->current_state==STATE_OK){ /* reset the acknowledgement flag (this should already have been done, but just in case...) */ temp_service->problem_has_been_acknowledged=FALSE; temp_service->acknowledgement_type=ACKNOWLEDGEMENT_NONE; #ifdef DEBUG_CHECKS printf("\tOriginally OK\n"); #endif /* the service check was okay, so the associated host must be up... */ if(temp_host->current_state!=HOST_UP){ #ifdef DEBUG_CHECKS printf("\tSECTION A1\n"); #endif /* verify the route to the host and send out host recovery notifications */ verify_route_to_host(temp_host,CHECK_OPTION_NONE); #ifdef REMOVED_041403 /* set the host problem flag (i.e. don't notify about recoveries for this service) */ temp_service->host_problem_at_last_check=TRUE; #endif } /* if a hard service recovery has occurred... */ if(hard_state_change==TRUE){ #ifdef DEBUG_CHECKS printf("\tSECTION A2\n"); #endif /* set the state type macro */ temp_service->state_type=HARD_STATE; /* log the service recovery */ log_service_event(temp_service); state_was_logged=TRUE; /* notify contacts about the service recovery */ service_notification(temp_service,NOTIFICATION_NORMAL,NULL,NULL); /* run the service event handler to handle the hard state change */ handle_service_event(temp_service); } /* else if a soft service recovery has occurred... */ else if(state_change==TRUE){ #ifdef DEBUG_CHECKS printf("\tSECTION A3\n"); #endif /* this is a soft recovery */ temp_service->state_type=SOFT_STATE; /* log the soft recovery */ log_service_event(temp_service); state_was_logged=TRUE; /* run the service event handler to handle the soft state change */ handle_service_event(temp_service); } /* else no service state change has occurred... */ /* should we obsessive over service checks? */ if(obsess_over_services==TRUE) obsessive_compulsive_service_check_processor(temp_service); /* reset all service variables because its okay now... */ temp_service->host_problem_at_last_check=FALSE; #ifdef REMOVED_041403 temp_service->no_recovery_notification=FALSE; #endif temp_service->current_attempt=1; temp_service->state_type=HARD_STATE; temp_service->last_hard_state=STATE_OK; temp_service->last_notification=(time_t)0; temp_service->next_notification=(time_t)0; temp_service->current_notification_number=0; temp_service->problem_has_been_acknowledged=FALSE; temp_service->acknowledgement_type=ACKNOWLEDGEMENT_NONE; temp_service->notified_on_unknown=FALSE; temp_service->notified_on_warning=FALSE; temp_service->notified_on_critical=FALSE; temp_service->no_more_notifications=FALSE; if(temp_service->check_type==SERVICE_CHECK_ACTIVE) temp_service->next_check=(time_t)(temp_service->last_check+(temp_service->check_interval*interval_length)); } /*******************************************/ /******* SERVICE CHECK PROBLEM LOGIC *******/ /*******************************************/ /* hey, something's not working quite like it should... */ else{ #ifdef DEBUG_CHECKS printf("\tOriginally PROBLEM\n"); #endif #ifdef REMOVED_041403 /* reset the recovery notification flag (it may get set again though) */ temp_service->no_recovery_notification=FALSE; #endif /* check the route to the host if its supposed to be up right now... */ if(temp_host->current_state==HOST_UP){ route_result=verify_route_to_host(temp_host,CHECK_OPTION_NONE); #ifdef DEBUG_CHECKS printf("\tSECTION B1\n"); #endif } /* else the host is either down or unreachable, so recheck it if necessary */ else{ #ifdef DEBUG_CHECKS printf("\tSECTION B2a\n"); #endif /* we're using aggressive host checking, so really do recheck the host... */ if(use_aggressive_host_checking==TRUE){ route_result=verify_route_to_host(temp_host,CHECK_OPTION_NONE); #ifdef DEBUG_CHECKS printf("\tSECTION B2b\n"); #endif } /* the service wobbled between non-OK states, so check the host... */ else if(state_change==TRUE && temp_service->last_hard_state!=STATE_OK){ route_result=verify_route_to_host(temp_host,CHECK_OPTION_NONE); #ifdef DEBUG_CHECKS printf("\tSECTION B2c\n"); #endif } /* else fake the host check, but (possibly) resend host notifications to contacts... */ else{ #ifdef DEBUG_CHECKS printf("\tSECTION B2d\n"); #endif #ifdef REMOVED_042903 /* log the initial state if the user wants to and this host hasn't been checked yet */ if(log_initial_states==TRUE && temp_host->has_been_checked==FALSE) log_host_event(temp_host); #endif /* if the host has never been checked before, set the checked flag */ if(temp_host->has_been_checked==FALSE) temp_host->has_been_checked=TRUE; /* update the last host check time */ temp_host->last_check=temp_service->last_check; /* fake the route check result */ route_result=temp_host->current_state; /* possibly re-send host notifications... */ host_notification(temp_host,NOTIFICATION_NORMAL,NULL,NULL); } } /* if the host is down or unreachable ... */ if(route_result!=HOST_UP){ #ifdef DEBUG_CHECKS printf("\tSECTION B3\n"); #endif /* "fake" a hard state change for the service - well, its not really fake, but it didn't get caught earlier... */ if(temp_service->last_hard_state!=temp_service->current_state) hard_state_change=TRUE; /* update last state change times */ if(state_change==TRUE || hard_state_change==TRUE) temp_service->last_state_change=temp_service->last_check; if(hard_state_change==TRUE) temp_service->last_hard_state_change=temp_service->last_check; /* put service into a hard state without attempting check retries and don't send out notifications about it */ temp_service->host_problem_at_last_check=TRUE; temp_service->state_type=HARD_STATE; temp_service->last_hard_state=temp_service->current_state; temp_service->current_attempt=1; } /* the host is up - it recovered since the last time the service was checked... */ else if(temp_service->host_problem_at_last_check==TRUE){ #ifdef DEBUG_CHECKS printf("\tSECTION B4\n"); #endif /* next time the service is checked we shouldn't get into this same case... */ temp_service->host_problem_at_last_check=FALSE; /* reset the current check counter, so we give the service a chance */ /* this helps prevent the case where service has N max check attempts, N-1 of which have already occurred. */ /* if we didn't do this, the next check might fail and result in a hard problem - we should really give it more time */ /* ADDED IF STATEMENT 01-17-05 EG */ /* 01-17-05: Services in hard problem states before hosts went down would sometimes come back as soft problem states after */ /* the hosts recovered. This caused problems, so hopefully this will fix it */ if(temp_service->state_type==SOFT_STATE) temp_service->current_attempt=1; #ifdef REMOVED_041403 /* don't send a recovery notification if the service recovers at the next check */ temp_service->no_recovery_notification=TRUE; #endif } /* if we should retry the service check, do so (except it the host is down or unreachable!) */ if(temp_service->current_attempt < temp_service->max_attempts){ #ifdef DEBUG_CHECKS printf("\tSECTION B5a\n"); #endif /* the host is down or unreachable, so don't attempt to retry the service check */ if(route_result!=HOST_UP){ #ifdef DEBUG_CHECKS printf("\tSECTION B5b\n"); #endif /* the host is not up, so reschedule the next service check at regular interval */ if(temp_service->check_type==SERVICE_CHECK_ACTIVE) temp_service->next_check=(time_t)(temp_service->last_check+(temp_service->check_interval*interval_length)); /* log the problem as a hard state if the host just went down */ if(hard_state_change==TRUE){ log_service_event(temp_service); state_was_logged=TRUE; } } /* the host is up, so continue to retry the service check */ else{ #ifdef DEBUG_CHECKS printf("\tSECTION B5c\n"); #endif /* this is a soft state */ temp_service->state_type=SOFT_STATE; /* log the service check retry */ log_service_event(temp_service); state_was_logged=TRUE; /* run the service event handler to handle the soft state */ handle_service_event(temp_service); #ifdef REMOVED_021803 /*** NOTE TO SELF - THIS SHOULD BE MOVED SOMEWHERE ELSE - 02/18/03 ***/ /*** MOVED UP TO ~ LINE 780 ***/ /* increment the current attempt number */ temp_service->current_attempt=temp_service->current_attempt+1; #endif if(temp_service->check_type==SERVICE_CHECK_ACTIVE) temp_service->next_check=(time_t)(temp_service->last_check+(temp_service->retry_interval*interval_length)); } } /* we've reached the maximum number of service rechecks, so handle the error */ else{ #ifdef DEBUG_CHECKS printf("\tSECTION B6a\n"); printf("\tMAXED OUT! HSC: %d\n",hard_state_change); #endif /* this is a hard state */ temp_service->state_type=HARD_STATE; /* if we've hard a hard state change... */ if(hard_state_change==TRUE){ #ifdef DEBUG_CHECKS printf("\tSECTION B6b\n"); #endif /* log the service problem (even if host is not up, which is new in 0.0.5) */ log_service_event(temp_service); state_was_logged=TRUE; } /* else log the problem (again) if this service is flagged as being volatile */ else if(temp_service->is_volatile==TRUE){ #ifdef DEBUG_CHECKS printf("\tSECTION B6c\n"); #endif log_service_event(temp_service); state_was_logged=TRUE; } /* check for start of flexible (non-fixed) scheduled downtime if we just had a hard error */ if(hard_state_change==TRUE && temp_service->pending_flex_downtime>0) check_pending_flex_service_downtime(temp_service); /* (re)send notifications out about this service problem if the host is up (and was at last check also) and the dependencies were okay... */ service_notification(temp_service,NOTIFICATION_NORMAL,NULL,NULL); /* run the service event handler if we changed state from the last hard state or if this service is flagged as being volatile */ if(hard_state_change==TRUE || temp_service->is_volatile==TRUE){ #ifdef DEBUG_CHECKS printf("\tSECTION B6d\n"); #endif handle_service_event(temp_service); } /* save the last hard state */ temp_service->last_hard_state=temp_service->current_state; /* reschedule the next check at the regular interval */ if(temp_service->check_type==SERVICE_CHECK_ACTIVE) temp_service->next_check=(time_t)(temp_service->last_check+(temp_service->check_interval*interval_length)); } /* should we obsessive over service checks? */ if(obsess_over_services==TRUE) obsessive_compulsive_service_check_processor(temp_service); } /* reschedule the next service check ONLY for active checks */ if(temp_service->check_type==SERVICE_CHECK_ACTIVE){ /* default is to reschedule service check unless a test below fails... */ temp_service->should_be_scheduled=TRUE; /* make sure we don't get ourselves into too much trouble... */ if(current_time>temp_service->next_check) temp_service->next_check=current_time; /* make sure we rescheduled the next service check at a valid time */ preferred_time=temp_service->next_check; get_next_valid_time(preferred_time,&next_valid_time,temp_service->check_period); temp_service->next_check=next_valid_time; /* services with non-recurring intervals do not get rescheduled */ if(temp_service->check_interval==0) temp_service->should_be_scheduled=FALSE; /* services with active checks disabled do not get rescheduled */ if(temp_service->checks_enabled==FALSE) temp_service->should_be_scheduled=FALSE; /* schedule a non-forced check if we can */ if(temp_service->should_be_scheduled==TRUE) schedule_service_check(temp_service,temp_service->next_check,FALSE); } #ifdef DEBUG_CHECKS printf("\tDONE\n"); #endif /* if we're stalking this state type and state was not already logged AND the plugin output changed since last check, log it now.. */ if(temp_service->state_type==HARD_STATE && state_change==FALSE && state_was_logged==FALSE && strcmp(old_plugin_output,temp_service->plugin_output)){ if((temp_service->current_state==STATE_OK && temp_service->stalk_on_ok==TRUE)) log_service_event(temp_service); else if((temp_service->current_state==STATE_WARNING && temp_service->stalk_on_warning==TRUE)) log_service_event(temp_service); else if((temp_service->current_state==STATE_UNKNOWN && temp_service->stalk_on_unknown==TRUE)) log_service_event(temp_service); else if((temp_service->current_state==STATE_CRITICAL && temp_service->stalk_on_critical==TRUE)) log_service_event(temp_service); } #ifdef USE_EVENT_BROKER /* send data to event broker */ broker_service_check(NEBTYPE_SERVICECHECK_PROCESSED,NEBFLAG_NONE,NEBATTR_NONE,temp_service,temp_service->check_type,queued_svc_msg.start_time,queued_svc_msg.finish_time,NULL,temp_service->latency,temp_service->execution_time,service_check_timeout,queued_svc_msg.early_timeout,queued_svc_msg.return_code,NULL,NULL); #endif /* set the checked flag */ temp_service->has_been_checked=TRUE; /* update the current service status log */ update_service_status(temp_service,FALSE); /* check to see if the service is flapping */ check_for_service_flapping(temp_service,TRUE); /* check to see if the associated host is flapping */ check_for_host_flapping(temp_host,TRUE); /* update service performance info */ update_service_performance_data(temp_service); /* break out if we've been here too long (max_check_reaper_time seconds) */ time(¤t_time); if((int)(current_time-reaper_start_time)>max_check_reaper_time) break; #if OLD_CRUD /* check for external commands if we're doing so as often as possible */ if(command_check_interval==-1) check_for_external_commands(); #endif } #ifdef DEBUG3 printf("Finished reaping service check results.\n"); #endif #ifdef DEBUG0 printf("reap_service_checks() end\n"); #endif return; } /* schedules an immediate or delayed service check */ void schedule_service_check(service *svc,time_t check_time,int forced){ timed_event *temp_event; timed_event *new_event; int found=FALSE; char temp_buffer[MAX_INPUT_BUFFER]; int use_original_event=TRUE; #ifdef DEBUG0 printf("schedule_service_check() start\n"); #endif /* don't schedule a check if active checks are disabled */ if((execute_service_checks==FALSE || svc->checks_enabled==FALSE) && forced==FALSE) return; /* allocate memory for a new event item */ new_event=(timed_event *)malloc(sizeof(timed_event)); if(new_event==NULL){ snprintf(temp_buffer,sizeof(temp_buffer),"Warning: Could not reschedule check of service '%s' on host '%s'!\n",svc->description,svc->host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_RUNTIME_WARNING,TRUE); return; } /* see if there are any other scheduled checks of this service in the queue */ for(temp_event=event_list_low;temp_event!=NULL;temp_event=temp_event->next){ if(temp_event->event_type==EVENT_SERVICE_CHECK && svc==(service *)temp_event->event_data){ found=TRUE; break; } } /* we found another service check event for this service in the queue - what should we do? */ if(found==TRUE && temp_event!=NULL){ /* use the originally scheduled check unless we decide otherwise */ use_original_event=TRUE; /* the original event is a forced check... */ if(svc->check_options & CHECK_OPTION_FORCE_EXECUTION){ /* the new event is also forced and its execution time is earlier than the original, so use it instead */ if(forced==TRUE && check_time < svc->next_check) use_original_event=FALSE; } /* the original event is not a forced check... */ else{ /* the new event is a forced check, so use it instead */ if(forced==TRUE) use_original_event=FALSE; /* the new event is not forced either and its execution time is earlier than the original, so use it instead */ else if(check_time < svc->next_check) use_original_event=FALSE; } /* the originally queued event won the battle, so keep it and exit */ if(use_original_event==TRUE){ free(new_event); return; } remove_event(temp_event,&event_list_low); free(temp_event); } /* set the next service check time */ svc->next_check=check_time; /* set the force service check option */ if(forced==TRUE) svc->check_options|=CHECK_OPTION_FORCE_EXECUTION; /* place the new event in the event queue */ new_event->event_type=EVENT_SERVICE_CHECK; new_event->event_data=(void *)svc; new_event->event_args=(void *)NULL; new_event->run_time=svc->next_check; new_event->recurring=FALSE; new_event->event_interval=0L; new_event->timing_func=NULL; new_event->compensate_for_time_change=TRUE; reschedule_event(new_event,&event_list_low); /* update the status log */ update_service_status(svc,FALSE); #ifdef DEBUG0 printf("schedule_service_check() end\n"); #endif return; } /* checks service dependencies */ int check_service_dependencies(service *svc,int dependency_type){ servicedependency *temp_dependency; service *temp_service; int state; #ifdef DEBUG0 printf("check_service_dependencies() start\n"); #endif /* check all dependencies... */ for(temp_dependency=get_first_servicedependency_by_dependent_service(svc->host_name,svc->description);temp_dependency!=NULL;temp_dependency=get_next_servicedependency_by_dependent_service(svc->host_name,svc->description,temp_dependency)){ /* only check dependencies of the desired type (notification or execution) */ if(temp_dependency->dependency_type!=dependency_type) continue; /* find the service we depend on... */ temp_service=find_service(temp_dependency->host_name,temp_dependency->service_description); if(temp_service==NULL) continue; /* get the status to use (use last hard state if its currently in a soft state) */ if(temp_service->state_type==SOFT_STATE && soft_state_dependencies==FALSE) state=temp_service->last_hard_state; else state=temp_service->current_state; /* is the service we depend on in state that fails the dependency tests? */ if(state==STATE_OK && temp_dependency->fail_on_ok==TRUE) return DEPENDENCIES_FAILED; if(state==STATE_WARNING && temp_dependency->fail_on_warning==TRUE) return DEPENDENCIES_FAILED; if(state==STATE_UNKNOWN && temp_dependency->fail_on_unknown==TRUE) return DEPENDENCIES_FAILED; if(state==STATE_CRITICAL && temp_dependency->fail_on_critical==TRUE) return DEPENDENCIES_FAILED; if((state==STATE_OK && temp_service->has_been_checked==FALSE) && temp_dependency->fail_on_pending==TRUE) return DEPENDENCIES_FAILED; /* immediate dependencies ok at this point - check parent dependencies if necessary */ if(temp_dependency->inherits_parent==TRUE){ if(check_service_dependencies(temp_service,dependency_type)!=DEPENDENCIES_OK) return DEPENDENCIES_FAILED; } } #ifdef DEBUG0 printf("check_service_dependencies() end\n"); #endif return DEPENDENCIES_OK; } /* checks host dependencies */ int check_host_dependencies(host *hst,int dependency_type){ hostdependency *temp_dependency; host *temp_host; #ifdef DEBUG0 printf("check_host_dependencies() start\n"); #endif /* check all dependencies... */ for(temp_dependency=get_first_hostdependency_by_dependent_host(hst->name);temp_dependency!=NULL;temp_dependency=get_next_hostdependency_by_dependent_host(hst->name,temp_dependency)){ /* only check dependencies of the desired type (notification or execution) */ if(temp_dependency->dependency_type!=dependency_type) continue; /* find the host we depend on... */ temp_host=find_host(temp_dependency->host_name); if(temp_host==NULL) continue; /* is the host we depend on in state that fails the dependency tests? */ if(temp_host->current_state==HOST_UP && temp_dependency->fail_on_up==TRUE) return DEPENDENCIES_FAILED; if(temp_host->current_state==HOST_DOWN && temp_dependency->fail_on_down==TRUE) return DEPENDENCIES_FAILED; if(temp_host->current_state==HOST_UNREACHABLE && temp_dependency->fail_on_unreachable==TRUE) return DEPENDENCIES_FAILED; if((temp_host->current_state==HOST_UP && temp_host->has_been_checked==FALSE) && temp_dependency->fail_on_pending==TRUE) return DEPENDENCIES_FAILED; /* immediate dependencies ok at this point - check parent dependencies if necessary */ if(temp_dependency->inherits_parent==TRUE){ if(check_host_dependencies(temp_host,dependency_type)!=DEPENDENCIES_OK) return DEPENDENCIES_FAILED; } } #ifdef DEBUG0 printf("check_host_dependencies() end\n"); #endif return DEPENDENCIES_OK; } /* check for services that never returned from a check... */ void check_for_orphaned_services(void){ service *temp_service; time_t current_time; time_t expected_time; char buffer[MAX_INPUT_BUFFER]; #ifdef DEBUG0 printf("check_for_orphaned_services() start\n"); #endif /* get the current time */ time(¤t_time); /* check all services... */ for(temp_service=service_list;temp_service!=NULL;temp_service=temp_service->next){ /* skip services that are not currently executing */ if(temp_service->is_executing==FALSE) continue; /* determine the time at which the check results should have come in (allow 10 minutes slack time) */ expected_time=(time_t)(temp_service->next_check+temp_service->latency+service_check_timeout+service_check_reaper_interval+600); /* this service was supposed to have executed a while ago, but for some reason the results haven't come back in... */ if(expected_timedescription,temp_service->host_name); buffer[sizeof(buffer)-1]='\x0'; write_to_logs_and_console(buffer,NSLOG_RUNTIME_WARNING,TRUE); /* decrement the number of running service checks */ if(currently_running_service_checks>0) currently_running_service_checks--; /* disable the executing flag */ temp_service->is_executing=FALSE; /* schedule an immediate check of the service */ schedule_service_check(temp_service,current_time,FALSE); } } #ifdef DEBUG0 printf("check_for_orphaned_services() end\n"); #endif return; } /* check freshness of service results */ void check_service_result_freshness(void){ service *temp_service; time_t current_time; time_t expiration_time; int freshness_threshold; char buffer[MAX_INPUT_BUFFER]; #ifdef DEBUG0 printf("check_service_result_freshness() start\n"); #endif #ifdef TEST_FRESHNESS printf("\n======FRESHNESS START======\n"); printf("CHECKFRESHNESS 1\n"); #endif /* bail out if we're not supposed to be checking freshness */ if(check_service_freshness==FALSE) return; /* get the current time */ time(¤t_time); #ifdef TEST_FRESHNESS printf("CHECKFRESHNESS 2: %lu\n",(unsigned long)current_time); #endif /* check all services... */ for(temp_service=service_list;temp_service!=NULL;temp_service=temp_service->next){ #ifdef TEST_FRESHNESS if(!strcmp(temp_service->description,"Freshness Check Test")) printf("Checking: %s/%s\n",temp_service->host_name,temp_service->description); #endif /* skip services we shouldn't be checking for freshness */ if(temp_service->check_freshness==FALSE) continue; /* skip services that are currently executing (problems here will be caught by orphaned service check) */ if(temp_service->is_executing==TRUE) continue; /* skip services that have both active and passive checks disabled */ if(temp_service->checks_enabled==FALSE && temp_service->accept_passive_service_checks==FALSE) continue; /* skip services that are already being freshened */ if(temp_service->is_being_freshened==TRUE) continue; /* see if the time is right... */ if(check_time_against_period(current_time,temp_service->check_period)==ERROR) continue; /* EXCEPTION */ /* don't check freshness of services without regular check intervals if we're using auto-freshness threshold */ if(temp_service->check_interval==0 && temp_service->freshness_threshold==0) continue; #ifdef TEST_FRESHNESS printf("CHECKFRESHNESS 3\n"); #endif /* use user-supplied freshness threshold or auto-calculate a freshness threshold to use? */ if(temp_service->freshness_threshold==0){ if(temp_service->state_type==HARD_STATE || temp_service->current_state==STATE_OK) freshness_threshold=(temp_service->check_interval*interval_length)+temp_service->latency+15; else freshness_threshold=(temp_service->retry_interval*interval_length)+temp_service->latency+15; } else freshness_threshold=temp_service->freshness_threshold; #ifdef TEST_FRESHNESS printf("THRESHOLD: SVC=%d, USE=%d\n",temp_service->freshness_threshold,freshness_threshold); #endif /* calculate expiration time */ /* CHANGED 11/10/05 EG - program start is only used in expiration time calculation if > last check AND active checks are enabled, so active checks can become stale immediately upon program startup */ /* CHANGED 02/25/06 SG - passive checks also become stale, so remove dependence on active check logic */ if(temp_service->has_been_checked==FALSE || program_start>temp_service->last_check) expiration_time=(time_t)(program_start+freshness_threshold); else expiration_time=(time_t)(temp_service->last_check+freshness_threshold); #ifdef TEST_FRESHNESS printf("HASBEENCHECKED: %d\n",temp_service->has_been_checked); printf("PROGRAM START: %lu\n",(unsigned long)program_start); printf("LAST CHECK: %lu\n",(unsigned long)temp_service->last_check); printf("CURRENT TIME: %lu\n",(unsigned long)current_time); printf("EXPIRE TIME: %lu\n",(unsigned long)expiration_time); #endif /* the results for the last check of this service are stale */ if(expiration_timedescription,temp_service->host_name,(current_time-expiration_time),freshness_threshold); buffer[sizeof(buffer)-1]='\x0'; write_to_logs_and_console(buffer,NSLOG_RUNTIME_WARNING,TRUE); /* set the freshen flag */ temp_service->is_being_freshened=TRUE; /* schedule an immediate forced check of the service */ schedule_service_check(temp_service,current_time,TRUE); } } #ifdef TEST_FRESHNESS printf("\n======FRESHNESS END======\n"); #endif #ifdef DEBUG0 printf("check_service_result_freshness() end\n"); #endif return; } /******************************************************************/ /******************* ROUTE/HOST CHECK FUNCTIONS *******************/ /******************************************************************/ /*** ON-DEMAND HOST CHECKS USE THIS FUNCTION ***/ /* check to see if we can reach the host */ int verify_route_to_host(host *hst, int check_options){ int result; #ifdef DEBUG0 printf("verify_route_to_host() start\n"); #endif /* reset latency, since on-demand checks have none */ hst->latency=0.0; /* check route to the host (propagate problems and recoveries both up and down the tree) */ result=check_host(hst,PROPAGATE_TO_PARENT_HOSTS | PROPAGATE_TO_CHILD_HOSTS,check_options); #ifdef DEBUG0 printf("verify_route_to_host() end\n"); #endif return result; } /*** SCHEDULED HOST CHECKS USE THIS FUNCTION ***/ /* run a scheduled host check */ int run_scheduled_host_check(host *hst){ time_t current_time; time_t preferred_time; time_t next_valid_time; int perform_check=TRUE; int time_is_valid=TRUE; #ifdef DEBUG0 printf("run_scheduled_host_check() start\n"); #endif /********************************************************************* NOTE: A lot of the checks that occur before the host is actually checked (checks enabled, time period, dependencies) are checked later in the run_host_check() function. The only reason we duplicate them here is to nicely reschedule the next host check as soon as possible, instead of at the next regular interval in the event we know that the host check will not be run at the current time *********************************************************************/ time(¤t_time); /* default time to reschedule the next host check */ preferred_time=current_time+(hst->check_interval*interval_length); /* if checks of the host are currently disabled... */ if(hst->checks_enabled==FALSE){ /* don't check the host if we're not forcing it through */ if(!(hst->check_options & CHECK_OPTION_FORCE_EXECUTION)) perform_check=FALSE; } /* make sure this is a valid time to check the host */ if(check_time_against_period((unsigned long)current_time,hst->check_period)==ERROR){ /* don't check the host if we're not forcing it through */ if(!(hst->check_options & CHECK_OPTION_FORCE_EXECUTION)) perform_check=FALSE; /* get the next valid time we can run the check */ preferred_time=current_time; /* set the invalid time flag */ time_is_valid=FALSE; } /* check host dependencies for execution */ if(check_host_dependencies(hst,EXECUTION_DEPENDENCY)==DEPENDENCIES_FAILED){ /* don't check the host if we're not forcing it through */ if(!(hst->check_options & CHECK_OPTION_FORCE_EXECUTION)) perform_check=FALSE; } /**** RUN THE SCHEDULED HOST CHECK ****/ /* check route to the host (propagate problems and recoveries both up and down the tree) */ if(perform_check==TRUE) check_host(hst,PROPAGATE_TO_PARENT_HOSTS | PROPAGATE_TO_CHILD_HOSTS,hst->check_options); /* clear the force execution flag */ if(hst->check_options & CHECK_OPTION_FORCE_EXECUTION) hst->check_options-=CHECK_OPTION_FORCE_EXECUTION; /* default is to schedule the host check unless test below fail */ hst->should_be_scheduled=TRUE; /* don't reschedule non-recurring host checks */ if(hst->check_interval==0) hst->should_be_scheduled=FALSE; /* don't reschedule hosts with active checks disabled */ if(hst->checks_enabled==FALSE) hst->should_be_scheduled=FALSE; /* make sure we rescheduled the next host check at a valid time */ get_next_valid_time(preferred_time,&next_valid_time,hst->check_period); /* the host could not be rescheduled properly - set the next check time for next year, but don't actually reschedule it */ if(time_is_valid==FALSE && next_valid_time==preferred_time){ hst->next_check=(time_t)(next_valid_time+(60*60*24*365)); hst->should_be_scheduled=FALSE; #ifdef DEBUG1 printf("Warning: Could not find any valid times to reschedule a check of host '%s'!\n",hst->name); #endif } /* this host could be rescheduled... */ else hst->next_check=next_valid_time; /* update the status data */ update_host_status(hst,FALSE); /* reschedule the next host check if we're able */ if(hst->should_be_scheduled==TRUE) schedule_host_check(hst,hst->next_check,FALSE); #ifdef DEBUG0 printf("run_scheduled_host_check() end\n"); #endif return OK; } /* check freshness of host results */ void check_host_result_freshness(void){ host *temp_host; time_t current_time; time_t expiration_time; int freshness_threshold; char buffer[MAX_INPUT_BUFFER]; #ifdef DEBUG0 printf("check_host_result_freshness() start\n"); #endif /* bail out if we're not supposed to be checking freshness */ if(check_host_freshness==FALSE) return; /* get the current time */ time(¤t_time); /* check all hosts... */ for(temp_host=host_list;temp_host!=NULL;temp_host=temp_host->next){ /* skip hosts we shouldn't be checking for freshness */ if(temp_host->check_freshness==FALSE) continue; /* skip hosts that have both active and passive checks disabled */ if(temp_host->checks_enabled==FALSE && temp_host->accept_passive_host_checks==FALSE) continue; /* skip hosts that are already being freshened */ if(temp_host->is_being_freshened==TRUE) continue; /* see if the time is right... */ if(check_time_against_period(current_time,temp_host->check_period)==ERROR) continue; /* use user-supplied freshness threshold or auto-calculate a freshness threshold to use? */ if(temp_host->freshness_threshold==0) freshness_threshold=(temp_host->check_interval*interval_length)+temp_host->latency+15; else freshness_threshold=temp_host->freshness_threshold; /* calculate expiration time */ /* CHANGED 11/10/05 EG - program start is only used in expiration time calculation if > last check AND active checks are enabled, so active checks can become stale immediately upon program startup */ if(temp_host->has_been_checked==FALSE || (temp_host->checks_enabled==TRUE && (program_start>temp_host->last_check))) expiration_time=(time_t)(program_start+freshness_threshold); else expiration_time=(time_t)(temp_host->last_check+freshness_threshold); /* the results for the last check of this host are stale */ if(expiration_timename,(current_time-expiration_time),freshness_threshold); buffer[sizeof(buffer)-1]='\x0'; write_to_logs_and_console(buffer,NSLOG_RUNTIME_WARNING,TRUE); /* set the freshen flag */ temp_host->is_being_freshened=TRUE; /* schedule an immediate forced check of the host */ schedule_host_check(temp_host,current_time,TRUE); } } #ifdef DEBUG0 printf("check_host_result_freshness() end\n"); #endif return; } /* see if the remote host is alive at all */ int check_host(host *hst, int propagation_options, int check_options){ int result=HOST_UP; int parent_result=HOST_UP; host *parent_host=NULL; hostsmember *temp_hostsmember=NULL; host *child_host=NULL; int return_result=HOST_UP; int max_check_attempts=1; int route_blocked=TRUE; int old_state=HOST_UP; struct timeval start_time; struct timeval end_time; double execution_time=0.0; char old_plugin_output[MAX_PLUGINOUTPUT_LENGTH]=""; #ifdef DEBUG0 printf("check_host() start\n"); #endif /* ADDED 06/20/2006 EG */ /* bail out if signal encountered */ if(sigrestart==TRUE || sigshutdown==TRUE) return hst->current_state; /* high resolution time for broker */ gettimeofday(&start_time,NULL); #ifdef USE_EVENT_BROKER /* send data to event broker */ end_time.tv_sec=0L; end_time.tv_usec=0L; broker_host_check(NEBTYPE_HOSTCHECK_INITIATE,NEBFLAG_NONE,NEBATTR_NONE,hst,HOST_CHECK_ACTIVE,hst->current_state,hst->state_type,start_time,end_time,hst->host_check_command,hst->latency,0.0,0,FALSE,0,NULL,NULL,NULL,NULL); #endif /* make sure we return the original host state unless it changes... */ return_result=hst->current_state; /* save old state - a host is always in a hard state when this function is called... */ hst->last_state=hst->current_state; hst->last_hard_state=hst->current_state; /* set the checked flag */ hst->has_been_checked=TRUE; /* clear the freshness flag */ hst->is_being_freshened=FALSE; /* save the old plugin output and host state for use with state stalking routines */ old_state=hst->current_state; strncpy(old_plugin_output,(hst->plugin_output==NULL)?"":hst->plugin_output,sizeof(old_plugin_output)-1); old_plugin_output[sizeof(old_plugin_output)-1]='\x0'; /***** HOST IS NOT UP INITIALLY *****/ /* if the host is already down or unreachable... */ if(hst->current_state!=HOST_UP){ /* set the state type (should already be set) */ hst->state_type=HARD_STATE; /* how many times should we retry checks for this host? */ if(use_aggressive_host_checking==FALSE) max_check_attempts=1; else max_check_attempts=hst->max_attempts; /* retry the host check as many times as necessary or allowed... */ for(hst->current_attempt=1;hst->current_attempt<=max_check_attempts;hst->current_attempt++){ /* ADDED 06/20/2006 EG */ /* bail out if signal encountered - use old state */ if(sigrestart==TRUE || sigshutdown==TRUE){ hst->current_attempt=1; hst->current_state=old_state; free(hst->plugin_output); hst->plugin_output=(char *)old_plugin_output; return hst->current_state; } /* check the host */ result=run_host_check(hst,check_options); /* the host recovered from a hard problem... */ if(result==HOST_UP){ /* update host state */ hst->current_state=HOST_UP; return_result=HOST_UP; /* handle the hard host recovery */ handle_host_state(hst); /* propagate the host recovery upwards (at least one parent should be up now) */ if(propagation_options & PROPAGATE_TO_PARENT_HOSTS){ /* propagate to all parent hosts */ for(temp_hostsmember=hst->parent_hosts;temp_hostsmember!=NULL;temp_hostsmember=temp_hostsmember->next){ /* find the parent host */ parent_host=find_host(temp_hostsmember->host_name); /* check the parent host (and propagate upwards) if its not up */ if(parent_host!=NULL && parent_host->current_state!=HOST_UP) check_host(parent_host,PROPAGATE_TO_PARENT_HOSTS,check_options); } } /* propagate the host recovery downwards (children may or may not be down) */ if(propagation_options & PROPAGATE_TO_CHILD_HOSTS){ /* check all child hosts... */ for(child_host=host_list;child_host!=NULL;child_host=child_host->next){ /* if this is a child of the host, check it if it is not marked as UP */ if(is_host_immediate_child_of_host(hst,child_host)==TRUE && child_host->current_state!=HOST_UP) check_host(child_host,PROPAGATE_TO_CHILD_HOSTS,check_options); } } break; } /* there is still a problem with the host... */ /* if this is the last check and the host is currently marked as being UNREACHABLE, make sure it hasn't changed to a DOWN state. */ /* to do this we have to check the (saved) status of all parent hosts. this situation can occur if a host is */ /* unreachable, one of its parent recovers, but the host does not return to an UP state. Even though the host is not UP, */ /* it has changed from an UNREACHABLE to a DOWN state */ else if(hst->last_state==HOST_UNREACHABLE && hst->current_attempt==max_check_attempts){ /* check all parent hosts */ for(temp_hostsmember=hst->parent_hosts;temp_hostsmember!=NULL;temp_hostsmember=temp_hostsmember->next){ /* find the parent host */ parent_host=find_host(temp_hostsmember->host_name); /* if at least one parent host is up, this host is no longer unreachable - it is now down instead */ if(parent_host->current_state==HOST_UP){ /* change the host state to DOWN */ hst->current_state=HOST_DOWN; break; } } } /* handle the host problem */ handle_host_state(hst); } /* readjust the current check number - added 01/10/05 EG */ hst->current_attempt--; } /***** HOST IS UP INITIALLY *****/ /* else the host is supposed to be up right now... */ else{ for(hst->current_attempt=1;hst->current_attempt<=hst->max_attempts;hst->current_attempt++){ /* ADDED 06/20/2006 EG */ /* bail out if signal encountered - use old state */ if(sigrestart==TRUE || sigshutdown==TRUE){ hst->current_attempt=1; hst->current_state=old_state; free(hst->plugin_output); hst->plugin_output=(char *)old_plugin_output; return hst->current_state; } /* run the host check */ result=run_host_check(hst,check_options); /* update state type */ if(result==HOST_UP) hst->state_type=(hst->current_attempt==1)?HARD_STATE:SOFT_STATE; else hst->state_type=(hst->current_attempt==hst->max_attempts)?HARD_STATE:SOFT_STATE; /*** HARD ERROR STATE ***/ /* if this is the last check and we still haven't had a recovery, check the parents, handle the hard state and propagate the check to children */ if(result!=HOST_UP && (hst->current_attempt==hst->max_attempts)){ /* check all parent hosts */ for(temp_hostsmember=hst->parent_hosts;temp_hostsmember!=NULL;temp_hostsmember=temp_hostsmember->next){ /* find the parent host */ parent_host=find_host(temp_hostsmember->host_name); /* check the parent host, assume its up if we can't find it, use the parent host's "old" status if we shouldn't propagate */ if(parent_host==NULL) parent_result=HOST_UP; else if(propagation_options & PROPAGATE_TO_PARENT_HOSTS) parent_result=check_host(parent_host,PROPAGATE_TO_PARENT_HOSTS,check_options); else parent_result=parent_host->current_state; /* if this parent host was up, the route is okay */ if(parent_result==HOST_UP) route_blocked=FALSE; /* we could break out of this loop once we've found one parent host that is up, but we won't because we want immediate notification of state changes (i.e. recoveries) for parent hosts */ } /* if this host has at least one parent host and the route to this host is blocked, it is unreachable */ if(route_blocked==TRUE && hst->parent_hosts!=NULL) return_result=HOST_UNREACHABLE; /* else the parent host is up (or there isn't a parent host), so this host must be down */ else return_result=HOST_DOWN; /* update host state */ hst->current_state=return_result; /* handle the hard host state (whether it is DOWN or UNREACHABLE) */ handle_host_state(hst); /* propagate the host problem to all child hosts (they should be unreachable now unless they have multiple parents) */ if(propagation_options & PROPAGATE_TO_CHILD_HOSTS){ /* check all child hosts... */ for(child_host=host_list;child_host!=NULL;child_host=child_host->next){ /* if this is a child of the host, check it if it is not marked as UP */ if(is_host_immediate_child_of_host(hst,child_host)==TRUE && child_host->current_state!=HOST_UP) check_host(child_host,PROPAGATE_TO_CHILD_HOSTS,check_options); } } } /*** SOFT ERROR STATE ***/ /* handle any soft error states (during host check retries that return a non-ok state) */ else if(result!=HOST_UP){ /* update the current host state */ hst->current_state=result; /* handle the host state */ handle_host_state(hst); /* update the status log with the current host info */ /* this needs to be called to update status data on soft error states */ update_host_status(hst,FALSE); } /*** SOFT RECOVERY STATE ***/ /* handle any soft recovery states (during host check retries that return an ok state) */ else if(result==HOST_UP && hst->current_attempt!=1){ /* update the current host state */ hst->current_state=result; /* handle the host state */ handle_host_state(hst); /* update the status log with the current host info */ /* this needs to be called to update status data on soft error states */ update_host_status(hst,FALSE); break; } /*** UNCHANGED OK STATE ***/ /* the host never went down */ else if(result==HOST_UP){ /* update the current host state */ hst->current_state=HOST_UP; /* this is the first check of the host */ if(hst->has_been_checked==FALSE){ /* set the checked flag */ hst->has_been_checked=TRUE; } /* handle the host state */ handle_host_state(hst); break; } } } /* adjust the current check number if we exceeded the max count */ if(hst->current_attempt>hst->max_attempts) hst->current_attempt=hst->max_attempts; /* make sure state type is hard */ hst->state_type=HARD_STATE; /* update the status log with the current host info */ update_host_status(hst,FALSE); /* if the host didn't change state and the plugin output differs from the last time it was checked, log the current state/output if state stalking is enabled */ if(hst->last_state==hst->current_state && strcmp(old_plugin_output,hst->plugin_output)){ if(hst->current_state==HOST_UP && hst->stalk_on_up==TRUE) log_host_event(hst); else if(hst->current_state==HOST_DOWN && hst->stalk_on_down==TRUE) log_host_event(hst); else if(hst->current_state==HOST_UNREACHABLE && hst->stalk_on_unreachable==TRUE) log_host_event(hst); } /* high resolution time for broker */ gettimeofday(&end_time,NULL); #ifdef USE_EVENT_BROKER /* send data to event broker */ execution_time=(double)((double)(end_time.tv_sec-start_time.tv_sec)+(double)((end_time.tv_usec-start_time.tv_usec)/1000)/1000.0); broker_host_check(NEBTYPE_HOSTCHECK_PROCESSED,NEBFLAG_NONE,NEBATTR_NONE,hst,HOST_CHECK_ACTIVE,hst->current_state,hst->state_type,start_time,end_time,hst->host_check_command,hst->latency,execution_time,0,FALSE,0,NULL,hst->plugin_output,hst->perf_data,NULL); #endif /* check to see if the associated host is flapping */ check_for_host_flapping(hst,TRUE); /* check for external commands if we're doing so as often as possible */ if(command_check_interval==-1) check_for_external_commands(); #ifdef DEBUG3 printf("\tHost Check Result: Host '%s' is ",hst->name); if(return_result==HOST_UP) printf("UP\n"); else if(return_result==HOST_DOWN) printf("DOWN\n"); else if(return_result==HOST_UNREACHABLE) printf("UNREACHABLE\n"); #endif #ifdef DEBUG0 printf("check_host() end\n"); #endif return return_result; } /* run an "alive" check on a host */ int run_host_check(host *hst, int check_options){ int result=STATE_OK; int return_result=HOST_UP; char processed_command[MAX_COMMAND_BUFFER]; char raw_command[MAX_COMMAND_BUFFER]; char temp_buffer[MAX_INPUT_BUFFER]; time_t current_time; time_t start_time; struct timeval start_time_hires; struct timeval end_time_hires; char *temp_ptr; int early_timeout=FALSE; double exectime; char temp_plugin_output[MAX_PLUGINOUTPUT_LENGTH]; #ifdef DEBUG0 printf("run_host_check() start\n"); #endif /* if we're not forcing the check, see if we should actually go through with it... */ if(!(check_options & CHECK_OPTION_FORCE_EXECUTION)){ time(¤t_time); /* make sure host checks are enabled */ if(execute_host_checks==FALSE || hst->checks_enabled==FALSE) return hst->current_state; /* make sure this is a valid time to check the host */ if(check_time_against_period((unsigned long)current_time,hst->check_period)==ERROR) return hst->current_state; /* check host dependencies for execution */ if(check_host_dependencies(hst,EXECUTION_DEPENDENCY)==DEPENDENCIES_FAILED) return hst->current_state; } /* if there is no host check command, just return with no error */ if(hst->host_check_command==NULL){ #ifdef DEBUG3 printf("\tNo host check command specified, so no check will be done (host state assumed to be unchanged)!\n"); #endif return HOST_UP; } /* grab the host macros */ clear_volatile_macros(); grab_host_macros(hst); grab_summary_macros(NULL); /* high resolution start time for event broker */ gettimeofday(&start_time_hires,NULL); /* get the last host check time */ time(&start_time); hst->last_check=start_time; /* get the raw command line */ get_raw_command_line(hst->host_check_command,raw_command,sizeof(raw_command),0); strip(raw_command); /* process any macros contained in the argument */ process_macros(raw_command,processed_command,sizeof(processed_command),0); strip(processed_command); #ifdef USE_EVENT_BROKER /* send data to event broker */ end_time_hires.tv_sec=0L; end_time_hires.tv_usec=0L; broker_host_check(NEBTYPE_HOSTCHECK_RAW_START,NEBFLAG_NONE,NEBATTR_NONE,hst,HOST_CHECK_ACTIVE,return_result,hst->state_type,start_time_hires,end_time_hires,hst->host_check_command,0.0,0.0,host_check_timeout,early_timeout,result,processed_command,hst->plugin_output,hst->perf_data,NULL); #endif #ifdef DEBUG3 printf("\t\tRaw Command: %s\n",raw_command); printf("\t\tProcessed Command: %s\n",processed_command); #endif /* clear plugin output and performance data buffers */ strcpy(hst->plugin_output,""); strcpy(hst->perf_data,""); /* run the host check command */ result=my_system(processed_command,host_check_timeout,&early_timeout,&exectime,temp_plugin_output,MAX_PLUGINOUTPUT_LENGTH-1); /* if the check timed out, report an error */ if(early_timeout==TRUE){ snprintf(hst->plugin_output,MAX_PLUGINOUTPUT_LENGTH-1,"Host check timed out after %d seconds\n",host_check_timeout); hst->plugin_output[MAX_PLUGINOUTPUT_LENGTH-1]='\x0'; /* log the timeout */ snprintf(temp_buffer,sizeof(temp_buffer)-1,"Warning: Host check command '%s' for host '%s' timed out after %d seconds\n",processed_command,hst->name,host_check_timeout); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_RUNTIME_WARNING,TRUE); } /* calculate total execution time */ hst->execution_time=exectime; /* record check type */ hst->check_type=HOST_CHECK_ACTIVE; /* check for empty plugin output */ if(!strcmp(temp_plugin_output,"")) strcpy(temp_plugin_output,"(No Information Returned From Host Check)"); /* first part of plugin output (up to pipe) is status info */ temp_ptr=strtok(temp_plugin_output,"|\n"); /* make sure the plugin output isn't NULL */ if(temp_ptr==NULL){ strncpy(hst->plugin_output,"(No output returned from host check)",MAX_PLUGINOUTPUT_LENGTH-1); hst->plugin_output[MAX_PLUGINOUTPUT_LENGTH-1]='\x0'; } else{ strip(temp_ptr); if(!strcmp(temp_ptr,"")){ strncpy(hst->plugin_output,"(No output returned from host check)",MAX_PLUGINOUTPUT_LENGTH-1); hst->plugin_output[MAX_PLUGINOUTPUT_LENGTH-1]='\x0'; } else{ strncpy(hst->plugin_output,temp_ptr,MAX_PLUGINOUTPUT_LENGTH-1); hst->plugin_output[MAX_PLUGINOUTPUT_LENGTH-1]='\x0'; } } /* second part of plugin output (after pipe) is performance data (which may or may not exist) */ temp_ptr=strtok(NULL,"\n"); /* grab performance data if we found it available */ if(temp_ptr!=NULL){ strip(temp_ptr); strncpy(hst->perf_data,temp_ptr,MAX_PLUGINOUTPUT_LENGTH-1); hst->perf_data[MAX_PLUGINOUTPUT_LENGTH-1]='\x0'; } /* replace semicolons in plugin output (but not performance data) with colons */ temp_ptr=hst->plugin_output; while((temp_ptr=strchr(temp_ptr,';'))) *temp_ptr=':'; /* if we're not doing aggressive host checking, let WARNING states indicate the host is up (fake the result to be STATE_OK) */ if(use_aggressive_host_checking==FALSE && result==STATE_WARNING) result=STATE_OK; if(result==STATE_OK) return_result=HOST_UP; else return_result=HOST_DOWN; /* high resolution end time for event broker */ gettimeofday(&end_time_hires,NULL); #ifdef USE_EVENT_BROKER /* send data to event broker */ broker_host_check(NEBTYPE_HOSTCHECK_RAW_END,NEBFLAG_NONE,NEBATTR_NONE,hst,HOST_CHECK_ACTIVE,return_result,hst->state_type,start_time_hires,end_time_hires,hst->host_check_command,0.0,exectime,host_check_timeout,early_timeout,result,processed_command,hst->plugin_output,hst->perf_data,NULL); #endif #ifdef DEBUG3 printf("\tHost Check Result: Host '%s' is ",hst->name); if(return_result==HOST_UP) printf("UP\n"); else printf("DOWN\n"); #endif #ifdef DEBUG0 printf("run_host_check() end\n"); #endif return return_result; } /* schedules an immediate or delayed host check */ void schedule_host_check(host *hst,time_t check_time,int forced){ timed_event *temp_event; timed_event *new_event; int found=FALSE; char temp_buffer[MAX_INPUT_BUFFER]; int use_original_event=TRUE; #ifdef DEBUG0 printf("schedule_host_check() start\n"); #endif /* don't schedule a check if active checks are disabled */ if((execute_host_checks==FALSE || hst->checks_enabled==FALSE) && forced==FALSE) return; /* allocate memory for a new event item */ new_event=(timed_event *)malloc(sizeof(timed_event)); if(new_event==NULL){ snprintf(temp_buffer,sizeof(temp_buffer),"Warning: Could not reschedule check of host '%s'!\n",hst->name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_RUNTIME_WARNING,TRUE); return; } /* see if there are any other scheduled checks of this host in the queue */ for(temp_event=event_list_low;temp_event!=NULL;temp_event=temp_event->next){ if(temp_event->event_type==EVENT_HOST_CHECK && hst==(host *)temp_event->event_data){ found=TRUE; break; } } /* we found another host check event for this host in the queue - what should we do? */ if(found==TRUE && temp_event!=NULL){ /* use the originally scheduled check unless we decide otherwise */ use_original_event=TRUE; /* the original event is a forced check... */ if(hst->check_options & CHECK_OPTION_FORCE_EXECUTION){ /* the new event is also forced and its execution time is earlier than the original, so use it instead */ if(forced==TRUE && check_time < hst->next_check) use_original_event=FALSE; } /* the original event is not a forced check... */ else{ /* the new event is a forced check, so use it instead */ if(forced==TRUE) use_original_event=FALSE; /* the new event is not forced either and its execution time is earlier than the original, so use it instead */ else if(check_time < hst->next_check) use_original_event=FALSE; } /* the originally queued event won the battle, so keep it and exit */ if(use_original_event==TRUE){ free(new_event); return; } remove_event(temp_event,&event_list_low); free(temp_event); } /* set the next host check time */ hst->next_check=check_time; /* set the force service check option */ if(forced==TRUE) hst->check_options|=CHECK_OPTION_FORCE_EXECUTION; /* place the new event in the event queue */ new_event->event_type=EVENT_HOST_CHECK; new_event->event_data=(void *)hst; new_event->event_args=(void *)NULL; new_event->run_time=hst->next_check; new_event->recurring=FALSE; new_event->event_interval=0L; new_event->timing_func=NULL; new_event->compensate_for_time_change=TRUE; reschedule_event(new_event,&event_list_low); /* update the status log */ update_host_status(hst,FALSE); #ifdef DEBUG0 printf("schedule_host_check() end\n"); #endif return; } nagios-2.6/base/commands.c0000664000076500007650000035325210353050230015057 0ustar nagiosnagios/***************************************************************************** * * COMMANDS.C - External command functions for Nagios * * Copyright (c) 1999-2005 Ethan Galstad (nagios@nagios.org) * Last Modified: 12-14-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. * *****************************************************************************/ #include "../include/config.h" #include "../include/common.h" #include "../include/comments.h" #include "../include/downtime.h" #include "../include/statusdata.h" #include "../include/perfdata.h" #include "../include/sretention.h" #include "../include/broker.h" #include "../include/nagios.h" extern char *config_file; extern char *log_file; extern char *command_file; extern char *temp_file; extern int sigshutdown; extern int sigrestart; extern int check_external_commands; extern int ipc_pipe[2]; extern time_t last_command_check; extern time_t last_command_status_update; extern int command_check_interval; extern int enable_notifications; extern int execute_service_checks; extern int accept_passive_service_checks; extern int execute_host_checks; extern int accept_passive_host_checks; extern int enable_event_handlers; extern int obsess_over_services; extern int obsess_over_hosts; extern int check_service_freshness; extern int check_host_freshness; extern int enable_failure_prediction; extern int process_performance_data; extern int log_external_commands; extern int log_passive_checks; extern unsigned long modified_host_process_attributes; extern unsigned long modified_service_process_attributes; extern char *global_host_event_handler; extern char *global_service_event_handler; extern timed_event *event_list_high; extern timed_event *event_list_low; extern host *host_list; extern service *service_list; extern FILE *command_file_fp; extern int command_file_fd; passive_check_result *passive_check_result_list=NULL; passive_check_result *passive_check_result_list_tail=NULL; extern pthread_t worker_threads[TOTAL_WORKER_THREADS]; extern circular_buffer external_command_buffer; /******************************************************************/ /****************** EXTERNAL COMMAND PROCESSING *******************/ /******************************************************************/ /* checks for the existence of the external command file and processes all commands found in it */ void check_for_external_commands(void){ char buffer[MAX_INPUT_BUFFER]; char command_id[MAX_INPUT_BUFFER]; char args[MAX_INPUT_BUFFER]; time_t entry_time; int command_type=CMD_NONE; char *temp_ptr; int update_status=FALSE; #ifdef DEBUG0 printf("check_for_external_commands() start\n"); #endif /* bail out if we shouldn't be checking for external commands */ if(check_external_commands==FALSE) return; /* update last command check time */ last_command_check=time(NULL); /* update the status log with new program information */ /* go easy on the frequency of this if we're checking often - only update program status every 10 seconds.... */ if(last_command_check<(last_command_status_update+10)) update_status=FALSE; else update_status=TRUE; if(update_status==TRUE){ last_command_status_update=last_command_check; update_program_status(FALSE); } /* reset passive check result list pointers */ passive_check_result_list=NULL; passive_check_result_list_tail=NULL; /* process all commands found in the buffer */ while(1){ /* get a lock on the buffer */ pthread_mutex_lock(&external_command_buffer.buffer_lock); /* if no items present, bail out */ if(external_command_buffer.items<=0){ pthread_mutex_unlock(&external_command_buffer.buffer_lock); break; } if(external_command_buffer.buffer[external_command_buffer.tail]){ strncpy(buffer,((char **)external_command_buffer.buffer)[external_command_buffer.tail],sizeof(buffer)-1); buffer[sizeof(buffer)-1]='\x0'; } else strcpy(buffer,""); /* free memory allocated for buffer slot */ free(((char **)external_command_buffer.buffer)[external_command_buffer.tail]); /* adjust tail counter and number of items */ external_command_buffer.tail=(external_command_buffer.tail + 1) % COMMAND_BUFFER_SLOTS; external_command_buffer.items--; /* release the lock on the buffer */ pthread_mutex_unlock(&external_command_buffer.buffer_lock); /* strip the buffer of newlines and carriage returns */ strip(buffer); #ifdef DEBUG3 printf("\tRaw command entry: %s\n",buffer); #endif /* get the command entry time */ temp_ptr=my_strtok(buffer,"["); if(temp_ptr==NULL) continue; temp_ptr=my_strtok(NULL,"]"); if(temp_ptr==NULL) continue; entry_time=(time_t)strtoul(temp_ptr,NULL,10); /* get the command identifier */ temp_ptr=my_strtok(NULL,";"); if(temp_ptr==NULL) continue; strncpy(command_id,temp_ptr+1,sizeof(command_id)-1); command_id[sizeof(command_id)-1]='\x0'; /* get the command arguments */ temp_ptr=my_strtok(NULL,"\n"); if(temp_ptr==NULL) strcpy(args,""); else{ strncpy(args,temp_ptr,sizeof(args)-1); args[sizeof(args)-1]='\x0'; } /* decide what type of command this is... */ /**************************/ /**** PROCESS COMMANDS ****/ /**************************/ if(!strcmp(command_id,"ENTER_STANDBY_MODE") || !strcmp(command_id,"DISABLE_NOTIFICATIONS")) command_type=CMD_DISABLE_NOTIFICATIONS; else if(!strcmp(command_id,"ENTER_ACTIVE_MODE") || !strcmp(command_id,"ENABLE_NOTIFICATIONS")) command_type=CMD_ENABLE_NOTIFICATIONS; else if(!strcmp(command_id,"SHUTDOWN_PROGRAM")) command_type=CMD_SHUTDOWN_PROCESS; else if(!strcmp(command_id,"RESTART_PROGRAM")) command_type=CMD_RESTART_PROCESS; else if(!strcmp(command_id,"SAVE_STATE_INFORMATION")) command_type=CMD_SAVE_STATE_INFORMATION; else if(!strcmp(command_id,"READ_STATE_INFORMATION")) command_type=CMD_READ_STATE_INFORMATION; else if(!strcmp(command_id,"ENABLE_EVENT_HANDLERS")) command_type=CMD_ENABLE_EVENT_HANDLERS; else if(!strcmp(command_id,"DISABLE_EVENT_HANDLERS")) command_type=CMD_DISABLE_EVENT_HANDLERS; else if(!strcmp(command_id,"FLUSH_PENDING_COMMANDS")) command_type=CMD_FLUSH_PENDING_COMMANDS; else if(!strcmp(command_id,"ENABLE_FAILURE_PREDICTION")) command_type=CMD_ENABLE_FAILURE_PREDICTION; else if(!strcmp(command_id,"DISABLE_FAILURE_PREDICTION")) command_type=CMD_DISABLE_FAILURE_PREDICTION; else if(!strcmp(command_id,"ENABLE_PERFORMANCE_DATA")) command_type=CMD_ENABLE_PERFORMANCE_DATA; else if(!strcmp(command_id,"DISABLE_PERFORMANCE_DATA")) command_type=CMD_DISABLE_PERFORMANCE_DATA; else if(!strcmp(command_id,"START_EXECUTING_HOST_CHECKS")) command_type=CMD_START_EXECUTING_HOST_CHECKS; else if(!strcmp(command_id,"STOP_EXECUTING_HOST_CHECKS")) command_type=CMD_STOP_EXECUTING_HOST_CHECKS; else if(!strcmp(command_id,"START_EXECUTING_SVC_CHECKS")) command_type=CMD_START_EXECUTING_SVC_CHECKS; else if(!strcmp(command_id,"STOP_EXECUTING_SVC_CHECKS")) command_type=CMD_STOP_EXECUTING_SVC_CHECKS; else if(!strcmp(command_id,"START_ACCEPTING_PASSIVE_HOST_CHECKS")) command_type=CMD_START_ACCEPTING_PASSIVE_HOST_CHECKS; else if(!strcmp(command_id,"STOP_ACCEPTING_PASSIVE_HOST_CHECKS")) command_type=CMD_STOP_ACCEPTING_PASSIVE_HOST_CHECKS; else if(!strcmp(command_id,"START_ACCEPTING_PASSIVE_SVC_CHECKS")) command_type=CMD_START_ACCEPTING_PASSIVE_SVC_CHECKS; else if(!strcmp(command_id,"STOP_ACCEPTING_PASSIVE_SVC_CHECKS")) command_type=CMD_STOP_ACCEPTING_PASSIVE_SVC_CHECKS; else if(!strcmp(command_id,"START_OBSESSING_OVER_HOST_CHECKS")) command_type=CMD_START_OBSESSING_OVER_HOST_CHECKS; else if(!strcmp(command_id,"STOP_OBSESSING_OVER_HOST_CHECKS")) command_type=CMD_STOP_OBSESSING_OVER_HOST_CHECKS; else if(!strcmp(command_id,"START_OBSESSING_OVER_SVC_CHECKS")) command_type=CMD_START_OBSESSING_OVER_SVC_CHECKS; else if(!strcmp(command_id,"STOP_OBSESSING_OVER_SVC_CHECKS")) command_type=CMD_STOP_OBSESSING_OVER_SVC_CHECKS; else if(!strcmp(command_id,"ENABLE_FLAP_DETECTION")) command_type=CMD_ENABLE_FLAP_DETECTION; else if(!strcmp(command_id,"DISABLE_FLAP_DETECTION")) command_type=CMD_DISABLE_FLAP_DETECTION; else if(!strcmp(command_id,"CHANGE_GLOBAL_HOST_EVENT_HANDLER")) command_type=CMD_CHANGE_GLOBAL_HOST_EVENT_HANDLER; else if(!strcmp(command_id,"CHANGE_GLOBAL_SVC_EVENT_HANDLER")) command_type=CMD_CHANGE_GLOBAL_SVC_EVENT_HANDLER; else if(!strcmp(command_id,"ENABLE_SERVICE_FRESHNESS_CHECKS")) command_type=CMD_ENABLE_SERVICE_FRESHNESS_CHECKS; else if(!strcmp(command_id,"DISABLE_SERVICE_FRESHNESS_CHECKS")) command_type=CMD_DISABLE_SERVICE_FRESHNESS_CHECKS; else if(!strcmp(command_id,"ENABLE_HOST_FRESHNESS_CHECKS")) command_type=CMD_ENABLE_HOST_FRESHNESS_CHECKS; else if(!strcmp(command_id,"DISABLE_HOST_FRESHNESS_CHECKS")) command_type=CMD_DISABLE_HOST_FRESHNESS_CHECKS; /*******************************/ /**** HOST-RELATED COMMANDS ****/ /*******************************/ else if(!strcmp(command_id,"ADD_HOST_COMMENT")) command_type=CMD_ADD_HOST_COMMENT; else if(!strcmp(command_id,"DEL_HOST_COMMENT")) command_type=CMD_DEL_HOST_COMMENT; else if(!strcmp(command_id,"DEL_ALL_HOST_COMMENTS")) command_type=CMD_DEL_ALL_HOST_COMMENTS; else if(!strcmp(command_id,"DELAY_HOST_NOTIFICATION")) command_type=CMD_DELAY_HOST_NOTIFICATION; else if(!strcmp(command_id,"ENABLE_HOST_NOTIFICATIONS")) command_type=CMD_ENABLE_HOST_NOTIFICATIONS; else if(!strcmp(command_id,"DISABLE_HOST_NOTIFICATIONS")) command_type=CMD_DISABLE_HOST_NOTIFICATIONS; else if(!strcmp(command_id,"ENABLE_ALL_NOTIFICATIONS_BEYOND_HOST")) command_type=CMD_ENABLE_ALL_NOTIFICATIONS_BEYOND_HOST; else if(!strcmp(command_id,"DISABLE_ALL_NOTIFICATIONS_BEYOND_HOST")) command_type=CMD_DISABLE_ALL_NOTIFICATIONS_BEYOND_HOST; else if(!strcmp(command_id,"ENABLE_HOST_AND_CHILD_NOTIFICATIONS")) command_type=CMD_ENABLE_HOST_AND_CHILD_NOTIFICATIONS; else if(!strcmp(command_id,"DISABLE_HOST_AND_CHILD_NOTIFICATIONS")) command_type=CMD_DISABLE_HOST_AND_CHILD_NOTIFICATIONS; else if(!strcmp(command_id,"ENABLE_HOST_SVC_NOTIFICATIONS")) command_type=CMD_ENABLE_HOST_SVC_NOTIFICATIONS; else if(!strcmp(command_id,"DISABLE_HOST_SVC_NOTIFICATIONS")) command_type=CMD_DISABLE_HOST_SVC_NOTIFICATIONS; else if(!strcmp(command_id,"ENABLE_HOST_SVC_CHECKS")) command_type=CMD_ENABLE_HOST_SVC_CHECKS; else if(!strcmp(command_id,"DISABLE_HOST_SVC_CHECKS")) command_type=CMD_DISABLE_HOST_SVC_CHECKS; else if(!strcmp(command_id,"ENABLE_PASSIVE_HOST_CHECKS")) command_type=CMD_ENABLE_PASSIVE_HOST_CHECKS; else if(!strcmp(command_id,"DISABLE_PASSIVE_HOST_CHECKS")) command_type=CMD_DISABLE_PASSIVE_HOST_CHECKS; else if(!strcmp(command_id,"SCHEDULE_HOST_SVC_CHECKS")) command_type=CMD_SCHEDULE_HOST_SVC_CHECKS; else if(!strcmp(command_id,"SCHEDULE_FORCED_HOST_SVC_CHECKS")) command_type=CMD_SCHEDULE_FORCED_HOST_SVC_CHECKS; else if(!strcmp(command_id,"ACKNOWLEDGE_HOST_PROBLEM")) command_type=CMD_ACKNOWLEDGE_HOST_PROBLEM; else if(!strcmp(command_id,"REMOVE_HOST_ACKNOWLEDGEMENT")) command_type=CMD_REMOVE_HOST_ACKNOWLEDGEMENT; else if(!strcmp(command_id,"ENABLE_HOST_EVENT_HANDLER")) command_type=CMD_ENABLE_HOST_EVENT_HANDLER; else if(!strcmp(command_id,"DISABLE_HOST_EVENT_HANDLER")) command_type=CMD_DISABLE_HOST_EVENT_HANDLER; else if(!strcmp(command_id,"ENABLE_HOST_CHECK")) command_type=CMD_ENABLE_HOST_CHECK; else if(!strcmp(command_id,"DISABLE_HOST_CHECK")) command_type=CMD_DISABLE_HOST_CHECK; else if(!strcmp(command_id,"SCHEDULE_HOST_CHECK")) command_type=CMD_SCHEDULE_HOST_CHECK; else if(!strcmp(command_id,"SCHEDULE_FORCED_HOST_CHECK")) command_type=CMD_SCHEDULE_FORCED_HOST_CHECK; else if(!strcmp(command_id,"SCHEDULE_HOST_DOWNTIME")) command_type=CMD_SCHEDULE_HOST_DOWNTIME; else if(!strcmp(command_id,"SCHEDULE_HOST_SVC_DOWNTIME")) command_type=CMD_SCHEDULE_HOST_SVC_DOWNTIME; else if(!strcmp(command_id,"DEL_HOST_DOWNTIME")) command_type=CMD_DEL_HOST_DOWNTIME; else if(!strcmp(command_id,"ENABLE_HOST_FLAP_DETECTION")) command_type=CMD_ENABLE_HOST_FLAP_DETECTION; else if(!strcmp(command_id,"DISABLE_HOST_FLAP_DETECTION")) command_type=CMD_DISABLE_HOST_FLAP_DETECTION; else if(!strcmp(command_id,"START_OBSESSING_OVER_HOST")) command_type=CMD_START_OBSESSING_OVER_HOST; else if(!strcmp(command_id,"STOP_OBSESSING_OVER_HOST")) command_type=CMD_STOP_OBSESSING_OVER_HOST; else if(!strcmp(command_id,"CHANGE_HOST_EVENT_HANDLER")) command_type=CMD_CHANGE_HOST_EVENT_HANDLER; else if(!strcmp(command_id,"CHANGE_HOST_CHECK_COMMAND")) command_type=CMD_CHANGE_HOST_CHECK_COMMAND; else if(!strcmp(command_id,"CHANGE_NORMAL_HOST_CHECK_INTERVAL")) command_type=CMD_CHANGE_NORMAL_HOST_CHECK_INTERVAL; else if(!strcmp(command_id,"CHANGE_MAX_HOST_CHECK_ATTEMPTS")) command_type=CMD_CHANGE_MAX_HOST_CHECK_ATTEMPTS; else if(!strcmp(command_id,"SCHEDULE_AND_PROPAGATE_TRIGGERED_HOST_DOWNTIME")) command_type=CMD_SCHEDULE_AND_PROPAGATE_TRIGGERED_HOST_DOWNTIME; else if(!strcmp(command_id,"SCHEDULE_AND_PROPAGATE_HOST_DOWNTIME")) command_type=CMD_SCHEDULE_AND_PROPAGATE_HOST_DOWNTIME; else if(!strcmp(command_id,"SET_HOST_NOTIFICATION_NUMBER")) command_type=CMD_SET_HOST_NOTIFICATION_NUMBER; /************************************/ /**** HOSTGROUP-RELATED COMMANDS ****/ /************************************/ else if(!strcmp(command_id,"ENABLE_HOSTGROUP_HOST_NOTIFICATIONS")) command_type=CMD_ENABLE_HOSTGROUP_HOST_NOTIFICATIONS; else if(!strcmp(command_id,"DISABLE_HOSTGROUP_HOST_NOTIFICATIONS")) command_type=CMD_DISABLE_HOSTGROUP_HOST_NOTIFICATIONS; else if(!strcmp(command_id,"ENABLE_HOSTGROUP_SVC_NOTIFICATIONS")) command_type=CMD_ENABLE_HOSTGROUP_SVC_NOTIFICATIONS; else if(!strcmp(command_id,"DISABLE_HOSTGROUP_SVC_NOTIFICATIONS")) command_type=CMD_DISABLE_HOSTGROUP_SVC_NOTIFICATIONS; else if(!strcmp(command_id,"ENABLE_HOSTGROUP_HOST_CHECKS")) command_type=CMD_ENABLE_HOSTGROUP_HOST_CHECKS; else if(!strcmp(command_id,"DISABLE_HOSTGROUP_HOST_CHECKS")) command_type=CMD_DISABLE_HOSTGROUP_HOST_CHECKS; else if(!strcmp(command_id,"ENABLE_HOSTGROUP_PASSIVE_HOST_CHECKS")) command_type=CMD_ENABLE_HOSTGROUP_PASSIVE_HOST_CHECKS; else if(!strcmp(command_id,"DISABLE_HOSTGROUP_PASSIVE_HOST_CHECKS")) command_type=CMD_DISABLE_HOSTGROUP_PASSIVE_HOST_CHECKS; else if(!strcmp(command_id,"ENABLE_HOSTGROUP_SVC_CHECKS")) command_type=CMD_ENABLE_HOSTGROUP_SVC_CHECKS; else if(!strcmp(command_id,"DISABLE_HOSTGROUP_SVC_CHECKS")) command_type=CMD_DISABLE_HOSTGROUP_SVC_CHECKS; else if(!strcmp(command_id,"ENABLE_HOSTGROUP_PASSIVE_SVC_CHECKS")) command_type=CMD_ENABLE_HOSTGROUP_PASSIVE_SVC_CHECKS; else if(!strcmp(command_id,"DISABLE_HOSTGROUP_PASSIVE_SVC_CHECKS")) command_type=CMD_DISABLE_HOSTGROUP_PASSIVE_SVC_CHECKS; else if(!strcmp(command_id,"SCHEDULE_HOSTGROUP_HOST_DOWNTIME")) command_type=CMD_SCHEDULE_HOSTGROUP_HOST_DOWNTIME; else if(!strcmp(command_id,"SCHEDULE_HOSTGROUP_SVC_DOWNTIME")) command_type=CMD_SCHEDULE_HOSTGROUP_SVC_DOWNTIME; /**********************************/ /**** SERVICE-RELATED COMMANDS ****/ /**********************************/ else if(!strcmp(command_id,"ADD_SVC_COMMENT")) command_type=CMD_ADD_SVC_COMMENT; else if(!strcmp(command_id,"DEL_SVC_COMMENT")) command_type=CMD_DEL_SVC_COMMENT; else if(!strcmp(command_id,"DEL_ALL_SVC_COMMENTS")) command_type=CMD_DEL_ALL_SVC_COMMENTS; else if(!strcmp(command_id,"SCHEDULE_SVC_CHECK")) command_type=CMD_SCHEDULE_SVC_CHECK; else if(!strcmp(command_id,"SCHEDULE_FORCED_SVC_CHECK")) command_type=CMD_SCHEDULE_FORCED_SVC_CHECK; else if(!strcmp(command_id,"ENABLE_SVC_CHECK")) command_type=CMD_ENABLE_SVC_CHECK; else if(!strcmp(command_id,"DISABLE_SVC_CHECK")) command_type=CMD_DISABLE_SVC_CHECK; else if(!strcmp(command_id,"ENABLE_PASSIVE_SVC_CHECKS")) command_type=CMD_ENABLE_PASSIVE_SVC_CHECKS; else if(!strcmp(command_id,"DISABLE_PASSIVE_SVC_CHECKS")) command_type=CMD_DISABLE_PASSIVE_SVC_CHECKS; else if(!strcmp(command_id,"DELAY_SVC_NOTIFICATION")) command_type=CMD_DELAY_SVC_NOTIFICATION; else if(!strcmp(command_id,"ENABLE_SVC_NOTIFICATIONS")) command_type=CMD_ENABLE_SVC_NOTIFICATIONS; else if(!strcmp(command_id,"DISABLE_SVC_NOTIFICATIONS")) command_type=CMD_DISABLE_SVC_NOTIFICATIONS; else if(!strcmp(command_id,"PROCESS_SERVICE_CHECK_RESULT")) command_type=CMD_PROCESS_SERVICE_CHECK_RESULT; else if(!strcmp(command_id,"PROCESS_HOST_CHECK_RESULT")) command_type=CMD_PROCESS_HOST_CHECK_RESULT; else if(!strcmp(command_id,"ENABLE_SVC_EVENT_HANDLER")) command_type=CMD_ENABLE_SVC_EVENT_HANDLER; else if(!strcmp(command_id,"DISABLE_SVC_EVENT_HANDLER")) command_type=CMD_DISABLE_SVC_EVENT_HANDLER; else if(!strcmp(command_id,"ENABLE_SVC_FLAP_DETECTION")) command_type=CMD_ENABLE_SVC_FLAP_DETECTION; else if(!strcmp(command_id,"DISABLE_SVC_FLAP_DETECTION")) command_type=CMD_DISABLE_SVC_FLAP_DETECTION; else if(!strcmp(command_id,"SCHEDULE_SVC_DOWNTIME")) command_type=CMD_SCHEDULE_SVC_DOWNTIME; else if(!strcmp(command_id,"DEL_SVC_DOWNTIME")) command_type=CMD_DEL_SVC_DOWNTIME; else if(!strcmp(command_id,"ACKNOWLEDGE_SVC_PROBLEM")) command_type=CMD_ACKNOWLEDGE_SVC_PROBLEM; else if(!strcmp(command_id,"REMOVE_SVC_ACKNOWLEDGEMENT")) command_type=CMD_REMOVE_SVC_ACKNOWLEDGEMENT; else if(!strcmp(command_id,"START_OBSESSING_OVER_SVC")) command_type=CMD_START_OBSESSING_OVER_SVC; else if(!strcmp(command_id,"STOP_OBSESSING_OVER_SVC")) command_type=CMD_STOP_OBSESSING_OVER_SVC; else if(!strcmp(command_id,"CHANGE_SVC_EVENT_HANDLER")) command_type=CMD_CHANGE_SVC_EVENT_HANDLER; else if(!strcmp(command_id,"CHANGE_SVC_CHECK_COMMAND")) command_type=CMD_CHANGE_SVC_CHECK_COMMAND; else if(!strcmp(command_id,"CHANGE_NORMAL_SVC_CHECK_INTERVAL")) command_type=CMD_CHANGE_NORMAL_SVC_CHECK_INTERVAL; else if(!strcmp(command_id,"CHANGE_RETRY_SVC_CHECK_INTERVAL")) command_type=CMD_CHANGE_RETRY_SVC_CHECK_INTERVAL; else if(!strcmp(command_id,"CHANGE_MAX_SVC_CHECK_ATTEMPTS")) command_type=CMD_CHANGE_MAX_SVC_CHECK_ATTEMPTS; else if(!strcmp(command_id,"SET_SVC_NOTIFICATION_NUMBER")) command_type=CMD_SET_SVC_NOTIFICATION_NUMBER; /***************************************/ /**** SERVICEGROUP-RELATED COMMANDS ****/ /***************************************/ else if(!strcmp(command_id,"ENABLE_SERVICEGROUP_HOST_NOTIFICATIONS")) command_type=CMD_ENABLE_SERVICEGROUP_HOST_NOTIFICATIONS; else if(!strcmp(command_id,"DISABLE_SERVICEGROUP_HOST_NOTIFICATIONS")) command_type=CMD_DISABLE_SERVICEGROUP_HOST_NOTIFICATIONS; else if(!strcmp(command_id,"ENABLE_SERVICEGROUP_SVC_NOTIFICATIONS")) command_type=CMD_ENABLE_SERVICEGROUP_SVC_NOTIFICATIONS; else if(!strcmp(command_id,"DISABLE_SERVICEGROUP_SVC_NOTIFICATIONS")) command_type=CMD_DISABLE_SERVICEGROUP_SVC_NOTIFICATIONS; else if(!strcmp(command_id,"ENABLE_SERVICEGROUP_HOST_CHECKS")) command_type=CMD_ENABLE_SERVICEGROUP_HOST_CHECKS; else if(!strcmp(command_id,"DISABLE_SERVICEGROUP_HOST_CHECKS")) command_type=CMD_DISABLE_SERVICEGROUP_HOST_CHECKS; else if(!strcmp(command_id,"ENABLE_SERVICEGROUP_PASSIVE_HOST_CHECKS")) command_type=CMD_ENABLE_SERVICEGROUP_PASSIVE_HOST_CHECKS; else if(!strcmp(command_id,"DISABLE_SERVICEGROUP_PASSIVE_HOST_CHECKS")) command_type=CMD_DISABLE_SERVICEGROUP_PASSIVE_HOST_CHECKS; else if(!strcmp(command_id,"ENABLE_SERVICEGROUP_SVC_CHECKS")) command_type=CMD_ENABLE_SERVICEGROUP_SVC_CHECKS; else if(!strcmp(command_id,"DISABLE_SERVICEGROUP_SVC_CHECKS")) command_type=CMD_DISABLE_SERVICEGROUP_SVC_CHECKS; else if(!strcmp(command_id,"ENABLE_SERVICEGROUP_PASSIVE_SVC_CHECKS")) command_type=CMD_ENABLE_SERVICEGROUP_PASSIVE_SVC_CHECKS; else if(!strcmp(command_id,"DISABLE_SERVICEGROUP_PASSIVE_SVC_CHECKS")) command_type=CMD_DISABLE_SERVICEGROUP_PASSIVE_SVC_CHECKS; else if(!strcmp(command_id,"SCHEDULE_SERVICEGROUP_HOST_DOWNTIME")) command_type=CMD_SCHEDULE_SERVICEGROUP_HOST_DOWNTIME; else if(!strcmp(command_id,"SCHEDULE_SERVICEGROUP_SVC_DOWNTIME")) command_type=CMD_SCHEDULE_SERVICEGROUP_SVC_DOWNTIME; /**** UNKNOWN COMMAND ****/ else{ /* log the bad external command */ snprintf(buffer,sizeof(buffer),"Warning: Unrecognized external command -> %s;%s\n",command_id,args); buffer[sizeof(buffer)-1]='\x0'; write_to_all_logs(buffer,NSLOG_EXTERNAL_COMMAND | NSLOG_RUNTIME_WARNING); continue; } /* log the external command */ snprintf(buffer,sizeof(buffer),"EXTERNAL COMMAND: %s;%s\n",command_id,args); buffer[sizeof(buffer)-1]='\x0'; if(command_type==CMD_PROCESS_SERVICE_CHECK_RESULT){ if(log_passive_checks==TRUE) write_to_all_logs(buffer,NSLOG_PASSIVE_CHECK); } else{ if(log_external_commands==TRUE) write_to_all_logs(buffer,NSLOG_EXTERNAL_COMMAND); } #ifdef USE_EVENT_BROKER /* send data to event broker */ broker_external_command(NEBTYPE_EXTERNALCOMMAND_START,NEBFLAG_NONE,NEBATTR_NONE,command_type,entry_time,command_id,args,NULL); #endif /* process the command if its not a passive check */ process_external_command(command_type,entry_time,args); #ifdef USE_EVENT_BROKER /* send data to event broker */ broker_external_command(NEBTYPE_EXTERNALCOMMAND_END,NEBFLAG_NONE,NEBATTR_NONE,command_type,entry_time,command_id,args,NULL); #endif } /**** PROCESS ALL PASSIVE SERVICE CHECK RESULTS AT ONE TIME ****/ if(passive_check_result_list!=NULL) process_passive_service_checks(); #ifdef DEBUG0 printf("check_for_external_commands() end\n"); #endif return; } /* top-level processor for a single external command */ void process_external_command(int cmd, time_t entry_time, char *args){ #ifdef DEBUG0 printf("process_external_command() start\n"); #endif #ifdef DEBUG3 printf("\tExternal Command Type: %d\n",cmd); printf("\tCommand Entry Time: %lu\n",(unsigned long)entry_time); printf("\tCommand Arguments: %s\n",args); #endif /* how shall we execute the command? */ switch(cmd){ /***************************/ /***** SYSTEM COMMANDS *****/ /***************************/ case CMD_SHUTDOWN_PROCESS: case CMD_RESTART_PROCESS: cmd_signal_process(cmd,args); break; case CMD_SAVE_STATE_INFORMATION: save_state_information(config_file,FALSE); break; case CMD_READ_STATE_INFORMATION: read_initial_state_information(config_file); break; case CMD_ENABLE_NOTIFICATIONS: enable_all_notifications(); break; case CMD_DISABLE_NOTIFICATIONS: disable_all_notifications(); break; case CMD_START_EXECUTING_SVC_CHECKS: start_executing_service_checks(); break; case CMD_STOP_EXECUTING_SVC_CHECKS: stop_executing_service_checks(); break; case CMD_START_ACCEPTING_PASSIVE_SVC_CHECKS: start_accepting_passive_service_checks(); break; case CMD_STOP_ACCEPTING_PASSIVE_SVC_CHECKS: stop_accepting_passive_service_checks(); break; case CMD_START_OBSESSING_OVER_SVC_CHECKS: start_obsessing_over_service_checks(); break; case CMD_STOP_OBSESSING_OVER_SVC_CHECKS: stop_obsessing_over_service_checks(); break; case CMD_START_EXECUTING_HOST_CHECKS: start_executing_host_checks(); break; case CMD_STOP_EXECUTING_HOST_CHECKS: stop_executing_host_checks(); break; case CMD_START_ACCEPTING_PASSIVE_HOST_CHECKS: start_accepting_passive_host_checks(); break; case CMD_STOP_ACCEPTING_PASSIVE_HOST_CHECKS: stop_accepting_passive_host_checks(); break; case CMD_START_OBSESSING_OVER_HOST_CHECKS: start_obsessing_over_host_checks(); break; case CMD_STOP_OBSESSING_OVER_HOST_CHECKS: stop_obsessing_over_host_checks(); break; case CMD_ENABLE_EVENT_HANDLERS: start_using_event_handlers(); break; case CMD_DISABLE_EVENT_HANDLERS: stop_using_event_handlers(); break; case CMD_ENABLE_FLAP_DETECTION: enable_flap_detection_routines(); break; case CMD_DISABLE_FLAP_DETECTION: disable_flap_detection_routines(); break; case CMD_ENABLE_SERVICE_FRESHNESS_CHECKS: enable_service_freshness_checks(); break; case CMD_DISABLE_SERVICE_FRESHNESS_CHECKS: disable_service_freshness_checks(); break; case CMD_ENABLE_HOST_FRESHNESS_CHECKS: enable_host_freshness_checks(); break; case CMD_DISABLE_HOST_FRESHNESS_CHECKS: disable_host_freshness_checks(); break; case CMD_ENABLE_FAILURE_PREDICTION: enable_all_failure_prediction(); break; case CMD_DISABLE_FAILURE_PREDICTION: disable_all_failure_prediction(); break; case CMD_ENABLE_PERFORMANCE_DATA: enable_performance_data(); break; case CMD_DISABLE_PERFORMANCE_DATA: disable_performance_data(); break; /***************************/ /***** HOST COMMANDS *****/ /***************************/ case CMD_ENABLE_HOST_CHECK: case CMD_DISABLE_HOST_CHECK: case CMD_ENABLE_PASSIVE_HOST_CHECKS: case CMD_DISABLE_PASSIVE_HOST_CHECKS: case CMD_ENABLE_HOST_SVC_CHECKS: case CMD_DISABLE_HOST_SVC_CHECKS: case CMD_ENABLE_HOST_NOTIFICATIONS: case CMD_DISABLE_HOST_NOTIFICATIONS: case CMD_ENABLE_ALL_NOTIFICATIONS_BEYOND_HOST: case CMD_DISABLE_ALL_NOTIFICATIONS_BEYOND_HOST: case CMD_ENABLE_HOST_AND_CHILD_NOTIFICATIONS: case CMD_DISABLE_HOST_AND_CHILD_NOTIFICATIONS: case CMD_ENABLE_HOST_SVC_NOTIFICATIONS: case CMD_DISABLE_HOST_SVC_NOTIFICATIONS: case CMD_ENABLE_HOST_FLAP_DETECTION: case CMD_DISABLE_HOST_FLAP_DETECTION: case CMD_ENABLE_HOST_EVENT_HANDLER: case CMD_DISABLE_HOST_EVENT_HANDLER: case CMD_START_OBSESSING_OVER_HOST: case CMD_STOP_OBSESSING_OVER_HOST: case CMD_SET_HOST_NOTIFICATION_NUMBER: process_host_command(cmd,entry_time,args); break; /*****************************/ /***** HOSTGROUP COMMANDS ****/ /*****************************/ case CMD_ENABLE_HOSTGROUP_HOST_NOTIFICATIONS: case CMD_DISABLE_HOSTGROUP_HOST_NOTIFICATIONS: case CMD_ENABLE_HOSTGROUP_SVC_NOTIFICATIONS: case CMD_DISABLE_HOSTGROUP_SVC_NOTIFICATIONS: case CMD_ENABLE_HOSTGROUP_HOST_CHECKS: case CMD_DISABLE_HOSTGROUP_HOST_CHECKS: case CMD_ENABLE_HOSTGROUP_PASSIVE_HOST_CHECKS: case CMD_DISABLE_HOSTGROUP_PASSIVE_HOST_CHECKS: case CMD_ENABLE_HOSTGROUP_SVC_CHECKS: case CMD_DISABLE_HOSTGROUP_SVC_CHECKS: case CMD_ENABLE_HOSTGROUP_PASSIVE_SVC_CHECKS: case CMD_DISABLE_HOSTGROUP_PASSIVE_SVC_CHECKS: process_hostgroup_command(cmd,entry_time,args); break; /***************************/ /***** SERVICE COMMANDS ****/ /***************************/ case CMD_ENABLE_SVC_CHECK: case CMD_DISABLE_SVC_CHECK: case CMD_ENABLE_PASSIVE_SVC_CHECKS: case CMD_DISABLE_PASSIVE_SVC_CHECKS: case CMD_ENABLE_SVC_NOTIFICATIONS: case CMD_DISABLE_SVC_NOTIFICATIONS: case CMD_ENABLE_SVC_FLAP_DETECTION: case CMD_DISABLE_SVC_FLAP_DETECTION: case CMD_ENABLE_SVC_EVENT_HANDLER: case CMD_DISABLE_SVC_EVENT_HANDLER: case CMD_START_OBSESSING_OVER_SVC: case CMD_STOP_OBSESSING_OVER_SVC: case CMD_SET_SVC_NOTIFICATION_NUMBER: process_service_command(cmd,entry_time,args); break; /********************************/ /***** SERVICEGROUP COMMANDS ****/ /********************************/ case CMD_ENABLE_SERVICEGROUP_HOST_NOTIFICATIONS: case CMD_DISABLE_SERVICEGROUP_HOST_NOTIFICATIONS: case CMD_ENABLE_SERVICEGROUP_SVC_NOTIFICATIONS: case CMD_DISABLE_SERVICEGROUP_SVC_NOTIFICATIONS: case CMD_ENABLE_SERVICEGROUP_HOST_CHECKS: case CMD_DISABLE_SERVICEGROUP_HOST_CHECKS: case CMD_ENABLE_SERVICEGROUP_PASSIVE_HOST_CHECKS: case CMD_DISABLE_SERVICEGROUP_PASSIVE_HOST_CHECKS: case CMD_ENABLE_SERVICEGROUP_SVC_CHECKS: case CMD_DISABLE_SERVICEGROUP_SVC_CHECKS: case CMD_ENABLE_SERVICEGROUP_PASSIVE_SVC_CHECKS: case CMD_DISABLE_SERVICEGROUP_PASSIVE_SVC_CHECKS: process_servicegroup_command(cmd,entry_time,args); break; /***************************/ /**** UNSORTED COMMANDS ****/ /***************************/ case CMD_ADD_HOST_COMMENT: case CMD_ADD_SVC_COMMENT: cmd_add_comment(cmd,entry_time,args); break; case CMD_DEL_HOST_COMMENT: case CMD_DEL_SVC_COMMENT: cmd_delete_comment(cmd,args); break; case CMD_DELAY_HOST_NOTIFICATION: case CMD_DELAY_SVC_NOTIFICATION: cmd_delay_notification(cmd,args); break; case CMD_SCHEDULE_SVC_CHECK: case CMD_SCHEDULE_FORCED_SVC_CHECK: cmd_schedule_check(cmd,args); break; case CMD_SCHEDULE_HOST_SVC_CHECKS: case CMD_SCHEDULE_FORCED_HOST_SVC_CHECKS: cmd_schedule_check(cmd,args); break; case CMD_DEL_ALL_HOST_COMMENTS: case CMD_DEL_ALL_SVC_COMMENTS: cmd_delete_all_comments(cmd,args); break; case CMD_PROCESS_SERVICE_CHECK_RESULT: cmd_process_service_check_result(cmd,entry_time,args); break; case CMD_PROCESS_HOST_CHECK_RESULT: cmd_process_host_check_result(cmd,entry_time,args); break; case CMD_ACKNOWLEDGE_HOST_PROBLEM: case CMD_ACKNOWLEDGE_SVC_PROBLEM: cmd_acknowledge_problem(cmd,args); break; case CMD_REMOVE_HOST_ACKNOWLEDGEMENT: case CMD_REMOVE_SVC_ACKNOWLEDGEMENT: cmd_remove_acknowledgement(cmd,args); break; case CMD_SCHEDULE_HOST_DOWNTIME: case CMD_SCHEDULE_SVC_DOWNTIME: case CMD_SCHEDULE_HOST_SVC_DOWNTIME: case CMD_SCHEDULE_HOSTGROUP_HOST_DOWNTIME: case CMD_SCHEDULE_HOSTGROUP_SVC_DOWNTIME: case CMD_SCHEDULE_SERVICEGROUP_HOST_DOWNTIME: case CMD_SCHEDULE_SERVICEGROUP_SVC_DOWNTIME: case CMD_SCHEDULE_AND_PROPAGATE_HOST_DOWNTIME: case CMD_SCHEDULE_AND_PROPAGATE_TRIGGERED_HOST_DOWNTIME: cmd_schedule_downtime(cmd,entry_time,args); break; case CMD_DEL_HOST_DOWNTIME: case CMD_DEL_SVC_DOWNTIME: cmd_delete_downtime(cmd,args); break; case CMD_CANCEL_ACTIVE_HOST_SVC_DOWNTIME: case CMD_CANCEL_PENDING_HOST_SVC_DOWNTIME: break; case CMD_SCHEDULE_HOST_CHECK: case CMD_SCHEDULE_FORCED_HOST_CHECK: cmd_schedule_check(cmd,args); break; case CMD_CHANGE_GLOBAL_HOST_EVENT_HANDLER: case CMD_CHANGE_GLOBAL_SVC_EVENT_HANDLER: case CMD_CHANGE_HOST_EVENT_HANDLER: case CMD_CHANGE_SVC_EVENT_HANDLER: case CMD_CHANGE_HOST_CHECK_COMMAND: case CMD_CHANGE_SVC_CHECK_COMMAND: cmd_change_command(cmd,args); break; case CMD_CHANGE_NORMAL_HOST_CHECK_INTERVAL: case CMD_CHANGE_NORMAL_SVC_CHECK_INTERVAL: case CMD_CHANGE_RETRY_SVC_CHECK_INTERVAL: cmd_change_check_interval(cmd,args); break; case CMD_CHANGE_MAX_HOST_CHECK_ATTEMPTS: case CMD_CHANGE_MAX_SVC_CHECK_ATTEMPTS: cmd_change_max_attempts(cmd,args); break; default: break; } #ifdef DEBUG0 printf("process_external_command() end\n"); #endif return; } /* processes an external host command */ int process_host_command(int cmd, time_t entry_time, char *args){ char *host_name=NULL; host *temp_host=NULL; service *temp_service; char *str=NULL; int intval; /* get the host name */ host_name=my_strtok(args,";"); if(host_name==NULL) return ERROR; /* find the host */ temp_host=find_host(host_name); if(temp_host==NULL) return ERROR; switch(cmd){ case CMD_ENABLE_HOST_NOTIFICATIONS: enable_host_notifications(temp_host); break; case CMD_DISABLE_HOST_NOTIFICATIONS: disable_host_notifications(temp_host); break; case CMD_ENABLE_HOST_AND_CHILD_NOTIFICATIONS: enable_and_propagate_notifications(temp_host,0,TRUE,TRUE,FALSE); break; case CMD_DISABLE_HOST_AND_CHILD_NOTIFICATIONS: disable_and_propagate_notifications(temp_host,0,TRUE,TRUE,FALSE); break; case CMD_ENABLE_ALL_NOTIFICATIONS_BEYOND_HOST: enable_and_propagate_notifications(temp_host,0,FALSE,TRUE,TRUE); case CMD_DISABLE_ALL_NOTIFICATIONS_BEYOND_HOST: disable_and_propagate_notifications(temp_host,0,FALSE,TRUE,TRUE); case CMD_ENABLE_HOST_SVC_NOTIFICATIONS: case CMD_DISABLE_HOST_SVC_NOTIFICATIONS: for(temp_service=service_list;temp_service!=NULL;temp_service=temp_service->next){ if(!strcmp(temp_service->host_name,host_name)){ if(cmd==CMD_ENABLE_HOST_SVC_NOTIFICATIONS) enable_service_notifications(temp_service); else disable_service_notifications(temp_service); } } break; case CMD_ENABLE_HOST_SVC_CHECKS: case CMD_DISABLE_HOST_SVC_CHECKS: for(temp_service=service_list;temp_service!=NULL;temp_service=temp_service->next){ if(!strcmp(temp_service->host_name,host_name)){ if(cmd==CMD_ENABLE_HOST_SVC_CHECKS) enable_service_checks(temp_service); else disable_service_checks(temp_service); } } break; case CMD_ENABLE_HOST_CHECK: enable_host_checks(temp_host); break; case CMD_DISABLE_HOST_CHECK: disable_host_checks(temp_host); break; case CMD_ENABLE_HOST_EVENT_HANDLER: enable_host_event_handler(temp_host); break; case CMD_DISABLE_HOST_EVENT_HANDLER: disable_host_event_handler(temp_host); break; case CMD_ENABLE_HOST_FLAP_DETECTION: enable_host_flap_detection(temp_host); break; case CMD_DISABLE_HOST_FLAP_DETECTION: disable_host_flap_detection(temp_host); break; case CMD_ENABLE_PASSIVE_HOST_CHECKS: enable_passive_host_checks(temp_host); break; case CMD_DISABLE_PASSIVE_HOST_CHECKS: disable_passive_host_checks(temp_host); break; case CMD_START_OBSESSING_OVER_HOST: start_obsessing_over_host(temp_host); break; case CMD_STOP_OBSESSING_OVER_HOST: stop_obsessing_over_host(temp_host); break; case CMD_SET_HOST_NOTIFICATION_NUMBER: if((str=my_strtok(NULL,";"))){ intval=atoi(str); set_host_notification_number(temp_host,intval); } break; default: break; } return OK; } /* processes an external hostgroup command */ int process_hostgroup_command(int cmd, time_t entry_time, char *args){ char *hostgroup_name=NULL; hostgroup *temp_hostgroup=NULL; hostgroupmember *temp_member=NULL; host *temp_host=NULL; service *temp_service=NULL; /* get the hostgroup name */ hostgroup_name=my_strtok(args,";"); if(hostgroup_name==NULL) return ERROR; /* find the hostgroup */ temp_hostgroup=find_hostgroup(hostgroup_name); if(temp_hostgroup==NULL) return ERROR; /* loop through all hosts in the hostgroup */ for(temp_member=temp_hostgroup->members;temp_member!=NULL;temp_member=temp_member->next){ temp_host=find_host(temp_member->host_name); if(temp_host==NULL) continue; switch(cmd){ case CMD_ENABLE_HOSTGROUP_HOST_NOTIFICATIONS: enable_host_notifications(temp_host); break; case CMD_DISABLE_HOSTGROUP_HOST_NOTIFICATIONS: disable_host_notifications(temp_host); break; case CMD_ENABLE_HOSTGROUP_HOST_CHECKS: enable_host_checks(temp_host); break; case CMD_DISABLE_HOSTGROUP_HOST_CHECKS: disable_host_checks(temp_host); break; case CMD_ENABLE_HOSTGROUP_PASSIVE_HOST_CHECKS: enable_passive_host_checks(temp_host); break; case CMD_DISABLE_HOSTGROUP_PASSIVE_HOST_CHECKS: disable_passive_host_checks(temp_host); break; default: /* loop through all services on the host */ for(temp_service=service_list;temp_service!=NULL;temp_service=temp_service->next){ if(!strcmp(temp_service->host_name,temp_host->name)){ switch(cmd){ case CMD_ENABLE_HOSTGROUP_SVC_NOTIFICATIONS: enable_service_notifications(temp_service); break; case CMD_DISABLE_HOSTGROUP_SVC_NOTIFICATIONS: disable_service_notifications(temp_service); break; case CMD_ENABLE_HOSTGROUP_SVC_CHECKS: enable_service_checks(temp_service); break; case CMD_DISABLE_HOSTGROUP_SVC_CHECKS: disable_service_checks(temp_service); break; case CMD_ENABLE_HOSTGROUP_PASSIVE_SVC_CHECKS: enable_passive_service_checks(temp_service); break; case CMD_DISABLE_HOSTGROUP_PASSIVE_SVC_CHECKS: disable_passive_service_checks(temp_service); break; default: break; } } } break; } } return OK; } /* processes an external service command */ int process_service_command(int cmd, time_t entry_time, char *args){ char *host_name=NULL; char *svc_description=NULL; service *temp_service=NULL; char *str=NULL; int intval; /* get the host name */ host_name=my_strtok(args,";"); if(host_name==NULL) return ERROR; /* get the service description */ svc_description=my_strtok(NULL,";"); if(svc_description==NULL) return ERROR; /* find the service */ temp_service=find_service(host_name,svc_description); if(temp_service==NULL) return ERROR; switch(cmd){ case CMD_ENABLE_SVC_NOTIFICATIONS: enable_service_notifications(temp_service); break; case CMD_DISABLE_SVC_NOTIFICATIONS: disable_service_notifications(temp_service); break; case CMD_ENABLE_SVC_CHECK: enable_service_checks(temp_service); break; case CMD_DISABLE_SVC_CHECK: disable_service_checks(temp_service); break; case CMD_ENABLE_SVC_EVENT_HANDLER: enable_service_event_handler(temp_service); break; case CMD_DISABLE_SVC_EVENT_HANDLER: disable_service_event_handler(temp_service); break; case CMD_ENABLE_SVC_FLAP_DETECTION: enable_service_flap_detection(temp_service); break; case CMD_DISABLE_SVC_FLAP_DETECTION: disable_service_flap_detection(temp_service); break; case CMD_ENABLE_PASSIVE_SVC_CHECKS: enable_passive_service_checks(temp_service); break; case CMD_DISABLE_PASSIVE_SVC_CHECKS: disable_passive_service_checks(temp_service); break; case CMD_START_OBSESSING_OVER_SVC: start_obsessing_over_service(temp_service); break; case CMD_STOP_OBSESSING_OVER_SVC: stop_obsessing_over_service(temp_service); break; case CMD_SET_SVC_NOTIFICATION_NUMBER: if((str=my_strtok(NULL,";"))){ intval=atoi(str); set_service_notification_number(temp_service,intval); } break; default: break; } return OK; } /* processes an external servicegroup command */ int process_servicegroup_command(int cmd, time_t entry_time, char *args){ char *servicegroup_name=NULL; servicegroup *temp_servicegroup=NULL; servicegroupmember *temp_member=NULL; host *temp_host=NULL; host *last_host=NULL; service *temp_service=NULL; /* get the servicegroup name */ servicegroup_name=my_strtok(args,";"); if(servicegroup_name==NULL) return ERROR; /* find the servicegroup */ temp_servicegroup=find_servicegroup(servicegroup_name); if(temp_servicegroup==NULL) return ERROR; switch(cmd){ case CMD_ENABLE_SERVICEGROUP_SVC_NOTIFICATIONS: case CMD_DISABLE_SERVICEGROUP_SVC_NOTIFICATIONS: case CMD_ENABLE_SERVICEGROUP_SVC_CHECKS: case CMD_DISABLE_SERVICEGROUP_SVC_CHECKS: case CMD_ENABLE_SERVICEGROUP_PASSIVE_SVC_CHECKS: case CMD_DISABLE_SERVICEGROUP_PASSIVE_SVC_CHECKS: /* loop through all servicegroup members */ for(temp_member=temp_servicegroup->members;temp_member!=NULL;temp_member=temp_member->next){ temp_service=find_service(temp_member->host_name,temp_member->service_description); if(temp_service==NULL) continue; switch(cmd){ case CMD_ENABLE_SERVICEGROUP_SVC_NOTIFICATIONS: enable_service_notifications(temp_service); break; case CMD_DISABLE_SERVICEGROUP_SVC_NOTIFICATIONS: disable_service_notifications(temp_service); break; case CMD_ENABLE_SERVICEGROUP_SVC_CHECKS: enable_service_checks(temp_service); break; case CMD_DISABLE_SERVICEGROUP_SVC_CHECKS: disable_service_checks(temp_service); break; case CMD_ENABLE_SERVICEGROUP_PASSIVE_SVC_CHECKS: enable_passive_service_checks(temp_service); break; case CMD_DISABLE_SERVICEGROUP_PASSIVE_SVC_CHECKS: disable_passive_service_checks(temp_service); break; default: break; } } break; case CMD_ENABLE_SERVICEGROUP_HOST_NOTIFICATIONS: case CMD_DISABLE_SERVICEGROUP_HOST_NOTIFICATIONS: case CMD_ENABLE_SERVICEGROUP_HOST_CHECKS: case CMD_DISABLE_SERVICEGROUP_HOST_CHECKS: case CMD_ENABLE_SERVICEGROUP_PASSIVE_HOST_CHECKS: case CMD_DISABLE_SERVICEGROUP_PASSIVE_HOST_CHECKS: /* loop through all hosts that have services belonging to the servicegroup */ last_host=NULL; for(temp_member=temp_servicegroup->members;temp_member!=NULL;temp_member=temp_member->next){ temp_host=find_host(temp_member->host_name); if(temp_host==NULL) continue; if(temp_host==last_host) continue; switch(cmd){ case CMD_ENABLE_SERVICEGROUP_HOST_NOTIFICATIONS: enable_host_notifications(temp_host); break; case CMD_DISABLE_SERVICEGROUP_HOST_NOTIFICATIONS: disable_host_notifications(temp_host); break; case CMD_ENABLE_SERVICEGROUP_HOST_CHECKS: enable_host_checks(temp_host); break; case CMD_DISABLE_SERVICEGROUP_HOST_CHECKS: disable_host_checks(temp_host); break; case CMD_ENABLE_SERVICEGROUP_PASSIVE_HOST_CHECKS: enable_passive_host_checks(temp_host); break; case CMD_DISABLE_SERVICEGROUP_PASSIVE_HOST_CHECKS: disable_passive_host_checks(temp_host); break; default: break; } last_host=temp_host; } break; default: break; } return OK; } /******************************************************************/ /*************** EXTERNAL COMMAND IMPLEMENTATIONS ****************/ /******************************************************************/ /* adds a host or service comment to the status log */ int cmd_add_comment(int cmd,time_t entry_time,char *args){ char *temp_ptr; host *temp_host; service *temp_service; char *host_name=""; char *svc_description=""; char *user; char *comment_data; int persistent=0; int result; #ifdef DEBUG0 printf("cmd_add_comment() start\n"); #endif /* get the host name */ host_name=my_strtok(args,";"); if(host_name==NULL) return ERROR; /* if we're adding a service comment... */ if(cmd==CMD_ADD_SVC_COMMENT){ /* get the service description */ svc_description=my_strtok(NULL,";"); if(svc_description==NULL) return ERROR; /* verify that the service is valid */ temp_service=find_service(host_name,svc_description); if(temp_service==NULL) return ERROR; } /* else verify that the host is valid */ temp_host=find_host(host_name); if(temp_host==NULL) return ERROR; /* get the persistent flag */ temp_ptr=my_strtok(NULL,";"); if(temp_ptr==NULL) return ERROR; persistent=atoi(temp_ptr); if(persistent>1) persistent=1; else if(persistent<0) persistent=0; /* get the name of the user who entered the comment */ user=my_strtok(NULL,";"); if(user==NULL) return ERROR; /* get the comment */ comment_data=my_strtok(NULL,"\n"); if(comment_data==NULL) return ERROR; /* add the comment */ result=add_new_comment((cmd==CMD_ADD_HOST_COMMENT)?HOST_COMMENT:SERVICE_COMMENT,USER_COMMENT,host_name,svc_description,entry_time,user,comment_data,persistent,COMMENTSOURCE_EXTERNAL,FALSE,(time_t)0,NULL); if(result<0) return ERROR; #ifdef DEBUG0 printf("cmd_add_comment() end\n"); #endif return OK; } /* removes a host or service comment from the status log */ int cmd_delete_comment(int cmd,char *args){ unsigned long comment_id; #ifdef DEBUG0 printf("cmd_del_comment() start\n"); #endif /* get the comment id we should delete */ comment_id=strtoul(args,NULL,10); if(comment_id==0) return ERROR; /* delete the specified comment */ if(cmd==CMD_DEL_HOST_COMMENT) delete_host_comment(comment_id); else delete_service_comment(comment_id); #ifdef DEBUG0 printf("cmd_del_comment() end\n"); #endif return OK; } /* removes all comments associated with a host or service from the status log */ int cmd_delete_all_comments(int cmd,char *args){ service *temp_service=NULL; host *temp_host=NULL; char *host_name=""; char *svc_description=""; #ifdef DEBUG0 printf("cmd_del_all_comments() start\n"); #endif /* get the host name */ host_name=my_strtok(args,";"); if(host_name==NULL) return ERROR; /* if we're deleting service comments... */ if(cmd==CMD_DEL_ALL_SVC_COMMENTS){ /* get the service description */ svc_description=my_strtok(NULL,";"); if(svc_description==NULL) return ERROR; /* verify that the service is valid */ temp_service=find_service(host_name,svc_description); if(temp_service==NULL) return ERROR; } /* else verify that the host is valid */ temp_host=find_host(host_name); if(temp_host==NULL) return ERROR; /* delete comments */ delete_all_comments((cmd==CMD_DEL_ALL_HOST_COMMENTS)?HOST_COMMENT:SERVICE_COMMENT,host_name,svc_description); #ifdef DEBUG0 printf("cmd_del_all_comments() end\n"); #endif return OK; } /* delays a host or service notification for given number of minutes */ int cmd_delay_notification(int cmd,char *args){ char *temp_ptr; host *temp_host=NULL; service *temp_service=NULL; char *host_name=""; char *svc_description=""; time_t delay_time; #ifdef DEBUG0 printf("cmd_delay_notification() start\n"); #endif /* get the host name */ host_name=my_strtok(args,";"); if(host_name==NULL) return ERROR; /* if this is a service notification delay... */ if(cmd==CMD_DELAY_SVC_NOTIFICATION){ /* get the service description */ svc_description=my_strtok(NULL,";"); if(svc_description==NULL) return ERROR; /* verify that the service is valid */ temp_service=find_service(host_name,svc_description); if(temp_service==NULL) return ERROR; } /* else verify that the host is valid */ else{ temp_host=find_host(host_name); if(temp_host==NULL) return ERROR; } /* get the time that we should delay until... */ temp_ptr=my_strtok(NULL,"\n"); if(temp_ptr==NULL) return ERROR; delay_time=strtoul(temp_ptr,NULL,10); /* delay the next notification... */ if(cmd==CMD_DELAY_HOST_NOTIFICATION) temp_host->next_host_notification=delay_time; else temp_service->next_notification=delay_time; #ifdef DEBUG0 printf("cmd_delay_notification() end\n"); #endif return OK; } /* schedules a host check at a particular time */ int cmd_schedule_check(int cmd,char *args){ char *temp_ptr; host *temp_host=NULL; service *temp_service=NULL; char *host_name=""; char *svc_description=""; time_t delay_time=0L; #ifdef DEBUG0 printf("cmd_schedule_check() start\n"); #endif /* get the host name */ host_name=my_strtok(args,";"); if(host_name==NULL) return ERROR; if(cmd==CMD_SCHEDULE_HOST_CHECK || cmd==CMD_SCHEDULE_FORCED_HOST_CHECK || cmd==CMD_SCHEDULE_HOST_SVC_CHECKS || cmd==CMD_SCHEDULE_FORCED_HOST_SVC_CHECKS){ /* verify that the host is valid */ temp_host=find_host(host_name); if(temp_host==NULL) return ERROR; } else{ /* get the service description */ svc_description=my_strtok(NULL,";"); if(svc_description==NULL) return ERROR; /* verify that the service is valid */ temp_service=find_service(host_name,svc_description); if(temp_service==NULL) return ERROR; } /* get the next check time */ temp_ptr=my_strtok(NULL,"\n"); if(temp_ptr==NULL) return ERROR; delay_time=strtoul(temp_ptr,NULL,10); /* schedule the check */ if(cmd==CMD_SCHEDULE_HOST_CHECK || cmd==CMD_SCHEDULE_FORCED_HOST_CHECK) schedule_host_check(temp_host,delay_time,(cmd==CMD_SCHEDULE_FORCED_HOST_CHECK)?TRUE:FALSE); else if(cmd==CMD_SCHEDULE_HOST_SVC_CHECKS || cmd==CMD_SCHEDULE_FORCED_HOST_SVC_CHECKS){ for(temp_service=service_list;temp_service!=NULL;temp_service=temp_service->next){ if(!strcmp(temp_service->host_name,host_name)) schedule_service_check(temp_service,delay_time,(cmd==CMD_SCHEDULE_FORCED_HOST_SVC_CHECKS)?TRUE:FALSE); } } else schedule_service_check(temp_service,delay_time,(cmd==CMD_SCHEDULE_FORCED_SVC_CHECK)?TRUE:FALSE); #ifdef DEBUG0 printf("cmd_schedule_check() end\n"); #endif return OK; } /* schedules all service checks on a host for a particular time */ int cmd_schedule_host_service_checks(int cmd,char *args, int force){ char *temp_ptr; host *temp_host=NULL; service *temp_service=NULL; char *host_name=""; time_t delay_time=0L; #ifdef DEBUG0 printf("cmd_schedule_host_service_checks() start\n"); #endif /* get the host name */ host_name=my_strtok(args,";"); if(host_name==NULL) return ERROR; /* verify that the host is valid */ temp_host=find_host(host_name); if(temp_host==NULL) return ERROR; /* get the next check time */ temp_ptr=my_strtok(NULL,"\n"); if(temp_ptr==NULL) return ERROR; delay_time=strtoul(temp_ptr,NULL,10); /* reschedule all services on the specified host */ for(temp_service=service_list;temp_service!=NULL;temp_service=temp_service->next){ if(!strcmp(temp_service->host_name,host_name)) schedule_service_check(temp_service,delay_time,force); } #ifdef DEBUG0 printf("cmd_schedule_host_service_checks() end\n"); #endif return OK; } /* schedules a program shutdown or restart */ int cmd_signal_process(int cmd, char *args){ time_t scheduled_time; char *temp_ptr; int result; #ifdef DEBUG0 printf("cmd_signal_process() start\n"); #endif /* get the time to schedule the event */ temp_ptr=my_strtok(args,"\n"); if(temp_ptr==NULL) scheduled_time=0L; else scheduled_time=strtoul(temp_ptr,NULL,10); /* add a scheduled program shutdown or restart to the event list */ result=schedule_new_event((cmd==CMD_SHUTDOWN_PROCESS)?EVENT_PROGRAM_SHUTDOWN:EVENT_PROGRAM_RESTART,TRUE,scheduled_time,FALSE,0,NULL,FALSE,NULL,NULL); #ifdef DEBUG0 printf("cmd_signal_process() end\n"); #endif return result; } /* processes results of an external service check */ int cmd_process_service_check_result(int cmd,time_t check_time,char *args){ char *temp_ptr; char *host_name; char *svc_description; int return_code; char *output; int result; #ifdef DEBUG0 printf("cmd_process_service_check_result() start\n"); #endif /* get the host name */ temp_ptr=my_strtok(args,";"); if(temp_ptr==NULL) return ERROR; host_name=strdup(temp_ptr); /* get the service description */ temp_ptr=my_strtok(NULL,";"); if(temp_ptr==NULL){ free(host_name); return ERROR; } svc_description=strdup(temp_ptr); /* get the service check return code */ temp_ptr=my_strtok(NULL,";"); if(temp_ptr==NULL){ free(host_name); free(svc_description); return ERROR; } return_code=atoi(temp_ptr); /* get the plugin output (may be empty) */ temp_ptr=my_strtok(NULL,"\n"); if(temp_ptr==NULL) output=strdup(""); else output=strdup(temp_ptr); /* submit the passive check result */ result=process_passive_service_check(check_time,host_name,svc_description,return_code,output); /* free memory */ free(host_name); free(svc_description); free(output); #ifdef DEBUG0 printf("cmd_process_service_check_result() end\n"); #endif return result; } /* submits a passive service check result for later processing */ int process_passive_service_check(time_t check_time, char *host_name, char *svc_description, int return_code, char *output){ passive_check_result *new_pcr=NULL; host *temp_host=NULL; service *temp_service=NULL; char *real_host_name=NULL; #ifdef DEBUG0 printf("process_passive_service_check() start\n"); #endif /* skip this service check result if we aren't accepting passive service checks */ if(accept_passive_service_checks==FALSE) return ERROR; /* make sure we have all required data */ if(host_name==NULL || svc_description==NULL || output==NULL) return ERROR; /* find the host by its name or address */ if(find_host(host_name)!=NULL) real_host_name=host_name; else{ for(temp_host=host_list;temp_host!=NULL;temp_host=temp_host->next){ if(!strcmp(host_name,temp_host->address)){ real_host_name=temp_host->name; break; } } } /* we couldn't find the host */ if(real_host_name==NULL) return ERROR; /* make sure the service exists */ if((temp_service=find_service(real_host_name,svc_description))==NULL) return ERROR; /* skip this is we aren't accepting passive checks for this service */ if(temp_service->accept_passive_service_checks==FALSE) return ERROR; /* allocate memory for the passive check result */ new_pcr=(passive_check_result *)malloc(sizeof(passive_check_result)); if(new_pcr==NULL) return ERROR; /* save the host name */ new_pcr->host_name=strdup(real_host_name); if(new_pcr->host_name==NULL){ free(new_pcr); return ERROR; } /* save the service description */ new_pcr->svc_description=strdup(svc_description); if(new_pcr->svc_description==NULL){ free(new_pcr->host_name); free(new_pcr); return ERROR; } /* save the return code */ new_pcr->return_code=return_code; /* make sure the return code is within bounds */ if(new_pcr->return_code<0 || new_pcr->return_code>3) new_pcr->return_code=STATE_UNKNOWN; /* save the output */ new_pcr->output=strdup(output); if(new_pcr->output==NULL){ free(new_pcr->svc_description); free(new_pcr->host_name); free(new_pcr); return ERROR; } new_pcr->check_time=check_time; new_pcr->next=NULL; /* add the passive check result to the end of the list in memory */ if(passive_check_result_list==NULL) passive_check_result_list=new_pcr; else passive_check_result_list_tail->next=new_pcr; passive_check_result_list_tail=new_pcr; #ifdef DEBUG0 printf("process_passive_service_check() end\n"); #endif return OK; } /* process passive host check result */ int cmd_process_host_check_result(int cmd,time_t check_time,char *args){ char *temp_ptr; char *host_name; int return_code; char *output; int result; #ifdef DEBUG0 printf("cmd_process_host_check_result() start\n"); #endif /* get the host name */ temp_ptr=my_strtok(args,";"); if(temp_ptr==NULL) return ERROR; host_name=strdup(temp_ptr); /* get the host check return code */ temp_ptr=my_strtok(NULL,";"); if(temp_ptr==NULL){ free(host_name); return ERROR; } return_code=atoi(temp_ptr); /* get the plugin output (may be empty) */ temp_ptr=my_strtok(NULL,"\n"); if(temp_ptr==NULL) output=strdup(""); else output=strdup(temp_ptr); /* submit the check result */ result=process_passive_host_check(check_time,host_name,return_code,output); /* free memory */ free(host_name); free(output); #ifdef DEBUG0 printf("cmd_process_host_check_result() end\n"); #endif return result; } /* process passive host check result */ /* this function is a bit more involved than for passive service checks, as we need to replicate most functions performed by check_route_to_host() */ int process_passive_host_check(time_t check_time, char *host_name, int return_code, char *output){ host *temp_host; char *real_host_name=""; struct timeval tv; char temp_plugin_output[MAX_PLUGINOUTPUT_LENGTH]=""; char old_plugin_output[MAX_PLUGINOUTPUT_LENGTH]=""; char *temp_ptr; char temp_buffer[MAX_INPUT_BUFFER]; #ifdef DEBUG0 printf("process_passive_host_check() start\n"); #endif /* skip this host check result if we aren't accepting passive host check results */ if(accept_passive_host_checks==FALSE) return ERROR; /* make sure we have all required data */ if(host_name==NULL || output==NULL) return ERROR; /* find the host by its name or address */ if((temp_host=find_host(host_name))!=NULL) real_host_name=host_name; else{ for(temp_host=host_list;temp_host!=NULL;temp_host=temp_host->next){ if(!strcmp(host_name,temp_host->address)){ real_host_name=temp_host->name; break; } } temp_host=find_host(real_host_name); } /* we couldn't find the host */ if(temp_host==NULL){ snprintf(temp_buffer,sizeof(temp_buffer),"Warning: Passive check result was received for host '%s', but the host could not be found!\n",host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_RUNTIME_WARNING,TRUE); return ERROR; } /* skip this is we aren't accepting passive checks for this host */ if(temp_host->accept_passive_host_checks==FALSE) return ERROR; /* make sure the return code is within bounds */ if(return_code<0 || return_code>2) return ERROR; /* save the plugin output */ strncpy(temp_plugin_output,output,MAX_PLUGINOUTPUT_LENGTH-1); temp_plugin_output[MAX_PLUGINOUTPUT_LENGTH-1]='\x0'; /********* LET'S DO IT (SUBSET OF NORMAL HOST CHECK OPERATIONS) ********/ /* set the checked flag */ temp_host->has_been_checked=TRUE; /* save old state */ temp_host->last_state=temp_host->current_state; if(temp_host->state_type==HARD_STATE) temp_host->last_hard_state=temp_host->current_state; /* NOTE TO SELF: Host state should be adjusted to reflect current host topology... */ /* record new state */ temp_host->current_state=return_code; /* record check type */ temp_host->check_type=HOST_CHECK_PASSIVE; /* record state type */ temp_host->state_type=HARD_STATE; /* set the current attempt - should this be set to max_attempts instead? */ temp_host->current_attempt=1; /* save the old plugin output and host state for use with state stalking routines */ strncpy(old_plugin_output,(temp_host->plugin_output==NULL)?"":temp_host->plugin_output,sizeof(old_plugin_output)-1); old_plugin_output[sizeof(old_plugin_output)-1]='\x0'; /* set the last host check time */ temp_host->last_check=check_time; /* clear plugin output and performance data buffers */ strcpy(temp_host->plugin_output,""); strcpy(temp_host->perf_data,""); /* passive checks have ZERO execution time! */ temp_host->execution_time=0.0; /* calculate latency */ gettimeofday(&tv,NULL); temp_host->latency=(double)((double)(tv.tv_sec-check_time)+(double)(tv.tv_usec/1000)/1000.0); if(temp_host->latency<0.0) temp_host->latency=0.0; /* check for empty plugin output */ if(!strcmp(temp_plugin_output,"")) strcpy(temp_plugin_output,"(No Information Returned From Host Check)"); /* first part of plugin output (up to pipe) is status info */ temp_ptr=strtok(temp_plugin_output,"|\n"); /* make sure the plugin output isn't NULL */ if(temp_ptr==NULL){ strncpy(temp_host->plugin_output,"(No output returned from host check)",MAX_PLUGINOUTPUT_LENGTH-1); temp_host->plugin_output[MAX_PLUGINOUTPUT_LENGTH-1]='\x0'; } else{ strip(temp_ptr); if(!strcmp(temp_ptr,"")){ strncpy(temp_host->plugin_output,"(No output returned from host check)",MAX_PLUGINOUTPUT_LENGTH-1); temp_host->plugin_output[MAX_PLUGINOUTPUT_LENGTH-1]='\x0'; } else{ strncpy(temp_host->plugin_output,temp_ptr,MAX_PLUGINOUTPUT_LENGTH-1); temp_host->plugin_output[MAX_PLUGINOUTPUT_LENGTH-1]='\x0'; } } /* second part of plugin output (after pipe) is performance data (which may or may not exist) */ temp_ptr=strtok(NULL,"\n"); /* grab performance data if we found it available */ if(temp_ptr!=NULL){ strip(temp_ptr); strncpy(temp_host->perf_data,temp_ptr,MAX_PLUGINOUTPUT_LENGTH-1); temp_host->perf_data[MAX_PLUGINOUTPUT_LENGTH-1]='\x0'; } /* replace semicolons in plugin output (but not performance data) with colons */ temp_ptr=temp_host->plugin_output; while((temp_ptr=strchr(temp_ptr,';'))) *temp_ptr=':'; /***** HANDLE THE HOST STATE *****/ handle_host_state(temp_host); /***** UPDATE HOST STATUS *****/ update_host_status(temp_host,FALSE); /****** STALKING STUFF *****/ /* if the host didn't change state and the plugin output differs from the last time it was checked, log the current state/output if state stalking is enabled */ if(temp_host->last_state==temp_host->current_state && strcmp(old_plugin_output,temp_host->plugin_output)){ if(temp_host->current_state==HOST_UP && temp_host->stalk_on_up==TRUE) log_host_event(temp_host); else if(temp_host->current_state==HOST_DOWN && temp_host->stalk_on_down==TRUE) log_host_event(temp_host); else if(temp_host->current_state==HOST_UNREACHABLE && temp_host->stalk_on_unreachable==TRUE) log_host_event(temp_host); } #ifdef USE_EVENT_BROKER /* send data to event broker */ broker_host_check(NEBTYPE_HOSTCHECK_PROCESSED,NEBFLAG_NONE,NEBATTR_NONE,temp_host,HOST_CHECK_PASSIVE,temp_host->current_state,temp_host->state_type,tv,tv,NULL,0.0,temp_host->execution_time,0,FALSE,return_code,NULL,temp_host->plugin_output,temp_host->perf_data,NULL); #endif /***** CHECK FOR FLAPPING *****/ check_for_host_flapping(temp_host,TRUE); #ifdef DEBUG0 printf("process_passive_host_check() end\n"); #endif return OK; } /* acknowledges a host or service problem */ int cmd_acknowledge_problem(int cmd,char *args){ service *temp_service=NULL; host *temp_host=NULL; char *host_name=""; char *svc_description=""; char *ack_author; char *ack_data; char *temp_ptr; int type=ACKNOWLEDGEMENT_NORMAL; int notify=TRUE; int persistent=TRUE; #ifdef DEBUG0 printf("cmd_acknowledge_problem() start\n"); #endif /* get the host name */ host_name=my_strtok(args,";"); if(host_name==NULL) return ERROR; /* verify that the host is valid */ temp_host=find_host(host_name); if(temp_host==NULL) return ERROR; /* this is a service acknowledgement */ if(cmd==CMD_ACKNOWLEDGE_SVC_PROBLEM){ /* get the service name */ svc_description=my_strtok(NULL,";"); if(svc_description==NULL) return ERROR; /* verify that the service is valid */ temp_service=find_service(temp_host->name,svc_description); if(temp_service==NULL) return ERROR; } /* get the type */ temp_ptr=my_strtok(NULL,";"); if(temp_ptr==NULL) return ERROR; type=atoi(temp_ptr); /* get the notification option */ temp_ptr=my_strtok(NULL,";"); if(temp_ptr==NULL) return ERROR; notify=(atoi(temp_ptr)>0)?TRUE:FALSE; /* get the persistent option */ temp_ptr=my_strtok(NULL,";"); if(temp_ptr==NULL) return ERROR; persistent=(atoi(temp_ptr)>0)?TRUE:FALSE; /* get the acknowledgement author */ temp_ptr=my_strtok(NULL,";"); if(temp_ptr==NULL) return ERROR; ack_author=strdup(temp_ptr); /* get the acknowledgement data */ temp_ptr=my_strtok(NULL,"\n"); if(temp_ptr==NULL) return ERROR; ack_data=strdup(temp_ptr); /* acknowledge the host problem */ if(cmd==CMD_ACKNOWLEDGE_HOST_PROBLEM) acknowledge_host_problem(temp_host,ack_author,ack_data,type,notify,persistent); /* acknowledge the service problem */ else acknowledge_service_problem(temp_service,ack_author,ack_data,type,notify,persistent); /* free memory */ free(ack_author); free(ack_data); #ifdef DEBUG0 printf("cmd_acknowledge_problem() end\n"); #endif return OK; } /* removes a host or service acknowledgement */ int cmd_remove_acknowledgement(int cmd,char *args){ service *temp_service=NULL; host *temp_host=NULL; char *host_name=""; char *svc_description=""; #ifdef DEBUG0 printf("cmd_remove_acknowledgement() start\n"); #endif /* get the host name */ host_name=my_strtok(args,";"); if(host_name==NULL) return ERROR; /* verify that the host is valid */ temp_host=find_host(host_name); if(temp_host==NULL) return ERROR; /* we are removing a service acknowledgement */ if(cmd==CMD_REMOVE_SVC_ACKNOWLEDGEMENT){ /* get the service name */ svc_description=my_strtok(NULL,";"); if(svc_description==NULL) return ERROR; /* verify that the service is valid */ temp_service=find_service(temp_host->name,svc_description); if(temp_service==NULL) return ERROR; } /* acknowledge the host problem */ if(cmd==CMD_REMOVE_HOST_ACKNOWLEDGEMENT) remove_host_acknowledgement(temp_host); /* acknowledge the service problem */ else remove_service_acknowledgement(temp_service); #ifdef DEBUG0 printf("cmd_remove_acknowledgement() end\n"); #endif return OK; } /* schedules downtime for a specific host or service */ int cmd_schedule_downtime(int cmd, time_t entry_time, char *args){ service *temp_service=NULL; host *temp_host=NULL; host *last_host=NULL; hostgroup *temp_hostgroup=NULL; hostgroupmember *temp_hgmember=NULL; servicegroup *temp_servicegroup=NULL; servicegroupmember *temp_sgmember=NULL; char *host_name=""; char *hostgroup_name=""; char *servicegroup_name=""; char *svc_description=""; char *temp_ptr; time_t start_time; time_t end_time; int fixed; unsigned long triggered_by; unsigned long duration; char *author=""; char *comment_data=""; unsigned long downtime_id; #ifdef DEBUG0 printf("cmd_schedule_downtime() start\n"); #endif if(cmd==CMD_SCHEDULE_HOSTGROUP_HOST_DOWNTIME || cmd==CMD_SCHEDULE_HOSTGROUP_SVC_DOWNTIME){ /* get the hostgroup name */ hostgroup_name=my_strtok(args,";"); if(hostgroup_name==NULL) return ERROR; /* verify that the hostgroup is valid */ temp_hostgroup=find_hostgroup(hostgroup_name); if(temp_hostgroup==NULL) return ERROR; } else if(cmd==CMD_SCHEDULE_SERVICEGROUP_HOST_DOWNTIME || cmd==CMD_SCHEDULE_SERVICEGROUP_SVC_DOWNTIME){ /* get the servicegroup name */ servicegroup_name=my_strtok(args,";"); if(servicegroup_name==NULL) return ERROR; /* verify that the servicegroup is valid */ temp_servicegroup=find_servicegroup(servicegroup_name); if(temp_servicegroup==NULL) return ERROR; } else{ /* get the host name */ host_name=my_strtok(args,";"); if(host_name==NULL) return ERROR; /* verify that the host is valid */ temp_host=find_host(host_name); if(temp_host==NULL) return ERROR; /* this is a service downtime */ if(cmd==CMD_SCHEDULE_SVC_DOWNTIME){ /* get the service name */ svc_description=my_strtok(NULL,";"); if(svc_description==NULL) return ERROR; /* verify that the service is valid */ temp_service=find_service(temp_host->name,svc_description); if(temp_service==NULL) return ERROR; } } /* get the start time */ temp_ptr=my_strtok(NULL,";"); if(temp_ptr==NULL) return ERROR; start_time=(time_t)strtoul(temp_ptr,NULL,10); /* get the end time */ temp_ptr=my_strtok(NULL,";"); if(temp_ptr==NULL) return ERROR; end_time=(time_t)strtoul(temp_ptr,NULL,10); /* get the fixed flag */ temp_ptr=my_strtok(NULL,";"); if(temp_ptr==NULL) return ERROR; fixed=atoi(temp_ptr); /* get the trigger id */ temp_ptr=my_strtok(NULL,";"); if(temp_ptr==NULL) return ERROR; triggered_by=strtoul(temp_ptr,NULL,10); /* get the duration */ temp_ptr=my_strtok(NULL,";"); if(temp_ptr==NULL) return ERROR; duration=strtoul(temp_ptr,NULL,10); /* get the author */ author=my_strtok(NULL,";"); if(author==NULL) return ERROR; /* get the comment */ comment_data=my_strtok(NULL,";"); if(comment_data==NULL) return ERROR; /* duration should be auto-calculated, not user-specified */ if(fixed>0) duration=(unsigned long)(end_time-start_time); /* schedule downtime */ switch(cmd){ case CMD_SCHEDULE_HOST_DOWNTIME: schedule_downtime(HOST_DOWNTIME,host_name,NULL,entry_time,author,comment_data,start_time,end_time,fixed,triggered_by,duration,&downtime_id); break; case CMD_SCHEDULE_SVC_DOWNTIME: schedule_downtime(SERVICE_DOWNTIME,host_name,svc_description,entry_time,author,comment_data,start_time,end_time,fixed,triggered_by,duration,&downtime_id); break; case CMD_SCHEDULE_HOST_SVC_DOWNTIME: for(temp_service=service_list;temp_service!=NULL;temp_service=temp_service->next){ if(!strcmp(temp_service->host_name,host_name)) schedule_downtime(SERVICE_DOWNTIME,host_name,temp_service->description,entry_time,author,comment_data,start_time,end_time,fixed,triggered_by,duration,&downtime_id); } break; case CMD_SCHEDULE_HOSTGROUP_HOST_DOWNTIME: for(temp_hgmember=temp_hostgroup->members;temp_hgmember!=NULL;temp_hgmember=temp_hgmember->next) schedule_downtime(HOST_DOWNTIME,temp_hgmember->host_name,NULL,entry_time,author,comment_data,start_time,end_time,fixed,triggered_by,duration,&downtime_id); break; case CMD_SCHEDULE_HOSTGROUP_SVC_DOWNTIME: for(temp_hgmember=temp_hostgroup->members;temp_hgmember!=NULL;temp_hgmember=temp_hgmember->next){ for(temp_service=service_list;temp_service!=NULL;temp_service=temp_service->next){ if(!strcmp(temp_service->host_name,temp_hgmember->host_name)) schedule_downtime(SERVICE_DOWNTIME,temp_service->host_name,temp_service->description,entry_time,author,comment_data,start_time,end_time,fixed,triggered_by,duration,&downtime_id); } } break; case CMD_SCHEDULE_SERVICEGROUP_HOST_DOWNTIME: last_host=NULL; for(temp_sgmember=temp_servicegroup->members;temp_sgmember!=NULL;temp_sgmember=temp_sgmember->next){ temp_host=find_host(temp_sgmember->host_name); if(temp_host==NULL) continue; if(last_host==temp_host) continue; schedule_downtime(HOST_DOWNTIME,temp_sgmember->host_name,NULL,entry_time,author,comment_data,start_time,end_time,fixed,triggered_by,duration,&downtime_id); last_host=temp_host; } break; case CMD_SCHEDULE_SERVICEGROUP_SVC_DOWNTIME: for(temp_sgmember=temp_servicegroup->members;temp_sgmember!=NULL;temp_sgmember=temp_sgmember->next) schedule_downtime(SERVICE_DOWNTIME,temp_sgmember->host_name,temp_sgmember->service_description,entry_time,author,comment_data,start_time,end_time,fixed,triggered_by,duration,&downtime_id); break; case CMD_SCHEDULE_AND_PROPAGATE_HOST_DOWNTIME: /* schedule downtime for "parent" host */ schedule_downtime(HOST_DOWNTIME,host_name,NULL,entry_time,author,comment_data,start_time,end_time,fixed,triggered_by,duration,&downtime_id); /* schedule (non-triggered) downtime for all child hosts */ schedule_and_propagate_downtime(temp_host,entry_time,author,comment_data,start_time,end_time,fixed,0,duration); break; case CMD_SCHEDULE_AND_PROPAGATE_TRIGGERED_HOST_DOWNTIME: /* schedule downtime for "parent" host */ schedule_downtime(HOST_DOWNTIME,host_name,NULL,entry_time,author,comment_data,start_time,end_time,fixed,triggered_by,duration,&downtime_id); /* schedule triggered downtime for all child hosts */ schedule_and_propagate_downtime(temp_host,entry_time,author,comment_data,start_time,end_time,fixed,downtime_id,duration); break; default: break; } #ifdef DEBUG0 printf("cmd_schedule_downtime() end\n"); #endif return OK; } /* deletes scheduled host or service downtime */ int cmd_delete_downtime(int cmd, char *args){ unsigned long downtime_id; char *temp_ptr; #ifdef DEBUG0 printf("cmd_delete_downtime() start\n"); #endif /* get the id of the downtime to delete */ temp_ptr=my_strtok(args,"\n"); if(temp_ptr==NULL) return ERROR; downtime_id=strtoul(temp_ptr,NULL,10); if(cmd==CMD_DEL_HOST_DOWNTIME) unschedule_downtime(HOST_DOWNTIME,downtime_id); else unschedule_downtime(SERVICE_DOWNTIME,downtime_id); #ifdef DEBUG0 printf("cmd_delete_downtime() end\n"); #endif return OK; } /* changes a host or service command */ int cmd_change_command(int cmd,char *args){ service *temp_service=NULL; host *temp_host=NULL; command *temp_command=NULL; char *host_name=""; char *svc_description=""; char *command_name=""; char *temp_ptr; char *temp_ptr2; unsigned long attr=MODATTR_NONE; #ifdef DEBUG0 printf("cmd_change_command() start\n"); #endif if(cmd!=CMD_CHANGE_GLOBAL_HOST_EVENT_HANDLER && cmd!=CMD_CHANGE_GLOBAL_SVC_EVENT_HANDLER){ /* get the host name */ host_name=my_strtok(args,";"); if(host_name==NULL) return ERROR; if(cmd==CMD_CHANGE_SVC_EVENT_HANDLER || cmd==CMD_CHANGE_SVC_CHECK_COMMAND){ /* get the service name */ svc_description=my_strtok(NULL,";"); if(svc_description==NULL) return ERROR; /* verify that the service is valid */ temp_service=find_service(host_name,svc_description); if(temp_service==NULL) return ERROR; } else{ /* verify that the host is valid */ temp_host=find_host(host_name); if(temp_host==NULL) return ERROR; } command_name=my_strtok(NULL,";"); } else command_name=my_strtok(args,";"); if(command_name==NULL) return ERROR; temp_ptr=strdup(command_name); if(temp_ptr==NULL) return ERROR; /* make sure the command exists */ temp_ptr2=my_strtok(temp_ptr,"!"); temp_command=find_command(temp_ptr2); if(temp_command==NULL) return ERROR; free(temp_ptr); temp_ptr=strdup(command_name); if(temp_ptr==NULL) return ERROR; switch(cmd){ case CMD_CHANGE_GLOBAL_HOST_EVENT_HANDLER: case CMD_CHANGE_GLOBAL_SVC_EVENT_HANDLER: if(cmd==CMD_CHANGE_GLOBAL_HOST_EVENT_HANDLER){ free(global_host_event_handler); global_host_event_handler=temp_ptr; attr=MODATTR_EVENT_HANDLER_COMMAND; modified_host_process_attributes|=attr; #ifdef USE_EVENT_BROKER /* send data to event broker */ broker_adaptive_program_data(NEBTYPE_ADAPTIVEPROGRAM_UPDATE,NEBFLAG_NONE,NEBATTR_NONE,cmd,attr,modified_host_process_attributes,MODATTR_NONE,modified_service_process_attributes,global_host_event_handler,global_service_event_handler,NULL); #endif } else{ free(global_service_event_handler); global_service_event_handler=temp_ptr; attr=MODATTR_EVENT_HANDLER_COMMAND; modified_service_process_attributes|=attr; #ifdef USE_EVENT_BROKER /* send data to event broker */ broker_adaptive_program_data(NEBTYPE_ADAPTIVEPROGRAM_UPDATE,NEBFLAG_NONE,NEBATTR_NONE,cmd,MODATTR_NONE,modified_host_process_attributes,attr,modified_service_process_attributes,global_host_event_handler,global_service_event_handler,NULL); #endif } /* update program status */ update_program_status(FALSE); break; case CMD_CHANGE_HOST_EVENT_HANDLER: case CMD_CHANGE_HOST_CHECK_COMMAND: if(cmd==CMD_CHANGE_HOST_EVENT_HANDLER){ free(temp_host->event_handler); temp_host->event_handler=temp_ptr; attr=MODATTR_EVENT_HANDLER_COMMAND; } else{ free(temp_host->host_check_command); temp_host->host_check_command=temp_ptr; attr=MODATTR_CHECK_COMMAND; } temp_host->modified_attributes|=attr; #ifdef USE_EVENT_BROKER /* send data to event broker */ broker_adaptive_host_data(NEBTYPE_ADAPTIVEHOST_UPDATE,NEBFLAG_NONE,NEBATTR_NONE,temp_host,cmd,attr,temp_host->modified_attributes,NULL); #endif /* update host status */ update_host_status(temp_host,FALSE); break; case CMD_CHANGE_SVC_EVENT_HANDLER: case CMD_CHANGE_SVC_CHECK_COMMAND: if(cmd==CMD_CHANGE_SVC_EVENT_HANDLER){ free(temp_service->event_handler); temp_service->event_handler=temp_ptr; attr=MODATTR_EVENT_HANDLER_COMMAND; } else{ free(temp_service->service_check_command); temp_service->service_check_command=temp_ptr; attr=MODATTR_CHECK_COMMAND; } temp_service->modified_attributes|=attr; #ifdef USE_EVENT_BROKER /* send data to event broker */ broker_adaptive_service_data(NEBTYPE_ADAPTIVESERVICE_UPDATE,NEBFLAG_NONE,NEBATTR_NONE,temp_service,cmd,attr,temp_service->modified_attributes,NULL); #endif /* update service status */ update_service_status(temp_service,FALSE); break; default: break; } #ifdef DEBUG0 printf("cmd_change_command() start\n"); #endif return OK; } /* changes a host or service check interval */ int cmd_change_check_interval(int cmd,char *args){ service *temp_service=NULL; host *temp_host=NULL; char *host_name=""; char *svc_description=""; char *temp_ptr; int interval; int old_interval; time_t preferred_time; time_t next_valid_time; unsigned long attr; #ifdef DEBUG0 printf("cmd_change_check_interval() start\n"); #endif /* get the host name */ host_name=my_strtok(args,";"); if(host_name==NULL) return ERROR; if(cmd==CMD_CHANGE_NORMAL_SVC_CHECK_INTERVAL || cmd==CMD_CHANGE_RETRY_SVC_CHECK_INTERVAL){ /* get the service name */ svc_description=my_strtok(NULL,";"); if(svc_description==NULL) return ERROR; /* verify that the service is valid */ temp_service=find_service(host_name,svc_description); if(temp_service==NULL) return ERROR; } else{ /* verify that the host is valid */ temp_host=find_host(host_name); if(temp_host==NULL) return ERROR; } temp_ptr=my_strtok(NULL,";"); if(temp_ptr==NULL) return ERROR; interval=atoi(temp_ptr); if(interval<0) return ERROR; switch(cmd){ case CMD_CHANGE_NORMAL_HOST_CHECK_INTERVAL: /* save the old check interval */ old_interval=temp_host->check_interval; /* modify the check interval */ temp_host->check_interval=interval; attr=MODATTR_NORMAL_CHECK_INTERVAL; temp_host->modified_attributes|=attr; /* schedule a host check if previous interval was 0 (checks were not regularly scheduled) */ if(old_interval==0 && temp_host->checks_enabled==TRUE){ /* set the host check flag */ temp_host->should_be_scheduled=TRUE; /* schedule a check for right now (or as soon as possible) */ time(&preferred_time); if(check_time_against_period(preferred_time,temp_host->check_period)==ERROR){ get_next_valid_time(preferred_time,&next_valid_time,temp_host->check_period); temp_host->next_check=next_valid_time; } else temp_host->next_check=preferred_time; /* schedule a check if we should */ if(temp_host->should_be_scheduled==TRUE) schedule_host_check(temp_host,temp_host->next_check,FALSE); } #ifdef USE_EVENT_BROKER /* send data to event broker */ broker_adaptive_host_data(NEBTYPE_ADAPTIVEHOST_UPDATE,NEBFLAG_NONE,NEBATTR_NONE,temp_host,cmd,attr,temp_host->modified_attributes,NULL); #endif /* update the status log with the host info */ update_host_status(temp_host,FALSE); break; case CMD_CHANGE_NORMAL_SVC_CHECK_INTERVAL: /* save the old check interval */ old_interval=temp_service->check_interval; /* modify the check interval */ temp_service->check_interval=interval; attr=MODATTR_NORMAL_CHECK_INTERVAL; temp_service->modified_attributes|=attr; /* schedule a service check if previous interval was 0 (checks were not regularly scheduled) */ if(old_interval==0 && temp_service->checks_enabled==TRUE && temp_service->check_interval!=0){ /* set the service check flag */ temp_service->should_be_scheduled=TRUE; /* schedule a check for right now (or as soon as possible) */ time(&preferred_time); if(check_time_against_period(preferred_time,temp_service->check_period)==ERROR){ get_next_valid_time(preferred_time,&next_valid_time,temp_service->check_period); temp_service->next_check=next_valid_time; } else temp_service->next_check=preferred_time; /* schedule a check if we should */ if(temp_service->should_be_scheduled==TRUE) schedule_service_check(temp_service,temp_service->next_check,FALSE); } #ifdef USE_EVENT_BROKER /* send data to event broker */ broker_adaptive_service_data(NEBTYPE_ADAPTIVESERVICE_UPDATE,NEBFLAG_NONE,NEBATTR_NONE,temp_service,cmd,attr,temp_service->modified_attributes,NULL); #endif /* update the status log with the service info */ update_service_status(temp_service,FALSE); break; case CMD_CHANGE_RETRY_SVC_CHECK_INTERVAL: temp_service->retry_interval=interval; attr=MODATTR_RETRY_CHECK_INTERVAL; temp_service->modified_attributes|=attr; #ifdef USE_EVENT_BROKER /* send data to event broker */ broker_adaptive_service_data(NEBTYPE_ADAPTIVESERVICE_UPDATE,NEBFLAG_NONE,NEBATTR_NONE,temp_service,cmd,attr,temp_service->modified_attributes,NULL); #endif /* update the status log with the service info */ update_service_status(temp_service,FALSE); break; default: break; } #ifdef DEBUG0 printf("cmd_change_check_interval() start\n"); #endif return OK; } /* changes a host or service max check attempts */ int cmd_change_max_attempts(int cmd,char *args){ service *temp_service=NULL; host *temp_host=NULL; char *host_name=""; char *svc_description=""; char *temp_ptr; int max_attempts; unsigned long attr; #ifdef DEBUG0 printf("cmd_change_max_attempts() start\n"); #endif /* get the host name */ host_name=my_strtok(args,";"); if(host_name==NULL) return ERROR; if(cmd==CMD_CHANGE_MAX_SVC_CHECK_ATTEMPTS){ /* get the service name */ svc_description=my_strtok(NULL,";"); if(svc_description==NULL) return ERROR; /* verify that the service is valid */ temp_service=find_service(host_name,svc_description); if(temp_service==NULL) return ERROR; } else{ /* verify that the host is valid */ temp_host=find_host(host_name); if(temp_host==NULL) return ERROR; } temp_ptr=my_strtok(NULL,";"); if(temp_ptr==NULL) return ERROR; max_attempts=atoi(temp_ptr); if(max_attempts<1) return ERROR; switch(cmd){ case CMD_CHANGE_MAX_HOST_CHECK_ATTEMPTS: temp_host->max_attempts=max_attempts; attr=MODATTR_MAX_CHECK_ATTEMPTS; temp_host->modified_attributes|=attr; /* adjust current attempt number if in a hard state */ if(temp_host->state_type==HARD_STATE && temp_host->current_state!=HOST_UP && temp_host->current_attempt>1) temp_host->current_attempt=temp_host->max_attempts; #ifdef USE_EVENT_BROKER /* send data to event broker */ broker_adaptive_host_data(NEBTYPE_ADAPTIVEHOST_UPDATE,NEBFLAG_NONE,NEBATTR_NONE,temp_host,cmd,attr,temp_host->modified_attributes,NULL); #endif /* update host status info */ update_host_status(temp_host,FALSE); break; case CMD_CHANGE_MAX_SVC_CHECK_ATTEMPTS: temp_service->max_attempts=max_attempts; attr=MODATTR_MAX_CHECK_ATTEMPTS; temp_service->modified_attributes|=attr; /* adjust current attempt number if in a hard state */ if(temp_service->state_type==HARD_STATE && temp_service->current_state!=STATE_OK && temp_service->current_attempt>1) temp_service->current_attempt=temp_service->max_attempts; #ifdef USE_EVENT_BROKER /* send data to event broker */ broker_adaptive_service_data(NEBTYPE_ADAPTIVESERVICE_UPDATE,NEBFLAG_NONE,NEBATTR_NONE,temp_service,cmd,attr,temp_service->modified_attributes,NULL); #endif /* update service status info */ update_service_status(temp_service,FALSE); break; default: break; } #ifdef DEBUG0 printf("cmd_change_max_attempts() start\n"); #endif return OK; } /******************************************************************/ /*************** INTERNAL COMMAND IMPLEMENTATIONS ****************/ /******************************************************************/ /* temporarily disables a service check */ void disable_service_checks(service *svc){ timed_event *temp_event; #ifdef DEBUG0 printf("disable_service_checks() start\n"); #endif /* set the attribute modified flag */ svc->modified_attributes|=MODATTR_ACTIVE_CHECKS_ENABLED; /* checks are already disabled */ if(svc->checks_enabled==FALSE) return; /* disable the service check... */ svc->checks_enabled=FALSE; svc->should_be_scheduled=FALSE; /* remove scheduled checks of this service from the event queue */ for(temp_event=event_list_low;temp_event!=NULL;temp_event=temp_event->next){ if(temp_event->event_type==EVENT_SERVICE_CHECK && svc==(service *)temp_event->event_data) break; } /* we found a check event to remove */ if(temp_event!=NULL){ remove_event(temp_event,&event_list_low); free(temp_event); } /* update the status log to reflect the new service state */ update_service_status(svc,FALSE); #ifdef DEBUG0 printf("disable_service_checks() end\n"); #endif return; } /* enables a service check */ void enable_service_checks(service *svc){ time_t preferred_time; time_t next_valid_time; #ifdef DEBUG0 printf("enable_service_checks() start\n"); #endif /* set the attribute modified flag */ svc->modified_attributes|=MODATTR_ACTIVE_CHECKS_ENABLED; /* checks are already enabled */ if(svc->checks_enabled==TRUE) return; /* enable the service check... */ svc->checks_enabled=TRUE; svc->should_be_scheduled=TRUE; /* services with no check intervals don't get checked */ if(svc->check_interval==0) svc->should_be_scheduled=FALSE; /* schedule a check for right now (or as soon as possible) */ time(&preferred_time); if(check_time_against_period(preferred_time,svc->check_period)==ERROR){ get_next_valid_time(preferred_time,&next_valid_time,svc->check_period); svc->next_check=next_valid_time; } else svc->next_check=preferred_time; /* schedule a check if we should */ if(svc->should_be_scheduled==TRUE) schedule_service_check(svc,svc->next_check,FALSE); /* update the status log to reflect the new service state */ update_service_status(svc,FALSE); #ifdef DEBUG0 printf("enable_service_checks() end\n"); #endif return; } /* enable notifications on a program-wide basis */ void enable_all_notifications(void){ #ifdef DEBUG0 printf("enable_all_notifications() start\n"); #endif /* set the attribute modified flag */ modified_host_process_attributes|=MODATTR_NOTIFICATIONS_ENABLED; modified_service_process_attributes|=MODATTR_NOTIFICATIONS_ENABLED; /* bail out if we're already set... */ if(enable_notifications==TRUE) return; /* update notification status */ enable_notifications=TRUE; /* update the status log */ update_program_status(FALSE); #ifdef DEBUG0 printf("enable_all_notifications() end\n"); #endif return; } /* disable notifications on a program-wide basis */ void disable_all_notifications(void){ #ifdef DEBUG0 printf("disable_all_notifications() start\n"); #endif /* set the attribute modified flag */ modified_host_process_attributes|=MODATTR_NOTIFICATIONS_ENABLED; modified_service_process_attributes|=MODATTR_NOTIFICATIONS_ENABLED; /* bail out if we're already set... */ if(enable_notifications==FALSE) return; /* update notification status */ enable_notifications=FALSE; /* update the status log */ update_program_status(FALSE); #ifdef DEBUG0 printf("disable_all_notifications() end\n"); #endif return; } /* enables notifications for a service */ void enable_service_notifications(service *svc){ #ifdef DEBUG0 printf("enable_service_notifications() start\n"); #endif /* set the attribute modified flag */ svc->modified_attributes|=MODATTR_NOTIFICATIONS_ENABLED; /* enable the service notifications... */ svc->notifications_enabled=TRUE; /* update the status log to reflect the new service state */ update_service_status(svc,FALSE); #ifdef DEBUG0 printf("enable_service_notifications() end\n"); #endif return; } /* disables notifications for a service */ void disable_service_notifications(service *svc){ #ifdef DEBUG0 printf("disable_service_notifications() start\n"); #endif /* set the attribute modified flag */ svc->modified_attributes|=MODATTR_NOTIFICATIONS_ENABLED; /* disable the service notifications... */ svc->notifications_enabled=FALSE; /* update the status log to reflect the new service state */ update_service_status(svc,FALSE); #ifdef DEBUG0 printf("disable_service_notifications() end\n"); #endif return; } /* enables notifications for a host */ void enable_host_notifications(host *hst){ #ifdef DEBUG0 printf("enable_host_notifications() start\n"); #endif /* set the attribute modified flag */ hst->modified_attributes|=MODATTR_NOTIFICATIONS_ENABLED; /* enable the host notifications... */ hst->notifications_enabled=TRUE; /* update the status log to reflect the new host state */ update_host_status(hst,FALSE); #ifdef DEBUG0 printf("enable_host_notifications() end\n"); #endif return; } /* disables notifications for a host */ void disable_host_notifications(host *hst){ #ifdef DEBUG0 printf("disable_host_notifications() start\n"); #endif /* set the attribute modified flag */ hst->modified_attributes|=MODATTR_NOTIFICATIONS_ENABLED; /* disable the host notifications... */ hst->notifications_enabled=FALSE; /* update the status log to reflect the new host state */ update_host_status(hst,FALSE); #ifdef DEBUG0 printf("disable_host_notifications() end\n"); #endif return; } /* enables notifications for all hosts and services "beyond" a given host */ void enable_and_propagate_notifications(host *hst, int level, int affect_top_host, int affect_hosts, int affect_services){ host *temp_host; service *temp_service; #ifdef DEBUG0 printf("enable_and_propagate_notifications() start\n"); #endif /* enable notification for top level host */ if(affect_top_host==TRUE && level==0) enable_host_notifications(hst); /* check all child hosts... */ for(temp_host=host_list;temp_host!=NULL;temp_host=temp_host->next){ if(is_host_immediate_child_of_host(hst,temp_host)==TRUE){ /* recurse... */ enable_and_propagate_notifications(temp_host,level+1,affect_top_host,affect_hosts,affect_services); /* enable notifications for this host */ if(affect_hosts==TRUE) enable_host_notifications(temp_host); /* enable notifications for all services on this host... */ if(affect_services==TRUE){ for(temp_service=service_list;temp_service!=NULL;temp_service=temp_service->next){ if(!strcmp(temp_service->host_name,temp_host->name)) enable_service_notifications(temp_service); } } } } #ifdef DEBUG0 printf("enable_and_propagate_notifications() end\n"); #endif return; } /* disables notifications for all hosts and services "beyond" a given host */ void disable_and_propagate_notifications(host *hst, int level, int affect_top_host, int affect_hosts, int affect_services){ host *temp_host; service *temp_service; #ifdef DEBUG0 printf("disable_and_propagate_notifications() start\n"); #endif if(hst==NULL) return; /* disable notifications for top host */ if(affect_top_host==TRUE && level==0) disable_host_notifications(hst); /* check all child hosts... */ for(temp_host=host_list;temp_host!=NULL;temp_host=temp_host->next){ if(is_host_immediate_child_of_host(hst,temp_host)==TRUE){ /* recurse... */ disable_and_propagate_notifications(temp_host,level+1,affect_top_host,affect_hosts,affect_services); /* disable notifications for this host */ if(affect_hosts==TRUE) disable_host_notifications(temp_host); /* disable notifications for all services on this host... */ if(affect_services==TRUE){ for(temp_service=service_list;temp_service!=NULL;temp_service=temp_service->next){ if(!strcmp(temp_service->host_name,temp_host->name)) disable_service_notifications(temp_service); } } } } #ifdef DEBUG0 printf("disable_and_propagate_notifications() end\n"); #endif return; } /* schedules downtime for all hosts "beyond" a given host */ void schedule_and_propagate_downtime(host *temp_host, time_t entry_time, char *author, char *comment_data, time_t start_time, time_t end_time, int fixed, unsigned long triggered_by, unsigned long duration){ host *this_host; #ifdef DEBUG0 printf("schedule_and_propagate_downtime() start\n"); #endif /* check all child hosts... */ for(this_host=host_list;this_host!=NULL;this_host=this_host->next){ if(is_host_immediate_child_of_host(temp_host,this_host)==TRUE){ /* recurse... */ schedule_and_propagate_downtime(this_host,entry_time,author,comment_data,start_time,end_time,fixed,triggered_by,duration); /* schedule downtime for this host */ schedule_downtime(HOST_DOWNTIME,this_host->name,NULL,entry_time,author,comment_data,start_time,end_time,fixed,triggered_by,duration,NULL); } } #ifdef DEBUG0 printf("schedule_and_propagate_downtime() end\n"); #endif return; } /* acknowledges a host problem */ void acknowledge_host_problem(host *hst, char *ack_author, char *ack_data, int type, int notify, int persistent){ time_t current_time; #ifdef DEBUG0 printf("acknowledge_host_problem() start\n"); #endif /* cannot acknowledge a non-existent problem */ if(hst->current_state==HOST_UP) return; #ifdef USE_EVENT_BROKER /* send data to event broker */ broker_acknowledgement_data(NEBTYPE_ACKNOWLEDGEMENT_ADD,NEBFLAG_NONE,NEBATTR_NONE,HOST_ACKNOWLEDGEMENT,(void *)hst,ack_author,ack_data,type,notify,persistent,NULL); #endif /* send out an acknowledgement notification */ if(notify==TRUE) host_notification(hst,NOTIFICATION_ACKNOWLEDGEMENT,ack_author,ack_data); /* set the acknowledgement flag */ hst->problem_has_been_acknowledged=TRUE; /* set the acknowledgement type */ hst->acknowledgement_type=(type==ACKNOWLEDGEMENT_STICKY)?ACKNOWLEDGEMENT_STICKY:ACKNOWLEDGEMENT_NORMAL; /* update the status log with the host info */ update_host_status(hst,FALSE); /* add a comment for the acknowledgement */ time(¤t_time); add_new_host_comment(ACKNOWLEDGEMENT_COMMENT,hst->name,current_time,ack_author,ack_data,persistent,COMMENTSOURCE_INTERNAL,FALSE,(time_t)0,NULL); #ifdef DEBUG0 printf("acknowledge_host_problem() end\n"); #endif return; } /* acknowledges a service problem */ void acknowledge_service_problem(service *svc, char *ack_author, char *ack_data, int type, int notify, int persistent){ time_t current_time; #ifdef DEBUG0 printf("acknowledge_service_problem() start\n"); #endif /* cannot acknowledge a non-existent problem */ if(svc->current_state==STATE_OK) return; #ifdef USE_EVENT_BROKER /* send data to event broker */ broker_acknowledgement_data(NEBTYPE_ACKNOWLEDGEMENT_ADD,NEBFLAG_NONE,NEBATTR_NONE,SERVICE_ACKNOWLEDGEMENT,(void *)svc,ack_author,ack_data,type,notify,persistent,NULL); #endif /* send out an acknowledgement notification */ if(notify==TRUE) service_notification(svc,NOTIFICATION_ACKNOWLEDGEMENT,ack_author,ack_data); /* set the acknowledgement flag */ svc->problem_has_been_acknowledged=TRUE; /* set the acknowledgement type */ svc->acknowledgement_type=(type==ACKNOWLEDGEMENT_STICKY)?ACKNOWLEDGEMENT_STICKY:ACKNOWLEDGEMENT_NORMAL; /* update the status log with the service info */ update_service_status(svc,FALSE); /* add a comment for the acknowledgement */ time(¤t_time); add_new_service_comment(ACKNOWLEDGEMENT_COMMENT,svc->host_name,svc->description,current_time,ack_author,ack_data,persistent,COMMENTSOURCE_INTERNAL,FALSE,(time_t)0,NULL); #ifdef DEBUG0 printf("acknowledge_service_problem() end\n"); #endif return; } /* removes a host acknowledgement */ void remove_host_acknowledgement(host *hst){ #ifdef DEBUG0 printf("remove_host_acknowledgement() start\n"); #endif /* set the acknowledgement flag */ hst->problem_has_been_acknowledged=FALSE; /* update the status log with the host info */ update_host_status(hst,FALSE); #ifdef DEBUG0 printf("remove_host_acknowledgement() end\n"); #endif return; } /* removes a service acknowledgement */ void remove_service_acknowledgement(service *svc){ #ifdef DEBUG0 printf("remove_service_acknowledgement() start\n"); #endif /* set the acknowledgement flag */ svc->problem_has_been_acknowledged=FALSE; /* update the status log with the service info */ update_service_status(svc,FALSE); #ifdef DEBUG0 printf("remove_service_acknowledgement() end\n"); #endif return; } /* starts executing service checks */ void start_executing_service_checks(void){ #ifdef DEBUG0 printf("start_executing_service_checks() start\n"); #endif /* set the attribute modified flag */ modified_service_process_attributes|=MODATTR_ACTIVE_CHECKS_ENABLED; /* bail out if we're already executing services */ if(execute_service_checks==TRUE) return; /* set the service check execution flag */ execute_service_checks=TRUE; /* update the status log with the program info */ update_program_status(FALSE); #ifdef DEBUG0 printf("start_executing_service_checks() end\n"); #endif return; } /* stops executing service checks */ void stop_executing_service_checks(void){ #ifdef DEBUG0 printf("stop_executing_service_checks() start\n"); #endif /* set the attribute modified flag */ modified_service_process_attributes|=MODATTR_ACTIVE_CHECKS_ENABLED; /* bail out if we're already not executing services */ if(execute_service_checks==FALSE) return; /* set the service check execution flag */ execute_service_checks=FALSE; /* update the status log with the program info */ update_program_status(FALSE); #ifdef DEBUG0 printf("stop_executing_service_checks() end\n"); #endif return; } /* starts accepting passive service checks */ void start_accepting_passive_service_checks(void){ #ifdef DEBUG0 printf("start_accepting_passive_service_checks() start\n"); #endif /* set the attribute modified flag */ modified_service_process_attributes|=MODATTR_PASSIVE_CHECKS_ENABLED; /* bail out if we're already accepting passive services */ if(accept_passive_service_checks==TRUE) return; /* set the service check flag */ accept_passive_service_checks=TRUE; /* update the status log with the program info */ update_program_status(FALSE); #ifdef DEBUG0 printf("start_accepting_passive_service_checks() end\n"); #endif return; } /* stops accepting passive service checks */ void stop_accepting_passive_service_checks(void){ #ifdef DEBUG0 printf("stop_accepting_passive_service_checks() start\n"); #endif /* set the attribute modified flag */ modified_service_process_attributes|=MODATTR_PASSIVE_CHECKS_ENABLED; /* bail out if we're already not accepting passive services */ if(accept_passive_service_checks==FALSE) return; /* set the service check flag */ accept_passive_service_checks=FALSE; /* update the status log with the program info */ update_program_status(FALSE); #ifdef DEBUG0 printf("stop_accepting_passive_service_checks() end\n"); #endif return; } /* enables passive service checks for a particular service */ void enable_passive_service_checks(service *svc){ #ifdef DEBUG0 printf("enable_passive_service_checks() start\n"); #endif /* set the attribute modified flag */ svc->modified_attributes|=MODATTR_PASSIVE_CHECKS_ENABLED; /* set the passive check flag */ svc->accept_passive_service_checks=TRUE; /* update the status log with the service info */ update_service_status(svc,FALSE); #ifdef DEBUG0 printf("enable_passive_service_checks() end\n"); #endif return; } /* disables passive service checks for a particular service */ void disable_passive_service_checks(service *svc){ #ifdef DEBUG0 printf("disable_passive_service_checks() start\n"); #endif /* set the attribute modified flag */ svc->modified_attributes|=MODATTR_PASSIVE_CHECKS_ENABLED; /* set the passive check flag */ svc->accept_passive_service_checks=FALSE; /* update the status log with the service info */ update_service_status(svc,FALSE); #ifdef DEBUG0 printf("disable_passive_service_checks() end\n"); #endif return; } /* starts executing host checks */ void start_executing_host_checks(void){ #ifdef DEBUG0 printf("start_executing_host_checks() start\n"); #endif /* set the attribute modified flag */ modified_host_process_attributes|=MODATTR_ACTIVE_CHECKS_ENABLED; /* bail out if we're already executing hosts */ if(execute_host_checks==TRUE) return; /* set the host check execution flag */ execute_host_checks=TRUE; /* update the status log with the program info */ update_program_status(FALSE); #ifdef DEBUG0 printf("start_executing_host_checks() end\n"); #endif return; } /* stops executing host checks */ void stop_executing_host_checks(void){ #ifdef DEBUG0 printf("stop_executing_host_checks() start\n"); #endif /* set the attribute modified flag */ modified_host_process_attributes|=MODATTR_ACTIVE_CHECKS_ENABLED; /* bail out if we're already not executing hosts */ if(execute_host_checks==FALSE) return; /* set the host check execution flag */ execute_host_checks=FALSE; /* update the status log with the program info */ update_program_status(FALSE); #ifdef DEBUG0 printf("stop_executing_host_checks() end\n"); #endif return; } /* starts accepting passive host checks */ void start_accepting_passive_host_checks(void){ #ifdef DEBUG0 printf("start_accepting_passive_host_checks() start\n"); #endif /* set the attribute modified flag */ modified_host_process_attributes|=MODATTR_PASSIVE_CHECKS_ENABLED; /* bail out if we're already accepting passive hosts */ if(accept_passive_host_checks==TRUE) return; /* set the host check flag */ accept_passive_host_checks=TRUE; /* update the status log with the program info */ update_program_status(FALSE); #ifdef DEBUG0 printf("start_accepting_passive_host_checks() end\n"); #endif return; } /* stops accepting passive host checks */ void stop_accepting_passive_host_checks(void){ #ifdef DEBUG0 printf("stop_accepting_passive_host_checks() start\n"); #endif /* set the attribute modified flag */ modified_host_process_attributes|=MODATTR_PASSIVE_CHECKS_ENABLED; /* bail out if we're already not accepting passive hosts */ if(accept_passive_host_checks==FALSE) return; /* set the host check flag */ accept_passive_host_checks=FALSE; /* update the status log with the program info */ update_program_status(FALSE); #ifdef DEBUG0 printf("stop_accepting_passive_host_checks() end\n"); #endif return; } /* enables passive host checks for a particular host */ void enable_passive_host_checks(host *hst){ #ifdef DEBUG0 printf("enable_passive_host_checks() start\n"); #endif /* set the attribute modified flag */ hst->modified_attributes|=MODATTR_PASSIVE_CHECKS_ENABLED; /* set the passive check flag */ hst->accept_passive_host_checks=TRUE; /* update the status log with the host info */ update_host_status(hst,FALSE); #ifdef DEBUG0 printf("enable_passive_host_checks() end\n"); #endif return; } /* disables passive host checks for a particular host */ void disable_passive_host_checks(host *hst){ #ifdef DEBUG0 printf("disable_passive_host_checks() start\n"); #endif /* set the attribute modified flag */ hst->modified_attributes|=MODATTR_PASSIVE_CHECKS_ENABLED; /* set the passive check flag */ hst->accept_passive_host_checks=FALSE; /* update the status log with the host info */ update_host_status(hst,FALSE); #ifdef DEBUG0 printf("disable_passive_host_checks() end\n"); #endif return; } /* enables event handlers on a program-wide basis */ void start_using_event_handlers(void){ #ifdef DEBUG0 printf("start_using_event_handlers() start\n"); #endif /* set the attribute modified flag */ modified_host_process_attributes|=MODATTR_EVENT_HANDLER_ENABLED; modified_service_process_attributes|=MODATTR_EVENT_HANDLER_ENABLED; /* set the event handler flag */ enable_event_handlers=TRUE; /* update the status log with the program info */ update_program_status(FALSE); #ifdef DEBUG0 printf("start_using_event_handlers() end\n"); #endif return; } /* disables event handlers on a program-wide basis */ void stop_using_event_handlers(void){ #ifdef DEBUG0 printf("stop_using_event_handlers() start\n"); #endif /* set the attribute modified flag */ modified_host_process_attributes|=MODATTR_EVENT_HANDLER_ENABLED; modified_service_process_attributes|=MODATTR_EVENT_HANDLER_ENABLED; /* set the event handler flag */ enable_event_handlers=FALSE; /* update the status log with the program info */ update_program_status(FALSE); #ifdef DEBUG0 printf("stop_using_event_handlers() end\n"); #endif return; } /* enables the event handler for a particular service */ void enable_service_event_handler(service *svc){ #ifdef DEBUG0 printf("enable_service_event_handler() start\n"); #endif /* set the attribute modified flag */ svc->modified_attributes|=MODATTR_EVENT_HANDLER_ENABLED; /* set the event handler flag */ svc->event_handler_enabled=TRUE; /* update the status log with the service info */ update_service_status(svc,FALSE); #ifdef DEBUG0 printf("enable_service_event_handler() end\n"); #endif return; } /* disables the event handler for a particular service */ void disable_service_event_handler(service *svc){ #ifdef DEBUG0 printf("disable_service_event_handler() start\n"); #endif /* set the attribute modified flag */ svc->modified_attributes|=MODATTR_EVENT_HANDLER_ENABLED; /* set the event handler flag */ svc->event_handler_enabled=FALSE; /* update the status log with the service info */ update_service_status(svc,FALSE); #ifdef DEBUG0 printf("disable_service_event_handler() end\n"); #endif return; } /* enables the event handler for a particular host */ void enable_host_event_handler(host *hst){ #ifdef DEBUG0 printf("enable_host_event_handler() start\n"); #endif /* set the attribute modified flag */ hst->modified_attributes|=MODATTR_EVENT_HANDLER_ENABLED; /* set the event handler flag */ hst->event_handler_enabled=TRUE; /* update the status log with the host info */ update_host_status(hst,FALSE); #ifdef DEBUG0 printf("enable_host_event_handler() end\n"); #endif return; } /* disables the event handler for a particular host */ void disable_host_event_handler(host *hst){ #ifdef DEBUG0 printf("disable_host_event_handler() start\n"); #endif /* set the attribute modified flag */ hst->modified_attributes|=MODATTR_EVENT_HANDLER_ENABLED; /* set the event handler flag */ hst->event_handler_enabled=FALSE; /* update the status log with the host info */ update_host_status(hst,FALSE); #ifdef DEBUG0 printf("disable_host_event_handler() end\n"); #endif return; } /* disables checks of a particular host */ void disable_host_checks(host *hst){ timed_event *temp_event; #ifdef DEBUG0 printf("disable_host_checks() start\n"); #endif /* set the attribute modified flag */ hst->modified_attributes|=MODATTR_ACTIVE_CHECKS_ENABLED; /* checks are already disabled */ if(hst->checks_enabled==FALSE) return; /* set the host check flag */ hst->checks_enabled=FALSE; hst->should_be_scheduled=FALSE; /* remove scheduled checks of this host from the event queue */ for(temp_event=event_list_low;temp_event!=NULL;temp_event=temp_event->next){ if(temp_event->event_type==EVENT_HOST_CHECK && hst==(host *)temp_event->event_data) break; } /* we found a check event to remove */ if(temp_event!=NULL){ remove_event(temp_event,&event_list_low); free(temp_event); } /* update the status log with the host info */ update_host_status(hst,FALSE); #ifdef DEBUG0 printf("disable_host_checks() end\n"); #endif return; } /* enables checks of a particular host */ void enable_host_checks(host *hst){ time_t preferred_time; time_t next_valid_time; #ifdef DEBUG0 printf("enable_host_checks() start\n"); #endif /* set the attribute modified flag */ hst->modified_attributes|=MODATTR_ACTIVE_CHECKS_ENABLED; /* checks are already enabled */ if(hst->checks_enabled==TRUE) return; /* set the host check flag */ hst->checks_enabled=TRUE; hst->should_be_scheduled=TRUE; /* hosts with no check intervals don't get checked */ if(hst->check_interval==0) hst->should_be_scheduled=FALSE; /* schedule a check for right now (or as soon as possible) */ time(&preferred_time); if(check_time_against_period(preferred_time,hst->check_period)==ERROR){ get_next_valid_time(preferred_time,&next_valid_time,hst->check_period); hst->next_check=next_valid_time; } else hst->next_check=preferred_time; /* schedule a check if we should */ if(hst->should_be_scheduled==TRUE) schedule_host_check(hst,hst->next_check,FALSE); /* update the status log with the host info */ update_host_status(hst,FALSE); #ifdef DEBUG0 printf("enable_host_checks() end\n"); #endif return; } /* start obsessing over service check results */ void start_obsessing_over_service_checks(void){ #ifdef DEBUG0 printf("start_obsessing_over_service_checks() start\n"); #endif /* set the attribute modified flag */ modified_service_process_attributes|=MODATTR_OBSESSIVE_HANDLER_ENABLED; /* set the service obsession flag */ obsess_over_services=TRUE; /* update the status log with the program info */ update_program_status(FALSE); #ifdef DEBUG0 printf("start_obsessing_over_service_checks() end\n"); #endif return; } /* stop obsessing over service check results */ void stop_obsessing_over_service_checks(void){ #ifdef DEBUG0 printf("stop_obsessing_over_service_checks() start\n"); #endif /* set the attribute modified flag */ modified_service_process_attributes|=MODATTR_OBSESSIVE_HANDLER_ENABLED; /* set the service obsession flag */ obsess_over_services=FALSE; /* update the status log with the program info */ update_program_status(FALSE); #ifdef DEBUG0 printf("stop_obsessing_over_service_checks() end\n"); #endif return; } /* start obsessing over host check results */ void start_obsessing_over_host_checks(void){ #ifdef DEBUG0 printf("start_obsessing_over_host_checks() start\n"); #endif /* set the attribute modified flag */ modified_host_process_attributes|=MODATTR_OBSESSIVE_HANDLER_ENABLED; /* set the host obsession flag */ obsess_over_hosts=TRUE; /* update the status log with the program info */ update_program_status(FALSE); #ifdef DEBUG0 printf("start_obsessing_over_host_checks() end\n"); #endif return; } /* stop obsessing over host check results */ void stop_obsessing_over_host_checks(void){ #ifdef DEBUG0 printf("stop_obsessing_over_host_checks() start\n"); #endif /* set the attribute modified flag */ modified_host_process_attributes|=MODATTR_OBSESSIVE_HANDLER_ENABLED; /* set the host obsession flag */ obsess_over_hosts=FALSE; /* update the status log with the program info */ update_program_status(FALSE); #ifdef DEBUG0 printf("stop_obsessing_over_host_checks() end\n"); #endif return; } /* enables service freshness checking */ void enable_service_freshness_checks(void){ #ifdef DEBUG0 printf("enable_service_freshness_checks() start\n"); #endif /* set the attribute modified flag */ modified_service_process_attributes|=MODATTR_FRESHNESS_CHECKS_ENABLED; /* set the freshness check flag */ check_service_freshness=TRUE; /* update the status log with the program info */ update_program_status(FALSE); #ifdef DEBUG0 printf("enable_service_freshness_checks() end\n"); #endif return; } /* disables service freshness checking */ void disable_service_freshness_checks(void){ #ifdef DEBUG0 printf("disable_service_freshness_checks() start\n"); #endif /* set the attribute modified flag */ modified_service_process_attributes|=MODATTR_FRESHNESS_CHECKS_ENABLED; /* set the freshness check flag */ check_service_freshness=FALSE; /* update the status log with the program info */ update_program_status(FALSE); #ifdef DEBUG0 printf("disable_service_freshness_checks() end\n"); #endif return; } /* enables host freshness checking */ void enable_host_freshness_checks(void){ #ifdef DEBUG0 printf("enable_host_freshness_checks() start\n"); #endif /* set the attribute modified flag */ modified_host_process_attributes|=MODATTR_FRESHNESS_CHECKS_ENABLED; /* set the freshness check flag */ check_host_freshness=TRUE; /* update the status log with the program info */ update_program_status(FALSE); #ifdef DEBUG0 printf("enable_host_freshness_checks() end\n"); #endif return; } /* disables host freshness checking */ void disable_host_freshness_checks(void){ #ifdef DEBUG0 printf("disable_host_freshness_checks() start\n"); #endif /* set the attribute modified flag */ modified_host_process_attributes|=MODATTR_FRESHNESS_CHECKS_ENABLED; /* set the freshness check flag */ check_host_freshness=FALSE; /* update the status log with the program info */ update_program_status(FALSE); #ifdef DEBUG0 printf("disable_host_freshness_checks() end\n"); #endif return; } /* enable failure prediction on a program-wide basis */ void enable_all_failure_prediction(void){ #ifdef DEBUG0 printf("enable_all_failure_prediction() start\n"); #endif /* set the attribute modified flag */ modified_host_process_attributes|=MODATTR_FAILURE_PREDICTION_ENABLED; modified_service_process_attributes|=MODATTR_FAILURE_PREDICTION_ENABLED; /* bail out if we're already set... */ if(enable_failure_prediction==TRUE) return; enable_failure_prediction=TRUE; /* update the status log */ update_program_status(FALSE); #ifdef DEBUG0 printf("enable_all_failure_prediction() end\n"); #endif return; } /* disable failure prediction on a program-wide basis */ void disable_all_failure_prediction(void){ #ifdef DEBUG0 printf("disable_all_failure_prediction() start\n"); #endif /* set the attribute modified flag */ modified_host_process_attributes|=MODATTR_FAILURE_PREDICTION_ENABLED; modified_service_process_attributes|=MODATTR_FAILURE_PREDICTION_ENABLED; /* bail out if we're already set... */ if(enable_failure_prediction==FALSE) return; enable_failure_prediction=FALSE; /* update the status log */ update_program_status(FALSE); #ifdef DEBUG0 printf("enable_all_failure_prediction() end\n"); #endif return; } /* enable performance data on a program-wide basis */ void enable_performance_data(void){ #ifdef DEBUG0 printf("enable_performance_data() start\n"); #endif /* set the attribute modified flag */ modified_host_process_attributes|=MODATTR_PERFORMANCE_DATA_ENABLED; modified_service_process_attributes|=MODATTR_PERFORMANCE_DATA_ENABLED; /* bail out if we're already set... */ if(process_performance_data==TRUE) return; process_performance_data=TRUE; /* update the status log */ update_program_status(FALSE); #ifdef DEBUG0 printf("enable_performance_data() end\n"); #endif return; } /* disable performance data on a program-wide basis */ void disable_performance_data(void){ #ifdef DEBUG0 printf("disable_performance_data() start\n"); #endif /* set the attribute modified flag */ modified_host_process_attributes|=MODATTR_PERFORMANCE_DATA_ENABLED; modified_service_process_attributes|=MODATTR_PERFORMANCE_DATA_ENABLED; /* bail out if we're already set... */ if(process_performance_data==FALSE) return; process_performance_data=FALSE; /* update the status log */ update_program_status(FALSE); #ifdef DEBUG0 printf("disable_performance_data() end\n"); #endif return; } /* start obsessing over a particular service */ void start_obsessing_over_service(service *svc){ #ifdef DEBUG0 printf("start_obsessing_over_service() start\n"); #endif /* set the attribute modified flag */ svc->modified_attributes|=MODATTR_OBSESSIVE_HANDLER_ENABLED; /* set the obsess over service flag */ svc->obsess_over_service=TRUE; /* update the status log with the service info */ update_service_status(svc,FALSE); #ifdef DEBUG0 printf("start_obsessing_over_service() end\n"); #endif return; } /* stop obsessing over a particular service */ void stop_obsessing_over_service(service *svc){ #ifdef DEBUG0 printf("stop_obsessing_over_service() start\n"); #endif /* set the attribute modified flag */ svc->modified_attributes|=MODATTR_OBSESSIVE_HANDLER_ENABLED; /* set the obsess over service flag */ svc->obsess_over_service=FALSE; /* update the status log with the service info */ update_service_status(svc,FALSE); #ifdef DEBUG0 printf("stop_obsessing_over_service() end\n"); #endif return; } /* start obsessing over a particular host */ void start_obsessing_over_host(host *hst){ #ifdef DEBUG0 printf("start_obsessing_over_host() start\n"); #endif /* set the attribute modified flag */ hst->modified_attributes|=MODATTR_OBSESSIVE_HANDLER_ENABLED; /* set the obsess over host flag */ hst->obsess_over_host=TRUE; /* update the status log with the host info */ update_host_status(hst,FALSE); #ifdef DEBUG0 printf("start_obsessing_over_host() end\n"); #endif return; } /* stop obsessing over a particular host */ void stop_obsessing_over_host(host *hst){ #ifdef DEBUG0 printf("stop_obsessing_over_host() start\n"); #endif /* set the attribute modified flag */ hst->modified_attributes|=MODATTR_OBSESSIVE_HANDLER_ENABLED; /* set the obsess over host flag */ hst->obsess_over_host=FALSE; /* update the status log with the host info */ update_host_status(hst,FALSE); #ifdef DEBUG0 printf("stop_obsessing_over_host() end\n"); #endif return; } /* sets the current notification number for a specific host */ void set_host_notification_number(host *hst, int num){ #ifdef DEBUG0 printf("set_host_notification_number() start\n"); #endif /* set the notification number */ hst->current_notification_number=num; /* update the status log with the host info */ update_host_status(hst,FALSE); #ifdef DEBUG0 printf("set_host_notification_number() end\n"); #endif return; } /* sets the current notification number for a specific service */ void set_service_notification_number(service *svc, int num){ #ifdef DEBUG0 printf("set_service_notification_number() start\n"); #endif /* set the notification number */ svc->current_notification_number=num; /* update the status log with the service info */ update_service_status(svc,FALSE); #ifdef DEBUG0 printf("set_service_notification_number() end\n"); #endif return; } /* process all passive service checks found in a given file */ void process_passive_service_checks(void){ service_message svc_msg; pid_t pid; passive_check_result *temp_pcr; passive_check_result *this_pcr; passive_check_result *next_pcr; #ifdef DEBUG0 printf("process_passive_service_checks() start\n"); #endif /* fork... */ pid=fork(); /* an error occurred while trying to fork */ if(pid==-1) return; /* if we are in the child process... */ if(pid==0){ /* become the process group leader */ setpgid(0,0); /* free allocated memory */ free_memory(); /* close read end of IPC pipe */ close(ipc_pipe[0]); /* reset signal handling */ reset_sighandler(); /* fork again... */ pid=fork(); /* the grandchild process should submit the service check result... */ if(pid==0){ /* write all service checks to the IPC pipe for later processing by the grandparent */ for(temp_pcr=passive_check_result_list;temp_pcr!=NULL;temp_pcr=temp_pcr->next){ strncpy(svc_msg.host_name,temp_pcr->host_name,sizeof(svc_msg.host_name)-1); svc_msg.host_name[sizeof(svc_msg.host_name)-1]='\x0'; strncpy(svc_msg.description,temp_pcr->svc_description,sizeof(svc_msg.description)-1); svc_msg.description[sizeof(svc_msg.description)-1]='\x0'; snprintf(svc_msg.output,sizeof(svc_msg.output)-1,"%s",temp_pcr->output); svc_msg.output[sizeof(svc_msg.output)-1]='\x0'; svc_msg.return_code=temp_pcr->return_code; svc_msg.parallelized=FALSE; svc_msg.exited_ok=TRUE; svc_msg.check_type=SERVICE_CHECK_PASSIVE; svc_msg.start_time.tv_sec=temp_pcr->check_time; svc_msg.start_time.tv_usec=0; svc_msg.finish_time=svc_msg.start_time; /* write the service check results... */ write_svc_message(&svc_msg); } } /* free memory for the passive service check result list */ this_pcr=passive_check_result_list; while(this_pcr!=NULL){ next_pcr=this_pcr->next; free(this_pcr->host_name); free(this_pcr->svc_description); free(this_pcr->output); free(this_pcr); this_pcr=next_pcr; } exit(OK); } /* else the parent should wait for the first child to return... */ else if(pid>0) waitpid(pid,NULL,0); /* free memory for the passive service check result list */ this_pcr=passive_check_result_list; while(this_pcr!=NULL){ next_pcr=this_pcr->next; free(this_pcr->host_name); free(this_pcr->svc_description); free(this_pcr->output); free(this_pcr); this_pcr=next_pcr; } passive_check_result_list=NULL; passive_check_result_list_tail=NULL; #ifdef DEBUG0 printf("process_passive_service_checks() end\n"); #endif return; } nagios-2.6/base/config.c0000664000076500007650000027526010354075066014544 0ustar nagiosnagios/***************************************************************************** * * CONFIG.C - Configuration input and verification routines for Nagios * * Copyright (c) 1999-2005 Ethan Galstad (nagios@nagios.org) * Last Modified: 12-26-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. * *****************************************************************************/ #include "../include/config.h" #include "../include/common.h" #include "../include/objects.h" #include "../include/nagios.h" #include "../include/broker.h" #include "../include/nebmods.h" #include "../include/nebmodules.h" extern char *log_file; extern char *command_file; extern char *temp_file; extern char *lock_file; extern char *log_archive_path; extern char *auth_file; extern char *p1_file; extern char *nagios_user; extern char *nagios_group; extern char *macro_x[MACRO_X_COUNT]; extern char *macro_user[MAX_USER_MACROS]; extern char *global_host_event_handler; extern char *global_service_event_handler; extern char *ocsp_command; extern char *ochp_command; extern char *illegal_object_chars; extern char *illegal_output_chars; extern int use_regexp_matches; extern int use_true_regexp_matching; extern int use_syslog; extern int log_notifications; extern int log_service_retries; extern int log_host_retries; extern int log_event_handlers; extern int log_external_commands; extern int log_passive_checks; extern int service_check_timeout; extern int host_check_timeout; extern int event_handler_timeout; extern int notification_timeout; extern int ocsp_timeout; extern int ochp_timeout; extern int log_initial_states; extern int daemon_mode; extern int daemon_dumps_core; extern int verify_config; extern int test_scheduling; extern double sleep_time; extern int interval_length; extern int service_inter_check_delay_method; extern int host_inter_check_delay_method; extern int service_interleave_factor_method; extern int max_host_check_spread; extern int max_service_check_spread; extern sched_info scheduling_info; extern int max_child_process_time; extern int max_parallel_service_checks; extern int command_check_interval; extern int service_check_reaper_interval; extern int service_freshness_check_interval; extern int host_freshness_check_interval; extern int auto_rescheduling_interval; extern int auto_rescheduling_window; extern int check_external_commands; extern int check_orphaned_services; extern int check_service_freshness; extern int check_host_freshness; extern int auto_reschedule_checks; extern int use_aggressive_host_checking; extern int soft_state_dependencies; extern int retain_state_information; extern int retention_update_interval; extern int use_retained_program_state; extern int use_retained_scheduling_info; extern int retention_scheduling_horizon; extern int log_rotation_method; extern int enable_notifications; extern int execute_service_checks; extern int accept_passive_service_checks; extern int execute_host_checks; extern int accept_passive_host_checks; extern int enable_event_handlers; extern int obsess_over_services; extern int obsess_over_hosts; extern int enable_failure_prediction; extern int aggregate_status_updates; extern int status_update_interval; extern int time_change_threshold; extern unsigned long event_broker_options; extern int process_performance_data; extern int enable_flap_detection; extern double low_service_flap_threshold; extern double high_service_flap_threshold; extern double low_host_flap_threshold; extern double high_host_flap_threshold; extern int date_format; extern contact *contact_list; extern contactgroup *contactgroup_list; extern host *host_list; extern hostgroup *hostgroup_list; extern service *service_list; extern servicegroup *servicegroup_list; extern notification *notification_list; extern command *command_list; extern timeperiod *timeperiod_list; extern serviceescalation *serviceescalation_list; extern servicedependency *servicedependency_list; extern hostdependency *hostdependency_list; extern hostescalation *hostescalation_list; extern hostextinfo *hostextinfo_list; extern serviceextinfo *serviceextinfo_list; extern host **host_hashlist; extern service **service_hashlist; /******************************************************************/ /************** CONFIGURATION INPUT FUNCTIONS *********************/ /******************************************************************/ /* read all configuration data */ int read_all_object_data(char *main_config_file){ int result=OK; int options; int cache=FALSE; #ifdef DEBUG0 printf("read_all_config_data() start\n"); #endif options=READ_ALL_OBJECT_DATA; /* cache object definitions if we're up and running */ if(verify_config==FALSE && test_scheduling==FALSE) cache=TRUE; /* read in all host configuration data from external sources */ result=read_object_config_data(main_config_file,options,cache); if(result!=OK) return ERROR; #ifdef DEBUG0 printf("read_all_config_data() end\n"); #endif return OK; } /* process the main configuration file */ int read_main_config_file(char *main_config_file){ char *input=NULL; char variable[MAX_INPUT_BUFFER]; char value[MAX_INPUT_BUFFER]; char temp_buffer[MAX_INPUT_BUFFER]; char error_message[MAX_INPUT_BUFFER]; char *temp; mmapfile *thefile; int current_line=0; int error=FALSE; int command_check_interval_is_seconds=FALSE; char *modptr; char *argptr; #ifdef DEBUG0 printf("read_main_config_file() start\n"); #endif #ifdef DEBUG1 printf("\tConfig file: %s\n",main_config_file); #endif /* open the config file for reading */ if((thefile=mmap_fopen(main_config_file))==NULL){ snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Cannot open main configuration file '%s' for reading!",main_config_file); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); return ERROR; } /* save the main config file macro */ if(macro_x[MACRO_MAINCONFIGFILE]!=NULL) free(macro_x[MACRO_MAINCONFIGFILE]); macro_x[MACRO_MAINCONFIGFILE]=(char *)strdup(main_config_file); if(macro_x[MACRO_MAINCONFIGFILE]!=NULL) strip(macro_x[MACRO_MAINCONFIGFILE]); /* process all lines in the config file */ while(1){ /* free memory */ free(input); /* read the next line */ if((input=mmap_fgets(thefile))==NULL) break; current_line=thefile->current_line; /* skip blank lines */ if(input[0]=='\x0' || input[0]=='\n' || input[0]=='\r') continue; strip(input); /* skip comments */ if(input[0]=='#' || input[0]==';') continue; /* skip external data directives */ if(strstr(input,"x")==input) continue; #ifdef DEBUG1 printf("\tLine %d = '%s'\n",current_line,input); #endif /* get the variable name */ temp=my_strtok(input,"="); /* if there is no variable name, return error */ if(temp==NULL){ strcpy(error_message,"NULL variable"); error=TRUE; break; } /* else the variable is good */ strncpy(variable,temp,sizeof(variable)); variable[sizeof(variable)-1]='\x0'; /* get the value */ temp=my_strtok(NULL,"\n"); /* if no value exists, return error */ if(temp==NULL){ strcpy(error_message,"NULL value"); error=TRUE; break; } /* else the value is good */ strncpy(value,temp,sizeof(value)); value[sizeof(value)-1]='\x0'; strip(value); /* process the variable/value */ if(!strcmp(variable,"resource_file")){ /* save the macro */ if(macro_x[MACRO_RESOURCEFILE]!=NULL) free(macro_x[MACRO_RESOURCEFILE]); macro_x[MACRO_RESOURCEFILE]=(char *)strdup(value); if(macro_x[MACRO_RESOURCEFILE]==NULL){ strcpy(error_message,"Could not allocate memory for macro"); error=TRUE; break; } strip(macro_x[MACRO_RESOURCEFILE]); #ifdef DEBUG1 printf("\t\tprocessing resource file '%s'\n",value); #endif read_resource_file(value); } else if(!strcmp(variable,"log_file")){ if(strlen(value)>MAX_FILENAME_LENGTH-1){ strcpy(error_message,"Log file is too long"); error=TRUE; break; } if(log_file!=NULL) free(log_file); log_file=(char *)strdup(value); strip(log_file); /* save the macro */ if(macro_x[MACRO_LOGFILE]!=NULL) free(macro_x[MACRO_LOGFILE]); macro_x[MACRO_LOGFILE]=(char *)strdup(log_file); if(macro_x[MACRO_LOGFILE]==NULL){ strcpy(error_message,"Could not allocate memory for macro"); error=TRUE; break; } strip(macro_x[MACRO_LOGFILE]); #ifdef DEBUG1 printf("\t\tlog_file set to '%s'\n",log_file); #endif } else if(!strcmp(variable,"command_file")){ if(strlen(value)>MAX_FILENAME_LENGTH-1){ strcpy(error_message,"Command file is too long"); error=TRUE; break; } if(command_file!=NULL) free(command_file); command_file=(char *)strdup(value); strip(command_file); /* save the macro */ if(macro_x[MACRO_COMMANDFILE]!=NULL) free(macro_x[MACRO_COMMANDFILE]); macro_x[MACRO_COMMANDFILE]=(char *)strdup(value); if(macro_x[MACRO_COMMANDFILE]==NULL){ strcpy(error_message,"Could not allocate memory for macro"); error=TRUE; break; } strip(macro_x[MACRO_COMMANDFILE]); #ifdef DEBUG1 printf("\t\tcommand_file set to '%s'\n",command_file); #endif } else if(!strcmp(variable,"temp_file")){ if(strlen(value)>MAX_FILENAME_LENGTH-1){ strcpy(error_message,"Temp file is too long"); error=TRUE; break; } if(temp_file!=NULL) free(temp_file); temp_file=(char *)strdup(value); strip(temp_file); /* save the macro */ if(macro_x[MACRO_TEMPFILE]!=NULL) free(macro_x[MACRO_TEMPFILE]); macro_x[MACRO_TEMPFILE]=(char *)strdup(temp_file); if(macro_x[MACRO_TEMPFILE]==NULL){ strcpy(error_message,"Could not allocate memory for macro"); error=TRUE; break; } strip(macro_x[MACRO_TEMPFILE]); #ifdef DEBUG1 printf("\t\ttemp_file set to '%s'\n",temp_file); #endif } else if(!strcmp(variable,"lock_file")){ if(strlen(value)>MAX_FILENAME_LENGTH-1){ strcpy(error_message,"Lock file is too long"); error=TRUE; break; } if(lock_file!=NULL) free(lock_file); lock_file=(char *)strdup(value); strip(lock_file); #ifdef DEBUG1 printf("\t\tlock_file set to '%s'\n",lock_file); #endif } else if(!strcmp(variable,"global_host_event_handler")){ if(global_host_event_handler!=NULL) free(global_host_event_handler); global_host_event_handler=(char *)strdup(value); if(global_host_event_handler==NULL){ strcpy(error_message,"Could not allocate memory for global host event handler"); error=TRUE; break; } strip(global_host_event_handler); #ifdef DEBUG1 printf("\t\tglobal_host_event_handler set to '%s'\n",global_host_event_handler); #endif } else if(!strcmp(variable,"global_service_event_handler")){ if(global_service_event_handler!=NULL) free(global_service_event_handler); global_service_event_handler=(char *)strdup(value); if(global_service_event_handler==NULL){ strcpy(error_message,"Could not allocate memory for global service event handler"); error=TRUE; break; } strip(global_service_event_handler); #ifdef DEBUG1 printf("\t\tglobal_service_event_handler set to '%s'\n",global_service_event_handler); #endif } else if(!strcmp(variable,"ocsp_command")){ if(ocsp_command!=NULL) free(ocsp_command); ocsp_command=(char *)strdup(value); if(ocsp_command==NULL){ strcpy(error_message,"Could not allocate memory for obsessive compulsive service processor command"); error=TRUE; break; } strip(ocsp_command); #ifdef DEBUG1 printf("\t\tocsp_command set to '%s'\n",ocsp_command); #endif } else if(!strcmp(variable,"ochp_command")){ if(ochp_command!=NULL) free(ochp_command); ochp_command=(char *)strdup(value); if(ochp_command==NULL){ strcpy(error_message,"Could not allocate memory for obsessive compulsive host processor command"); error=TRUE; break; } strip(ochp_command); #ifdef DEBUG1 printf("\t\tochp_command set to '%s'\n",ochp_command); #endif } else if(!strcmp(variable,"nagios_user")){ if(nagios_user!=NULL) free(nagios_user); nagios_user=(char *)strdup(value); if(nagios_user==NULL){ strcpy(error_message,"Could not allocate memory for nagios user"); error=TRUE; break; } strip(nagios_user); #ifdef DEBUG1 printf("\t\tnagios_user set to '%s'\n",nagios_user); #endif } else if(!strcmp(variable,"nagios_group")){ if(nagios_group!=NULL) free(nagios_group); nagios_group=(char *)strdup(value); if(nagios_group==NULL){ strcpy(error_message,"Could not allocate memory for nagios group"); error=TRUE; break; } strip(nagios_group); #ifdef DEBUG1 printf("\t\tnagios_group set to '%s'\n",nagios_group); #endif } else if(!strcmp(variable,"admin_email")){ /* save the macro */ if(macro_x[MACRO_ADMINEMAIL]!=NULL) free(macro_x[MACRO_ADMINEMAIL]); macro_x[MACRO_ADMINEMAIL]=(char *)strdup(value); if(macro_x[MACRO_ADMINEMAIL]==NULL){ strcpy(error_message,"Could not allocate memory for admin email address"); error=TRUE; break; } strip(macro_x[MACRO_ADMINEMAIL]); #ifdef DEBUG1 printf("\t\tmacro_admin_email set to '%s'\n",macro_x[MACRO_ADMINEMAIL]); #endif } else if(!strcmp(variable,"admin_pager")){ /* save the macro */ if(macro_x[MACRO_ADMINPAGER]!=NULL) free(macro_x[MACRO_ADMINPAGER]); macro_x[MACRO_ADMINPAGER]=(char *)strdup(value); if(macro_x[MACRO_ADMINPAGER]==NULL){ strcpy(error_message,"Could not allocate memory for admin pager"); error=TRUE; break; } strip(macro_x[MACRO_ADMINPAGER]); #ifdef DEBUG1 printf("\t\tmacro_admin_pager set to '%s'\n",macro_x[MACRO_ADMINPAGER]); #endif } else if(!strcmp(variable,"use_syslog")){ if(strlen(value)!=1||value[0]<'0'||value[0]>'1'){ strcpy(error_message,"Illegal value for use_syslog"); error=TRUE; break; } strip(value); use_syslog=(atoi(value)>0)?TRUE:FALSE; #ifdef DEBUG1 printf("\t\tuse_syslog set to %s\n",(use_syslog==TRUE)?"TRUE":"FALSE"); #endif } else if(!strcmp(variable,"log_notifications")){ if(strlen(value)!=1||value[0]<'0'||value[0]>'1'){ strcpy(error_message,"Illegal value for log_notifications"); error=TRUE; break; } strip(value); log_notifications=(atoi(value)>0)?TRUE:FALSE; #ifdef DEBUG1 printf("\t\tlog_notifications set to %s\n",(log_notifications==TRUE)?"TRUE":"FALSE"); #endif } else if(!strcmp(variable,"log_service_retries")){ if(strlen(value)!=1||value[0]<'0'||value[0]>'1'){ strcpy(error_message,"Illegal value for log_service_retries"); error=TRUE; break; } strip(value); log_service_retries=(atoi(value)>0)?TRUE:FALSE; #ifdef DEBUG1 printf("\t\tlog_service_retries set to %s\n",(log_service_retries==TRUE)?"TRUE":"FALSE"); #endif } else if(!strcmp(variable,"log_host_retries")){ if(strlen(value)!=1||value[0]<'0'||value[0]>'1'){ strcpy(error_message,"Illegal value for log_host_retries"); error=TRUE; break; } strip(value); log_host_retries=(atoi(value)>0)?TRUE:FALSE; #ifdef DEBUG1 printf("\t\tlog_host_retries set to %s\n",(log_host_retries==TRUE)?"TRUE":"FALSE"); #endif } else if(!strcmp(variable,"log_event_handlers")){ if(strlen(value)!=1||value[0]<'0'||value[0]>'1'){ strcpy(error_message,"Illegal value for log_event_handlers"); error=TRUE; break; } strip(value); log_event_handlers=(atoi(value)>0)?TRUE:FALSE; #ifdef DEBUG1 printf("\t\tlog_event_handlers set to %s\n",(log_event_handlers==TRUE)?"TRUE":"FALSE"); #endif } else if(!strcmp(variable,"log_external_commands")){ if(strlen(value)!=1||value[0]<'0'||value[0]>'1'){ strcpy(error_message,"Illegal value for log_external_commands"); error=TRUE; break; } strip(value); log_external_commands=(atoi(value)>0)?TRUE:FALSE; #ifdef DEBUG1 printf("\t\tlog_external_commands set to %s\n",(log_external_commands==TRUE)?"TRUE":"FALSE"); #endif } else if(!strcmp(variable,"log_passive_checks")){ if(strlen(value)!=1||value[0]<'0'||value[0]>'1'){ strcpy(error_message,"Illegal value for log_passive_checks"); error=TRUE; break; } strip(value); log_passive_checks=(atoi(value)>0)?TRUE:FALSE; #ifdef DEBUG1 printf("\t\tlog_passive_checks set to %s\n",(log_passive_checks==TRUE)?"TRUE":"FALSE"); #endif } else if(!strcmp(variable,"log_initial_states")){ if(strlen(value)!=1||value[0]<'0'||value[0]>'1'){ strcpy(error_message,"Illegal value for log_initial_states"); error=TRUE; break; } strip(value); log_initial_states=(atoi(value)>0)?TRUE:FALSE; #ifdef DEBUG1 printf("\t\tlog_initial_states set to %s\n",(log_initial_states==TRUE)?"TRUE":"FALSE"); #endif } else if(!strcmp(variable,"retain_state_information")){ if(strlen(value)!=1||value[0]<'0'||value[0]>'1'){ strcpy(error_message,"Illegal value for retain_state_information"); error=TRUE; break; } strip(value); retain_state_information=(atoi(value)>0)?TRUE:FALSE; #ifdef DEBUG1 printf("\t\tretain_state_information set to %s\n",(retain_state_information==TRUE)?"TRUE":"FALSE"); #endif } else if(!strcmp(variable,"retention_update_interval")){ strip(value); retention_update_interval=atoi(value); if(retention_update_interval<0){ strcpy(error_message,"Illegal value for retention_update_interval"); error=TRUE; break; } #ifdef DEBUG1 printf("\t\tretention_update_interval set to %d\n",retention_update_interval); #endif } else if(!strcmp(variable,"use_retained_program_state")){ if(strlen(value)!=1||value[0]<'0'||value[0]>'1'){ strcpy(error_message,"Illegal value for use_retained_program_state"); error=TRUE; break; } strip(value); use_retained_program_state=(atoi(value)>0)?TRUE:FALSE; #ifdef DEBUG1 printf("\t\tuse_retained_program_state set to %s\n",(use_retained_program_state==TRUE)?"TRUE":"FALSE"); #endif } else if(!strcmp(variable,"use_retained_scheduling_info")){ if(strlen(value)!=1||value[0]<'0'||value[0]>'1'){ strcpy(error_message,"Illegal value for use_retained_scheduling_info"); error=TRUE; break; } strip(value); use_retained_scheduling_info=(atoi(value)>0)?TRUE:FALSE; #ifdef DEBUG1 printf("\t\tuse_retained_scheduling_info set to %s\n",(use_retained_scheduling_info==TRUE)?"TRUE":"FALSE"); #endif } else if(!strcmp(variable,"retention_scheduling_horizon")){ strip(value); retention_scheduling_horizon=atoi(value); if(retention_scheduling_horizon<=0){ strcpy(error_message,"Illegal value for retention_scheduling_horizon"); error=TRUE; break; } #ifdef DEBUG1 printf("\t\tretention_scheduling_horizon set to %d\n",retention_scheduling_horizon); #endif } else if(!strcmp(variable,"obsess_over_services")){ if(strlen(value)!=1||value[0]<'0'||value[0]>'1'){ strcpy(error_message,"Illegal value for obsess_over_services"); error=TRUE; break; } strip(value); obsess_over_services=(atoi(value)>0)?TRUE:FALSE; #ifdef DEBUG1 printf("\t\tobsess_over_services set to %s\n",(obsess_over_services==TRUE)?"TRUE":"FALSE"); #endif } else if(!strcmp(variable,"obsess_over_hosts")){ if(strlen(value)!=1||value[0]<'0'||value[0]>'1'){ strcpy(error_message,"Illegal value for obsess_over_hosts"); error=TRUE; break; } strip(value); obsess_over_hosts=(atoi(value)>0)?TRUE:FALSE; #ifdef DEBUG1 printf("\t\tobsess_over_hosts set to %s\n",(obsess_over_hosts==TRUE)?"TRUE":"FALSE"); #endif } else if(!strcmp(variable,"service_check_timeout")){ strip(value); service_check_timeout=atoi(value); if(service_check_timeout<=0){ strcpy(error_message,"Illegal value for service_check_timeout"); error=TRUE; break; } #ifdef DEBUG1 printf("\t\tservice_check_timeout set to %d\n",service_check_timeout); #endif } else if(!strcmp(variable,"host_check_timeout")){ strip(value); host_check_timeout=atoi(value); if(host_check_timeout<=0){ strcpy(error_message,"Illegal value for host_check_timeout"); error=TRUE; break; } #ifdef DEBUG1 printf("\t\thost_check_timeout set to %d\n",host_check_timeout); #endif } else if(!strcmp(variable,"event_handler_timeout")){ strip(value); event_handler_timeout=atoi(value); if(event_handler_timeout<=0){ strcpy(error_message,"Illegal value for event_handler_timeout"); error=TRUE; break; } #ifdef DEBUG1 printf("\t\tevent_handler_timeout set to %d\n",event_handler_timeout); #endif } else if(!strcmp(variable,"notification_timeout")){ strip(value); notification_timeout=atoi(value); if(notification_timeout<=0){ strcpy(error_message,"Illegal value for notification_timeout"); error=TRUE; break; } #ifdef DEBUG1 printf("\t\tnotification_timeout set to %d\n",notification_timeout); #endif } else if(!strcmp(variable,"ocsp_timeout")){ strip(value); ocsp_timeout=atoi(value); if(ocsp_timeout<=0){ strcpy(error_message,"Illegal value for ocsp_timeout"); error=TRUE; break; } #ifdef DEBUG1 printf("\t\tocsp_timeout set to %d\n",ocsp_timeout); #endif } else if(!strcmp(variable,"ochp_timeout")){ strip(value); ochp_timeout=atoi(value); if(ochp_timeout<=0){ strcpy(error_message,"Illegal value for ochp_timeout"); error=TRUE; break; } #ifdef DEBUG1 printf("\t\tochp_timeout set to %d\n",ochp_timeout); #endif } else if(!strcmp(variable,"use_agressive_host_checking") || !strcmp(variable,"use_aggressive_host_checking")){ if(strlen(value)!=1||value[0]<'0'||value[0]>'1'){ strcpy(error_message,"Illegal value for use_aggressive_host_checking"); error=TRUE; break; } strip(value); use_aggressive_host_checking=(atoi(value)>0)?TRUE:FALSE; #ifdef DEBUG1 printf("\t\tuse_aggressive_host_checking set to %s\n",(use_aggressive_host_checking==TRUE)?"TRUE":"FALSE"); #endif } else if(!strcmp(variable,"soft_state_dependencies")){ if(strlen(value)!=1||value[0]<'0'||value[0]>'1'){ strcpy(error_message,"Illegal value for soft_state_dependencies"); error=TRUE; break; } strip(value); soft_state_dependencies=(atoi(value)>0)?TRUE:FALSE; #ifdef DEBUG1 printf("\t\tsoft_state_dependencies set to %s\n",(soft_state_dependencies==TRUE)?"TRUE":"FALSE"); #endif } else if(!strcmp(variable,"log_rotation_method")){ if(!strcmp(value,"n")) log_rotation_method=LOG_ROTATION_NONE; else if(!strcmp(value,"h")) log_rotation_method=LOG_ROTATION_HOURLY; else if(!strcmp(value,"d")) log_rotation_method=LOG_ROTATION_DAILY; else if(!strcmp(value,"w")) log_rotation_method=LOG_ROTATION_WEEKLY; else if(!strcmp(value,"m")) log_rotation_method=LOG_ROTATION_MONTHLY; else{ strcpy(error_message,"Illegal value for log_rotation_method"); error=TRUE; break; } #ifdef DEBUG1 printf("\t\tlog_rotation_method set to %d\n",log_rotation_method); #endif } else if(!strcmp(variable,"log_archive_path")){ if(strlen(value)>MAX_FILENAME_LENGTH-1){ strcpy(error_message,"Log archive path too long"); error=TRUE; break; } if(log_archive_path!=NULL) free(log_archive_path); log_archive_path=(char *)strdup(value); strip(log_archive_path); #ifdef DEBUG1 printf("\t\tlog_archive_path set to '%s'\n",log_archive_path); #endif } else if(!strcmp(variable,"enable_event_handlers")){ strip(value); enable_event_handlers=(atoi(value)>0)?TRUE:FALSE; #ifdef DEBUG1 printf("\t\tenable_event_handlers set to %s\n",(enable_event_handlers==TRUE)?"TRUE":"FALSE"); #endif } else if(!strcmp(variable,"enable_notifications")){ strip(value); enable_notifications=(atoi(value)>0)?TRUE:FALSE; #ifdef DEBUG1 printf("\t\tenable_notifications set to %s\n",(enable_notifications==TRUE)?"TRUE":"FALSE"); #endif } else if(!strcmp(variable,"execute_service_checks")){ strip(value); execute_service_checks=(atoi(value)>0)?TRUE:FALSE; #ifdef DEBUG1 printf("\t\texecute_service_checks set to %s\n",(execute_service_checks==TRUE)?"TRUE":"FALSE"); #endif } else if(!strcmp(variable,"accept_passive_service_checks")){ strip(value); accept_passive_service_checks=(atoi(value)>0)?TRUE:FALSE; #ifdef DEBUG1 printf("\t\taccept_passive_service_checks set to %s\n",(accept_passive_service_checks==TRUE)?"TRUE":"FALSE"); #endif } else if(!strcmp(variable,"execute_host_checks")){ strip(value); execute_host_checks=(atoi(value)>0)?TRUE:FALSE; #ifdef DEBUG1 printf("\t\texecute_host_checks set to %s\n",(execute_host_checks==TRUE)?"TRUE":"FALSE"); #endif } else if(!strcmp(variable,"accept_passive_host_checks")){ strip(value); accept_passive_host_checks=(atoi(value)>0)?TRUE:FALSE; #ifdef DEBUG1 printf("\t\taccept_passive_host_checks set to %s\n",(accept_passive_host_checks==TRUE)?"TRUE":"FALSE"); #endif } else if(!strcmp(variable,"service_inter_check_delay_method")){ if(!strcmp(value,"n")) service_inter_check_delay_method=ICD_NONE; else if(!strcmp(value,"d")) service_inter_check_delay_method=ICD_DUMB; else if(!strcmp(value,"s")) service_inter_check_delay_method=ICD_SMART; else{ service_inter_check_delay_method=ICD_USER; scheduling_info.service_inter_check_delay=strtod(value,NULL); if(scheduling_info.service_inter_check_delay<=0.0){ strcpy(error_message,"Illegal value for service_inter_check_delay_method"); error=TRUE; break; } } #ifdef DEBUG1 printf("\t\tservice_inter_check_delay_method set to %d\n",service_inter_check_delay_method); #endif } else if(!strcmp(variable,"max_service_check_spread")){ strip(value); max_service_check_spread=atoi(value); if(max_service_check_spread<1){ strcpy(error_message,"Illegal value for max_service_check_spread"); error=TRUE; break; } #ifdef DEBUG1 printf("\t\tmax_service_check_spread set to %d\n",max_service_check_spread); #endif } else if(!strcmp(variable,"host_inter_check_delay_method")){ if(!strcmp(value,"n")) host_inter_check_delay_method=ICD_NONE; else if(!strcmp(value,"d")) host_inter_check_delay_method=ICD_DUMB; else if(!strcmp(value,"s")) host_inter_check_delay_method=ICD_SMART; else{ host_inter_check_delay_method=ICD_USER; scheduling_info.host_inter_check_delay=strtod(value,NULL); if(scheduling_info.host_inter_check_delay<=0.0){ strcpy(error_message,"Illegal value for host_inter_check_delay_method"); error=TRUE; break; } } #ifdef DEBUG1 printf("\t\thost_inter_check_delay_method set to %d\n",host_inter_check_delay_method); #endif } else if(!strcmp(variable,"max_host_check_spread")){ strip(value); max_host_check_spread=atoi(value); if(max_host_check_spread<1){ strcpy(error_message,"Illegal value for max_host_check_spread"); error=TRUE; break; } #ifdef DEBUG1 printf("\t\tmax_host_check_spread set to %d\n",max_host_check_spread); #endif } else if(!strcmp(variable,"service_interleave_factor")){ if(!strcmp(value,"s")) service_interleave_factor_method=ILF_SMART; else{ service_interleave_factor_method=ILF_USER; scheduling_info.service_interleave_factor=atoi(value); if(scheduling_info.service_interleave_factor<1) scheduling_info.service_interleave_factor=1; } } else if(!strcmp(variable,"max_concurrent_checks")){ strip(value); max_parallel_service_checks=atoi(value); if(max_parallel_service_checks<0){ strcpy(error_message,"Illegal value for max_concurrent_checks"); error=TRUE; break; } #ifdef DEBUG1 printf("\t\tmax_parallel_service_checks set to %d\n",max_parallel_service_checks); #endif } else if(!strcmp(variable,"service_reaper_frequency")){ strip(value); service_check_reaper_interval=atoi(value); if(service_check_reaper_interval<1){ strcpy(error_message,"Illegal value for service_reaper_frequency"); error=TRUE; break; } #ifdef DEBUG1 printf("\t\tservice_check_reaper_interval set to %d\n",service_check_reaper_interval); #endif } else if(!strcmp(variable,"sleep_time")){ strip(value); sleep_time=atof(value); if(sleep_time<=0.0){ strcpy(error_message,"Illegal value for sleep_time"); error=TRUE; break; } #ifdef DEBUG1 printf("\t\tsleep_time set to %f\n",sleep_time); #endif } else if(!strcmp(variable,"interval_length")){ strip(value); interval_length=atoi(value); if(interval_length<1){ strcpy(error_message,"Illegal value for interval_length"); error=TRUE; break; } #ifdef DEBUG1 printf("\t\tinterval_length set to %d\n",interval_length); #endif } else if(!strcmp(variable,"check_external_commands")){ if(strlen(value)!=1||value[0]<'0'||value[0]>'1'){ strcpy(error_message,"Illegal value for check_external_commands"); error=TRUE; break; } strip(value); check_external_commands=(atoi(value)>0)?TRUE:FALSE; #ifdef DEBUG1 printf("\t\tcheck_external_commands set to %s\n",(check_external_commands==TRUE)?"TRUE":"FALSE"); #endif } else if(!strcmp(variable,"command_check_interval")){ strip(value); command_check_interval_is_seconds=(strstr(value,"s"))?TRUE:FALSE; command_check_interval=atoi(value); if(command_check_interval<-1 || command_check_interval==0){ strcpy(error_message,"Illegal value for command_check_interval"); error=TRUE; break; } #ifdef DEBUG1 printf("\t\tcommand_check_interval set to %d\n",command_check_interval); #endif } else if(!strcmp(variable,"check_for_orphaned_services")){ if(strlen(value)!=1||value[0]<'0'||value[0]>'1'){ strcpy(error_message,"Illegal value for check_for_orphaned_services"); error=TRUE; break; } strip(value); check_orphaned_services=(atoi(value)>0)?TRUE:FALSE; #ifdef DEBUG1 printf("\t\tcheck_orphaned_services set to %s\n",(check_orphaned_services==TRUE)?"TRUE":"FALSE"); #endif } else if(!strcmp(variable,"check_service_freshness")){ if(strlen(value)!=1||value[0]<'0'||value[0]>'1'){ strcpy(error_message,"Illegal value for check_service_freshness"); error=TRUE; break; } strip(value); check_service_freshness=(atoi(value)>0)?TRUE:FALSE; #ifdef DEBUG1 printf("\t\tcheck_service_freshness set to %s\n",(check_service_freshness==TRUE)?"TRUE":"FALSE"); #endif } else if(!strcmp(variable,"check_host_freshness")){ if(strlen(value)!=1||value[0]<'0'||value[0]>'1'){ strcpy(error_message,"Illegal value for check_host_freshness"); error=TRUE; break; } strip(value); check_host_freshness=(atoi(value)>0)?TRUE:FALSE; #ifdef DEBUG1 printf("\t\tcheck_host_freshness set to %s\n",(check_host_freshness==TRUE)?"TRUE":"FALSE"); #endif } else if(!strcmp(variable,"service_freshness_check_interval") || !strcmp(variable,"freshness_check_interval")){ strip(value); service_freshness_check_interval=atoi(value); if(service_freshness_check_interval<=0){ strcpy(error_message,"Illegal value for service_freshness_check_interval"); error=TRUE; break; } #ifdef DEBUG1 printf("\t\tservice_freshness_check_interval set to %d\n",service_freshness_check_interval); #endif } else if(!strcmp(variable,"host_freshness_check_interval")){ strip(value); host_freshness_check_interval=atoi(value); if(host_freshness_check_interval<=0){ strcpy(error_message,"Illegal value for host_freshness_check_interval"); error=TRUE; break; } #ifdef DEBUG1 printf("\t\thost_freshness_check_interval set to %d\n",host_freshness_check_interval); #endif } else if(!strcmp(variable,"auto_reschedule_checks")){ if(strlen(value)!=1||value[0]<'0'||value[0]>'1'){ strcpy(error_message,"Illegal value for auto_reschedule_checks"); error=TRUE; break; } strip(value); auto_reschedule_checks=(atoi(value)>0)?TRUE:FALSE; #ifdef DEBUG1 printf("\t\tauto_reschedule_checks set to %s\n",(auto_reschedule_checks==TRUE)?"TRUE":"FALSE"); #endif } else if(!strcmp(variable,"auto_rescheduling_interval")){ strip(value); auto_rescheduling_interval=atoi(value); if(auto_rescheduling_interval<=0){ strcpy(error_message,"Illegal value for auto_rescheduling_interval"); error=TRUE; break; } #ifdef DEBUG1 printf("\t\tauto_rescheduling_interval set to %d\n",auto_rescheduling_interval); #endif } else if(!strcmp(variable,"auto_rescheduling_window")){ strip(value); auto_rescheduling_window=atoi(value); if(auto_rescheduling_window<=0){ strcpy(error_message,"Illegal value for auto_rescheduling_window"); error=TRUE; break; } #ifdef DEBUG1 printf("\t\tauto_rescheduling_window set to %d\n",auto_rescheduling_window); #endif } else if(!strcmp(variable,"aggregate_status_updates")){ strip(value); aggregate_status_updates=(atoi(value)>0)?TRUE:FALSE; #ifdef DEBUG1 printf("\t\taggregate_status_updates to %s\n",(aggregate_status_updates==TRUE)?"TRUE":"FALSE"); #endif } else if(!strcmp(variable,"status_update_interval")){ strip(value); status_update_interval=atoi(value); if(status_update_interval<=1){ strcpy(error_message,"Illegal value for status_update_interval"); error=TRUE; break; } #ifdef DEBUG1 printf("\t\tstatus_update_interval set to %d\n",status_update_interval); #endif } else if(!strcmp(variable,"time_change_threshold")){ strip(value); time_change_threshold=atoi(value); if(time_change_threshold<=5){ strcpy(error_message,"Illegal value for time_change_threshold"); error=TRUE; break; } #ifdef DEBUG1 printf("\t\ttime_change_threshold set to %d\n",time_change_threshold); #endif } else if(!strcmp(variable,"process_performance_data")){ strip(value); process_performance_data=(atoi(value)>0)?TRUE:FALSE; #ifdef DEBUG1 printf("\t\tprocess_performance_data set to %s\n",(process_performance_data==TRUE)?"TRUE":"FALSE"); #endif } else if(!strcmp(variable,"enable_flap_detection")){ strip(value); enable_flap_detection=(atoi(value)>0)?TRUE:FALSE; #ifdef DEBUG1 printf("\t\tenable_flap_detection set to %s\n",(enable_flap_detection==TRUE)?"TRUE":"FALSE"); #endif } else if(!strcmp(variable,"enable_failure_prediction")){ strip(value); enable_failure_prediction=(atoi(value)>0)?TRUE:FALSE; #ifdef DEBUG1 printf("\t\tenable_failure_prediction set to %s\n",(enable_failure_prediction==TRUE)?"TRUE":"FALSE"); #endif } else if(!strcmp(variable,"low_service_flap_threshold")){ low_service_flap_threshold=strtod(value,NULL); if(low_service_flap_threshold<=0.0 || low_service_flap_threshold>=100.0){ strcpy(error_message,"Illegal value for low_service_flap_threshold"); error=TRUE; break; } #ifdef DEBUG1 printf("\t\tlow_service_flap_threshold set to %f\n",low_service_flap_threshold); #endif } else if(!strcmp(variable,"high_service_flap_threshold")){ high_service_flap_threshold=strtod(value,NULL); if(high_service_flap_threshold<=0.0 || high_service_flap_threshold>100.0){ strcpy(error_message,"Illegal value for high_service_flap_threshold"); error=TRUE; break; } #ifdef DEBUG1 printf("\t\thigh_service_flap_threshold set to %f\n",high_service_flap_threshold); #endif } else if(!strcmp(variable,"low_host_flap_threshold")){ low_host_flap_threshold=strtod(value,NULL); if(low_host_flap_threshold<=0.0 || low_host_flap_threshold>=100.0){ strcpy(error_message,"Illegal value for low_host_flap_threshold"); error=TRUE; break; } #ifdef DEBUG1 printf("\t\tlow_host_flap_threshold set to %f\n",low_host_flap_threshold); #endif } else if(!strcmp(variable,"high_host_flap_threshold")){ high_host_flap_threshold=strtod(value,NULL); if(high_host_flap_threshold<=0.0 || high_host_flap_threshold>100.0){ strcpy(error_message,"Illegal value for high_host_flap_threshold"); error=TRUE; break; } #ifdef DEBUG1 printf("\t\thigh_host_flap_threshold set to %f\n",high_host_flap_threshold); #endif } else if(!strcmp(variable,"date_format")){ strip(value); if(!strcmp(value,"euro")) date_format=DATE_FORMAT_EURO; else if(!strcmp(value,"iso8601")) date_format=DATE_FORMAT_ISO8601; else if(!strcmp(value,"strict-iso8601")) date_format=DATE_FORMAT_STRICT_ISO8601; else date_format=DATE_FORMAT_US; #ifdef DEBUG1 printf("\t\tdate_format set to %d\n",date_format); #endif } else if(!strcmp(variable,"p1_file")){ if(strlen(value)>MAX_FILENAME_LENGTH-1){ strcpy(error_message,"P1 file is too long"); error=TRUE; break; } if(p1_file!=NULL) free(p1_file); p1_file=(char *)strdup(value); strip(p1_file); #ifdef DEBUG1 printf("\t\tp1_file set to '%s'\n",p1_file); #endif } else if(!strcmp(variable,"event_broker_options")){ strip(value); if(!strcmp(value,"-1")) event_broker_options=BROKER_EVERYTHING; else event_broker_options=strtoul(value,NULL,0); #ifdef DEBUG1 printf("\t\tevent_broker_options set to %d\n",event_broker_options); #endif } else if(!strcmp(variable,"illegal_object_name_chars")){ illegal_object_chars=strdup(value); #ifdef DEBUG1 printf("\t\tillegal_object_name_chars set to '%s'\n",illegal_object_chars); #endif } else if(!strcmp(variable,"illegal_macro_output_chars")){ illegal_output_chars=strdup(value); #ifdef DEBUG1 printf("\t\tillegal_macro_output_chars set to '%s'\n",illegal_output_chars); #endif } else if(!strcmp(variable,"broker_module")){ modptr=strtok(value," \n"); argptr=strtok(NULL,"\n"); #ifdef USE_EVENT_BROKER neb_add_module(modptr,argptr,TRUE); #endif } else if(!strcmp(variable,"use_regexp_matching")){ strip(value); use_regexp_matches=(atoi(value)>0)?TRUE:FALSE; #ifdef DEBUG1 printf("\t\tuse_regexp_matches to %s\n",(use_regexp_matches==TRUE)?"TRUE":"FALSE"); #endif } else if(!strcmp(variable,"use_true_regexp_matching")){ strip(value); use_true_regexp_matching=(atoi(value)>0)?TRUE:FALSE; #ifdef DEBUG1 printf("\t\tuse_true_regexp_matching to %s\n",(use_true_regexp_matching==TRUE)?"TRUE":"FALSE"); #endif } else if(!strcmp(variable,"daemon_dumps_core")){ if(strlen(value)!=1||value[0]<'0'||value[0]>'1'){ strcpy(error_message,"Illegal value for daemon_dumps_core"); error=TRUE; break; } strip(value); daemon_dumps_core=(atoi(value)>0)?TRUE:FALSE; #ifdef DEBUG1 printf("\t\tdaemon_dumps_core set to %s\n",(daemon_dumps_core==TRUE)?"TRUE":"FALSE"); #endif } /*** AUTH_FILE VARIABLE USED BY EMBEDDED PERL INTERPRETER ***/ else if(!strcmp(variable,"auth_file")){ if(strlen(value)>MAX_FILENAME_LENGTH-1){ strcpy(error_message,"Auth file is too long"); error=TRUE; break; } if(auth_file!=NULL) free(auth_file); auth_file=(char *)strdup(value); strip(auth_file); #ifdef DEBUG1 printf("\t\tauth_file set to '%s'\n",auth_file); #endif } /* ignore old/external variables */ else if(!strcmp(variable,"status_file")) continue; else if(!strcmp(variable,"comment_file")) continue; else if(!strcmp(variable,"downtime_file")) continue; else if(!strcmp(variable,"perfdata_timeout")) continue; else if(strstr(variable,"host_perfdata")==variable) continue; else if(strstr(variable,"service_perfdata")==variable) continue; else if(strstr(input,"cfg_file=")==input || strstr(input,"cfg_dir=")==input) continue; else if(strstr(input,"state_retention_file=")==input) continue; else if(strstr(input,"object_cache_file=")==input) continue; /* we don't know what this variable is... */ else{ strcpy(error_message,"UNKNOWN VARIABLE"); error=TRUE; break; } } /* adjust values */ if(command_check_interval_is_seconds==FALSE && command_check_interval!=-1) command_check_interval*=interval_length; if(error==TRUE){ snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error in configuration file '%s' - Line %d (%s)",main_config_file,current_line,error_message); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); return ERROR; } /* free leftover memory and close the file */ free(input); mmap_fclose(thefile); /* make sure a log file has been specified */ strip(log_file); if(!strcmp(log_file,"")){ if(daemon_mode==FALSE) printf("Error: Log file is not specified anywhere in main config file '%s'!\n",main_config_file); return ERROR; } #ifdef DEBUG0 printf("read_main_config_file() end\n"); #endif return OK; } /* processes macros in resource file */ int read_resource_file(char *resource_file){ char temp_buffer[MAX_INPUT_BUFFER]; char *input=NULL; char variable[MAX_INPUT_BUFFER]; char value[MAX_INPUT_BUFFER]; char *temp_ptr; mmapfile *thefile; int current_line=1; int error=FALSE; int user_index=0; #ifdef DEBUG0 printf("read_resource_file() start\n"); #endif #ifdef DEBUG1 printf("processing resource file '%s'\n",resource_file); #endif if((thefile=mmap_fopen(resource_file))==NULL){ snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Cannot open resource file '%s' for reading!",resource_file); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); return ERROR; } /* process all lines in the resource file */ while(1){ /* free memory */ free(input); /* read the next line */ if((input=mmap_fgets(thefile))==NULL) break; current_line=thefile->current_line; /* skip blank lines and comments */ if(input[0]=='#' || input[0]=='\x0' || input[0]=='\n' || input[0]=='\r') continue; strip(input); /* get the variable name */ temp_ptr=my_strtok(input,"="); /* if there is no variable name, return error */ if(temp_ptr==NULL){ snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: NULL variable - Line %d of resource file '%s'",current_line,resource_file); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); error=TRUE; break; } /* else the variable is good */ strncpy(variable,temp_ptr,sizeof(variable)); variable[sizeof(variable)-1]='\x0'; /* get the value */ temp_ptr=my_strtok(NULL,"\n"); /* if no value exists, return error */ if(temp_ptr==NULL){ snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: NULL variable value - Line %d of resource file '%s'",current_line,resource_file); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); error=TRUE; break; } /* else the value is good */ strncpy(value,temp_ptr,sizeof(value)); value[sizeof(value)-1]='\x0'; strip(value); /* what should we do with the variable/value pair? */ /* check for macro declarations */ if(variable[0]=='$' && variable[strlen(variable)-1]=='$'){ /* $USERx$ macro declarations */ if(strstr(variable,"$USER")==variable && strlen(variable)>5){ user_index=atoi(variable+5)-1; if(user_index>=0 && user_index512){ snprintf(temp_buffer,sizeof(temp_buffer),"Warning: Size of service_message struct (%d bytes) is > POSIX-guaranteed atomic write size (512 bytes). Service checks results may get lost or mangled!",sizeof(service_message)); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_VERIFICATION_WARNING,TRUE); warnings++; } /*****************************************/ /* check each service... */ /*****************************************/ if(verify_config==TRUE) printf("Checking services...\n"); if(service_hashlist==NULL){ snprintf(temp_buffer,sizeof(temp_buffer),"Error: There are no services defined!"); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_VERIFICATION_ERROR,TRUE); errors++; } total_objects=0; for(temp_service=service_list;temp_service!=NULL;temp_service=temp_service->next){ total_objects++; found=FALSE; /* check for a valid host */ temp_host=find_host(temp_service->host_name); /* we couldn't find an associated host! */ if(!temp_host){ snprintf(temp_buffer,sizeof(temp_buffer),"Error: Host '%s' specified in service '%s' not defined anywhere!",temp_service->host_name,temp_service->description); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_VERIFICATION_ERROR,TRUE); errors++; } /* check the event handler command */ if(temp_service->event_handler!=NULL){ /* check the event handler command */ strncpy(temp_buffer,temp_service->event_handler,sizeof(temp_buffer)); temp_buffer[sizeof(temp_buffer)-1]='\x0'; /* get the command name, leave any arguments behind */ temp_command_name=my_strtok(temp_buffer,"!"); temp_command=find_command(temp_command_name); if(temp_command==NULL){ snprintf(temp_buffer,sizeof(temp_buffer),"Error: Event handler command '%s' specified in service '%s' for host '%s' not defined anywhere",temp_command_name,temp_service->description,temp_service->host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_VERIFICATION_ERROR,TRUE); errors++; } } /* check the service check_command */ strncpy(temp_buffer,temp_service->service_check_command,sizeof(temp_buffer)); temp_buffer[sizeof(temp_buffer)-1]='\x0'; /* get the command name, leave any arguments behind */ temp_command_name=my_strtok(temp_buffer,"!"); temp_command=find_command(temp_command_name); if(temp_command==NULL){ snprintf(temp_buffer,sizeof(temp_buffer),"Error: Service check command '%s' specified in service '%s' for host '%s' not defined anywhere!",temp_command_name,temp_service->description,temp_service->host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_VERIFICATION_ERROR,TRUE); errors++; } /* check for sane recovery options */ if(temp_service->notify_on_recovery==TRUE && temp_service->notify_on_warning==FALSE && temp_service->notify_on_critical==FALSE){ snprintf(temp_buffer,sizeof(temp_buffer),"Warning: Recovery notification option in service '%s' for host '%s' doesn't make any sense - specify warning and/or critical options as well",temp_service->description,temp_service->host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_VERIFICATION_WARNING,TRUE); warnings++; } /* reset the found flag */ found=FALSE; /* check for valid contactgroups */ for(temp_contactgroupsmember=temp_service->contact_groups;temp_contactgroupsmember!=NULL;temp_contactgroupsmember=temp_contactgroupsmember->next){ temp_contactgroup=find_contactgroup(temp_contactgroupsmember->group_name); if(temp_contactgroup==NULL){ snprintf(temp_buffer,sizeof(temp_buffer),"Error: Contact group '%s' specified in service '%s' for host '%s' is not defined anywhere!",temp_contactgroupsmember->group_name,temp_service->description,temp_service->host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_VERIFICATION_ERROR,TRUE); errors++; } } /* check to see if there is at least one contact group */ if(temp_service->contact_groups==NULL){ snprintf(temp_buffer,sizeof(temp_buffer),"Warning: Service '%s' on host '%s' has no default contact group(s) defined!",temp_service->description,temp_service->host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_VERIFICATION_WARNING,TRUE); warnings++; } /* verify service check timeperiod */ if(temp_service->check_period==NULL){ snprintf(temp_buffer,sizeof(temp_buffer),"Warning: Service '%s' on host '%s' has no check time period defined!",temp_service->description,temp_service->host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_VERIFICATION_WARNING,TRUE); warnings++; } else{ temp_timeperiod=find_timeperiod(temp_service->check_period); if(temp_timeperiod==NULL){ snprintf(temp_buffer,sizeof(temp_buffer),"Error: Check period '%s' specified for service '%s' on host '%s' is not defined anywhere!",temp_service->check_period,temp_service->description,temp_service->host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_VERIFICATION_ERROR,TRUE); errors++; } } /* check service notification timeperiod */ if(temp_service->notification_period==NULL){ snprintf(temp_buffer,sizeof(temp_buffer),"Warning: Service '%s' on host '%s' has no notification time period defined!",temp_service->description,temp_service->host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_VERIFICATION_WARNING,TRUE); warnings++; } else{ temp_timeperiod=find_timeperiod(temp_service->notification_period); if(temp_timeperiod==NULL){ snprintf(temp_buffer,sizeof(temp_buffer),"Error: Notification period '%s' specified for service '%s' on host '%s' is not defined anywhere!",temp_service->notification_period,temp_service->description,temp_service->host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_VERIFICATION_ERROR,TRUE); errors++; } } /* see if the notification interval is less than the check interval */ if(temp_service->notification_intervalcheck_interval && temp_service->notification_interval!=0){ snprintf(temp_buffer,sizeof(temp_buffer),"Warning: Service '%s' on host '%s' has a notification interval less than its check interval! Notifications are only re-sent after checks are made, so the effective notification interval will be that of the check interval.",temp_service->description,temp_service->host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_VERIFICATION_WARNING,TRUE); warnings++; } /* check for illegal characters in service description */ if(contains_illegal_object_chars(temp_service->description)==TRUE){ snprintf(temp_buffer,sizeof(temp_buffer),"Error: The description string for service '%s' on host '%s' contains one or more illegal characters.",temp_service->description,temp_service->host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_VERIFICATION_ERROR,TRUE); errors++; } } if(verify_config==TRUE) printf("\tChecked %d services.\n",total_objects); #ifdef DEBUG1 printf("\tCompleted service verification checks\n"); #endif /*****************************************/ /* check all hosts... */ /*****************************************/ if(verify_config==TRUE) printf("Checking hosts...\n"); if(host_hashlist==NULL){ snprintf(temp_buffer,sizeof(temp_buffer),"Error: There are no hosts defined!"); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_VERIFICATION_ERROR,TRUE); errors++; } total_objects=0; for(temp_host=host_list;temp_host!=NULL;temp_host=temp_host->next){ total_objects++; found=FALSE; /* make sure each host has at least one service associated with it */ for(temp_service=service_list;temp_service!=NULL;temp_service=temp_service->next){ if(!strcmp(temp_service->host_name,temp_host->name)){ found=TRUE; break; } } /* we couldn't find a service associated with this host! */ if(found==FALSE){ snprintf(temp_buffer,sizeof(temp_buffer),"Warning: Host '%s' has no services associated with it!",temp_host->name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_VERIFICATION_WARNING,TRUE); warnings++; } found=FALSE; #ifdef REMOVED_061303 /* make sure each host is a member of at least one hostgroup */ for(temp_hostgroup=hostgroup_list;temp_hostgroup!=NULL;temp_hostgroup=temp_hostgroup->next){ temp_hostgroupmember=find_hostgroupmember(temp_host->name,temp_hostgroup); if(temp_hostgroupmember!=NULL){ found=TRUE; break; } } /* we couldn't find the host in any host groups */ if(found==FALSE){ snprintf(temp_buffer,sizeof(temp_buffer),"Warning: Host '%s' is not a member of any host groups!",temp_host->name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_VERIFICATION_WARNING,TRUE); warnings++; } #endif /* check the event handler command */ if(temp_host->event_handler!=NULL){ /* check the event handler command */ strncpy(temp_buffer,temp_host->event_handler,sizeof(temp_buffer)); temp_buffer[sizeof(temp_buffer)-1]='\x0'; /* get the command name, leave any arguments behind */ temp_command_name=my_strtok(temp_buffer,"!"); temp_command=find_command(temp_command_name); if(temp_command==NULL){ snprintf(temp_buffer,sizeof(temp_buffer),"Error: Event handler command '%s' specified for host '%s' not defined anywhere",temp_command_name,temp_host->name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_VERIFICATION_ERROR,TRUE); errors++; } } /* hosts that don't have check commands defined shouldn't ever be checked... */ if(temp_host->host_check_command!=NULL){ /* check the host check_command */ strncpy(temp_buffer,temp_host->host_check_command,sizeof(temp_buffer)); temp_buffer[sizeof(temp_buffer)-1]='\x0'; /* get the command name, leave any arguments behind */ temp_command_name=my_strtok(temp_buffer,"!"); temp_command=find_command(temp_command_name); if(temp_command==NULL){ snprintf(temp_buffer,sizeof(temp_buffer),"Error: Host check command '%s' specified for host '%s' is not defined anywhere!",temp_command_name,temp_host->name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_VERIFICATION_ERROR,TRUE); errors++; } } /* check host check timeperiod */ if(temp_host->check_period!=NULL){ temp_timeperiod=find_timeperiod(temp_host->check_period); if(temp_timeperiod==NULL){ snprintf(temp_buffer,sizeof(temp_buffer),"Error: Check period '%s' specified for host '%s' is not defined anywhere!",temp_host->check_period,temp_host->name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_VERIFICATION_ERROR,TRUE); errors++; } } /* check all contact groups */ for(temp_contactgroupsmember=temp_host->contact_groups;temp_contactgroupsmember!=NULL;temp_contactgroupsmember=temp_contactgroupsmember->next){ temp_contactgroup=find_contactgroup(temp_contactgroupsmember->group_name); if(temp_contactgroup==NULL){ snprintf(temp_buffer,sizeof(temp_buffer),"Error: Contact group '%s' specified in host '%s' is not defined anywhere!",temp_contactgroupsmember->group_name,temp_host->name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_VERIFICATION_ERROR,TRUE); errors++; } } /* check to see if there is at least one contact group */ if(temp_host->contact_groups==NULL){ snprintf(temp_buffer,sizeof(temp_buffer),"Error: Host '%s' has no default contact group(s) defined!",temp_host->name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_VERIFICATION_ERROR,TRUE); errors++; } /* check notification timeperiod */ if(temp_host->notification_period!=NULL){ temp_timeperiod=find_timeperiod(temp_host->notification_period); if(temp_timeperiod==NULL){ snprintf(temp_buffer,sizeof(temp_buffer),"Error: Notification period '%s' specified for host '%s' is not defined anywhere!",temp_host->notification_period,temp_host->name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_VERIFICATION_ERROR,TRUE); errors++; } } /* check all parent parent host */ for(temp_hostsmember=temp_host->parent_hosts;temp_hostsmember!=NULL;temp_hostsmember=temp_hostsmember->next){ if(find_host(temp_hostsmember->host_name)==NULL){ snprintf(temp_buffer,sizeof(temp_buffer),"Error: '%s' is not a valid parent for host '%s'!",temp_hostsmember->host_name,temp_host->name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_VERIFICATION_ERROR,TRUE); errors++; } } /* check for sane recovery options */ if(temp_host->notify_on_recovery==TRUE && temp_host->notify_on_down==FALSE && temp_host->notify_on_unreachable==FALSE){ snprintf(temp_buffer,sizeof(temp_buffer),"Warning: Recovery notification option in host '%s' definition doesn't make any sense - specify down and/or unreachable options as well",temp_host->name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_VERIFICATION_WARNING,TRUE); warnings++; } /* check for illegal characters in host name */ if(contains_illegal_object_chars(temp_host->name)==TRUE){ snprintf(temp_buffer,sizeof(temp_buffer),"Error: The name of host '%s' contains one or more illegal characters.",temp_host->name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_VERIFICATION_ERROR,TRUE); errors++; } } if(verify_config==TRUE) printf("\tChecked %d hosts.\n",total_objects); #ifdef DEBUG1 printf("\tCompleted host verification checks\n"); #endif /*****************************************/ /* check each host group... */ /*****************************************/ if(verify_config==TRUE) printf("Checking host groups...\n"); if(hostgroup_list==NULL){ snprintf(temp_buffer,sizeof(temp_buffer),"Error: There are no host groups defined!"); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_VERIFICATION_ERROR,TRUE); errors++; } for(temp_hostgroup=hostgroup_list,total_objects=0;temp_hostgroup!=NULL;temp_hostgroup=temp_hostgroup->next,total_objects++){ /* check all group members */ for(temp_hostgroupmember=temp_hostgroup->members;temp_hostgroupmember!=NULL;temp_hostgroupmember=temp_hostgroupmember->next){ temp_host=find_host(temp_hostgroupmember->host_name); if(temp_host==NULL){ snprintf(temp_buffer,sizeof(temp_buffer),"Error: Host '%s' specified in host group '%s' is not defined anywhere!",temp_hostgroupmember->host_name,temp_hostgroup->group_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_VERIFICATION_ERROR,TRUE); errors++; } } /* check for illegal characters in hostgroup name */ if(contains_illegal_object_chars(temp_hostgroup->group_name)==TRUE){ snprintf(temp_buffer,sizeof(temp_buffer),"Error: The name of hostgroup '%s' contains one or more illegal characters.",temp_hostgroup->group_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_VERIFICATION_ERROR,TRUE); errors++; } } if(verify_config==TRUE) printf("\tChecked %d host groups.\n",total_objects); #ifdef DEBUG1 printf("\tCompleted hostgroup verification checks\n"); #endif /*****************************************/ /* check each service group... */ /*****************************************/ if(verify_config==TRUE) printf("Checking service groups...\n"); for(temp_servicegroup=servicegroup_list,total_objects=0;temp_servicegroup!=NULL;temp_servicegroup=temp_servicegroup->next,total_objects++){ /* check all group members */ for(temp_servicegroupmember=temp_servicegroup->members;temp_servicegroupmember!=NULL;temp_servicegroupmember=temp_servicegroupmember->next){ temp_service=find_service(temp_servicegroupmember->host_name,temp_servicegroupmember->service_description); if(temp_service==NULL){ snprintf(temp_buffer,sizeof(temp_buffer),"Error: Service '%s' on host '%s' specified in service group '%s' is not defined anywhere!",temp_servicegroupmember->service_description,temp_servicegroupmember->host_name,temp_servicegroup->group_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_VERIFICATION_ERROR,TRUE); errors++; } } /* check for illegal characters in servicegroup name */ if(contains_illegal_object_chars(temp_servicegroup->group_name)==TRUE){ snprintf(temp_buffer,sizeof(temp_buffer),"Error: The name of servicegroup '%s' contains one or more illegal characters.",temp_servicegroup->group_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_VERIFICATION_ERROR,TRUE); errors++; } } if(verify_config==TRUE) printf("\tChecked %d service groups.\n",total_objects); #ifdef DEBUG1 printf("\tCompleted servicegroup verification checks\n"); #endif /*****************************************/ /* check all contacts... */ /*****************************************/ if(verify_config==TRUE) printf("Checking contacts...\n"); if(contact_list==NULL){ snprintf(temp_buffer,sizeof(temp_buffer),"Error: There are no contacts defined!"); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_VERIFICATION_ERROR,TRUE); errors++; } for(temp_contact=contact_list,total_objects=0;temp_contact!=NULL;temp_contact=temp_contact->next,total_objects++){ /* check service notification commands */ if(temp_contact->service_notification_commands==NULL){ snprintf(temp_buffer,sizeof(temp_buffer),"Error: Contact '%s' has no service notification commands defined!",temp_contact->name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_VERIFICATION_ERROR,TRUE); errors++; } else for(temp_commandsmember=temp_contact->service_notification_commands;temp_commandsmember!=NULL;temp_commandsmember=temp_commandsmember->next){ /* check the host notification command */ strncpy(temp_buffer,temp_commandsmember->command,sizeof(temp_buffer)); temp_buffer[sizeof(temp_buffer)-1]='\x0'; /* get the command name, leave any arguments behind */ temp_command_name=my_strtok(temp_buffer,"!"); temp_command=find_command(temp_command_name); if(temp_command==NULL){ snprintf(temp_buffer,sizeof(temp_buffer),"Error: Service notification command '%s' specified for contact '%s' is not defined anywhere!",temp_command_name,temp_contact->name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_VERIFICATION_ERROR,TRUE); errors++; } } /* check host notification commands */ if(temp_contact->host_notification_commands==NULL){ snprintf(temp_buffer,sizeof(temp_buffer),"Error: Contact '%s' has no host notification commands defined!",temp_contact->name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_VERIFICATION_ERROR,TRUE); errors++; } else for(temp_commandsmember=temp_contact->host_notification_commands;temp_commandsmember!=NULL;temp_commandsmember=temp_commandsmember->next){ /* check the host notification command */ strncpy(temp_buffer,temp_commandsmember->command,sizeof(temp_buffer)); temp_buffer[sizeof(temp_buffer)-1]='\x0'; /* get the command name, leave any arguments behind */ temp_command_name=my_strtok(temp_buffer,"!"); temp_command=find_command(temp_command_name); if(temp_command==NULL){ sprintf(temp_buffer,"Error: Host notification command '%s' specified for contact '%s' is not defined anywhere!",temp_command_name,temp_contact->name); write_to_logs_and_console(temp_buffer,NSLOG_VERIFICATION_ERROR,TRUE); errors++; } } /* check service notification timeperiod */ if(temp_contact->service_notification_period==NULL){ snprintf(temp_buffer,sizeof(temp_buffer),"Warning: Contact '%s' has no service notification time period defined!",temp_contact->name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_VERIFICATION_WARNING,TRUE); warnings++; } else{ temp_timeperiod=find_timeperiod(temp_contact->service_notification_period); if(temp_timeperiod==NULL){ snprintf(temp_buffer,sizeof(temp_buffer),"Error: Service notification period '%s' specified for contact '%s' is not defined anywhere!",temp_contact->service_notification_period,temp_contact->name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_VERIFICATION_ERROR,TRUE); errors++; } } /* check host notification timeperiod */ if(temp_contact->host_notification_period==NULL){ snprintf(temp_buffer,sizeof(temp_buffer),"Warning: Contact '%s' has no host notification time period defined!",temp_contact->name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_VERIFICATION_WARNING,TRUE); warnings++; } else{ temp_timeperiod=find_timeperiod(temp_contact->host_notification_period); if(temp_timeperiod==NULL){ snprintf(temp_buffer,sizeof(temp_buffer),"Error: Host notification period '%s' specified for contact '%s' is not defined anywhere!",temp_contact->host_notification_period,temp_contact->name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_VERIFICATION_ERROR,TRUE); errors++; } } found=FALSE; /* make sure the contact belongs to at least one contact group */ for(temp_contactgroup=contactgroup_list;temp_contactgroup!=NULL;temp_contactgroup=temp_contactgroup->next){ temp_contactgroupmember=find_contactgroupmember(temp_contact->name,temp_contactgroup); if(temp_contactgroupmember!=NULL){ found=TRUE; break; } } /* we couldn't find the contact in any contact groups */ if(found==FALSE){ snprintf(temp_buffer,sizeof(temp_buffer),"Warning: Contact '%s' is not a member of any contact groups!",temp_contact->name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_VERIFICATION_WARNING,TRUE); warnings++; } /* check for sane host recovery options */ if(temp_contact->notify_on_host_recovery==TRUE && temp_contact->notify_on_host_down==FALSE && temp_contact->notify_on_host_unreachable==FALSE){ snprintf(temp_buffer,sizeof(temp_buffer),"Warning: Host recovery notification option for contact '%s' doesn't make any sense - specify down and/or unreachable options as well",temp_contact->name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_VERIFICATION_WARNING,TRUE); warnings++; } /* check for sane service recovery options */ if(temp_contact->notify_on_service_recovery==TRUE && temp_contact->notify_on_service_critical==FALSE && temp_contact->notify_on_service_warning==FALSE){ snprintf(temp_buffer,sizeof(temp_buffer),"Warning: Service recovery notification option for contact '%s' doesn't make any sense - specify critical and/or warning options as well",temp_contact->name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_VERIFICATION_WARNING,TRUE); warnings++; } /* check for illegal characters in contact name */ if(contains_illegal_object_chars(temp_contact->name)==TRUE){ snprintf(temp_buffer,sizeof(temp_buffer),"Error: The name of contact '%s' contains one or more illegal characters.",temp_contact->name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_VERIFICATION_ERROR,TRUE); errors++; } } if(verify_config==TRUE) printf("\tChecked %d contacts.\n",total_objects); #ifdef DEBUG1 printf("\tCompleted contact verification checks\n"); #endif /*****************************************/ /* check each contact group... */ /*****************************************/ if(verify_config==TRUE) printf("Checking contact groups...\n"); if(contactgroup_list==NULL){ snprintf(temp_buffer,sizeof(temp_buffer),"Error: There are no contact groups defined!\n"); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_VERIFICATION_ERROR,TRUE); errors++; } for(temp_contactgroup=contactgroup_list,total_objects=0;temp_contactgroup!=NULL;temp_contactgroup=temp_contactgroup->next,total_objects++){ found=FALSE; /* make sure each contactgroup is used in at least one host or service definition or escalation */ for(temp_host=host_list;temp_host!=NULL;temp_host=temp_host->next){ for(temp_contactgroupsmember=temp_host->contact_groups;temp_contactgroupsmember!=NULL;temp_contactgroupsmember=temp_contactgroupsmember->next){ if(!strcmp(temp_contactgroup->group_name,temp_contactgroupsmember->group_name)){ found=TRUE; break; } } if(found==TRUE) break; } if(found==FALSE){ for(temp_service=service_list;temp_service!=NULL;temp_service=temp_service->next){ for(temp_contactgroupsmember=temp_service->contact_groups;temp_contactgroupsmember!=NULL;temp_contactgroupsmember=temp_contactgroupsmember->next){ if(!strcmp(temp_contactgroup->group_name,temp_contactgroupsmember->group_name)){ found=TRUE; break; } } if(found==TRUE) break; } } if(found==FALSE){ for(temp_se=serviceescalation_list;temp_se!=NULL;temp_se=temp_se->next){ for(temp_contactgroupsmember=temp_se->contact_groups;temp_contactgroupsmember!=NULL;temp_contactgroupsmember=temp_contactgroupsmember->next){ if(!strcmp(temp_contactgroup->group_name,temp_contactgroupsmember->group_name)){ found=TRUE; break; } } if(found==TRUE) break; } } if(found==FALSE){ for(temp_he=hostescalation_list;temp_he!=NULL;temp_he=temp_he->next){ for(temp_contactgroupsmember=temp_he->contact_groups;temp_contactgroupsmember!=NULL;temp_contactgroupsmember=temp_contactgroupsmember->next){ if(!strcmp(temp_contactgroup->group_name,temp_contactgroupsmember->group_name)){ found=TRUE; break; } } if(found==TRUE) break; } } /* we couldn't find a hostgroup or service */ if(found==FALSE){ snprintf(temp_buffer,sizeof(temp_buffer),"Warning: Contact group '%s' is not used in any host/service definitions or host/service escalations!",temp_contactgroup->group_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_VERIFICATION_WARNING,TRUE); warnings++; } /* check all the group members */ for(temp_contactgroupmember=temp_contactgroup->members;temp_contactgroupmember!=NULL;temp_contactgroupmember=temp_contactgroupmember->next){ temp_contact=find_contact(temp_contactgroupmember->contact_name); if(temp_contact==NULL){ snprintf(temp_buffer,sizeof(temp_buffer),"Error: Contact '%s' specified in contact group '%s' is not defined anywhere!",temp_contactgroupmember->contact_name,temp_contactgroup->group_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_VERIFICATION_ERROR,TRUE); errors++; } } /* check for illegal characters in contactgroup name */ if(contains_illegal_object_chars(temp_contactgroup->group_name)==TRUE){ snprintf(temp_buffer,sizeof(temp_buffer),"Error: The name of contact group '%s' contains one or more illegal characters.",temp_contactgroup->group_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_VERIFICATION_ERROR,TRUE); errors++; } } if(verify_config==TRUE) printf("\tChecked %d contact groups.\n",total_objects); #ifdef DEBUG1 printf("\tCompleted contact group verification checks\n"); #endif /*****************************************/ /* check all service escalations... */ /*****************************************/ if(verify_config==TRUE) printf("Checking service escalations...\n"); for(temp_se=serviceescalation_list,total_objects=0;temp_se!=NULL;temp_se=temp_se->next,total_objects++){ /* find the service */ temp_service=find_service(temp_se->host_name,temp_se->description); if(temp_service==NULL){ snprintf(temp_buffer,sizeof(temp_buffer),"Error: Service '%s' on host '%s' specified in service escalation is not defined anywhere!",temp_se->description,temp_se->host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_VERIFICATION_ERROR,TRUE); errors++; } /* find the timeperiod */ if(temp_se->escalation_period!=NULL){ temp_timeperiod=find_timeperiod(temp_se->escalation_period); if(temp_timeperiod==NULL){ snprintf(temp_buffer,sizeof(temp_buffer),"Error: Escalation period '%s' specified in service escalation for service '%s' on host '%s' is not defined anywhere!",temp_se->escalation_period,temp_se->description,temp_se->host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_VERIFICATION_ERROR,TRUE); errors++; } } /* find the contact groups */ for(temp_contactgroupsmember=temp_se->contact_groups;temp_contactgroupsmember!=NULL;temp_contactgroupsmember=temp_contactgroupsmember->next){ /* find the contact group */ temp_contactgroup=find_contactgroup(temp_contactgroupsmember->group_name); if(temp_contactgroup==NULL){ snprintf(temp_buffer,sizeof(temp_buffer),"Error: Contact group '%s' specified in service escalation for service '%s' on host '%s' is not defined anywhere!",temp_contactgroupsmember->group_name,temp_se->description,temp_se->host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_VERIFICATION_ERROR,TRUE); errors++; } } } if(verify_config==TRUE) printf("\tChecked %d service escalations.\n",total_objects); #ifdef DEBUG1 printf("\tCompleted service escalation checks\n"); #endif /*****************************************/ /* check all service dependencies... */ /*****************************************/ if(verify_config==TRUE) printf("Checking service dependencies...\n"); for(temp_sd=servicedependency_list,total_objects=0;temp_sd!=NULL;temp_sd=temp_sd->next,total_objects++){ /* find the dependent service */ temp_service=find_service(temp_sd->dependent_host_name,temp_sd->dependent_service_description); if(temp_service==NULL){ snprintf(temp_buffer,sizeof(temp_buffer),"Error: Dependent service '%s' on host '%s' specified in service dependency for service '%s' on host '%s' is not defined anywhere!",temp_sd->dependent_service_description,temp_sd->dependent_host_name,temp_sd->service_description,temp_sd->host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_VERIFICATION_ERROR,TRUE); errors++; } /* find the service we're depending on */ temp_service2=find_service(temp_sd->host_name,temp_sd->service_description); if(temp_service2==NULL){ snprintf(temp_buffer,sizeof(temp_buffer),"Error: Service '%s' on host '%s' specified in service dependency for service '%s' on host '%s' is not defined anywhere!",temp_sd->service_description,temp_sd->host_name,temp_sd->dependent_service_description,temp_sd->dependent_host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_VERIFICATION_ERROR,TRUE); errors++; } /* make sure they're not the same service */ if(temp_service==temp_service2){ snprintf(temp_buffer,sizeof(temp_buffer),"Error: Service dependency definition for service '%s' on host '%s' is circular (it depends on itself)!",temp_sd->dependent_service_description,temp_sd->dependent_host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_VERIFICATION_ERROR,TRUE); errors++; } } if(verify_config==TRUE) printf("\tChecked %d service dependencies.\n",total_objects); #ifdef DEBUG1 printf("\tCompleted service dependency checks\n"); #endif /*****************************************/ /* check all host escalations... */ /*****************************************/ if(verify_config==TRUE) printf("Checking host escalations...\n"); for(temp_he=hostescalation_list,total_objects=0;temp_he!=NULL;temp_he=temp_he->next,total_objects++){ /* find the host */ temp_host=find_host(temp_he->host_name); if(temp_host==NULL){ snprintf(temp_buffer,sizeof(temp_buffer),"Error: Host '%s' specified in host escalation is not defined anywhere!",temp_he->host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_VERIFICATION_ERROR,TRUE); errors++; } /* find the timeperiod */ if(temp_he->escalation_period!=NULL){ temp_timeperiod=find_timeperiod(temp_he->escalation_period); if(temp_timeperiod==NULL){ snprintf(temp_buffer,sizeof(temp_buffer),"Error: Escalation period '%s' specified in host escalation for host '%s' is not defined anywhere!",temp_he->escalation_period,temp_he->host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_VERIFICATION_ERROR,TRUE); errors++; } } /* find the contact groups */ for(temp_contactgroupsmember=temp_he->contact_groups;temp_contactgroupsmember!=NULL;temp_contactgroupsmember=temp_contactgroupsmember->next){ /* find the contact group */ temp_contactgroup=find_contactgroup(temp_contactgroupsmember->group_name); if(temp_contactgroup==NULL){ snprintf(temp_buffer,sizeof(temp_buffer),"Error: Contact group '%s' specified in host escalation for host '%s' is not defined anywhere!",temp_contactgroupsmember->group_name,temp_he->host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_VERIFICATION_ERROR,TRUE); errors++; } } } if(verify_config==TRUE) printf("\tChecked %d host escalations.\n",total_objects); #ifdef DEBUG1 printf("\tCompleted host escalation checks\n"); #endif /*****************************************/ /* check all host dependencies... */ /*****************************************/ if(verify_config==TRUE) printf("Checking host dependencies...\n"); for(temp_hd=hostdependency_list,total_objects=0;temp_hd!=NULL;temp_hd=temp_hd->next,total_objects++){ /* find the dependent host */ temp_host=find_host(temp_hd->dependent_host_name); if(temp_host==NULL){ snprintf(temp_buffer,sizeof(temp_buffer),"Error: Dependent host specified in host dependency for host '%s' is not defined anywhere!",temp_hd->dependent_host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_VERIFICATION_ERROR,TRUE); errors++; } /* find the host we're depending on */ temp_host2=find_host(temp_hd->host_name); if(temp_host2==NULL){ snprintf(temp_buffer,sizeof(temp_buffer),"Error: Host specified in host dependency for host '%s' is not defined anywhere!",temp_hd->dependent_host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_VERIFICATION_ERROR,TRUE); errors++; } /* make sure they're not the same host */ if(temp_host==temp_host2){ snprintf(temp_buffer,sizeof(temp_buffer),"Error: Host dependency definition for host '%s' is circular (it depends on itself)!",temp_hd->dependent_host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_VERIFICATION_ERROR,TRUE); errors++; } } if(verify_config==TRUE) printf("\tChecked %d host dependencies.\n",total_objects); #ifdef DEBUG1 printf("\tCompleted host dependency checks\n"); #endif /*****************************************/ /* check all commands... */ /*****************************************/ if(verify_config==TRUE) printf("Checking commands...\n"); for(temp_command=command_list,total_objects=0;temp_command!=NULL;temp_command=temp_command->next,total_objects++){ /* check for illegal characters in command name */ if(contains_illegal_object_chars(temp_command->name)==TRUE){ snprintf(temp_buffer,sizeof(temp_buffer),"Error: The name of command '%s' contains one or more illegal characters.",temp_command->name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_VERIFICATION_ERROR,TRUE); errors++; } } if(verify_config==TRUE) printf("\tChecked %d commands.\n",total_objects); #ifdef DEBUG1 printf("\tCompleted command checks\n"); #endif /*****************************************/ /* check all timeperiods... */ /*****************************************/ if(verify_config==TRUE) printf("Checking time periods...\n"); for(temp_timeperiod=timeperiod_list,total_objects=0;temp_timeperiod!=NULL;temp_timeperiod=temp_timeperiod->next,total_objects++){ /* check for illegal characters in timeperiod name */ if(contains_illegal_object_chars(temp_timeperiod->name)==TRUE){ snprintf(temp_buffer,sizeof(temp_buffer),"Error: The name of time period '%s' contains one or more illegal characters.",temp_timeperiod->name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_VERIFICATION_ERROR,TRUE); errors++; } } if(verify_config==TRUE) printf("\tChecked %d time periods.\n",total_objects); #ifdef DEBUG1 printf("\tCompleted command checks\n"); #endif /*****************************************/ /* check extended host information... */ /*****************************************/ if(verify_config==TRUE) printf("Checking extended host info definitions...\n"); for(temp_hostextinfo=hostextinfo_list,total_objects=0;temp_hostextinfo!=NULL;temp_hostextinfo=temp_hostextinfo->next,total_objects++){ /* find the host */ temp_host=find_host(temp_hostextinfo->host_name); if(temp_host==NULL){ snprintf(temp_buffer,sizeof(temp_buffer),"Error: Host '%s' specified in extended host information is not defined anywhere!",temp_hostextinfo->host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_VERIFICATION_ERROR,TRUE); errors++; } } if(verify_config==TRUE) printf("\tChecked %d extended host info definitions.\n",total_objects); #ifdef DEBUG1 printf("\tCompleted extended host info checks\n"); #endif /*****************************************/ /* check extended service information... */ /*****************************************/ if(verify_config==TRUE) printf("Checking extended service info definitions...\n"); for(temp_serviceextinfo=serviceextinfo_list,total_objects=0;temp_serviceextinfo!=NULL;temp_serviceextinfo=temp_serviceextinfo->next,total_objects++){ /* find the service */ temp_service=find_service(temp_serviceextinfo->host_name,temp_serviceextinfo->description); if(temp_service==NULL){ snprintf(temp_buffer,sizeof(temp_buffer),"Error: Service '%s' on host '%s' specified in extended service information is not defined anywhere!",temp_serviceextinfo->description,temp_serviceextinfo->host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_VERIFICATION_ERROR,TRUE); errors++; } } if(verify_config==TRUE) printf("\tChecked %d extended service info definitions.\n",total_objects); #ifdef DEBUG1 printf("\tCompleted extended service info checks\n"); #endif /********************************************/ /* check for circular paths between hosts */ /********************************************/ if(verify_config==TRUE) printf("Checking for circular paths between hosts...\n"); /* check routes between all hosts */ found=FALSE; result=OK; for(temp_host=host_list;temp_host!=NULL;temp_host=temp_host->next){ /* clear checked flag for all hosts */ for(temp_host2=host_list;temp_host2!=NULL;temp_host2=temp_host2->next) temp_host2->circular_path_checked=FALSE; found=check_for_circular_path(temp_host,temp_host); if(found==TRUE){ sprintf(temp_buffer,"Error: There is a circular parent/child path that exists for host '%s'!",temp_host->name); write_to_logs_and_console(temp_buffer,NSLOG_VERIFICATION_ERROR,TRUE); result=ERROR; } } if(result==ERROR) errors++; #ifdef DEBUG1 printf("\tCompleted circular path checks\n"); #endif /********************************************/ /* check for circular dependencies */ /********************************************/ if(verify_config==TRUE) printf("Checking for circular host and service dependencies...\n"); /* check execution dependencies between all services */ for(temp_sd=servicedependency_list;temp_sd!=NULL;temp_sd=temp_sd->next){ /* clear checked flag for all dependencies */ for(temp_sd2=servicedependency_list;temp_sd2!=NULL;temp_sd2=temp_sd2->next) temp_sd2->circular_path_checked=FALSE; found=check_for_circular_servicedependency(temp_sd,temp_sd,EXECUTION_DEPENDENCY); if(found==TRUE){ sprintf(temp_buffer,"Error: A circular execution dependency (which could result in a deadlock) exists for service '%s' on host '%s'!",temp_sd->service_description,temp_sd->host_name); write_to_logs_and_console(temp_buffer,NSLOG_VERIFICATION_ERROR,TRUE); errors++; } } /* check notification dependencies between all services */ for(temp_sd=servicedependency_list;temp_sd!=NULL;temp_sd=temp_sd->next){ /* clear checked flag for all dependencies */ for(temp_sd2=servicedependency_list;temp_sd2!=NULL;temp_sd2=temp_sd2->next) temp_sd2->circular_path_checked=FALSE; found=check_for_circular_servicedependency(temp_sd,temp_sd,NOTIFICATION_DEPENDENCY); if(found==TRUE){ sprintf(temp_buffer,"Error: A circular notification dependency (which could result in a deadlock) exists for service '%s' on host '%s'!",temp_sd->service_description,temp_sd->host_name); write_to_logs_and_console(temp_buffer,NSLOG_VERIFICATION_ERROR,TRUE); errors++; } } /* check execution dependencies between all hosts */ for(temp_hd=hostdependency_list;temp_hd!=NULL;temp_hd=temp_hd->next){ /* clear checked flag for all dependencies */ for(temp_hd2=hostdependency_list;temp_hd2!=NULL;temp_hd2=temp_hd2->next) temp_hd2->circular_path_checked=FALSE; found=check_for_circular_hostdependency(temp_hd,temp_hd,EXECUTION_DEPENDENCY); if(found==TRUE){ sprintf(temp_buffer,"Error: A circular execution dependency (which could result in a deadlock) exists for host '%s'!",temp_hd->host_name); write_to_logs_and_console(temp_buffer,NSLOG_VERIFICATION_ERROR,TRUE); errors++; } } /* check notification dependencies between all hosts */ for(temp_hd=hostdependency_list;temp_hd!=NULL;temp_hd=temp_hd->next){ /* clear checked flag for all dependencies */ for(temp_hd2=hostdependency_list;temp_hd2!=NULL;temp_hd2=temp_hd2->next) temp_hd2->circular_path_checked=FALSE; found=check_for_circular_hostdependency(temp_hd,temp_hd,NOTIFICATION_DEPENDENCY); if(found==TRUE){ sprintf(temp_buffer,"Error: A circular notification dependency (which could result in a deadlock) exists for host '%s'!",temp_hd->host_name); write_to_logs_and_console(temp_buffer,NSLOG_VERIFICATION_ERROR,TRUE); errors++; } } #ifdef DEBUG1 printf("\tCompleted circular host and service dependency checks\n"); #endif /********************************************/ /* check global event handler commands... */ /********************************************/ if(verify_config==TRUE) printf("Checking global event handlers...\n"); if(global_host_event_handler!=NULL){ /* check the event handler command */ strncpy(temp_buffer,global_host_event_handler,sizeof(temp_buffer)); temp_buffer[sizeof(temp_buffer)-1]='\x0'; /* get the command name, leave any arguments behind */ temp_command_name=my_strtok(temp_buffer,"!"); temp_command=find_command(temp_command_name); if(temp_command==NULL){ snprintf(temp_buffer,sizeof(temp_buffer),"Error: Global host event handler command '%s' is not defined anywhere!",temp_command_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_VERIFICATION_ERROR,TRUE); errors++; } } if(global_service_event_handler!=NULL){ /* check the event handler command */ strncpy(temp_buffer,global_service_event_handler,sizeof(temp_buffer)); temp_buffer[sizeof(temp_buffer)-1]='\x0'; /* get the command name, leave any arguments behind */ temp_command_name=my_strtok(temp_buffer,"!"); temp_command=find_command(temp_command_name); if(temp_command==NULL){ snprintf(temp_buffer,sizeof(temp_buffer),"Error: Global service event handler command '%s' is not defined anywhere!",temp_command_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_VERIFICATION_ERROR,TRUE); errors++; } } #ifdef DEBUG1 printf("\tCompleted global event handler command checks\n"); #endif /**************************************************/ /* check obsessive processor commands... */ /**************************************************/ if(verify_config==TRUE) printf("Checking obsessive compulsive processor commands...\n"); if(ocsp_command!=NULL){ strncpy(temp_buffer,ocsp_command,sizeof(temp_buffer)); temp_buffer[sizeof(temp_buffer)-1]='\x0'; /* get the command name, leave any arguments behind */ temp_command_name=my_strtok(temp_buffer,"!"); temp_command=find_command(temp_command_name); if(temp_command==NULL){ snprintf(temp_buffer,sizeof(temp_buffer),"Error: Obsessive compulsive service processor command '%s' is not defined anywhere!",temp_command_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_VERIFICATION_ERROR,TRUE); errors++; } } if(ochp_command!=NULL){ strncpy(temp_buffer,ochp_command,sizeof(temp_buffer)); temp_buffer[sizeof(temp_buffer)-1]='\x0'; /* get the command name, leave any arguments behind */ temp_command_name=my_strtok(temp_buffer,"!"); temp_command=find_command(temp_command_name); if(temp_command==NULL){ snprintf(temp_buffer,sizeof(temp_buffer),"Error: Obsessive compulsive host processor command '%s' is not defined anywhere!",temp_command_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_VERIFICATION_ERROR,TRUE); errors++; } } #ifdef DEBUG1 printf("\tCompleted obsessive compulsive processor command checks\n"); #endif /**************************************************/ /* check various settings... */ /**************************************************/ if(verify_config==TRUE) printf("Checking misc settings...\n"); /* warn if user didn't specify any illegal macro output chars */ if(illegal_output_chars==NULL){ sprintf(temp_buffer,"Warning: Nothing specified for illegal_macro_output_chars variable!\n"); write_to_logs_and_console(temp_buffer,NSLOG_VERIFICATION_WARNING,TRUE); warnings++; } /* count number of services associated with each host (we need this for flap detection)... */ for(temp_service=service_list;temp_service!=NULL;temp_service=temp_service->next){ if((temp_host=find_host(temp_service->host_name))){ temp_host->total_services++; temp_host->total_service_check_interval+=temp_service->check_interval; } } if(verify_config==TRUE){ printf("\n"); printf("Total Warnings: %d\n",warnings); printf("Total Errors: %d\n",errors); } #ifdef DEBUG0 printf("pre_flight_check() end\n"); #endif return (errors>0)?ERROR:OK; } nagios-2.6/base/events.c0000664000076500007650000015402510512470706014572 0ustar nagiosnagios/***************************************************************************** * * EVENTS.C - Timed event functions for Nagios * * Copyright (c) 1999-2006 Ethan Galstad (nagios@nagios.org) * Last Modified: 10-09-2006 * * 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. * *****************************************************************************/ #include "../include/config.h" #include "../include/common.h" #include "../include/comments.h" #include "../include/downtime.h" #include "../include/statusdata.h" #include "../include/nagios.h" #include "../include/broker.h" #include "../include/sretention.h" extern char *config_file; extern time_t program_start; extern time_t last_command_check; extern int sigshutdown; extern int sigrestart; extern double sleep_time; extern int interval_length; extern int service_inter_check_delay_method; extern int host_inter_check_delay_method; extern int service_interleave_factor_method; extern int max_host_check_spread; extern int max_service_check_spread; extern int command_check_interval; extern int service_check_reaper_interval; extern int service_freshness_check_interval; extern int host_freshness_check_interval; extern int auto_rescheduling_interval; extern int auto_rescheduling_window; extern int check_external_commands; extern int check_orphaned_services; extern int check_service_freshness; extern int check_host_freshness; extern int auto_reschedule_checks; extern int retain_state_information; extern int retention_update_interval; extern int max_parallel_service_checks; extern int currently_running_service_checks; extern int aggregate_status_updates; extern int status_update_interval; extern int log_rotation_method; extern int service_check_timeout; extern int execute_service_checks; extern int execute_host_checks; extern int time_change_threshold; extern int non_parallelized_check_running; timed_event *event_list_low=NULL; timed_event *event_list_high=NULL; extern host *host_list; extern service *service_list; sched_info scheduling_info; /******************************************************************/ /************ EVENT SCHEDULING/HANDLING FUNCTIONS *****************/ /******************************************************************/ /* initialize the event timing loop before we start monitoring */ void init_timing_loop(void){ host *temp_host; service *temp_service; time_t current_time; unsigned long interval_to_use; int total_interleave_blocks=0; int current_interleave_block=1; int interleave_block_index=0; int mult_factor; int is_valid_time; time_t next_valid_time; int schedule_check; double max_inter_check_delay=0.0; #ifdef DEBUG0 printf("init_timing_loop() start\n"); #endif /* get the time right now */ time(¤t_time); /******** GET BASIC HOST/SERVICE INFO ********/ scheduling_info.total_services=0; scheduling_info.total_scheduled_services=0; scheduling_info.total_hosts=0; scheduling_info.total_scheduled_hosts=0; scheduling_info.average_services_per_host=0.0; scheduling_info.average_scheduled_services_per_host=0.0; scheduling_info.service_check_interval_total=0; scheduling_info.average_service_inter_check_delay=0.0; scheduling_info.host_check_interval_total=0; scheduling_info.average_host_inter_check_delay=0.0; /* get info on service checks to be scheduled */ for(temp_service=service_list;temp_service!=NULL;temp_service=temp_service->next){ schedule_check=TRUE; /* service has no check interval */ if(temp_service->check_interval==0) schedule_check=FALSE; /* active checks are disabled */ if(temp_service->checks_enabled==FALSE) schedule_check=FALSE; /* are there any valid times this service can be checked? */ is_valid_time=check_time_against_period(current_time,temp_service->check_period); if(is_valid_time==ERROR){ get_next_valid_time(current_time,&next_valid_time,temp_service->check_period); if(current_time==next_valid_time) schedule_check=FALSE; } if(schedule_check==TRUE){ scheduling_info.total_scheduled_services++; /* used later in inter-check delay calculations */ scheduling_info.service_check_interval_total+=temp_service->check_interval; } else{ temp_service->should_be_scheduled=FALSE; #ifdef DEBUG1 printf("Service '%s' on host '%s' should not be scheduled.\n",temp_service->description,temp_service->host_name); #endif } scheduling_info.total_services++; } /* get info on host checks to be scheduled */ for(temp_host=host_list;temp_host!=NULL;temp_host=temp_host->next){ schedule_check=TRUE; /* host has no check interval */ if(temp_host->check_interval==0) schedule_check=FALSE; /* active checks are disabled */ if(temp_host->checks_enabled==FALSE) schedule_check=FALSE; /* are there any valid times this host can be checked? */ is_valid_time=check_time_against_period(current_time,temp_host->check_period); if(is_valid_time==ERROR){ get_next_valid_time(current_time,&next_valid_time,temp_host->check_period); if(current_time==next_valid_time) schedule_check=FALSE; } if(schedule_check==TRUE){ scheduling_info.total_scheduled_hosts++; /* this is used later in inter-check delay calculations */ scheduling_info.host_check_interval_total+=temp_host->check_interval; } else{ temp_host->should_be_scheduled=FALSE; #ifdef DEBUG1 printf("Host '%s' should not be scheduled\n",temp_host->name); #endif } scheduling_info.total_hosts++; } scheduling_info.average_services_per_host=(double)((double)scheduling_info.total_services/(double)scheduling_info.total_hosts); scheduling_info.average_scheduled_services_per_host=(double)((double)scheduling_info.total_scheduled_services/(double)scheduling_info.total_hosts); /******** DETERMINE SERVICE SCHEDULING PARAMS ********/ /* default max service check spread (in minutes) */ scheduling_info.max_service_check_spread=max_service_check_spread; /* how should we determine the service inter-check delay to use? */ switch(service_inter_check_delay_method){ case ICD_NONE: /* don't spread checks out - useful for testing parallelization code */ scheduling_info.service_inter_check_delay=0.0; break; case ICD_DUMB: /* be dumb and just schedule checks 1 second apart */ scheduling_info.service_inter_check_delay=1.0; break; case ICD_USER: /* the user specified a delay, so don't try to calculate one */ break; case ICD_SMART: default: /* be smart and calculate the best delay to use to minimize local load... */ if(scheduling_info.total_scheduled_services>0 && scheduling_info.service_check_interval_total>0){ /* adjust the check interval total to correspond to the interval length */ scheduling_info.service_check_interval_total=(scheduling_info.service_check_interval_total*interval_length); /* calculate the average check interval for services */ scheduling_info.average_service_check_interval=(double)((double)scheduling_info.service_check_interval_total/(double)scheduling_info.total_scheduled_services); /* calculate the average inter check delay (in seconds) needed to evenly space the service checks out */ scheduling_info.average_service_inter_check_delay=(double)(scheduling_info.average_service_check_interval/(double)scheduling_info.total_scheduled_services); /* set the global inter check delay value */ scheduling_info.service_inter_check_delay=scheduling_info.average_service_inter_check_delay; /* calculate max inter check delay and see if we should use that instead */ max_inter_check_delay=(double)((scheduling_info.max_service_check_spread*60.0)/(double)scheduling_info.total_scheduled_services); if(scheduling_info.service_inter_check_delay>max_inter_check_delay) scheduling_info.service_inter_check_delay=max_inter_check_delay; } else scheduling_info.service_inter_check_delay=0.0; #ifdef DEBUG1 printf("\tTotal scheduled service checks: %d\n",scheduling_info.total_scheduled_services); printf("\tService check interval total: %lu\n",scheduling_info.service_check_interval_total); printf("\tAverage service check interval: %0.2f sec\n",scheduling_info.average_service_check_interval); printf("\tService inter-check delay: %0.2f sec\n",scheduling_info.service_inter_check_delay); #endif } /* how should we determine the service interleave factor? */ switch(service_interleave_factor_method){ case ILF_USER: /* the user supplied a value, so don't do any calculation */ break; case ILF_SMART: default: /* protect against a divide by zero problem - shouldn't happen, but just in case... */ if(scheduling_info.total_hosts==0) scheduling_info.total_hosts=1; scheduling_info.service_interleave_factor=(int)(ceil(scheduling_info.average_scheduled_services_per_host)); #ifdef DEBUG1 printf("\tTotal scheduled service checks: %d\n",scheduling_info.total_scheduled_services); printf("\tTotal hosts: %d\n",scheduling_info.total_hosts); printf("\tService Interleave factor: %d\n",scheduling_info.service_interleave_factor); #endif } /* calculate number of service interleave blocks */ if(scheduling_info.service_interleave_factor==0) total_interleave_blocks=scheduling_info.total_scheduled_services; else total_interleave_blocks=(int)ceil((double)scheduling_info.total_scheduled_services/(double)scheduling_info.service_interleave_factor); scheduling_info.first_service_check=(time_t)0L; scheduling_info.last_service_check=(time_t)0L; #ifdef DEBUG1 printf("Total scheduled services: %d\n",scheduling_info.total_scheduled_services); printf("Service Interleave factor: %d\n",scheduling_info.service_interleave_factor); printf("Total service interleave blocks: %d\n",total_interleave_blocks); printf("Service inter-check delay: %2.1f\n",scheduling_info.service_inter_check_delay); #endif /******** SCHEDULE SERVICE CHECKS ********/ /* determine check times for service checks (with interleaving to minimize remote load) */ current_interleave_block=0; for(temp_service=service_list;temp_service!=NULL && scheduling_info.service_interleave_factor>0;){ #ifdef DEBUG1 printf("\tCurrent Interleave Block: %d\n",current_interleave_block); #endif for(interleave_block_index=0;interleave_block_indexnext){ /* skip this service if it shouldn't be scheduled */ if(temp_service->should_be_scheduled==FALSE) continue; /* skip services that are already scheduled (from retention data) */ if(temp_service->next_check!=(time_t)0) continue; /* interleave block index should only be increased when we find a schedulable service */ /* moved from for() loop 11/05/05 EG */ interleave_block_index++; mult_factor=current_interleave_block+(interleave_block_index*total_interleave_blocks); #ifdef DEBUG1 printf("\t\tService '%s' on host '%s'\n",temp_service->description,temp_service->host_name); printf("\t\t\tCIB: %d, IBI: %d, TIB: %d, SIF: %d\n",current_interleave_block,interleave_block_index,total_interleave_blocks,scheduling_info.service_interleave_factor); printf("\t\t\tMult factor: %d\n",mult_factor); #endif /* set the preferred next check time for the service */ temp_service->next_check=(time_t)(current_time+(mult_factor*scheduling_info.service_inter_check_delay)); #ifdef DEBUG1 printf("\t\t\tPreferred Check Time: %lu --> %s",(unsigned long)temp_service->next_check,ctime(&temp_service->next_check)); #endif /* make sure the service can actually be scheduled when we want */ is_valid_time=check_time_against_period(temp_service->next_check,temp_service->check_period); if(is_valid_time==ERROR){ get_next_valid_time(temp_service->next_check,&next_valid_time,temp_service->check_period); temp_service->next_check=next_valid_time; } #ifdef DEBUG1 printf("\t\t\tActual Check Time: %lu --> %s",(unsigned long)temp_service->next_check,ctime(&temp_service->next_check)); #endif if(scheduling_info.first_service_check==(time_t)0 || (temp_service->next_checknext_check; if(temp_service->next_check > scheduling_info.last_service_check) scheduling_info.last_service_check=temp_service->next_check; } current_interleave_block++; } /* add scheduled service checks to event queue */ for(temp_service=service_list;temp_service!=NULL;temp_service=temp_service->next){ /* skip services that shouldn't be scheduled */ if(temp_service->should_be_scheduled==FALSE) continue; /* create a new service check event */ schedule_new_event(EVENT_SERVICE_CHECK,FALSE,temp_service->next_check,FALSE,0,NULL,TRUE,(void *)temp_service,NULL); } /******** DETERMINE HOST SCHEDULING PARAMS ********/ scheduling_info.first_host_check=(time_t)0L; scheduling_info.last_host_check=(time_t)0L; /* default max host check spread (in minutes) */ scheduling_info.max_host_check_spread=max_host_check_spread; /* how should we determine the host inter-check delay to use? */ switch(host_inter_check_delay_method){ case ICD_NONE: /* don't spread checks out */ scheduling_info.host_inter_check_delay=0.0; break; case ICD_DUMB: /* be dumb and just schedule checks 1 second apart */ scheduling_info.host_inter_check_delay=1.0; break; case ICD_USER: /* the user specified a delay, so don't try to calculate one */ break; case ICD_SMART: default: /* be smart and calculate the best delay to use to minimize local load... */ if(scheduling_info.total_scheduled_hosts>0 && scheduling_info.host_check_interval_total>0){ /* adjust the check interval total to correspond to the interval length */ scheduling_info.host_check_interval_total=(scheduling_info.host_check_interval_total*interval_length); /* calculate the average check interval for hosts */ scheduling_info.average_host_check_interval=(double)((double)scheduling_info.host_check_interval_total/(double)scheduling_info.total_scheduled_hosts); /* calculate the average inter check delay (in seconds) needed to evenly space the host checks out */ scheduling_info.average_host_inter_check_delay=(double)(scheduling_info.average_host_check_interval/(double)scheduling_info.total_scheduled_hosts); /* set the global inter check delay value */ scheduling_info.host_inter_check_delay=scheduling_info.average_host_inter_check_delay; /* calculate max inter check delay and see if we should use that instead */ max_inter_check_delay=(double)((scheduling_info.max_host_check_spread*60.0)/(double)scheduling_info.total_scheduled_hosts); if(scheduling_info.host_inter_check_delay>max_inter_check_delay) scheduling_info.host_inter_check_delay=max_inter_check_delay; } else scheduling_info.host_inter_check_delay=0.0; #ifdef DEBUG1 printf("\tTotal scheduled host checks: %d\n",scheduling_info.total_scheduled_hosts); printf("\tHost check interval total: %lu\n",scheduling_info.host_check_interval_total); printf("\tAverage host check interval: %0.2f sec\n",scheduling_info.average_host_check_interval); printf("\tHost inter-check delay: %0.2f sec\n",scheduling_info.host_inter_check_delay); #endif } /******** SCHEDULE HOST CHECKS ********/ /* determine check times for host checks */ mult_factor=0; for(temp_host=host_list;temp_host!=NULL;temp_host=temp_host->next){ /* skip hosts that shouldn't be scheduled */ if(temp_host->should_be_scheduled==FALSE) continue; /* skip hosts that are already scheduled (from retention data) */ if(temp_host->next_check!=(time_t)0) continue; #ifdef DEBUG1 printf("\t\tHost '%s'\n",temp_host->name); #endif /* calculate preferred host check time */ temp_host->next_check=(time_t)(current_time+(mult_factor*scheduling_info.host_inter_check_delay)); #ifdef DEBUG1 printf("\t\t\tPreferred Check Time: %lu --> %s",(unsigned long)temp_host->next_check,ctime(&temp_host->next_check)); #endif /* make sure the host can actually be scheduled at this time */ is_valid_time=check_time_against_period(temp_host->next_check,temp_host->check_period); if(is_valid_time==ERROR){ get_next_valid_time(temp_host->next_check,&next_valid_time,temp_host->check_period); temp_host->next_check=next_valid_time; } #ifdef DEBUG1 printf("\t\t\tActual Check Time: %lu --> %s",(unsigned long)temp_host->next_check,ctime(&temp_host->next_check)); #endif if(scheduling_info.first_host_check==(time_t)0 || (temp_host->next_checknext_check; if(temp_host->next_check > scheduling_info.last_host_check) scheduling_info.last_host_check=temp_host->next_check; mult_factor++; } /* add scheduled host checks to event queue */ for(temp_host=host_list;temp_host!=NULL;temp_host=temp_host->next){ /* skip hosts that shouldn't be scheduled */ if(temp_host->should_be_scheduled==FALSE) continue; /* schedule a new host check event */ schedule_new_event(EVENT_HOST_CHECK,FALSE,temp_host->next_check,FALSE,0,NULL,TRUE,(void *)temp_host,NULL); } /******** SCHEDULE MISC EVENTS ********/ /* add a host and service check rescheduling event */ if(auto_reschedule_checks==TRUE) schedule_new_event(EVENT_RESCHEDULE_CHECKS,TRUE,current_time+auto_rescheduling_interval,TRUE,auto_rescheduling_interval,NULL,TRUE,NULL,NULL); /* add a service check reaper event */ schedule_new_event(EVENT_SERVICE_REAPER,TRUE,current_time+service_check_reaper_interval,TRUE,service_check_reaper_interval,NULL,TRUE,NULL,NULL); /* add an orphaned service check event */ if(check_orphaned_services==TRUE) schedule_new_event(EVENT_ORPHAN_CHECK,TRUE,current_time+(service_check_timeout*2),TRUE,(service_check_timeout*2),NULL,TRUE,NULL,NULL); /* add a service result "freshness" check event */ if(check_service_freshness==TRUE) schedule_new_event(EVENT_SFRESHNESS_CHECK,TRUE,current_time+service_freshness_check_interval,TRUE,service_freshness_check_interval,NULL,TRUE,NULL,NULL); /* add a host result "freshness" check event */ if(check_host_freshness==TRUE) schedule_new_event(EVENT_HFRESHNESS_CHECK,TRUE,current_time+host_freshness_check_interval,TRUE,host_freshness_check_interval,NULL,TRUE,NULL,NULL); /* add a status save event */ if(aggregate_status_updates==TRUE) schedule_new_event(EVENT_STATUS_SAVE,TRUE,current_time+status_update_interval,TRUE,status_update_interval,NULL,TRUE,NULL,NULL); /* add an external command check event if needed */ if(check_external_commands==TRUE){ if(command_check_interval==-1) interval_to_use=(unsigned long)60; else interval_to_use=(unsigned long)command_check_interval; schedule_new_event(EVENT_COMMAND_CHECK,TRUE,current_time+interval_to_use,TRUE,interval_to_use,NULL,TRUE,NULL,NULL); } /* add a log rotation event if necessary */ if(log_rotation_method!=LOG_ROTATION_NONE) schedule_new_event(EVENT_LOG_ROTATION,TRUE,get_next_log_rotation_time(),TRUE,0,get_next_log_rotation_time,TRUE,NULL,NULL); /* add a retention data save event if needed */ if(retain_state_information==TRUE && retention_update_interval>0) schedule_new_event(EVENT_RETENTION_SAVE,TRUE,current_time+(retention_update_interval*60),TRUE,(retention_update_interval*60),NULL,TRUE,NULL,NULL); #ifdef DEBUG0 printf("init_timing_loop() end\n"); #endif return; } /* displays service check scheduling information */ void display_scheduling_info(void){ float minimum_concurrent_checks; float max_reaper_interval; int suggestions=0; printf("Projected scheduling information for host and service\n"); printf("checks is listed below. This information assumes that\n"); printf("you are going to start running Nagios with your current\n"); printf("config files.\n\n"); printf("HOST SCHEDULING INFORMATION\n"); printf("---------------------------\n"); printf("Total hosts: %d\n",scheduling_info.total_hosts); printf("Total scheduled hosts: %d\n",scheduling_info.total_scheduled_hosts); printf("Host inter-check delay method: "); if(host_inter_check_delay_method==ICD_NONE) printf("NONE\n"); else if(host_inter_check_delay_method==ICD_DUMB) printf("DUMB\n"); else if(host_inter_check_delay_method==ICD_SMART){ printf("SMART\n"); printf("Average host check interval: %.2f sec\n",scheduling_info.average_host_check_interval); } else printf("USER-SUPPLIED VALUE\n"); printf("Host inter-check delay: %.2f sec\n",scheduling_info.host_inter_check_delay); printf("Max host check spread: %d min\n",scheduling_info.max_host_check_spread); printf("First scheduled check: %s",(scheduling_info.total_scheduled_hosts==0)?"N/A\n":ctime(&scheduling_info.first_host_check)); printf("Last scheduled check: %s",(scheduling_info.total_scheduled_hosts==0)?"N/A\n":ctime(&scheduling_info.last_host_check)); printf("\n\n"); printf("SERVICE SCHEDULING INFORMATION\n"); printf("-------------------------------\n"); printf("Total services: %d\n",scheduling_info.total_services); printf("Total scheduled services: %d\n",scheduling_info.total_scheduled_services); printf("Service inter-check delay method: "); if(service_inter_check_delay_method==ICD_NONE) printf("NONE\n"); else if(service_inter_check_delay_method==ICD_DUMB) printf("DUMB\n"); else if(service_inter_check_delay_method==ICD_SMART){ printf("SMART\n"); printf("Average service check interval: %.2f sec\n",scheduling_info.average_service_check_interval); } else printf("USER-SUPPLIED VALUE\n"); printf("Inter-check delay: %.2f sec\n",scheduling_info.service_inter_check_delay); printf("Interleave factor method: %s\n",(service_interleave_factor_method==ILF_USER)?"USER-SUPPLIED VALUE":"SMART"); if(service_interleave_factor_method==ILF_SMART) printf("Average services per host: %.2f\n",scheduling_info.average_services_per_host); printf("Service interleave factor: %d\n",scheduling_info.service_interleave_factor); printf("Max service check spread: %d min\n",scheduling_info.max_service_check_spread); printf("First scheduled check: %s",ctime(&scheduling_info.first_service_check)); printf("Last scheduled check: %s",ctime(&scheduling_info.last_service_check)); printf("\n\n"); printf("CHECK PROCESSING INFORMATION\n"); printf("----------------------------\n"); printf("Service check reaper interval: %d sec\n",service_check_reaper_interval); printf("Max concurrent service checks: "); if(max_parallel_service_checks==0) printf("Unlimited\n"); else printf("%d\n",max_parallel_service_checks); printf("\n\n"); printf("PERFORMANCE SUGGESTIONS\n"); printf("-----------------------\n"); /* check sanity of host inter-check delay */ if(scheduling_info.host_inter_check_delay<=10.0 && scheduling_info.total_scheduled_hosts>0){ printf("* Host checks might be scheduled too closely together - consider increasing 'check_interval' option for your hosts\n"); suggestions++; } /* assume a 100% (2x) service check burst for max concurrent checks */ if(scheduling_info.service_inter_check_delay==0.0) minimum_concurrent_checks=ceil(service_check_reaper_interval*2.0); minimum_concurrent_checks=ceil((service_check_reaper_interval*2.0)/scheduling_info.service_inter_check_delay); if(((int)minimum_concurrent_checks > max_parallel_service_checks) && max_parallel_service_checks!=0){ printf("* Value for 'max_concurrent_checks' option should >= %d\n",(int)minimum_concurrent_checks); suggestions++; } /* assume a 100% (2x) service check burst for service check reaper */ max_reaper_interval=floor((double)SERVICE_BUFFER_SLOTS/scheduling_info.service_inter_check_delay); if(max_reaper_interval<2.0) max_reaper_interval=2.0; if(max_reaper_interval>30.0) max_reaper_interval=30.0; if((int)max_reaper_interval= 2 seconds\n"); suggestions++; } if(suggestions==0) printf("I have no suggestions - things look okay.\n"); printf("\n"); return; } /* schedule a new timed event */ int schedule_new_event(int event_type, int high_priority, time_t run_time, int recurring, unsigned long event_interval, void *timing_func, int compensate_for_time_change, void *event_data, void *event_args){ timed_event **event_list; timed_event *new_event; #ifdef DEBUG0 printf("schedule_new_event() start\n"); #endif if(high_priority==TRUE) event_list=&event_list_high; else event_list=&event_list_low; new_event=(timed_event *)malloc(sizeof(timed_event)); if(new_event!=NULL){ new_event->event_type=event_type; new_event->event_data=event_data; new_event->event_args=event_args; new_event->run_time=run_time; new_event->recurring=recurring; new_event->event_interval=event_interval; new_event->timing_func=timing_func; new_event->compensate_for_time_change=compensate_for_time_change; } else return ERROR; /* add the event to the event list */ add_event(new_event,event_list); #ifdef DEBUG0 printf("schedule_new_event() end\n"); #endif return OK; } /* reschedule an event in order of execution time */ void reschedule_event(timed_event *event,timed_event **event_list){ time_t current_time; time_t (*timingfunc)(void); #ifdef DEBUG0 printf("reschedule_event() start\n"); #endif /*printf("INITIAL TIME: %s",ctime(&event->run_time));*/ /* reschedule recurring events... */ if(event->recurring==TRUE){ /* use custom timing function */ if(event->timing_func!=NULL){ timingfunc=event->timing_func; event->run_time=(*timingfunc)(); } /* normal recurring events */ else{ event->run_time=event->run_time+event->event_interval; time(¤t_time); if(event->run_timerun_time=current_time; } } /*printf("RESCHEDULED TIME: %s",ctime(&event->run_time));*/ /* add the event to the event list */ add_event(event,event_list); #ifdef DEBUG0 printf("reschedule_event() end\n"); #endif return; } /* remove event from schedule */ int deschedule_event(int event_type, int high_priority, void *event_data, void *event_args){ timed_event **event_list; timed_event *temp_event; int found=FALSE; #ifdef DEBUG0 printf("deschedule_event() start\n"); #endif if(high_priority==TRUE) event_list=&event_list_high; else event_list=&event_list_low; for(temp_event=*event_list;temp_event!=NULL;temp_event=temp_event->next){ if(temp_event->event_type==event_type && temp_event->event_data==event_data && temp_event->event_args==event_args){ found=TRUE; break; } } /* remove the event from the event list */ if (found){ remove_event(temp_event,event_list); free(temp_event); } else{ return ERROR; } #ifdef DEBUG0 printf("deschedule_event() end\n"); #endif return OK; } /* add an event to list ordered by execution time */ void add_event(timed_event *event,timed_event **event_list){ timed_event *temp_event; timed_event *first_event; #ifdef DEBUG0 printf("add_event() start\n"); #endif event->next=NULL; first_event=*event_list; /* add the event to the head of the list if there are no other events */ if(*event_list==NULL) *event_list=event; /* add event to head of the list if it should be executed first */ else if(event->run_time < first_event->run_time){ event->next=*event_list; *event_list=event; } /* else place the event according to next execution time */ else{ temp_event=*event_list; while(temp_event!=NULL){ if(temp_event->next==NULL){ temp_event->next=event; break; } if(event->run_time < temp_event->next->run_time){ event->next=temp_event->next; temp_event->next=event; break; } temp_event=temp_event->next; } } #ifdef USE_EVENT_BROKER /* send event data to broker */ broker_timed_event(NEBTYPE_TIMEDEVENT_ADD,NEBFLAG_NONE,NEBATTR_NONE,event,NULL); #endif #ifdef DEBUG0 printf("add_event() end\n"); #endif return; } /* remove an event from the queue */ void remove_event(timed_event *event,timed_event **event_list){ timed_event *temp_event; #ifdef DEBUG0 printf("remove_event() start\n"); #endif #ifdef USE_EVENT_BROKER /* send event data to broker */ broker_timed_event(NEBTYPE_TIMEDEVENT_REMOVE,NEBFLAG_NONE,NEBATTR_NONE,event,NULL); #endif if(*event_list==NULL) return; if(*event_list==event) *event_list=event->next; else{ for(temp_event=*event_list;temp_event!=NULL;temp_event=temp_event->next){ if(temp_event->next==event){ temp_event->next=temp_event->next->next; event->next=NULL; break; } } } #ifdef DEBUG0 printf("remove_event() end\n"); #endif return; } /* this is the main event handler loop */ int event_execution_loop(void){ timed_event *temp_event; timed_event sleep_event; time_t last_time; time_t current_time; int run_event=TRUE; host *temp_host; service *temp_service; struct timespec delay; struct timeval tv; #ifdef DEBUG0 printf("event_execution_loop() start\n"); #endif time(&last_time); /* initialize fake "sleep" event */ sleep_event.event_type=EVENT_SLEEP; sleep_event.run_time=last_time; sleep_event.recurring=FALSE; sleep_event.event_interval=0L; sleep_event.compensate_for_time_change=FALSE; sleep_event.timing_func=FALSE; sleep_event.event_data=FALSE; sleep_event.event_args=FALSE; while(1){ /* see if we should exit or restart (a signal was encountered) */ if(sigshutdown==TRUE || sigrestart==TRUE) break; /* if we don't have any events to handle, exit */ if(event_list_high==NULL && event_list_low==NULL){ #ifdef DEBUG1 printf("There aren't any events that need to be handled!\n"); #endif break; } /* get the current time */ time(¤t_time); /* hey, wait a second... we traveled back in time! */ if(current_time=time_change_threshold) compensate_for_system_time_change((unsigned long)last_time,(unsigned long)current_time); /* keep track of the last time */ last_time=current_time; #ifdef DEBUG3 printf("\n"); printf("*** Event Check Loop ***\n"); printf("\tCurrent time: %s",ctime(¤t_time)); if(event_list_high!=NULL) printf("\tNext High Priority Event Time: %s",ctime(&event_list_high->run_time)); else printf("\tNo high priority events are scheduled...\n"); if(event_list_low!=NULL) printf("\tNext Low Priority Event Time: %s",ctime(&event_list_low->run_time)); else printf("\tNo low priority events are scheduled...\n"); printf("Current/Max Outstanding Service Checks: %d/%d\n",currently_running_service_checks,max_parallel_service_checks); #endif /* handle high priority events */ if(event_list_high!=NULL && (current_time>=event_list_high->run_time)){ /* remove the first event from the timing loop */ temp_event=event_list_high; event_list_high=event_list_high->next; /* handle the event */ handle_timed_event(temp_event); /* reschedule the event if necessary */ if(temp_event->recurring==TRUE) reschedule_event(temp_event,&event_list_high); /* else free memory associated with the event */ else free(temp_event); } /* handle low priority events */ else if(event_list_low!=NULL && (current_time>=event_list_low->run_time)){ /* default action is to execute the event */ run_event=TRUE; /* run a few checks before executing a service check... */ if(event_list_low->event_type==EVENT_SERVICE_CHECK){ temp_service=(service *)event_list_low->event_data; /* update service check latency */ gettimeofday(&tv,NULL); temp_service->latency=(double)((double)(tv.tv_sec-event_list_low->run_time)+(double)(tv.tv_usec/1000)/1000.0); /* don't run a service check if we're not supposed to right now */ if(execute_service_checks==FALSE && !(temp_service->check_options & CHECK_OPTION_FORCE_EXECUTION)){ #ifdef DEBUG3 printf("\tWe're not executing service checks right now...\n"); #endif /* remove the service check from the event queue and reschedule it for a later time */ /* 12/20/05 since event was not executed, it needs to be remove()'ed to maintain sync with event broker modules */ temp_event=event_list_low; remove_event(temp_event,&event_list_low); /* event_list_low=event_list_low->next; */ if(temp_service->state_type==SOFT_STATE && temp_service->current_state!=STATE_OK) temp_service->next_check=(time_t)(temp_service->next_check+(temp_service->retry_interval*interval_length)); else temp_service->next_check=(time_t)(temp_service->next_check+(temp_service->check_interval*interval_length)); temp_event->run_time=temp_service->next_check; reschedule_event(temp_event,&event_list_low); update_service_status(temp_service,FALSE); run_event=FALSE; } /* don't run a service check if we're already maxed out on the number of parallel service checks... */ if(max_parallel_service_checks!=0 && (currently_running_service_checks >= max_parallel_service_checks)){ #ifdef DEBUG3 printf("\tMax concurrent service checks (%d) has been reached. Delaying further checks until previous checks are complete...\n",max_parallel_service_checks); #endif run_event=FALSE; } /* don't run a service check that can't be parallized if there are other checks out there... */ if(temp_service->parallelize==FALSE && currently_running_service_checks>0){ #ifdef DEBUG3 printf("\tA non-parallelizable check is queued for execution, but there are still other checks executing. We'll wait...\n"); #endif run_event=FALSE; } /* a service check that shouldn't be parallized with other checks is currently running, so don't execute another check */ if(non_parallelized_check_running==TRUE){ #ifdef DEBUG3 printf("\tA non-parallelizable check is currently running, so we have to wait before executing other checks...\n"); #endif run_event=FALSE; } } /* run a few checks before executing a host check... */ if(event_list_low->event_type==EVENT_HOST_CHECK){ temp_host=(host *)event_list_low->event_data; /* update host check latency */ gettimeofday(&tv,NULL); temp_host->latency=(double)((double)(tv.tv_sec-event_list_low->run_time)+(double)(tv.tv_usec/1000)/1000.0); /* don't run a host check if we're not supposed to right now */ if(execute_host_checks==FALSE && !(temp_host->check_options & CHECK_OPTION_FORCE_EXECUTION)){ #ifdef DEBUG3 printf("\tWe're not executing host checks right now...\n"); #endif /* remove the host check from the event queue and reschedule it for a later time */ /* 12/20/05 since event was not executed, it needs to be remove()'ed to maintain sync with event broker modules */ temp_event=event_list_low; remove_event(temp_event,&event_list_low); /* event_list_low=event_list_low->next; */ temp_host->next_check=(time_t)(temp_host->next_check+(temp_host->check_interval*interval_length)); temp_event->run_time=temp_host->next_check; reschedule_event(temp_event,&event_list_low); update_host_status(temp_host,FALSE); run_event=FALSE; } } /* run the event except... */ if(run_event==TRUE){ /* remove the first event from the timing loop */ temp_event=event_list_low; event_list_low=event_list_low->next; /* handle the event */ handle_timed_event(temp_event); /* reschedule the event if necessary */ if(temp_event->recurring==TRUE) reschedule_event(temp_event,&event_list_low); /* else free memory associated with the event */ else free(temp_event); } /* wait a while so we don't hog the CPU... */ else{ #ifdef USE_NANOSLEEP delay.tv_sec=(time_t)sleep_time; delay.tv_nsec=(long)((sleep_time-(double)delay.tv_sec)*1000000000); nanosleep(&delay,NULL); #else delay.tv_sec=(time_t)sleep_time; if(delay.tv_sec==0L) delay.tv_sec=1; delay.tv_nsec=0L; sleep((unsigned int)delay.tv_sec); #endif } } /* we don't have anything to do at this moment in time... */ else if((event_list_high==NULL || (current_timerun_time)) && (event_list_low==NULL || (current_timerun_time))){ /* check for external commands if we're supposed to check as often as possible */ if(command_check_interval==-1) check_for_external_commands(); /* set time to sleep so we don't hog the CPU... */ #ifdef USE_NANOSLEEP delay.tv_sec=(time_t)sleep_time; delay.tv_nsec=(long)((sleep_time-(double)delay.tv_sec)*1000000000); #else delay.tv_sec=(time_t)sleep_time; if(delay.tv_sec==0L) delay.tv_sec=1; delay.tv_nsec=0L; #endif #ifdef USE_EVENT_BROKER /* populate fake "sleep" event */ sleep_event.run_time=current_time; sleep_event.event_data=(void *)&delay; /* send event data to broker */ broker_timed_event(NEBTYPE_TIMEDEVENT_SLEEP,NEBFLAG_NONE,NEBATTR_NONE,&sleep_event,NULL); #endif /* wait a while so we don't hog the CPU... */ #ifdef USE_NANOSLEEP nanosleep(&delay,NULL); #else sleep((unsigned int)delay.tv_sec); #endif } } #ifdef DEBUG0 printf("event_execution_loop() end\n"); #endif return OK; } /* handles a timed event */ int handle_timed_event(timed_event *event){ host *temp_host=NULL; service *temp_service=NULL; char temp_buffer[MAX_INPUT_BUFFER]; void (*userfunc)(void *); #ifdef DEBUG0 printf("handle_timed_event() start\n"); #endif #ifdef USE_EVENT_BROKER /* send event data to broker */ broker_timed_event(NEBTYPE_TIMEDEVENT_EXECUTE,NEBFLAG_NONE,NEBATTR_NONE,event,NULL); #endif #ifdef DEBUG3 printf("*** Event Details ***\n"); printf("\tEvent time: %s",ctime(&event->run_time)); printf("\tEvent type: %d ",event->event_type); #endif /* how should we handle the event? */ switch(event->event_type){ case EVENT_SERVICE_CHECK: #ifdef DEBUG3 printf("(service check)\n"); temp_service=(service *)event->event_data; printf("\t\tService Description: %s\n",temp_service->description); printf("\t\tAssociated Host: %s\n",temp_service->host_name); #endif /* run a service check */ temp_service=(service *)event->event_data; run_service_check(temp_service); break; case EVENT_HOST_CHECK: #ifdef DEBUG3 printf("(host check)\n"); temp_host=(host *)event->event_data; printf("\t\tHost: %s\n",temp_host->name); #endif /* run a host check */ temp_host=(host *)event->event_data; run_scheduled_host_check(temp_host); break; case EVENT_COMMAND_CHECK: #ifdef DEBUG3 printf("(external command check)\n"); #endif /* check for external commands */ check_for_external_commands(); break; case EVENT_LOG_ROTATION: #ifdef DEBUG3 printf("(log file rotation)\n"); #endif /* rotate the log file */ rotate_log_file(event->run_time); break; case EVENT_PROGRAM_SHUTDOWN: #ifdef DEBUG3 printf("(program shutdown)\n"); #endif /* set the shutdown flag */ sigshutdown=TRUE; /* log the shutdown */ snprintf(temp_buffer,sizeof(temp_buffer),"PROGRAM_SHUTDOWN event encountered, shutting down...\n"); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_PROCESS_INFO,TRUE); break; case EVENT_PROGRAM_RESTART: #ifdef DEBUG3 printf("(program restart)\n"); #endif /* set the restart flag */ sigrestart=TRUE; /* log the restart */ snprintf(temp_buffer,sizeof(temp_buffer),"PROGRAM_RESTART event encountered, restarting...\n"); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_PROCESS_INFO,TRUE); break; case EVENT_SERVICE_REAPER: #ifdef DEBUG3 printf("(service check reaper)\n"); #endif /* reap service check results */ reap_service_checks(); break; case EVENT_ORPHAN_CHECK: #ifdef DEBUG3 printf("(orphaned service check)\n"); #endif /* check for orphaned services */ check_for_orphaned_services(); break; case EVENT_RETENTION_SAVE: #ifdef DEBUG3 printf("(retention save)\n"); #endif /* save state retention data */ save_state_information(config_file,TRUE); break; case EVENT_STATUS_SAVE: #ifdef DEBUG3 printf("(status save)\n"); #endif /* save all status data (program, host, and service) */ update_all_status_data(); break; case EVENT_SCHEDULED_DOWNTIME: #ifdef DEBUG3 printf("(scheduled downtime)\n"); #endif /* process scheduled downtime info */ handle_scheduled_downtime((scheduled_downtime *)event->event_data); break; case EVENT_SFRESHNESS_CHECK: #ifdef DEBUG3 printf("(service result freshness check)\n"); #endif /* check service result freshness */ check_service_result_freshness(); break; case EVENT_HFRESHNESS_CHECK: #ifdef DEBUG3 printf("(host result freshness check)\n"); #endif /* check host result freshness */ check_host_result_freshness(); break; case EVENT_EXPIRE_DOWNTIME: #ifdef DEBUG3 printf("(expire downtime)\n"); #endif /* check for expired scheduled downtime entries */ check_for_expired_downtime(); break; case EVENT_RESCHEDULE_CHECKS: #ifdef DEBUG3 printf("(reschedule checks)\n"); #endif /* adjust scheduling of host and service checks */ adjust_check_scheduling(); break; case EVENT_EXPIRE_COMMENT: #ifdef DEBUG3 printf("(expire comment)\n"); #endif /* check for expired comment */ check_for_expired_comment((unsigned long)event->event_data); break; case EVENT_USER_FUNCTION: #ifdef DEBUG3 printf("(user function)\n"); #endif /* run a user-defined function */ if(event->event_data!=NULL){ userfunc=event->event_data; (*userfunc)(event->event_args); } break; default: break; } #ifdef DEBUG0 printf("handle_timed_event() end\n"); #endif return OK; } /* adjusts scheduling of host and service checks */ void adjust_check_scheduling(void){ timed_event *temp_event; service *temp_service=NULL; host *temp_host=NULL; double projected_host_check_overhead=0.9; double projected_service_check_overhead=0.1; time_t current_time; time_t first_window_time=0L; time_t last_window_time=0L; time_t last_check_time=0L; time_t new_run_time=0L; int total_checks=0; int current_check=0; double inter_check_delay=0.0; double current_icd_offset=0.0; double total_check_exec_time=0.0; double last_check_exec_time=0.0; int adjust_scheduling=FALSE; double exec_time_factor=0.0; double current_exec_time=0.0; double current_exec_time_offset=0.0; double new_run_time_offset=0.0; #ifdef DEBUG0 printf("adjust_check_scheduling() start\n"); #endif /* TODO: - Track host check overhead on a per-host bases - Figure out how to calculate service check overhead */ /* determine our adjustment window */ time(¤t_time); first_window_time=current_time; last_window_time=first_window_time+auto_rescheduling_window; /* get current scheduling data */ for(temp_event=event_list_low;temp_event!=NULL;temp_event=temp_event->next){ /* skip events outside of our current window */ if(temp_event->run_time<=first_window_time) continue; if(temp_event->run_time>last_window_time) break; if(temp_event->event_type==EVENT_HOST_CHECK){ temp_host=(host *)temp_event->event_data; if(temp_host==NULL) continue; /* ignore forced checks */ if(temp_host->check_options & CHECK_OPTION_FORCE_EXECUTION) continue; /* does the last check "bump" into this one? */ if((unsigned long)(last_check_time+last_check_exec_time)>temp_event->run_time) adjust_scheduling=TRUE; last_check_time=temp_event->run_time; /* calculate time needed to perform check */ last_check_exec_time=temp_host->execution_time+projected_host_check_overhead; total_check_exec_time+=last_check_exec_time; } else if(temp_event->event_type==EVENT_SERVICE_CHECK){ temp_service=(service *)temp_event->event_data; if(temp_service==NULL) continue; /* ignore forced checks */ if(temp_service->check_options & CHECK_OPTION_FORCE_EXECUTION) continue; /* does the last check "bump" into this one? */ if((unsigned long)(last_check_time+last_check_exec_time)>temp_event->run_time) adjust_scheduling=TRUE; last_check_time=temp_event->run_time; /* calculate time needed to perform check */ /* NOTE: service check execution time is not taken into account, as service checks are run in parallel */ last_check_exec_time=projected_service_check_overhead; total_check_exec_time+=last_check_exec_time; } else continue; total_checks++; } /* nothing to do... */ if(total_checks==0 || adjust_scheduling==FALSE){ /* printf("\n\n"); printf("NOTHING TO DO!\n"); printf("# CHECKS: %d\n",total_checks); printf("WINDOW TIME: %d\n",auto_rescheduling_window); printf("EXEC TIME: %.3f\n",total_check_exec_time); */ return; } if((unsigned long)total_check_exec_time>auto_rescheduling_window){ inter_check_delay=0.0; exec_time_factor=(double)((double)auto_rescheduling_window/total_check_exec_time); } else{ inter_check_delay=(double)((((double)auto_rescheduling_window)-total_check_exec_time)/(double)(total_checks*1.0)); exec_time_factor=1.0; } /* printf("\n\n"); printf("TOTAL CHECKS: %d\n",total_checks); printf("WINDOW TIME: %d\n",auto_rescheduling_window); printf("EXEC TIME: %.3f\n",total_check_exec_time); printf("ICD: %.3f\n",inter_check_delay); printf("EXEC FACTOR: %.3f\n",exec_time_factor); */ /* adjust check scheduling */ current_icd_offset=(inter_check_delay/2.0); for(temp_event=event_list_low;temp_event!=NULL;temp_event=temp_event->next){ /* skip events outside of our current window */ if(temp_event->run_time<=first_window_time) continue; if(temp_event->run_time>last_window_time) break; if(temp_event->event_type==EVENT_HOST_CHECK){ temp_host=(host *)temp_event->event_data; if(temp_host==NULL) continue; /* ignore forced checks */ if(temp_host->check_options & CHECK_OPTION_FORCE_EXECUTION) continue; current_exec_time=((temp_host->execution_time+projected_host_check_overhead)*exec_time_factor); } else if(temp_event->event_type==EVENT_SERVICE_CHECK){ temp_service=(service *)temp_event->event_data; if(temp_service==NULL) continue; /* ignore forced checks */ if(temp_service->check_options & CHECK_OPTION_FORCE_EXECUTION) continue; /* NOTE: service check execution time is not taken into account, as service checks are run in parallel */ current_exec_time=(projected_service_check_overhead*exec_time_factor); } else continue; current_check++; new_run_time_offset=current_exec_time_offset+current_icd_offset; new_run_time=(time_t)(first_window_time+(unsigned long)new_run_time_offset); /* printf(" CURRENT CHECK #: %d\n",current_check); printf(" CURRENT ICD OFFSET: %.3f\n",current_icd_offset); printf(" CURRENT EXEC TIME: %.3f\n",current_exec_time); printf(" CURRENT EXEC OFFSET: %.3f\n",current_exec_time_offset); printf(" NEW RUN TIME: %lu\n",new_run_time); */ if(temp_event->event_type==EVENT_HOST_CHECK){ temp_event->run_time=new_run_time; temp_host->next_check=new_run_time; update_host_status(temp_host,FALSE); } else{ temp_event->run_time=new_run_time; temp_service->next_check=new_run_time; update_service_status(temp_service,FALSE); } current_icd_offset+=inter_check_delay; current_exec_time_offset+=current_exec_time; } /* resort event list (some events may be out of order at this point) */ resort_event_list(&event_list_low); #ifdef DEBUG0 printf("adjust_check_scheduling() end\n"); #endif return; } /* attempts to compensate for a change in the system time */ void compensate_for_system_time_change(unsigned long last_time,unsigned long current_time){ char buffer[MAX_INPUT_BUFFER]; unsigned long time_difference; timed_event *temp_event; service *temp_service; host *temp_host; time_t (*timingfunc)(void); #ifdef DEBUG0 printf("compensate_for_system_time_change() start\n"); #endif /* we moved back in time... */ if(last_time>current_time) time_difference=last_time-current_time; /* we moved into the future... */ else time_difference=current_time-last_time; /* log the time change */ snprintf(buffer,sizeof(buffer),"Warning: A system time change of %lu seconds (%s in time) has been detected. Compensating...\n",time_difference,(last_time>current_time)?"backwards":"forwards"); buffer[sizeof(buffer)-1]='\x0'; write_to_logs_and_console(buffer,NSLOG_PROCESS_INFO | NSLOG_RUNTIME_WARNING,TRUE); /* adjust the next run time for all high priority timed events */ for(temp_event=event_list_high;temp_event!=NULL;temp_event=temp_event->next){ /* skip special events that occur at specific times... */ if(temp_event->compensate_for_time_change==FALSE) continue; /* use custom timing function */ if(temp_event->timing_func!=NULL){ timingfunc=temp_event->timing_func; temp_event->run_time=(*timingfunc)(); } /* else use standard adjustment */ else adjust_timestamp_for_time_change(last_time,current_time,time_difference,&temp_event->run_time); } /* resort event list (some events may be out of order at this point) */ resort_event_list(&event_list_high); /* adjust the next run time for all low priority timed events */ for(temp_event=event_list_low;temp_event!=NULL;temp_event=temp_event->next){ /* skip special events that occur at specific times... */ if(temp_event->compensate_for_time_change==FALSE) continue; /* use custom timing function */ if(temp_event->timing_func!=NULL){ timingfunc=temp_event->timing_func; temp_event->run_time=(*timingfunc)(); } /* else use standard adjustment */ else adjust_timestamp_for_time_change(last_time,current_time,time_difference,&temp_event->run_time); } /* resort event list (some events may be out of order at this point) */ resort_event_list(&event_list_low); /* adjust service timestamps */ for(temp_service=service_list;temp_service!=NULL;temp_service=temp_service->next){ adjust_timestamp_for_time_change(last_time,current_time,time_difference,&temp_service->last_notification); adjust_timestamp_for_time_change(last_time,current_time,time_difference,&temp_service->last_check); adjust_timestamp_for_time_change(last_time,current_time,time_difference,&temp_service->next_check); adjust_timestamp_for_time_change(last_time,current_time,time_difference,&temp_service->last_state_change); adjust_timestamp_for_time_change(last_time,current_time,time_difference,&temp_service->last_hard_state_change); /* recalculate next re-notification time */ temp_service->next_notification=get_next_service_notification_time(temp_service,temp_service->last_notification); /* update the status data */ update_service_status(temp_service,FALSE); } /* adjust host timestamps */ for(temp_host=host_list;temp_host!=NULL;temp_host=temp_host->next){ adjust_timestamp_for_time_change(last_time,current_time,time_difference,&temp_host->last_host_notification); adjust_timestamp_for_time_change(last_time,current_time,time_difference,&temp_host->last_check); adjust_timestamp_for_time_change(last_time,current_time,time_difference,&temp_host->next_check); adjust_timestamp_for_time_change(last_time,current_time,time_difference,&temp_host->last_state_change); adjust_timestamp_for_time_change(last_time,current_time,time_difference,&temp_host->last_hard_state_change); adjust_timestamp_for_time_change(last_time,current_time,time_difference,&temp_host->last_state_history_update); /* recalculate next re-notification time */ temp_host->next_host_notification=get_next_host_notification_time(temp_host,temp_host->last_host_notification); /* update the status data */ update_host_status(temp_host,FALSE); } /* adjust program timestamps */ adjust_timestamp_for_time_change(last_time,current_time,time_difference,&program_start); adjust_timestamp_for_time_change(last_time,current_time,time_difference,&last_command_check); /* update the status data */ update_program_status(FALSE); #ifdef DEBUG0 printf("compensate_for_system_time_change() end\n"); #endif return; } /* resorts an event list by event execution time - needed when compensating for system time changes */ void resort_event_list(timed_event **event_list){ timed_event *temp_event_list; timed_event *temp_event; timed_event *next_event; /* move current event list to temp list */ temp_event_list=*event_list; *event_list=NULL; /* move all events to the new event list */ for(temp_event=temp_event_list;temp_event!=NULL;temp_event=next_event){ next_event=temp_event->next; /* add the event to the newly created event list so it will be resorted */ temp_event->next=NULL; add_event(temp_event,event_list); } return; } /* adjusts a timestamp variable in accordance with a system time change */ void adjust_timestamp_for_time_change(time_t last_time, time_t current_time, unsigned long time_difference, time_t *ts){ /* we shouldn't do anything with epoch values */ if(*ts==(time_t)0) return; /* we moved back in time... */ if(last_time>current_time){ /* we can't precede the UNIX epoch */ if(time_difference>(unsigned long)*ts) *ts=(time_t)0; else *ts=(time_t)(*ts-time_difference); } /* we moved into the future... */ else *ts=(time_t)(*ts+time_difference); return; } nagios-2.6/base/flapping.c0000664000076500007650000005041210433352477015067 0ustar nagiosnagios/***************************************************************************** * * FLAPPING.C - State flap detection and handling routines for Nagios * * Copyright (c) 2001-2005 Ethan Galstad (nagios@nagios.org) * Last Modified: 05-18-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/comments.h" #include "../include/statusdata.h" #include "../include/nagios.h" #include "../include/broker.h" extern int interval_length; extern int enable_flap_detection; extern double low_service_flap_threshold; extern double high_service_flap_threshold; extern double low_host_flap_threshold; extern double high_host_flap_threshold; /******************************************************************/ /******************** FLAP DETECTION FUNCTIONS ********************/ /******************************************************************/ /* detects service flapping */ void check_for_service_flapping(service *svc, int update_history){ int is_flapping=FALSE; int x,y; int last_state_history_value=STATE_OK; double curved_changes=0.0; double curved_percent_change=0.0; double low_threshold=0.0; double high_threshold=0.0; double low_curve_value=0.75; double high_curve_value=1.25; #ifdef DEBUG0 printf("check_for_service_flapping() start\n"); #endif /* if this is a soft service state and not a soft recovery, don't record this in the history */ /* only hard states and soft recoveries get recorded for flap detection */ if(svc->state_type==SOFT_STATE && svc->current_state!=STATE_OK) return; /* what threshold values should we use (global or service-specific)? */ low_threshold=(svc->low_flap_threshold<=0.0)?low_service_flap_threshold:svc->low_flap_threshold; high_threshold=(svc->high_flap_threshold<=0.0)?high_service_flap_threshold:svc->high_flap_threshold; if(update_history==TRUE){ /* record the current state in the state history */ svc->state_history[svc->state_history_index]=svc->current_state; /* increment state history index to next available slot */ svc->state_history_index++; if(svc->state_history_index>=MAX_STATE_HISTORY_ENTRIES) svc->state_history_index=0; } /* calculate overall and curved percent state changes */ for(x=0,y=svc->state_history_index;xstate_history[y]; y++; if(y>=MAX_STATE_HISTORY_ENTRIES) y=0; continue; } if(last_state_history_value!=svc->state_history[y]) curved_changes+=(((double)(x-1)*(high_curve_value-low_curve_value))/((double)(MAX_STATE_HISTORY_ENTRIES-2)))+low_curve_value; last_state_history_value=svc->state_history[y]; y++; if(y>=MAX_STATE_HISTORY_ENTRIES) y=0; } /* calculate overall percent change in state */ curved_percent_change=(double)(((double)curved_changes*100.0)/(double)(MAX_STATE_HISTORY_ENTRIES-1)); svc->percent_state_change=curved_percent_change; /* are we flapping, undecided, or what?... */ /* we're undecided, so don't change the current flap state */ if(curved_percent_change>low_threshold && curved_percent_change=high_threshold) is_flapping=TRUE; /* so what should we do (if anything)? */ /* don't do anything if we don't have flap detection enabled on a program-wide basis */ if(enable_flap_detection==FALSE) return; /* don't do anything if we don't have flap detection enabled for this service */ if(svc->flap_detection_enabled==FALSE) return; /* did the service just start flapping? */ if(is_flapping==TRUE && svc->is_flapping==FALSE) set_service_flap(svc,curved_percent_change,high_threshold,low_threshold); /* did the service just stop flapping? */ else if(is_flapping==FALSE && svc->is_flapping==TRUE) clear_service_flap(svc,curved_percent_change,high_threshold,low_threshold); #ifdef DEBUG0 printf("check_for_service_flapping() end\n"); #endif return; } /* detects host flapping */ void check_for_host_flapping(host *hst, int update_history){ int is_flapping=FALSE; int x; int last_state_history_value=HOST_UP; unsigned long wait_threshold; double curved_changes=0.0; double curved_percent_change=0.0; time_t current_time; double low_threshold=0.0; double high_threshold=0.0; double low_curve_value=0.75; double high_curve_value=1.25; #ifdef DEBUG0 printf("check_for_host_flapping() start\n"); #endif time(¤t_time); /* period to wait for updating archived state info if we have no state change */ if(hst->total_services==0) wait_threshold=hst->notification_interval*interval_length; else wait_threshold=(hst->total_service_check_interval*interval_length)/hst->total_services; /* if we haven't waited long enough since last record, only update if we've had a state change */ if((current_time-hst->last_state_history_update)state_history[(hst->state_history_index==0)?MAX_STATE_HISTORY_ENTRIES-1:hst->state_history_index-1]; /* if we haven't had a state change since our last recorded state, bail out */ if(last_state_history_value==hst->current_state) return; } /* what thresholds should we use (global or host-specific)? */ low_threshold=(hst->low_flap_threshold<=0.0)?low_host_flap_threshold:hst->low_flap_threshold; high_threshold=(hst->high_flap_threshold<=0.0)?high_host_flap_threshold:hst->high_flap_threshold; if(update_history==TRUE){ /* update the last record time */ hst->last_state_history_update=current_time; /* record the current state in the state history */ hst->state_history[hst->state_history_index]=hst->current_state; /* increment state history index to next available slot */ hst->state_history_index++; if(hst->state_history_index>=MAX_STATE_HISTORY_ENTRIES) hst->state_history_index=0; } /* calculate overall changes in state */ for(x=0;xstate_history[x]; continue; } if(last_state_history_value!=hst->state_history[x]) curved_changes+=(((double)(x-1)*(high_curve_value-low_curve_value))/((double)(MAX_STATE_HISTORY_ENTRIES-2)))+low_curve_value; last_state_history_value=hst->state_history[x]; } /* calculate overall percent change in state */ curved_percent_change=(double)(((double)curved_changes*100.0)/(double)(MAX_STATE_HISTORY_ENTRIES-1)); hst->percent_state_change=curved_percent_change; /* are we flapping, undecided, or what?... */ /* we're undecided, so don't change the current flap state */ if(curved_percent_change>low_threshold && curved_percent_change=high_threshold) is_flapping=TRUE; /* so what should we do (if anything)? */ /* don't do anything if we don't have flap detection enabled on a program-wide basis */ if(enable_flap_detection==FALSE) return; /* don't do anything if we don't have flap detection enabled for this host */ if(hst->flap_detection_enabled==FALSE) return; /* did the host just start flapping? */ if(is_flapping==TRUE && hst->is_flapping==FALSE) set_host_flap(hst,curved_percent_change,high_threshold,low_threshold); /* did the host just stop flapping? */ else if(is_flapping==FALSE && hst->is_flapping==TRUE) clear_host_flap(hst,curved_percent_change,high_threshold,low_threshold); #ifdef DEBUG0 printf("check_for_host_flapping() end\n"); #endif return; } /******************************************************************/ /********************* FLAP HANDLING FUNCTIONS ********************/ /******************************************************************/ /* handles a service that is flapping */ void set_service_flap(service *svc, double percent_change, double high_threshold, double low_threshold){ char buffer[MAX_INPUT_BUFFER]; #ifdef DEBUG0 printf("set_service_flap() start\n"); #endif /* log a notice - this one is parsed by the history CGI */ snprintf(buffer,sizeof(buffer)-1,"SERVICE FLAPPING ALERT: %s;%s;STARTED; Service appears to have started flapping (%2.1f%% change >= %2.1f%% threshold)\n",svc->host_name,svc->description,percent_change,high_threshold); buffer[sizeof(buffer)-1]='\x0'; write_to_all_logs(buffer,NSLOG_RUNTIME_WARNING); /* add a non-persistent comment to the service */ snprintf(buffer,sizeof(buffer)-1,"Notifications for this service are being suppressed because it was detected as having been flapping between different states (%2.1f%% change >= %2.1f%% threshold). When the service state stabilizes and the flapping stops, notifications will be re-enabled.",percent_change,high_threshold); buffer[sizeof(buffer)-1]='\x0'; add_new_service_comment(FLAPPING_COMMENT,svc->host_name,svc->description,time(NULL),"(Nagios Process)",buffer,0,COMMENTSOURCE_INTERNAL,FALSE,(time_t)0,&(svc->flapping_comment_id)); /* set the flapping indicator */ svc->is_flapping=TRUE; #ifdef USE_EVENT_BROKER /* send data to event broker */ broker_flapping_data(NEBTYPE_FLAPPING_START,NEBFLAG_NONE,NEBATTR_NONE,SERVICE_FLAPPING,svc,percent_change,high_threshold,low_threshold,NULL); #endif /* see if we should check to send a recovery notification out when flapping stops */ if(svc->current_state!=STATE_OK && svc->current_notification_number>0) svc->check_flapping_recovery_notification=TRUE; else svc->check_flapping_recovery_notification=FALSE; /* send a notification */ service_notification(svc,NOTIFICATION_FLAPPINGSTART,NULL,NULL); #ifdef DEBUG0 printf("set_service_flap() end\n"); #endif return; } /* handles a service that has stopped flapping */ void clear_service_flap(service *svc, double percent_change, double high_threshold, double low_threshold){ char buffer[MAX_INPUT_BUFFER]; #ifdef DEBUG0 printf("clear_service_flap() start\n"); #endif /* log a notice - this one is parsed by the history CGI */ snprintf(buffer,sizeof(buffer)-1,"SERVICE FLAPPING ALERT: %s;%s;STOPPED; Service appears to have stopped flapping (%2.1f%% change < %2.1f%% threshold)\n",svc->host_name,svc->description,percent_change,low_threshold); buffer[sizeof(buffer)-1]='\x0'; write_to_all_logs(buffer,NSLOG_INFO_MESSAGE); /* delete the comment we added earlier */ if(svc->flapping_comment_id!=0) delete_service_comment(svc->flapping_comment_id); svc->flapping_comment_id=0; /* clear the flapping indicator */ svc->is_flapping=FALSE; #ifdef USE_EVENT_BROKER /* send data to event broker */ broker_flapping_data(NEBTYPE_FLAPPING_STOP,NEBFLAG_NONE,NEBATTR_FLAPPING_STOP_NORMAL,SERVICE_FLAPPING,svc,percent_change,high_threshold,low_threshold,NULL); #endif /* send a notification */ service_notification(svc,NOTIFICATION_FLAPPINGSTOP,NULL,NULL); /* should we send a recovery notification? */ if(svc->check_flapping_recovery_notification==TRUE && svc->current_state==STATE_OK) service_notification(svc,NOTIFICATION_NORMAL,NULL,NULL); /* clear the recovery notification flag */ svc->check_flapping_recovery_notification=FALSE; #ifdef DEBUG0 printf("clear_service_flap() end\n"); #endif return; } /* handles a host that is flapping */ void set_host_flap(host *hst, double percent_change, double high_threshold, double low_threshold){ char buffer[MAX_INPUT_BUFFER]; #ifdef DEBUG0 printf("set_host_flap() start\n"); #endif /* log a notice - this one is parsed by the history CGI */ snprintf(buffer,sizeof(buffer)-1,"HOST FLAPPING ALERT: %s;STARTED; Host appears to have started flapping (%2.1f%% change > %2.1f%% threshold)\n",hst->name,percent_change,high_threshold); buffer[sizeof(buffer)-1]='\x0'; write_to_all_logs(buffer,NSLOG_RUNTIME_WARNING); /* add a non-persistent comment to the host */ snprintf(buffer,sizeof(buffer)-1,"Notifications for this host are being suppressed because it was detected as having been flapping between different states (%2.1f%% change > %2.1f%% threshold). When the host state stabilizes and the flapping stops, notifications will be re-enabled.",percent_change,high_threshold); buffer[sizeof(buffer)-1]='\x0'; add_new_host_comment(FLAPPING_COMMENT,hst->name,time(NULL),"(Nagios Process)",buffer,0,COMMENTSOURCE_INTERNAL,FALSE,(time_t)0,&(hst->flapping_comment_id)); /* set the flapping indicator */ hst->is_flapping=TRUE; #ifdef USE_EVENT_BROKER /* send data to event broker */ broker_flapping_data(NEBTYPE_FLAPPING_START,NEBFLAG_NONE,NEBATTR_NONE,HOST_FLAPPING,hst,percent_change,high_threshold,low_threshold,NULL); #endif /* see if we should check to send a recovery notification out when flapping stops */ if(hst->current_state!=HOST_UP && hst->current_notification_number>0) hst->check_flapping_recovery_notification=TRUE; else hst->check_flapping_recovery_notification=FALSE; /* send a notification */ host_notification(hst,NOTIFICATION_FLAPPINGSTART,NULL,NULL); #ifdef DEBUG0 printf("set_host_flap() end\n"); #endif return; } /* handles a host that has stopped flapping */ void clear_host_flap(host *hst, double percent_change, double high_threshold, double low_threshold){ char buffer[MAX_INPUT_BUFFER]; #ifdef DEBUG0 printf("clear_host_flap() start\n"); #endif /* log a notice - this one is parsed by the history CGI */ snprintf(buffer,sizeof(buffer)-1,"HOST FLAPPING ALERT: %s;STOPPED; Host appears to have stopped flapping (%2.1f%% change < %2.1f%% threshold)\n",hst->name,percent_change,low_threshold); buffer[sizeof(buffer)-1]='\x0'; write_to_all_logs(buffer,NSLOG_INFO_MESSAGE); /* delete the comment we added earlier */ if(hst->flapping_comment_id!=0) delete_host_comment(hst->flapping_comment_id); hst->flapping_comment_id=0; /* clear the flapping indicator */ hst->is_flapping=FALSE; #ifdef USE_EVENT_BROKER /* send data to event broker */ broker_flapping_data(NEBTYPE_FLAPPING_STOP,NEBFLAG_NONE,NEBATTR_FLAPPING_STOP_NORMAL,HOST_FLAPPING,hst,percent_change,high_threshold,low_threshold,NULL); #endif /* send a notification */ host_notification(hst,NOTIFICATION_FLAPPINGSTOP,NULL,NULL); /* should we send a recovery notification? */ if(hst->check_flapping_recovery_notification==TRUE && hst->current_state==HOST_UP) host_notification(hst,NOTIFICATION_NORMAL,NULL,NULL); /* clear the recovery notification flag */ hst->check_flapping_recovery_notification=FALSE; #ifdef DEBUG0 printf("clear_host_flap() end\n"); #endif return; } /******************************************************************/ /***************** FLAP DETECTION STATUS FUNCTIONS ****************/ /******************************************************************/ /* enables flap detection on a program wide basis */ void enable_flap_detection_routines(void){ #ifdef DEBUG0 printf("enable_flap_detection() start\n"); #endif /* set flap detection flag */ enable_flap_detection=TRUE; /* update program status */ update_program_status(FALSE); #ifdef DEBUG0 printf("enable_flap_detection() end\n"); #endif return; } /* disables flap detection on a program wide basis */ void disable_flap_detection_routines(void){ #ifdef DEBUG0 printf("disable_flap_detection() start\n"); #endif /* set flap detection flag */ enable_flap_detection=FALSE; /* update program status */ update_program_status(FALSE); #ifdef DEBUG0 printf("disable_flap_detection() end\n"); #endif return; } /* enables flap detection for a specific host */ void enable_host_flap_detection(host *hst){ int x; #ifdef DEBUG0 printf("enable_host_flap_detection() start\n"); #endif /* nothing to do... */ if(hst->flap_detection_enabled==TRUE) return; /* reset the archived state history */ for(x=0;xstate_history[x]=hst->current_state; /* reset percent state change indicator */ hst->percent_state_change=0.0; /* set the flap detection enabled flag */ hst->flap_detection_enabled=TRUE; /* update host status */ update_host_status(hst,FALSE); #ifdef DEBUG0 printf("enable_host_flap_detection() end\n"); #endif return; } /* disables flap detection for a specific host */ void disable_host_flap_detection(host *hst){ char buffer[MAX_INPUT_BUFFER]; #ifdef DEBUG0 printf("disable_host_flap_detection() start\n"); #endif /* nothing to do... */ if(hst->flap_detection_enabled==FALSE) return; /* set the flap detection enabled flag */ hst->flap_detection_enabled=FALSE; /* if the host was flapping, remove the flapping indicator */ if(hst->is_flapping==TRUE){ hst->is_flapping=FALSE; /* delete the original comment we added earlier */ if(hst->flapping_comment_id!=0) delete_host_comment(hst->flapping_comment_id); hst->flapping_comment_id=0; /* log a notice - this one is parsed by the history CGI */ snprintf(buffer,sizeof(buffer)-1,"HOST FLAPPING ALERT: %s;DISABLED; Flap detection has been disabled\n",hst->name); buffer[sizeof(buffer)-1]='\x0'; write_to_all_logs(buffer,NSLOG_INFO_MESSAGE); #ifdef USE_EVENT_BROKER /* send data to event broker */ broker_flapping_data(NEBTYPE_FLAPPING_STOP,NEBFLAG_NONE,NEBATTR_FLAPPING_STOP_DISABLED,HOST_FLAPPING,hst,hst->percent_state_change,0.0,0.0,NULL); #endif } /* reset the percent change indicator */ hst->percent_state_change=0.0; /* update host status */ update_host_status(hst,FALSE); #ifdef DEBUG0 printf("disable_host_flap_detection() end\n"); #endif return; } /* enables flap detection for a specific service */ void enable_service_flap_detection(service *svc){ int x; #ifdef DEBUG0 printf("enable_service_flap_detection() start\n"); #endif /* nothing to do... */ if(svc->flap_detection_enabled==TRUE) return; /* reset the archived state history */ for(x=0;xstate_history[x]=svc->current_state; /* reset percent state change indicator */ svc->percent_state_change=0.0; /* set the flap detection enabled flag */ svc->flap_detection_enabled=TRUE; /* update service status */ update_service_status(svc,FALSE); #ifdef DEBUG0 printf("enable_service_flap_detection() end\n"); #endif return; } /* disables flap detection for a specific service */ void disable_service_flap_detection(service *svc){ char buffer[MAX_INPUT_BUFFER]; #ifdef DEBUG0 printf("disable_service_flap_detection() start\n"); #endif /* nothing to do... */ if(svc->flap_detection_enabled==FALSE) return; /* set the flap detection enabled flag */ svc->flap_detection_enabled=FALSE; /* if the service was flapping, remove the flapping indicator */ if(svc->is_flapping==TRUE){ svc->is_flapping=FALSE; /* delete the original comment we added earlier */ if(svc->flapping_comment_id!=0) delete_service_comment(svc->flapping_comment_id); svc->flapping_comment_id=0; /* log a notice - this one is parsed by the history CGI */ snprintf(buffer,sizeof(buffer)-1,"SERVICE FLAPPING ALERT: %s;%s;DISABLED; Flap detection has been disabled\n",svc->host_name,svc->description); buffer[sizeof(buffer)-1]='\x0'; write_to_all_logs(buffer,NSLOG_INFO_MESSAGE); #ifdef USE_EVENT_BROKER /* send data to event broker */ broker_flapping_data(NEBTYPE_FLAPPING_STOP,NEBFLAG_NONE,NEBATTR_FLAPPING_STOP_DISABLED,SERVICE_FLAPPING,svc,svc->percent_state_change,0.0,0.0,NULL); #endif } /* reset the percent change indicator */ svc->percent_state_change=0.0; /* update service status */ update_service_status(svc,FALSE); #ifdef DEBUG0 printf("disable_service_flap_detection() end\n"); #endif return; } nagios-2.6/base/logging.c0000664000076500007650000003014610347414405014711 0ustar nagiosnagios/***************************************************************************** * * LOGGING.C - Log file functions for use with Nagios * * Copyright (c) 1999-2005 Ethan Galstad (nagios@nagios.org) * Last Modified: 12-12-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. * *****************************************************************************/ #include "../include/config.h" #include "../include/common.h" #include "../include/statusdata.h" #include "../include/nagios.h" #include "../include/broker.h" extern char *log_file; extern char *temp_file; extern char *log_archive_path; extern char *macro_x[MACRO_X_COUNT]; extern host *host_list; extern service *service_list; extern int use_syslog; extern int log_service_retries; extern int log_initial_states; extern unsigned long logging_options; extern unsigned long syslog_options; extern int verify_config; extern int test_scheduling; extern time_t last_log_rotation; extern int log_rotation_method; extern int daemon_mode; /******************************************************************/ /************************ LOGGING FUNCTIONS ***********************/ /******************************************************************/ /* write something to the log file, syslog, and possibly the console */ int write_to_logs_and_console(char *buffer, unsigned long data_type, int display){ int len; int x; #ifdef DEBUG0 printf("write_to_logs_and_console() start\n"); #endif /* strip unnecessary newlines */ len=strlen(buffer); for(x=len-1;x>=0;x--){ if(buffer[x]=='\n') buffer[x]='\x0'; else break; } /* write messages to the logs */ write_to_all_logs(buffer,data_type); /* write message to the console */ if(display==TRUE) write_to_console(buffer); #ifdef DEBUG0 printf("write_to_logs_and_console() end\n"); #endif return OK; } /* write something to the console */ int write_to_console(char *buffer){ #ifdef DEBUG0 printf("write_to_console() start\n"); #endif /* should we print to the console? */ if(daemon_mode==FALSE) printf("%s\n",buffer); #ifdef DEBUG0 printf("write_to_console() end\n"); #endif return OK; } /* write something to the log file and syslog facility */ int write_to_all_logs(char *buffer, unsigned long data_type){ #ifdef DEBUG0 printf("write_to_all_logs() start\n"); #endif /* write to syslog */ write_to_syslog(buffer,data_type); /* write to main log */ write_to_log(buffer,data_type,NULL); #ifdef DEBUG0 printf("write_to_all_logs() end\n"); #endif return OK; } /* write something to the log file and syslog facility */ int write_to_all_logs_with_timestamp(char *buffer, unsigned long data_type, time_t *timestamp){ #ifdef DEBUG0 printf("write_to_all_logs_with_timestamp() start\n"); #endif /* write to syslog */ write_to_syslog(buffer,data_type); /* write to main log */ write_to_log(buffer,data_type,timestamp); #ifdef DEBUG0 printf("write_to_all_logs_with_timestamp() end\n"); #endif return OK; } /* write something to the nagios log file */ int write_to_log(char *buffer, unsigned long data_type, time_t *timestamp){ FILE *fp; time_t log_time; #ifdef DEBUG0 printf("write_to_log() start\n"); #endif /* don't log anything if we're not actually running... */ if(verify_config==TRUE || test_scheduling==TRUE) return OK; /* make sure we can log this type of entry */ if(!(data_type & logging_options)) return OK; fp=fopen(log_file,"a+"); if(fp==NULL){ if(daemon_mode==FALSE) printf("Warning: Cannot open log file '%s' for writing\n",log_file); return ERROR; } /* what timestamp should we use? */ if(timestamp==NULL) time(&log_time); else log_time=*timestamp; /* strip any newlines from the end of the buffer */ strip(buffer); /* write the buffer to the log file */ fprintf(fp,"[%lu] %s\n",log_time,buffer); fclose(fp); #ifdef USE_EVENT_BROKER /* send data to the event broker */ broker_log_data(NEBTYPE_LOG_DATA,NEBFLAG_NONE,NEBATTR_NONE,buffer,data_type,log_time,NULL); #endif #ifdef DEBUG0 printf("write_to_log() end\n"); #endif return OK; } /* write something to the syslog facility */ int write_to_syslog(char *buffer, unsigned long data_type){ #ifdef DEBUG0 printf("write_to_syslog() start\n"); #endif /* don't log anything if we're not actually running... */ if(verify_config==TRUE || test_scheduling==TRUE) return OK; /* bail out if we shouldn't write to syslog */ if(use_syslog==FALSE) return OK; /* make sure we should log this type of entry */ if(!(data_type & syslog_options)) return OK; /* write the buffer to the syslog facility */ syslog(LOG_USER|LOG_INFO,"%s",buffer); #ifdef DEBUG0 printf("write_to_syslog() end\n"); #endif return OK; } /* write a service problem/recovery to the nagios log file */ int log_service_event(service *svc){ char temp_buffer[MAX_INPUT_BUFFER]; unsigned long log_options; host *temp_host; #ifdef DEBUG0 printf("log_service_event() start\n"); #endif /* don't log soft errors if the user doesn't want to */ if(svc->state_type==SOFT_STATE && !log_service_retries) return OK; /* get the log options */ if(svc->current_state==STATE_UNKNOWN) log_options=NSLOG_SERVICE_UNKNOWN; else if(svc->current_state==STATE_WARNING) log_options=NSLOG_SERVICE_WARNING; else if(svc->current_state==STATE_CRITICAL) log_options=NSLOG_SERVICE_CRITICAL; else log_options=NSLOG_SERVICE_OK; /* find the associated host */ temp_host=find_host(svc->host_name); /* grab service macros */ clear_volatile_macros(); grab_host_macros(temp_host); grab_service_macros(svc); grab_summary_macros(NULL); snprintf(temp_buffer,sizeof(temp_buffer),"SERVICE ALERT: %s;%s;%s;%s;%s;%s\n",svc->host_name,svc->description,macro_x[MACRO_SERVICESTATE],macro_x[MACRO_SERVICESTATETYPE],macro_x[MACRO_SERVICEATTEMPT],svc->plugin_output); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_all_logs(temp_buffer,log_options); #ifdef DEBUG0 printf("log_service_event() end\n"); #endif return OK; } /* write a host problem/recovery to the log file */ int log_host_event(host *hst){ char temp_buffer[MAX_INPUT_BUFFER]; unsigned long log_options=0L; #ifdef DEBUG0 printf("log_host_event() start\n"); #endif /* grab the host macros */ clear_volatile_macros(); grab_host_macros(hst); grab_summary_macros(NULL); /* get the log options */ if(hst->current_state==HOST_DOWN) log_options=NSLOG_HOST_DOWN; else if(hst->current_state==HOST_UNREACHABLE) log_options=NSLOG_HOST_UNREACHABLE; else log_options=NSLOG_HOST_UP; snprintf(temp_buffer,sizeof(temp_buffer),"HOST ALERT: %s;%s;%s;%s;%s\n",hst->name,macro_x[MACRO_HOSTSTATE],macro_x[MACRO_HOSTSTATETYPE],macro_x[MACRO_HOSTATTEMPT],hst->plugin_output); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_all_logs(temp_buffer,log_options); #ifdef DEBUG0 printf("log_host_event() start\n"); #endif return OK; } /* logs host states */ int log_host_states(int type, time_t *timestamp){ char temp_buffer[MAX_INPUT_BUFFER]; host *temp_host; /* bail if we shouldn't be logging initial states */ if(type==INITIAL_STATES && log_initial_states==FALSE) return OK; /* grab summary macros */ grab_summary_macros(NULL); for(temp_host=host_list;temp_host!=NULL;temp_host=temp_host->next){ /* grab the host macros */ clear_volatile_macros(); grab_host_macros(temp_host); snprintf(temp_buffer,sizeof(temp_buffer),"%s HOST STATE: %s;%s;%s;%s;%s\n",(type==INITIAL_STATES)?"INITIAL":"CURRENT",temp_host->name,macro_x[MACRO_HOSTSTATE],macro_x[MACRO_HOSTSTATETYPE],macro_x[MACRO_HOSTATTEMPT],temp_host->plugin_output); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_all_logs_with_timestamp(temp_buffer,NSLOG_INFO_MESSAGE,timestamp); } return OK; } /* logs service states */ int log_service_states(int type, time_t *timestamp){ char temp_buffer[MAX_INPUT_BUFFER]; service *temp_service; host *temp_host; /* bail if we shouldn't be logging initial states */ if(type==INITIAL_STATES && log_initial_states==FALSE) return OK; /* grab summary macros */ grab_summary_macros(NULL); for(temp_service=service_list;temp_service!=NULL;temp_service=temp_service->next){ /* find the associated host */ temp_host=find_host(temp_service->host_name); /* grab service macros */ clear_volatile_macros(); grab_host_macros(temp_host); grab_service_macros(temp_service); snprintf(temp_buffer,sizeof(temp_buffer),"%s SERVICE STATE: %s;%s;%s;%s;%s;%s\n",(type==INITIAL_STATES)?"INITIAL":"CURRENT",temp_service->host_name,temp_service->description,macro_x[MACRO_SERVICESTATE],macro_x[MACRO_SERVICESTATETYPE],macro_x[MACRO_SERVICEATTEMPT],temp_service->plugin_output); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_all_logs_with_timestamp(temp_buffer,NSLOG_INFO_MESSAGE,timestamp); } return OK; } /* rotates the main log file */ int rotate_log_file(time_t rotation_time){ char temp_buffer[MAX_INPUT_BUFFER]; char method_string[16]; char log_archive[MAX_FILENAME_LENGTH]; struct tm *t; int rename_result; #ifdef DEBUG0 printf("rotate_log_file() start\n"); #endif if(log_rotation_method==LOG_ROTATION_NONE){ #ifdef DEBUG1 printf("\tWe're not supposed to be doing log rotations!\n"); #endif return OK; } else if(log_rotation_method==LOG_ROTATION_HOURLY) strcpy(method_string,"HOURLY"); else if(log_rotation_method==LOG_ROTATION_DAILY) strcpy(method_string,"DAILY"); else if(log_rotation_method==LOG_ROTATION_WEEKLY) strcpy(method_string,"WEEKLY"); else if(log_rotation_method==LOG_ROTATION_MONTHLY) strcpy(method_string,"MONTHLY"); else return ERROR; /* update the last log rotation time and status log */ last_log_rotation=time(NULL); update_program_status(FALSE); t=localtime(&rotation_time); /* get the archived filename to use */ snprintf(log_archive,sizeof(log_archive),"%s%snagios-%02d-%02d-%d-%02d.log",log_archive_path,(log_archive_path[strlen(log_archive_path)-1]=='/')?"":"/",t->tm_mon+1,t->tm_mday,t->tm_year+1900,t->tm_hour); log_archive[sizeof(log_archive)-1]='\x0'; /* rotate the log file */ rename_result=my_rename(log_file,log_archive); if(rename_result){ #ifdef DEBUG1 printf("\tError: Could not rotate main log file to '%s'\n",log_archive); #endif return ERROR; } #ifdef USE_EVENT_BROKER /* REMOVED - log rotation events are already handled by NEBTYPE_TIMEDEVENT_EXECUTE... */ /* send data to the event broker */ /* broker_log_data(NEBTYPE_LOG_ROTATION,NEBFLAG_NONE,NEBATTR_NONE,log_archive,log_rotation_method,0,NULL); */ #endif /* record the log rotation after it has been done... */ snprintf(temp_buffer,sizeof(temp_buffer),"LOG ROTATION: %s\n",method_string); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_all_logs_with_timestamp(temp_buffer,NSLOG_PROCESS_INFO,&rotation_time); /* record log file version format */ write_log_file_info(&rotation_time); /* log current host and service state */ log_host_states(CURRENT_STATES,&rotation_time); log_service_states(CURRENT_STATES,&rotation_time); #ifdef DEBUG3 printf("\tRotated main log file to '%s'\n",log_archive); #endif #ifdef DEBUG0 printf("rotate_log_file() end\n"); #endif return OK; } /* record log file version/info */ int write_log_file_info(time_t *timestamp){ char temp_buffer[MAX_INPUT_BUFFER]; #ifdef DEBUG0 printf("write_log_file_info() start\n"); #endif /* write log version */ snprintf(temp_buffer,sizeof(temp_buffer),"LOG VERSION: %s\n",LOG_VERSION_2); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_all_logs_with_timestamp(temp_buffer,NSLOG_PROCESS_INFO,timestamp); #ifdef DEBUG0 printf("write_log_file_info() end\n"); #endif return OK; } nagios-2.6/base/nagios.c0000664000076500007650000006347010532717360014553 0ustar nagiosnagios/***************************************************************************** * * NAGIOS.C - Core Program Code For Nagios * * Program: Nagios * Version: 2.6 * License: GPL * Copyright (c) 1999-2006 Ethan Galstad (http://www.nagios.org) * * First Written: 01-28-1999 (start of development) * Last Modified: 11-27-2006 * * Description: * * Nagios is a network monitoring tool that will check hosts and services * that you specify. It has the ability to notify contacts via email, pager, * or other user-defined methods when a service or host goes down and * recovers. Service and host monitoring is done through the use of external * plugins which can be developed independently of Nagios. * * 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. * *****************************************************************************/ #include "../include/config.h" #include "../include/common.h" #include "../include/objects.h" #include "../include/comments.h" #include "../include/downtime.h" #include "../include/statusdata.h" #include "../include/nagios.h" #include "../include/sretention.h" #include "../include/perfdata.h" #include "../include/broker.h" #include "../include/nebmods.h" #include "../include/nebmodules.h" char *config_file=NULL; char *log_file=NULL; char *command_file=NULL; char *temp_file=NULL; char *lock_file=NULL; char *log_archive_path=NULL; char *p1_file=NULL; /**** EMBEDDED PERL ****/ char *auth_file=NULL; /**** EMBEDDED PERL INTERPRETER AUTH FILE ****/ char *nagios_user=NULL; char *nagios_group=NULL; char *macro_x[MACRO_X_COUNT]; char *macro_x_names[MACRO_X_COUNT]; char *macro_argv[MAX_COMMAND_ARGUMENTS]; char *macro_user[MAX_USER_MACROS]; char *macro_contactaddress[MAX_CONTACT_ADDRESSES]; char *macro_ondemand; char *global_host_event_handler=NULL; char *global_service_event_handler=NULL; char *ocsp_command=NULL; char *ochp_command=NULL; char *illegal_object_chars=NULL; char *illegal_output_chars=NULL; int use_regexp_matches=FALSE; int use_true_regexp_matching=FALSE; int use_syslog=DEFAULT_USE_SYSLOG; int log_notifications=DEFAULT_NOTIFICATION_LOGGING; int log_service_retries=DEFAULT_LOG_SERVICE_RETRIES; int log_host_retries=DEFAULT_LOG_HOST_RETRIES; int log_event_handlers=DEFAULT_LOG_EVENT_HANDLERS; int log_initial_states=DEFAULT_LOG_INITIAL_STATES; int log_external_commands=DEFAULT_LOG_EXTERNAL_COMMANDS; int log_passive_checks=DEFAULT_LOG_PASSIVE_CHECKS; unsigned long logging_options=0; unsigned long syslog_options=0; int service_check_timeout=DEFAULT_SERVICE_CHECK_TIMEOUT; int host_check_timeout=DEFAULT_HOST_CHECK_TIMEOUT; int event_handler_timeout=DEFAULT_EVENT_HANDLER_TIMEOUT; int notification_timeout=DEFAULT_NOTIFICATION_TIMEOUT; int ocsp_timeout=DEFAULT_OCSP_TIMEOUT; int ochp_timeout=DEFAULT_OCHP_TIMEOUT; double sleep_time=DEFAULT_SLEEP_TIME; int interval_length=DEFAULT_INTERVAL_LENGTH; int service_inter_check_delay_method=ICD_SMART; int host_inter_check_delay_method=ICD_SMART; int service_interleave_factor_method=ILF_SMART; int max_host_check_spread=DEFAULT_HOST_CHECK_SPREAD; int max_service_check_spread=DEFAULT_SERVICE_CHECK_SPREAD; int command_check_interval=DEFAULT_COMMAND_CHECK_INTERVAL; int service_check_reaper_interval=DEFAULT_SERVICE_REAPER_INTERVAL; int max_check_reaper_time=DEFAULT_MAX_REAPER_TIME; int service_freshness_check_interval=DEFAULT_FRESHNESS_CHECK_INTERVAL; int host_freshness_check_interval=DEFAULT_FRESHNESS_CHECK_INTERVAL; int auto_rescheduling_interval=DEFAULT_AUTO_RESCHEDULING_INTERVAL; int non_parallelized_check_running=FALSE; int check_external_commands=DEFAULT_CHECK_EXTERNAL_COMMANDS; int check_orphaned_services=DEFAULT_CHECK_ORPHANED_SERVICES; int check_service_freshness=DEFAULT_CHECK_SERVICE_FRESHNESS; int check_host_freshness=DEFAULT_CHECK_HOST_FRESHNESS; int auto_reschedule_checks=DEFAULT_AUTO_RESCHEDULE_CHECKS; int auto_rescheduling_window=DEFAULT_AUTO_RESCHEDULING_WINDOW; time_t last_command_check=0L; time_t last_command_status_update=0L; time_t last_log_rotation=0L; int use_aggressive_host_checking=DEFAULT_AGGRESSIVE_HOST_CHECKING; int soft_state_dependencies=FALSE; int retain_state_information=FALSE; int retention_update_interval=DEFAULT_RETENTION_UPDATE_INTERVAL; int use_retained_program_state=TRUE; int use_retained_scheduling_info=FALSE; int retention_scheduling_horizon=DEFAULT_RETENTION_SCHEDULING_HORIZON; unsigned long modified_host_process_attributes=MODATTR_NONE; unsigned long modified_service_process_attributes=MODATTR_NONE; int log_rotation_method=LOG_ROTATION_NONE; int sigshutdown=FALSE; int sigrestart=FALSE; int restarting=FALSE; int verify_config=FALSE; int test_scheduling=FALSE; int daemon_mode=FALSE; int daemon_dumps_core=TRUE; int ipc_pipe[2]; int max_parallel_service_checks=DEFAULT_MAX_PARALLEL_SERVICE_CHECKS; int currently_running_service_checks=0; time_t program_start=0L; int nagios_pid=0; int enable_notifications=TRUE; int execute_service_checks=TRUE; int accept_passive_service_checks=TRUE; int execute_host_checks=TRUE; int accept_passive_host_checks=TRUE; int enable_event_handlers=TRUE; int obsess_over_services=FALSE; int obsess_over_hosts=FALSE; int enable_failure_prediction=TRUE; int aggregate_status_updates=TRUE; int status_update_interval=DEFAULT_STATUS_UPDATE_INTERVAL; int time_change_threshold=DEFAULT_TIME_CHANGE_THRESHOLD; unsigned long event_broker_options=BROKER_NOTHING; int process_performance_data=DEFAULT_PROCESS_PERFORMANCE_DATA; int enable_flap_detection=DEFAULT_ENABLE_FLAP_DETECTION; double low_service_flap_threshold=DEFAULT_LOW_SERVICE_FLAP_THRESHOLD; double high_service_flap_threshold=DEFAULT_HIGH_SERVICE_FLAP_THRESHOLD; double low_host_flap_threshold=DEFAULT_LOW_HOST_FLAP_THRESHOLD; double high_host_flap_threshold=DEFAULT_HIGH_HOST_FLAP_THRESHOLD; int date_format=DATE_FORMAT_US; int command_file_fd; FILE *command_file_fp; int command_file_created=FALSE; extern contact *contact_list; extern contactgroup *contactgroup_list; extern hostgroup *hostgroup_list; extern timed_event *event_list_high; extern timed_event *event_list_low; extern command *command_list; extern timeperiod *timeperiod_list; extern serviceescalation *serviceescalation_list; notification *notification_list; service_message svc_msg; circular_buffer external_command_buffer; circular_buffer service_result_buffer; pthread_t worker_threads[TOTAL_WORKER_THREADS]; /* Following main() declaration required by older versions of Perl ut 5.00503 */ #ifdef EMBEDDEDPERL int main(int argc, char **argv, char **env){ #else int main(int argc, char **argv){ #endif int result; int error=FALSE; char buffer[MAX_INPUT_BUFFER]; int display_license=FALSE; int display_help=FALSE; int c; #ifdef HAVE_GETOPT_H int option_index=0; static struct option long_options[]= { {"help",no_argument,0,'h'}, {"version",no_argument,0,'V'}, {"license",no_argument,0,'V'}, {"verify",no_argument,0,'v'}, {"daemon",no_argument,0,'d'}, {0,0,0,0} }; #endif /* make sure we have the correct number of command line arguments */ if(argc<2) error=TRUE; /* get all command line arguments */ while(1){ #ifdef HAVE_GETOPT_H c=getopt_long(argc,argv,"+hVvds",long_options,&option_index); #else c=getopt(argc,argv,"+hVvds"); #endif if(c==-1 || c==EOF) break; switch(c){ case '?': /* usage */ case 'h': display_help=TRUE; break; case 'V': /* version */ display_license=TRUE; break; case 'v': /* verify */ verify_config=TRUE; break; case 's': /* scheduling check */ test_scheduling=TRUE; break; case 'd': /* daemon mode */ daemon_mode=TRUE; break; default: break; } } if(daemon_mode==FALSE){ printf("\nNagios %s\n",PROGRAM_VERSION); printf("Copyright (c) 1999-2006 Ethan Galstad (http://www.nagios.org)\n"); printf("Last Modified: %s\n",PROGRAM_MODIFICATION_DATE); printf("License: GPL\n\n"); } /* just display the license */ if(display_license==TRUE){ printf("This program is free software; you can redistribute it and/or modify\n"); printf("it under the terms of the GNU General Public License version 2 as\n"); printf("published by the Free Software Foundation.\n\n"); printf("This program is distributed in the hope that it will be useful,\n"); printf("but WITHOUT ANY WARRANTY; without even the implied warranty of\n"); printf("MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"); printf("GNU General Public License for more details.\n\n"); printf("You should have received a copy of the GNU General Public License\n"); printf("along with this program; if not, write to the Free Software\n"); printf("Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\n\n"); exit(OK); } /* make sure we got the main config file on the command line... */ if(optind>=argc) error=TRUE; /* if there are no command line options (or if we encountered an error), print usage */ if(error==TRUE || display_help==TRUE){ printf("Usage: %s [option] \n",argv[0]); printf("\n"); printf("Options:\n"); printf("\n"); printf(" -v Reads all data in the configuration files and performs a basic\n"); printf(" verification/sanity check. Always make sure you verify your\n"); printf(" config data before (re)starting Nagios.\n"); printf("\n"); printf(" -s Shows projected/recommended check scheduling information based\n"); printf(" on the current data in the configuration files.\n"); printf("\n"); printf(" -d Starts Nagios in daemon mode (instead of as a foreground process).\n"); printf(" This is the recommended way of starting Nagios for normal operation.\n"); printf("\n"); printf("Visit the Nagios website at http://www.nagios.org for bug fixes, new\n"); printf("releases, online documentation, FAQs, information on subscribing to\n"); printf("the mailing lists, and commercial and contract support for Nagios.\n"); printf("\n"); exit(ERROR); } /* config file is last argument specified */ config_file=(char *)strdup(argv[optind]); if(config_file==NULL){ printf("Error allocating memory.\n"); exit(ERROR); } /* make sure the config file uses an absolute path */ if(config_file[0]!='/'){ /* save the name of the config file */ strncpy(buffer,config_file,sizeof(buffer)); buffer[sizeof(buffer)-1]='\x0'; /* reallocate a larger chunk of memory */ config_file=(char *)realloc(config_file,MAX_FILENAME_LENGTH); if(config_file==NULL){ printf("Error allocating memory.\n"); exit(ERROR); } /* get absolute path of current working directory */ getcwd(config_file,MAX_FILENAME_LENGTH); /* append a forward slash */ strncat(config_file,"/",MAX_FILENAME_LENGTH-2); config_file[MAX_FILENAME_LENGTH-1]='\x0'; /* append the config file to the path */ strncat(config_file,buffer,MAX_FILENAME_LENGTH-strlen(config_file)-1); config_file[MAX_FILENAME_LENGTH-1]='\x0'; } /* we're just verifying the configuration... */ if(verify_config==TRUE){ /* reset program variables */ reset_variables(); printf("Reading configuration data...\n\n"); /* read in the configuration files (main config file, resource and object config files) */ if((result=read_main_config_file(config_file))==OK){ /* drop privileges */ if((result=drop_privileges(nagios_user,nagios_group))==ERROR) printf("Failed to drop privileges. Aborting."); else /* read object config files */ result=read_all_object_data(config_file); } /* there was a problem reading the config files */ if(result!=OK){ /* if the config filename looks fishy, warn the user */ if(!strstr(config_file,"nagios.cfg")){ printf("\n***> The name of the main configuration file looks suspicious...\n"); printf("\n"); printf(" Make sure you are specifying the name of the MAIN configuration file on\n"); printf(" the command line and not the name of another configuration file. The\n"); printf(" main configuration file is typically '/usr/local/nagios/etc/nagios.cfg'\n"); } printf("\n***> One or more problems was encountered while processing the config files...\n"); printf("\n"); printf(" Check your configuration file(s) to ensure that they contain valid\n"); printf(" directives and data defintions. If you are upgrading from a previous\n"); printf(" version of Nagios, you should be aware that some variables/definitions\n"); printf(" may have been removed or modified in this version. Make sure to read\n"); printf(" the HTML documentation regarding the config files, as well as the\n"); printf(" 'Whats New' section to find out what has changed.\n\n"); } /* the config files were okay, so run the pre-flight check */ else{ printf("Running pre-flight check on configuration data...\n\n"); /* run the pre-flight check to make sure things look okay... */ result=pre_flight_check(); if(result==OK) printf("\nThings look okay - No serious problems were detected during the pre-flight check\n"); else{ printf("\n***> One or more problems was encountered while running the pre-flight check...\n"); printf("\n"); printf(" Check your configuration file(s) to ensure that they contain valid\n"); printf(" directives and data defintions. If you are upgrading from a previous\n"); printf(" version of Nagios, you should be aware that some variables/definitions\n"); printf(" may have been removed or modified in this version. Make sure to read\n"); printf(" the HTML documentation regarding the config files, as well as the\n"); printf(" 'Whats New' section to find out what has changed.\n\n"); } } /* clean up after ourselves */ cleanup(); /* free config_file */ free(config_file); /* exit */ exit(result); } /* we're just testing scheduling... */ else if(test_scheduling==TRUE){ /* reset program variables */ reset_variables(); /* read in the configuration files (main config file and all host config files) */ if((result=read_main_config_file(config_file))==OK){ /* drop privileges */ if((result=drop_privileges(nagios_user,nagios_group))==ERROR) printf("Failed to drop privileges. Aborting."); else /* read object config files */ result=read_all_object_data(config_file); } if(result!=OK) printf("***> One or more problems was encountered while reading configuration data...\n"); /* run the pre-flight check to make sure everything looks okay */ else if((result=pre_flight_check())!=OK) printf("***> One or more problems was encountered while running the pre-flight check...\n"); if(result==OK){ /* initialize the event timing loop */ init_timing_loop(); /* display scheduling information */ display_scheduling_info(); } /* clean up after ourselves */ cleanup(); /* exit */ exit(result); } /* else start to monitor things... */ else{ /* keep monitoring things until we get a shutdown command */ do{ /* reset program variables */ reset_variables(); /* get program (re)start time and save as macro */ program_start=time(NULL); if(macro_x[MACRO_PROCESSSTARTTIME]!=NULL) free(macro_x[MACRO_PROCESSSTARTTIME]); macro_x[MACRO_PROCESSSTARTTIME]=(char *)malloc(MAX_DATETIME_LENGTH); if(macro_x[MACRO_PROCESSSTARTTIME]!=NULL){ snprintf(macro_x[MACRO_PROCESSSTARTTIME],MAX_DATETIME_LENGTH,"%lu",(unsigned long)program_start); macro_x[MACRO_PROCESSSTARTTIME][MAX_DATETIME_LENGTH-1]='\x0'; } /* get PID */ nagios_pid=(int)getpid(); /* read in the configuration files (main and resource config files) */ result=read_main_config_file(config_file); /* drop privileges */ if(drop_privileges(nagios_user,nagios_group)==ERROR){ snprintf(buffer,sizeof(buffer),"Failed to drop privileges. Aborting."); buffer[sizeof(buffer)-1]='\x0'; write_to_logs_and_console(buffer,NSLOG_PROCESS_INFO | NSLOG_RUNTIME_ERROR | NSLOG_CONFIG_ERROR,TRUE); cleanup(); exit(ERROR); } #ifdef USE_EVENT_BROKER /* initialize modules */ neb_init_modules(); neb_init_callback_list(); #endif /* this must be logged after we read config data, as user may have changed location of main log file */ snprintf(buffer,sizeof(buffer),"Nagios %s starting... (PID=%d)\n",PROGRAM_VERSION,(int)getpid()); buffer[sizeof(buffer)-1]='\x0'; write_to_logs_and_console(buffer,NSLOG_PROCESS_INFO,TRUE); /* write log version/info */ write_log_file_info(NULL); #ifdef USE_EVENT_BROKER /* load modules */ neb_load_all_modules(); /* send program data to broker */ broker_program_state(NEBTYPE_PROCESS_PRELAUNCH,NEBFLAG_NONE,NEBATTR_NONE,NULL); #endif /* read in all object config data */ if(result==OK) result=read_all_object_data(config_file); /* there was a problem reading the config files */ if(result!=OK){ snprintf(buffer,sizeof(buffer),"Bailing out due to one or more errors encountered in the configuration files. Run Nagios from the command line with the -v option to verify your config before restarting. (PID=%d)\n",(int)getpid()); buffer[sizeof(buffer)-1]='\x0'; write_to_logs_and_console(buffer,NSLOG_PROCESS_INFO | NSLOG_RUNTIME_ERROR | NSLOG_CONFIG_ERROR,TRUE); /* close and delete the external command file if we were restarting */ if(sigrestart==TRUE) close_command_file(); #ifdef USE_EVENT_BROKER /* send program data to broker */ broker_program_state(NEBTYPE_PROCESS_SHUTDOWN,NEBFLAG_PROCESS_INITIATED,NEBATTR_SHUTDOWN_ABNORMAL,NULL); #endif cleanup(); exit(ERROR); } /* run the pre-flight check to make sure everything looks okay*/ result=pre_flight_check(); /* there was a problem running the pre-flight check */ if(result!=OK){ snprintf(buffer,sizeof(buffer),"Bailing out due to errors encountered while running the pre-flight check. Run Nagios from the command line with the -v option to verify your config before restarting. (PID=%d)\n",(int)getpid()); buffer[sizeof(buffer)-1]='\x0'; write_to_logs_and_console(buffer,NSLOG_PROCESS_INFO | NSLOG_RUNTIME_ERROR | NSLOG_VERIFICATION_ERROR ,TRUE); /* close and delete the external command file if we were restarting */ if(sigrestart==TRUE) close_command_file(); #ifdef USE_EVENT_BROKER /* send program data to broker */ broker_program_state(NEBTYPE_PROCESS_SHUTDOWN,NEBFLAG_PROCESS_INITIATED,NEBATTR_SHUTDOWN_ABNORMAL,NULL); #endif cleanup(); exit(ERROR); } /* initialize embedded Perl interpreter */ if(sigrestart==FALSE){ #ifdef EMBEDDEDPERL init_embedded_perl(env); #else init_embedded_perl(NULL); #endif } /* handle signals (interrupts) */ setup_sighandler(); #ifdef USE_EVENT_BROKER /* send program data to broker */ broker_program_state(NEBTYPE_PROCESS_START,NEBFLAG_NONE,NEBATTR_NONE,NULL); #endif /* enter daemon mode (unless we're restarting...) */ if(daemon_mode==TRUE && sigrestart==FALSE){ #if (defined DEBUG0 || defined DEBUG1 || defined DEBUG2 || defined DEBUG3 || defined DEBUG4 || defined DEBUG5) printf("$0: Cannot enter daemon mode with DEBUG option(s) enabled. We'll run as a foreground process instead...\n"); daemon_mode=FALSE; #else daemon_init(); snprintf(buffer,sizeof(buffer),"Finished daemonizing... (New PID=%d)\n",(int)getpid()); buffer[sizeof(buffer)-1]='\x0'; write_to_all_logs(buffer,NSLOG_PROCESS_INFO); /* get new PID */ nagios_pid=(int)getpid(); #endif } /* open the command file (named pipe) for reading */ result=open_command_file(); if(result!=OK){ snprintf(buffer,sizeof(buffer),"Bailing out due to errors encountered while trying to initialize the external command file... (PID=%d)\n",(int)getpid()); buffer[sizeof(buffer)-1]='\x0'; write_to_logs_and_console(buffer,NSLOG_PROCESS_INFO | NSLOG_RUNTIME_ERROR ,TRUE); #ifdef USE_EVENT_BROKER /* send program data to broker */ broker_program_state(NEBTYPE_PROCESS_SHUTDOWN,NEBFLAG_PROCESS_INITIATED,NEBATTR_SHUTDOWN_ABNORMAL,NULL); #endif cleanup(); exit(ERROR); } /* initialize status data */ initialize_status_data(config_file); /* initialize comment data */ initialize_comment_data(config_file); /* initialize scheduled downtime data */ initialize_downtime_data(config_file); /* initialize performance data */ initialize_performance_data(config_file); /* read initial service and host state information */ read_initial_state_information(config_file); /* initialize the event timing loop */ init_timing_loop(); /* update all status data (with retained information) */ update_all_status_data(); /* log initial host and service state */ log_host_states(INITIAL_STATES,NULL); log_service_states(INITIAL_STATES,NULL); /* create pipe used for service check IPC */ if(pipe(ipc_pipe)){ snprintf(buffer,sizeof(buffer),"Error: Could not initialize service check IPC pipe...\n"); buffer[sizeof(buffer)-1]='\x0'; write_to_logs_and_console(buffer,NSLOG_PROCESS_INFO | NSLOG_RUNTIME_ERROR,TRUE); #ifdef USE_EVENT_BROKER /* send program data to broker */ broker_program_state(NEBTYPE_PROCESS_SHUTDOWN,NEBFLAG_PROCESS_INITIATED,NEBATTR_SHUTDOWN_ABNORMAL,NULL); #endif cleanup(); exit(ERROR); } /* read end of the pipe should be non-blocking */ fcntl(ipc_pipe[0],F_SETFL,O_NONBLOCK); /* initialize service result worker threads */ result=init_service_result_worker_thread(); if(result!=OK){ snprintf(buffer,sizeof(buffer),"Bailing out due to errors encountered while trying to initialize service result worker thread... (PID=%d)\n",(int)getpid()); buffer[sizeof(buffer)-1]='\x0'; write_to_logs_and_console(buffer,NSLOG_PROCESS_INFO | NSLOG_RUNTIME_ERROR ,TRUE); #ifdef USE_EVENT_BROKER /* send program data to broker */ broker_program_state(NEBTYPE_PROCESS_SHUTDOWN,NEBFLAG_PROCESS_INITIATED,NEBATTR_SHUTDOWN_ABNORMAL,NULL); #endif cleanup(); exit(ERROR); } /* reset the restart flag */ sigrestart=FALSE; #ifdef USE_EVENT_BROKER /* send program data to broker */ broker_program_state(NEBTYPE_PROCESS_EVENTLOOPSTART,NEBFLAG_NONE,NEBATTR_NONE,NULL); #endif /***** start monitoring all services *****/ /* (doesn't return until a restart or shutdown signal is encountered) */ event_execution_loop(); #ifdef USE_EVENT_BROKER /* send program data to broker */ broker_program_state(NEBTYPE_PROCESS_EVENTLOOPEND,NEBFLAG_NONE,NEBATTR_NONE,NULL); if(sigshutdown==TRUE) broker_program_state(NEBTYPE_PROCESS_SHUTDOWN,NEBFLAG_USER_INITIATED,NEBATTR_SHUTDOWN_NORMAL,NULL); else if(sigrestart==TRUE) broker_program_state(NEBTYPE_PROCESS_RESTART,NEBFLAG_USER_INITIATED,NEBATTR_RESTART_NORMAL,NULL); #endif /* save service and host state information */ save_state_information(config_file,FALSE); /* clean up the status data */ cleanup_status_data(config_file,TRUE); /* clean up the comment data */ cleanup_comment_data(config_file); /* clean up the scheduled downtime data */ cleanup_downtime_data(config_file); /* clean up performance data */ cleanup_performance_data(config_file); /* close the original pipe used for IPC (we'll create a new one if restarting) */ close(ipc_pipe[0]); close(ipc_pipe[1]); /* close and delete the external command file FIFO unless we're restarting */ if(sigrestart==FALSE) close_command_file(); /* cleanup embedded perl interpreter */ if(sigrestart==FALSE) deinit_embedded_perl(); /* cleanup worker threads */ shutdown_service_result_worker_thread(); /* shutdown stuff... */ if(sigshutdown==TRUE){ /* make sure lock file has been removed - it may not have been if we received a shutdown command */ if(daemon_mode==TRUE) unlink(lock_file); /* log a shutdown message */ snprintf(buffer,sizeof(buffer),"Successfully shutdown... (PID=%d)\n",(int)getpid()); buffer[sizeof(buffer)-1]='\x0'; write_to_logs_and_console(buffer,NSLOG_PROCESS_INFO,TRUE); } /* clean up after ourselves */ cleanup(); }while(sigrestart==TRUE && sigshutdown==FALSE); /* free misc memory */ free(config_file); } return OK; } nagios-2.6/base/nagiostats.c0000664000076500007650000011167210532717361015446 0ustar nagiosnagios/***************************************************************************** * * NAGIOSTATS.C - Displays Nagios Statistics * * Program: Nagiostats * Version: 2.6 * License: GPL * Copyright (c) 2003-2006 Ethan Galstad (nagios@nagios.org) * * Last Modified: 11-27-2006 * * 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. * *****************************************************************************/ #include "../include/config.h" #include "../include/common.h" #include "../include/nagios.h" #include "../include/locations.h" #define STATUS_NO_DATA 0 #define STATUS_INFO_DATA 1 #define STATUS_PROGRAM_DATA 2 #define STATUS_HOST_DATA 3 #define STATUS_SERVICE_DATA 4 char main_config_file[MAX_INPUT_BUFFER]=DEFAULT_CONFIG_FILE; char status_file[MAX_INPUT_BUFFER]=DEFAULT_STATUS_FILE; char *mrtg_variables=NULL; int mrtg_mode=FALSE; time_t status_creation_date=0L; char *status_version=NULL; time_t program_start=0L; int status_service_entries=0; int status_host_entries=0; double min_service_state_change=0.0; int have_min_service_state_change=FALSE; double max_service_state_change=0.0; int have_max_service_state_change=FALSE; double average_service_state_change=0.0; double min_active_service_state_change=0.0; int have_min_active_service_state_change=FALSE; double max_active_service_state_change=0.0; int have_max_active_service_state_change=FALSE; double average_active_service_state_change=0.0; double min_active_service_latency=0.0; int have_min_active_service_latency=FALSE; double max_active_service_latency=0.0; int have_max_active_service_latency=FALSE; double average_active_service_latency=0.0; double min_active_service_execution_time=0.0; int have_min_active_service_execution_time=FALSE; double max_active_service_execution_time=0.0; int have_max_active_service_execution_time=FALSE; double average_active_service_execution_time=0.0; double min_passive_service_state_change=0.0; int have_min_passive_service_state_change=FALSE; double max_passive_service_state_change=0.0; int have_max_passive_service_state_change=FALSE; double average_passive_service_state_change=0.0; int have_min_host_state_change=FALSE; double min_host_state_change=0.0; int have_max_host_state_change=FALSE; double max_host_state_change=0.0; double average_host_state_change=0.0; int have_min_active_host_state_change=FALSE; double min_active_host_state_change=0.0; int have_max_active_host_state_change=FALSE; double max_active_host_state_change=0.0; double average_active_host_state_change=0.0; int have_min_active_host_latency=FALSE; double min_active_host_latency=0.0; int have_max_active_host_latency=FALSE; double max_active_host_latency=0.0; double average_active_host_latency=0.0; int have_min_active_host_execution_time=FALSE; double min_active_host_execution_time=0.0; int have_max_active_host_execution_time=FALSE; double max_active_host_execution_time=0.0; double average_active_host_execution_time=0.0; double min_passive_host_state_change=0.0; int have_min_passive_host_state_change=FALSE; double max_passive_host_state_change=0.0; int have_max_passive_host_state_change=FALSE; double average_passive_host_state_change=0.0; int passive_service_checks=0; int active_service_checks=0; int services_ok=0; int services_warning=0; int services_unknown=0; int services_critical=0; int services_flapping=0; int services_in_downtime=0; int services_checked=0; int services_scheduled=0; int passive_host_checks=0; int active_host_checks=0; int hosts_up=0; int hosts_down=0; int hosts_unreachable=0; int hosts_flapping=0; int hosts_in_downtime=0; int hosts_checked=0; int hosts_scheduled=0; int passive_services_checked_last_1min=0; int passive_services_checked_last_5min=0; int passive_services_checked_last_15min=0; int passive_services_checked_last_1hour=0; int active_services_checked_last_1min=0; int active_services_checked_last_5min=0; int active_services_checked_last_15min=0; int active_services_checked_last_1hour=0; int passive_hosts_checked_last_1min=0; int passive_hosts_checked_last_5min=0; int passive_hosts_checked_last_15min=0; int passive_hosts_checked_last_1hour=0; int active_hosts_checked_last_1min=0; int active_hosts_checked_last_5min=0; int active_hosts_checked_last_15min=0; int active_hosts_checked_last_1hour=0; int display_mrtg_values(void); int display_stats(void); int read_config_file(void); int read_status_file(void); void strip(char *); void get_time_breakdown(unsigned long,int *,int *,int *,int *); int main(int argc, char **argv){ int result; int error=FALSE; int display_license=FALSE; int display_help=FALSE; int c; #ifdef HAVE_GETOPT_H int option_index=0; static struct option long_options[]= { {"help",no_argument,0,'h'}, {"version",no_argument,0,'V'}, {"license",no_argument,0,'L'}, {"config",required_argument,0,'c'}, {"mrtg",no_argument,0,'m'}, {"data",required_argument,0,'d'}, {0,0,0,0} }; #endif /* get all command line arguments */ while(1){ #ifdef HAVE_GETOPT_H c=getopt_long(argc,argv,"+hVLc:md:",long_options,&option_index); #else c=getopt(argc,argv,"+hVLc:md:"); #endif if(c==-1 || c==EOF) break; switch(c){ case '?': case 'h': display_help=TRUE; break; case 'V': display_license=TRUE; break; case 'L': display_license=TRUE; break; case 'c': strncpy(main_config_file,optarg,sizeof(main_config_file)); main_config_file[sizeof(main_config_file)-1]='\x0'; break; case 'm': mrtg_mode=TRUE; break; case 'd': mrtg_variables=strdup(optarg); break; default: break; } } if(mrtg_mode==FALSE){ printf("\nNagios Stats %s\n",PROGRAM_VERSION); printf("Copyright (c) 2003-2005 Ethan Galstad (www.nagios.org)\n"); printf("Last Modified: %s\n",PROGRAM_MODIFICATION_DATE); printf("License: GPL\n\n"); } /* just display the license */ if(display_license==TRUE){ printf("This program is free software; you can redistribute it and/or modify\n"); printf("it under the terms of the GNU General Public License version 2 as\n"); printf("published by the Free Software Foundation.\n\n"); printf("This program is distributed in the hope that it will be useful,\n"); printf("but WITHOUT ANY WARRANTY; without even the implied warranty of\n"); printf("MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"); printf("GNU General Public License for more details.\n\n"); printf("You should have received a copy of the GNU General Public License\n"); printf("along with this program; if not, write to the Free Software\n"); printf("Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\n\n"); exit(OK); } /* if there are no command line options (or if we encountered an error), print usage */ if(error==TRUE || display_help==TRUE){ printf("Usage: %s [options]\n",argv[0]); printf("\n"); printf("Startup:\n"); printf(" -V, --version display program version information and exit.\n"); printf(" -L, --license display license information and exit.\n"); printf(" -h, --help display usage information and exit.\n"); printf("\n"); printf("Input file:\n"); printf(" -c, --config=FILE specifies location of main Nagios config file.\n"); printf("\n"); printf("Output:\n"); printf(" -m, --mrtg display output in MRTG compatible format.\n"); printf(" -d, --data=VARS comma-seperated list of variables to output in MRTG\n"); printf(" (or compatible) format. See possible values below.\n"); printf(" Percentages are rounded, times are in milliseconds.\n"); printf("\n"); printf("MRTG DATA VARIABLES (-d option):\n"); printf(" NUMSERVICES total number of services.\n"); printf(" NUMHOSTS total number of hosts.\n"); printf(" NUMSVCOK number of services OK.\n"); printf(" NUMSVCWARN number of services WARNING.\n"); printf(" NUMSVCUNKN number of services UNKNOWN.\n"); printf(" NUMSVCCRIT number of services CRITICAL.\n"); printf(" NUMSVCPROB number of service problems (WARNING, UNKNOWN or CRITIAL).\n"); printf(" NUMSVCCHECKED number of services that have been checked since start.\n"); printf(" NUMSVCSCHEDULED number of services that are currently scheduled to be checked.\n"); printf(" NUMSVCFLAPPING number of services that are currently flapping.\n"); printf(" NUMSVCDOWNTIME number of services that are currently in downtime.\n"); printf(" NUMHSTUP number of hosts UP.\n"); printf(" NUMHSTDOWN number of hosts DOWN.\n"); printf(" NUMHSTUNR number of hosts UNREACHABLE.\n"); printf(" NUMHSTPROB number of host problems (DOWN or UNREACHABLE).\n"); printf(" NUMHSTCHECKED number of hosts that have been checked since start.\n"); printf(" NUMHSTSCHEDULED number of hosts that are currently scheduled to be checked.\n"); printf(" NUMHSTFLAPPING number of hosts that are currently flapping.\n"); printf(" NUMHSTDOWNTIME number of hosts that are currently in downtime.\n"); printf(" xxxACTSVCLAT MIN/MAX/AVG active service check latency (ms).\n"); printf(" xxxACTSVCEXT MIN/MAX/AVG active service check execution time (ms).\n"); printf(" xxxACTSVCPSC MIN/MAX/AVG active service check %% state change.\n"); printf(" xxxPSVSVCPSC MIN/MAX/AVG passive service check %% state change.\n"); printf(" xxxSVCPSC MIN/MAX/AVG service check %% state change.\n"); printf(" xxxACTHSTLAT MIN/MAX/AVG active host check latency (ms).\n"); printf(" xxxACTHSTEXT MIN/MAX/AVG active host check execution time (ms).\n"); printf(" xxxACTHSTPSC MIN/MAX/AVG active host check %% state change.\n"); printf(" xxxPSVHSTPSC MIN/MAX/AVG passive host check %% state change.\n"); printf(" xxxHSTPSC MIN/MAX/AVG host check %% state change.\n"); printf(" NUMACTHSTCHKxM number of active host checks in last 1/5/15/60 minutes.\n"); printf(" NUMPSVHSTCHKxM number of passive host checks in last 1/5/15/60 minutes.\n"); printf(" NUMACTSVCCHKxM number of active service checks in last 1/5/15/60 minutes.\n"); printf(" NUMPSVSVCCHKxM number of passive service checks in last 1/5/15/60 minutes.\n"); printf("\n"); printf(" Note: Replace x's in MRTG variable names with 'MIN', 'MAX', 'AVG', or the\n"); printf(" the appropriate number (i.e. '1', '5', '15', or '60').\n"); printf("\n"); exit(ERROR); } /* read main config file */ result=read_config_file(); if(result==ERROR && mrtg_mode==FALSE){ printf("Error processing config file '%s'\n",main_config_file); return ERROR; } /* read the status file */ result=read_status_file(); if(result==ERROR && mrtg_mode==FALSE){ printf("Error reading status file '%s'\n",status_file); return ERROR; } /* display stats */ if(mrtg_mode==FALSE) display_stats(); else display_mrtg_values(); return OK; } int display_mrtg_values(void){ char *temp_ptr; /* process all variables */ for(temp_ptr=strtok(mrtg_variables,",");temp_ptr!=NULL;temp_ptr=strtok(NULL,",")){ if(!strcmp(temp_ptr,"NUMSERVICES")) printf("%d\n",status_service_entries); else if(!strcmp(temp_ptr,"NUMHOSTS")) printf("%d\n",status_host_entries); /* active service check latency */ else if(!strcmp(temp_ptr,"MINACTSVCLAT")) printf("%d\n",(int)(min_active_service_latency*1000)); else if(!strcmp(temp_ptr,"MAXACTSVCLAT")) printf("%d\n",(int)(max_active_service_latency*1000)); else if(!strcmp(temp_ptr,"AVGACTSVCLAT")) printf("%d\n",(int)(average_active_service_latency*1000)); /* active service check execution time */ else if(!strcmp(temp_ptr,"MINACTSVCEXT")) printf("%d\n",(int)(min_active_service_execution_time*1000)); else if(!strcmp(temp_ptr,"MAXACTSVCEXT")) printf("%d\n",(int)(max_active_service_execution_time*1000)); else if(!strcmp(temp_ptr,"AVGACTSVCEXT")) printf("%d\n",(int)(average_active_service_execution_time*1000)); /* active service check percent state change */ else if(!strcmp(temp_ptr,"MINACTSVCPSC")) printf("%d\n",(int)min_active_service_state_change); else if(!strcmp(temp_ptr,"MAXACTSVCPSC")) printf("%d\n",(int)max_active_service_state_change); else if(!strcmp(temp_ptr,"AVGACTSVCPSC")) printf("%d\n",(int)average_active_service_state_change); /* passive service check percent state change */ else if(!strcmp(temp_ptr,"MINPSVSVCPSC")) printf("%d\n",(int)min_passive_service_state_change); else if(!strcmp(temp_ptr,"MAXPSVSVCPSC")) printf("%d\n",(int)max_passive_service_state_change); else if(!strcmp(temp_ptr,"AVGPSVSVCPSC")) printf("%d\n",(int)average_passive_service_state_change); /* service check percent state change */ else if(!strcmp(temp_ptr,"MINSVCPSC")) printf("%d\n",(int)min_service_state_change); else if(!strcmp(temp_ptr,"MAXSVCPSC")) printf("%d\n",(int)max_service_state_change); else if(!strcmp(temp_ptr,"AVGSVCPSC")) printf("%d\n",(int)average_service_state_change); /* active host check latency */ else if(!strcmp(temp_ptr,"MINACTHSTLAT")) printf("%d\n",(int)(min_active_host_latency*1000)); else if(!strcmp(temp_ptr,"MAXACTHSTLAT")) printf("%d\n",(int)(max_active_host_latency*1000)); else if(!strcmp(temp_ptr,"AVGACTHSTLAT")) printf("%d\n",(int)(average_active_host_latency*1000)); /* active host check execution time */ else if(!strcmp(temp_ptr,"MINACTHSTEXT")) printf("%d\n",(int)(min_active_host_execution_time*1000)); else if(!strcmp(temp_ptr,"MAXACTHSTEXT")) printf("%d\n",(int)(max_active_host_execution_time*1000)); else if(!strcmp(temp_ptr,"AVGACTHSTEXT")) printf("%d\n",(int)(average_active_host_execution_time*1000)); /* active host check percent state change */ else if(!strcmp(temp_ptr,"MINACTHSTPSC")) printf("%d\n",(int)min_active_host_state_change); else if(!strcmp(temp_ptr,"MAXACTHSTPSC")) printf("%d\n",(int)max_active_host_state_change); else if(!strcmp(temp_ptr,"AVGACTHSTPSC")) printf("%d\n",(int)average_active_host_state_change); /* passive host check percent state change */ else if(!strcmp(temp_ptr,"MINPSVHSTPSC")) printf("%d\n",(int)min_passive_host_state_change); else if(!strcmp(temp_ptr,"MAXPSVHSTPSC")) printf("%d\n",(int)max_passive_host_state_change); else if(!strcmp(temp_ptr,"AVGPSVHSTPSC")) printf("%d\n",(int)average_passive_host_state_change); /* host check percent state change */ else if(!strcmp(temp_ptr,"MINHSTPSC")) printf("%d\n",(int)min_host_state_change); else if(!strcmp(temp_ptr,"MAXHSTPSC")) printf("%d\n",(int)max_host_state_change); else if(!strcmp(temp_ptr,"AVGHSTPSC")) printf("%d\n",(int)average_host_state_change); /* active host checks over time */ else if(!strcmp(temp_ptr,"NUMACTHSTCHK1M")) printf("%d\n",active_hosts_checked_last_1min); else if(!strcmp(temp_ptr,"NUMACTHSTCHK5M")) printf("%d\n",active_hosts_checked_last_5min); else if(!strcmp(temp_ptr,"NUMACTHSTCHK15M")) printf("%d\n",active_hosts_checked_last_15min); else if(!strcmp(temp_ptr,"NUMACTHSTCHK60M")) printf("%d\n",active_hosts_checked_last_1hour); /* passive host checks over time */ else if(!strcmp(temp_ptr,"NUMPSVHSTCHK1M")) printf("%d\n",passive_hosts_checked_last_1min); else if(!strcmp(temp_ptr,"NUMPSVHSTCHK5M")) printf("%d\n",passive_hosts_checked_last_5min); else if(!strcmp(temp_ptr,"NUMPSVHSTCHK15M")) printf("%d\n",passive_hosts_checked_last_15min); else if(!strcmp(temp_ptr,"NUMPSVHSTCHK60M")) printf("%d\n",passive_hosts_checked_last_1hour); /* active service checks over time */ else if(!strcmp(temp_ptr,"NUMACTSVCCHK1M")) printf("%d\n",active_services_checked_last_1min); else if(!strcmp(temp_ptr,"NUMACTSVCCHK5M")) printf("%d\n",active_services_checked_last_5min); else if(!strcmp(temp_ptr,"NUMACTSVCCHK15M")) printf("%d\n",active_services_checked_last_15min); else if(!strcmp(temp_ptr,"NUMACTSVCCHK60M")) printf("%d\n",active_services_checked_last_1hour); /* passive service checks over time */ else if(!strcmp(temp_ptr,"NUMPSVSVCCHK1M")) printf("%d\n",passive_services_checked_last_1min); else if(!strcmp(temp_ptr,"NUMPSVSVCCHK5M")) printf("%d\n",passive_services_checked_last_5min); else if(!strcmp(temp_ptr,"NUMPSVSVCCHK15M")) printf("%d\n",passive_services_checked_last_15min); else if(!strcmp(temp_ptr,"NUMPSVSVCCHK60M")) printf("%d\n",passive_services_checked_last_1hour); /* service states */ else if(!strcmp(temp_ptr,"NUMSVCOK")) printf("%d\n",services_ok); else if(!strcmp(temp_ptr,"NUMSVCWARN")) printf("%d\n",services_warning); else if(!strcmp(temp_ptr,"NUMSVCUNKN")) printf("%d\n",services_unknown); else if(!strcmp(temp_ptr,"NUMSVCCRIT")) printf("%d\n",services_critical); else if(!strcmp(temp_ptr,"NUMSVCPROB")) printf("%d\n",services_warning+services_unknown+services_critical); /* misc service info */ else if(!strcmp(temp_ptr,"NUMSVCCHECKED")) printf("%d\n",services_checked); else if(!strcmp(temp_ptr,"NUMSVCSCHEDULED")) printf("%d\n",services_scheduled); else if(!strcmp(temp_ptr,"NUMSVCFLAPPING")) printf("%d\n",services_flapping); else if(!strcmp(temp_ptr,"NUMSVCDOWNTIME")) printf("%d\n",services_in_downtime); /* host states */ else if(!strcmp(temp_ptr,"NUMHSTUP")) printf("%d\n",hosts_up); else if(!strcmp(temp_ptr,"NUMHSTDOWN")) printf("%d\n",hosts_down); else if(!strcmp(temp_ptr,"NUMHSTUNR")) printf("%d\n",hosts_unreachable); else if(!strcmp(temp_ptr,"NUMHSTPROB")) printf("%d\n",hosts_down+hosts_unreachable); /* misc host info */ else if(!strcmp(temp_ptr,"NUMHSTCHECKED")) printf("%d\n",hosts_checked); else if(!strcmp(temp_ptr,"NUMHSTSCHEDULED")) printf("%d\n",hosts_scheduled); else if(!strcmp(temp_ptr,"NUMHSTFLAPPING")) printf("%d\n",hosts_flapping); else if(!strcmp(temp_ptr,"NUMHSTDOWNTIME")) printf("%d\n",hosts_in_downtime); else printf("%s\n",temp_ptr); } return OK; } int display_stats(void){ time_t current_time; unsigned long time_difference; int days; int hours; int minutes; int seconds; time(¤t_time); printf("CURRENT STATUS DATA\n"); printf("----------------------------------------------------\n"); printf("Status File: %s\n",status_file); time_difference=(current_time-status_creation_date); get_time_breakdown(time_difference,&days,&hours,&minutes,&seconds); printf("Status File Age: %dd %dh %dm %ds\n",days,hours,minutes,seconds); printf("Status File Version: %s\n",status_version); printf("\n"); time_difference=(current_time-program_start); get_time_breakdown(time_difference,&days,&hours,&minutes,&seconds); printf("Program Running Time: %dd %dh %dm %ds\n",days,hours,minutes,seconds); printf("\n"); printf("Total Services: %d\n",status_service_entries); printf("Services Checked: %d\n",services_checked); printf("Services Scheduled: %d\n",services_scheduled); printf("Active Service Checks: %d\n",active_service_checks); printf("Passive Service Checks: %d\n",passive_service_checks); printf("Total Service State Change: %.3f / %.3f / %.3f %%\n",min_service_state_change,max_service_state_change,average_service_state_change); printf("Active Service Latency: %.3f / %.3f / %.3f sec\n",min_active_service_latency,max_active_service_latency,average_active_service_latency); printf("Active Service Execution Time: %.3f / %.3f / %.3f sec\n",min_active_service_execution_time,max_active_service_execution_time,average_active_service_execution_time); printf("Active Service State Change: %.3f / %.3f / %.3f %%\n",min_active_service_state_change,max_active_service_state_change,average_active_service_state_change); printf("Active Services Last 1/5/15/60 min: %d / %d / %d / %d\n",active_services_checked_last_1min,active_services_checked_last_5min,active_services_checked_last_15min,active_services_checked_last_1hour); printf("Passive Service State Change: %.3f / %.3f / %.3f %%\n",min_passive_service_state_change,max_passive_service_state_change,average_passive_service_state_change); printf("Passive Services Last 1/5/15/60 min: %d / %d / %d / %d\n",passive_services_checked_last_1min,passive_services_checked_last_5min,passive_services_checked_last_15min,passive_services_checked_last_1hour); printf("Services Ok/Warn/Unk/Crit: %d / %d / %d / %d\n",services_ok,services_warning,services_unknown,services_critical); printf("Services Flapping: %d\n",services_flapping); printf("Services In Downtime: %d\n",services_in_downtime); printf("\n"); printf("Total Hosts: %d\n",status_host_entries); printf("Hosts Checked: %d\n",hosts_checked); printf("Hosts Scheduled: %d\n",hosts_scheduled); printf("Active Host Checks: %d\n",active_host_checks); printf("Passive Host Checks: %d\n",passive_host_checks); printf("Total Host State Change: %.3f / %.3f / %.3f %%\n",min_host_state_change,max_host_state_change,average_host_state_change); printf("Active Host Latency: %.3f / %.3f / %.3f sec\n",min_active_host_latency,max_active_host_latency,average_active_host_latency); printf("Active Host Execution Time: %.3f / %.3f / %.3f sec\n",min_active_host_execution_time,max_active_host_execution_time,average_active_host_execution_time); printf("Active Host State Change: %.3f / %.3f / %.3f %%\n",min_active_host_state_change,max_active_host_state_change,average_active_host_state_change); printf("Active Hosts Last 1/5/15/60 min: %d / %d / %d / %d\n",active_hosts_checked_last_1min,active_hosts_checked_last_5min,active_hosts_checked_last_15min,active_hosts_checked_last_1hour); printf("Passive Host State Change: %.3f / %.3f / %.3f %%\n",min_passive_host_state_change,max_passive_host_state_change,average_passive_host_state_change); printf("Passive Hosts Last 1/5/15/60 min: %d / %d / %d / %d\n",passive_hosts_checked_last_1min,passive_hosts_checked_last_5min,passive_hosts_checked_last_15min,passive_hosts_checked_last_1hour); printf("Hosts Up/Down/Unreach: %d / %d / %d\n",hosts_up,hosts_down,hosts_unreachable); printf("Hosts Flapping: %d\n",hosts_flapping); printf("Hosts In Downtime: %d\n",hosts_in_downtime); printf("\n"); printf("\n"); /* printf("CURRENT COMMENT DATA\n"); printf("----------------------------------------------------\n"); printf("\n"); printf("\n"); printf("CURRENT DOWNTIME DATA\n"); printf("----------------------------------------------------\n"); printf("\n"); */ return OK; } int read_config_file(void){ char temp_buffer[MAX_INPUT_BUFFER]; FILE *fp; char *var; char *val; fp=fopen(main_config_file,"r"); if(fp==NULL) return ERROR; /* read all lines in the status file */ while(fgets(temp_buffer,sizeof(temp_buffer)-1,fp)){ strip(temp_buffer); /* skip blank lines and comments */ if(temp_buffer[0]=='#' || temp_buffer[0]=='\x0') continue; var=strtok(temp_buffer,"="); val=strtok(NULL,"\n"); if(val==NULL) continue; if(!strcmp(var,"status_file") || !strcmp(var,"status_log") || !strcmp(var,"xsddefault_status_log")){ strncpy(status_file,val,sizeof(status_file)); status_file[sizeof(status_file)-1]='\x0'; } } fclose(fp); return OK; } int read_status_file(void){ char temp_buffer[MAX_INPUT_BUFFER]; FILE *fp; int data_type=STATUS_NO_DATA; char *var; char *val; time_t current_time; unsigned long time_difference; double execution_time=0.0; double latency=0.0; int check_type=SERVICE_CHECK_ACTIVE; int current_state=STATE_OK; double state_change=0.0; int is_flapping=FALSE; int downtime_depth=0; time_t last_check=0L; int should_be_scheduled=TRUE; int has_been_checked=TRUE; time(¤t_time); fp=fopen(status_file,"r"); if(fp==NULL) return ERROR; /* read all lines in the status file */ while(fgets(temp_buffer,sizeof(temp_buffer)-1,fp)){ strip(temp_buffer); /* skip blank lines and comments */ if(temp_buffer[0]=='#' || temp_buffer[0]=='\x0') continue; else if(!strcmp(temp_buffer,"info {")) data_type=STATUS_INFO_DATA; else if(!strcmp(temp_buffer,"program {")) data_type=STATUS_PROGRAM_DATA; else if(!strcmp(temp_buffer,"host {")){ data_type=STATUS_HOST_DATA; status_host_entries++; } else if(!strcmp(temp_buffer,"service {")){ data_type=STATUS_SERVICE_DATA; status_service_entries++; } else if(!strcmp(temp_buffer,"}")){ switch(data_type){ case STATUS_INFO_DATA: break; case STATUS_PROGRAM_DATA: break; case STATUS_HOST_DATA: average_host_state_change=(((average_host_state_change*((double)status_host_entries-1.0))+state_change)/(double)status_host_entries); if(have_min_host_state_change==FALSE || min_host_state_change>state_change){ have_min_host_state_change=TRUE; min_host_state_change=state_change; } if(have_max_host_state_change==FALSE || max_host_state_changelatency){ have_min_active_host_latency=TRUE; min_active_host_latency=latency; } if(have_max_active_host_latency==FALSE || max_active_host_latencyexecution_time){ have_min_active_host_execution_time=TRUE; min_active_host_execution_time=execution_time; } if(have_max_active_host_execution_time==FALSE || max_active_host_execution_timestate_change){ have_min_active_host_state_change=TRUE; min_active_host_state_change=state_change; } if(have_max_active_host_state_change==FALSE || max_active_host_state_changestate_change){ have_min_passive_host_state_change=TRUE; min_passive_host_state_change=state_change; } if(have_max_passive_host_state_change==FALSE || max_passive_host_state_change0) hosts_in_downtime++; if(has_been_checked==TRUE) hosts_checked++; if(should_be_scheduled==TRUE) hosts_scheduled++; break; case STATUS_SERVICE_DATA: average_service_state_change=(((average_service_state_change*((double)status_service_entries-1.0))+state_change)/(double)status_service_entries); if(have_min_service_state_change==FALSE || min_service_state_change>state_change){ have_min_service_state_change=TRUE; min_service_state_change=state_change; } if(have_max_service_state_change==FALSE || max_service_state_changelatency){ have_min_active_service_latency=TRUE; min_active_service_latency=latency; } if(have_max_active_service_latency==FALSE || max_active_service_latencyexecution_time){ have_min_active_service_execution_time=TRUE; min_active_service_execution_time=execution_time; } if(have_max_active_service_execution_time==FALSE || max_active_service_execution_timestate_change){ have_min_active_service_state_change=TRUE; min_active_service_state_change=state_change; } if(have_max_active_service_state_change==FALSE || max_active_service_state_changestate_change){ have_min_passive_service_state_change=TRUE; min_passive_service_state_change=state_change; } if(have_max_passive_service_state_change==FALSE || max_passive_service_state_change0) services_in_downtime++; if(has_been_checked==TRUE) services_checked++; if(should_be_scheduled==TRUE) services_scheduled++; break; default: break; } data_type=STATUS_NO_DATA; execution_time=0.0; latency=0.0; check_type=0; current_state=0; state_change=0.0; is_flapping=FALSE; downtime_depth=0; last_check=(time_t)0; has_been_checked=FALSE; should_be_scheduled=FALSE; } else if(data_type!=STATUS_NO_DATA){ var=strtok(temp_buffer,"="); val=strtok(NULL,"\n"); if(val==NULL) continue; switch(data_type){ case STATUS_INFO_DATA: if(!strcmp(var,"created")) status_creation_date=strtoul(val,NULL,10); else if(!strcmp(var,"version")) status_version=strdup(val); break; case STATUS_PROGRAM_DATA: if(!strcmp(var,"program_start")) program_start=strtoul(val,NULL,10); break; case STATUS_HOST_DATA: if(!strcmp(var,"check_execution_time")) execution_time=strtod(val,NULL); else if(!strcmp(var,"check_latency")) latency=strtod(val,NULL); else if(!strcmp(var,"percent_state_change")) state_change=strtod(val,NULL); else if(!strcmp(var,"check_type")) check_type=atoi(val); else if(!strcmp(var,"current_state")) current_state=atoi(val); else if(!strcmp(var,"is_flapping")) is_flapping=(atoi(val)>0)?TRUE:FALSE; else if(!strcmp(var,"scheduled_downtime_depth")) downtime_depth=atoi(val); else if(!strcmp(var,"last_check")) last_check=strtoul(val,NULL,10); else if(!strcmp(var,"has_been_checked")) has_been_checked=(atoi(val)>0)?TRUE:FALSE; else if(!strcmp(var,"should_be_scheduled")) should_be_scheduled=(atoi(val)>0)?TRUE:FALSE; break; case STATUS_SERVICE_DATA: if(!strcmp(var,"check_execution_time")) execution_time=strtod(val,NULL); else if(!strcmp(var,"check_latency")) latency=strtod(val,NULL); else if(!strcmp(var,"percent_state_change")) state_change=strtod(val,NULL); else if(!strcmp(var,"check_type")) check_type=atoi(val); else if(!strcmp(var,"current_state")) current_state=atoi(val); else if(!strcmp(var,"is_flapping")) is_flapping=(atoi(val)>0)?TRUE:FALSE; else if(!strcmp(var,"scheduled_downtime_depth")) downtime_depth=atoi(val); else if(!strcmp(var,"last_check")) last_check=strtoul(val,NULL,10); else if(!strcmp(var,"has_been_checked")) has_been_checked=(atoi(val)>0)?TRUE:FALSE; else if(!strcmp(var,"should_be_scheduled")) should_be_scheduled=(atoi(val)>0)?TRUE:FALSE; break; default: break; } } } fclose(fp); return OK; } /* strip newline, carriage return, and tab characters from beginning and end of a string */ void strip(char *buffer){ register int x; register int y; register int z; if(buffer==NULL || buffer[0]=='\x0') return; /* strip end of string */ y=(int)strlen(buffer); for(x=y-1;x>=0;x--){ if(buffer[x]==' ' || buffer[x]=='\n' || buffer[x]=='\r' || buffer[x]=='\t' || buffer[x]==13) buffer[x]='\x0'; else break; } /* strip beginning of string (by shifting) */ y=(int)strlen(buffer); for(x=0;x0){ for(z=x;zfilename=(char *)strdup(filename); new_module->args=(args==NULL)?NULL:(char *)strdup(args); new_module->should_be_loaded=should_be_loaded; new_module->is_currently_loaded=FALSE; for(x=0;xinfo[x]=NULL; new_module->module_handle=NULL; new_module->init_func=NULL; new_module->deinit_func=NULL; #ifdef HAVE_PTHREAD_H new_module->thread_id=(pthread_t)NULL; #endif /* add module to head of list */ new_module->next=neb_module_list; neb_module_list=new_module; #ifdef DEBUG printf("Added module: name='%s', args='%s', should_be_loaded='%d'\n",filename,args,should_be_loaded); #endif return OK; } /* free memory allocated to module list */ int neb_free_module_list(void){ nebmodule *temp_module; nebmodule *next_module; int x; for(temp_module=neb_module_list;temp_module;){ next_module=temp_module->next; free(temp_module->filename); free(temp_module->args); for(x=0;xinfo[x]); free(temp_module); temp_module=next_module; } neb_module_list=NULL; return OK; } /****************************************************************************/ /****************************************************************************/ /* LOAD/UNLOAD FUNCTIONS */ /****************************************************************************/ /****************************************************************************/ /* load all modules */ int neb_load_all_modules(void){ nebmodule *temp_module; int result; for(temp_module=neb_module_list;temp_module;temp_module=temp_module->next){ result=neb_load_module(temp_module); } return OK; } /* load a particular module */ int neb_load_module(nebmodule *mod){ char temp_buffer[MAX_INPUT_BUFFER]; int (*initfunc)(int,char *,void *); int *module_version_ptr; int result; if(mod==NULL || mod->filename==NULL) return ERROR; /* don't reopen the module */ if(mod->is_currently_loaded==TRUE) return OK; /* don't load modules unless they should be loaded */ if(mod->should_be_loaded==FALSE) return ERROR; /* load the module */ #ifdef USE_LTDL mod->module_handle=lt_dlopen(mod->filename); #else mod->module_handle=dlopen(mod->filename,RTLD_NOW|RTLD_GLOBAL); #endif if(mod->module_handle==NULL){ #ifdef USE_LTDL snprintf(temp_buffer,sizeof(temp_buffer),"Error: Could not load module '%s' -> %s\n",mod->filename,lt_dlerror()); #else snprintf(temp_buffer,sizeof(temp_buffer),"Error: Could not load module '%s' -> %s\n",mod->filename,dlerror()); #endif temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_all_logs(temp_buffer,NSLOG_RUNTIME_ERROR); return ERROR; } /* mark the module as being loaded */ mod->is_currently_loaded=TRUE; /* find module API version */ #ifdef USE_LTDL module_version_ptr=(int *)lt_dlsym(mod->module_handle,"__neb_api_version"); #else module_version_ptr=(int *)dlsym(mod->module_handle,"__neb_api_version"); #endif /* check the module API version */ if(module_version_ptr==NULL || ((*module_version_ptr)!=CURRENT_NEB_API_VERSION)){ snprintf(temp_buffer,sizeof(temp_buffer),"Error: Module '%s' is using an old or unspecified version of the event broker API. Module will be unloaded.\n",mod->filename); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_all_logs(temp_buffer,NSLOG_RUNTIME_ERROR); neb_unload_module(mod,NEBMODULE_FORCE_UNLOAD,NEBMODULE_ERROR_API_VERSION); return ERROR; } /* locate the initialization function */ #ifdef USE_LTDL mod->init_func=lt_dlsym(mod->module_handle,"nebmodule_init"); #else mod->init_func=dlsym(mod->module_handle,"nebmodule_init"); #endif /* if the init function could not be located, unload the module */ if(mod->init_func==NULL){ snprintf(temp_buffer,sizeof(temp_buffer),"Error: Could not locate nebmodule_init() in module '%s'. Module will be unloaded.\n",mod->filename); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_all_logs(temp_buffer,NSLOG_RUNTIME_ERROR); neb_unload_module(mod,NEBMODULE_FORCE_UNLOAD,NEBMODULE_ERROR_NO_INIT); return ERROR; } /* run the module's init function */ initfunc=mod->init_func; result=(*initfunc)(NEBMODULE_NORMAL_LOAD,mod->args,mod->module_handle); /* if the init function returned an error, unload the module */ if(result!=OK){ snprintf(temp_buffer,sizeof(temp_buffer),"Error: Function nebmodule_init() in module '%s' returned an error. Module will be unloaded.\n",mod->filename); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_all_logs(temp_buffer,NSLOG_RUNTIME_ERROR); neb_unload_module(mod,NEBMODULE_FORCE_UNLOAD,NEBMODULE_ERROR_BAD_INIT); return ERROR; } snprintf(temp_buffer,sizeof(temp_buffer),"Event broker module '%s' initialized successfully.\n",mod->filename); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_all_logs(temp_buffer,NSLOG_INFO_MESSAGE); /* locate the de-initialization function (may or may not be present) */ #ifdef USE_LTDL mod->deinit_func=lt_dlsym(mod->module_handle,"nebmodule_deinit"); #else mod->deinit_func=dlsym(mod->module_handle,"nebmodule_deinit"); #endif #ifdef DEBUG printf("Module '%s' loaded with return code of '%d'\n",mod->filename,result); if(mod->deinit_func!=NULL) printf("\tnebmodule_deinit() found\n"); #endif return OK; } /* close (unload) all modules that are currently loaded */ int neb_unload_all_modules(int flags, int reason){ nebmodule *temp_module; for(temp_module=neb_module_list;temp_module;temp_module=temp_module->next){ /* skip modules that are not loaded */ if(temp_module->is_currently_loaded==FALSE) continue; /* skip modules that do not have a valid handle */ if(temp_module->module_handle==NULL) continue; /* close/unload the module */ neb_unload_module(temp_module,flags,reason); } return OK; } /* close (unload) a particular module */ int neb_unload_module(nebmodule *mod, int flags, int reason){ char temp_buffer[MAX_INPUT_BUFFER]; int (*deinitfunc)(int,int); int result; if(mod==NULL) return ERROR; #ifdef DEBUG printf("Attempting to unload module '%s': flags=%d, reason=%d\n",mod->filename,flags,reason); #endif /* call the de-initialization function if available (and the module was initialized) */ if(mod->deinit_func && reason!=NEBMODULE_ERROR_BAD_INIT){ deinitfunc=mod->deinit_func; /* module can opt to not be unloaded */ result=(*deinitfunc)(flags,reason); /* if module doesn't want to be unloaded, exit with error (unless its being forced) */ if(result!=OK && !(flags & NEBMODULE_FORCE_UNLOAD)) return ERROR; } /* deregister all of the module's callbacks */ neb_deregister_module_callbacks(mod); /* unload the module */ #ifdef USE_LTDL result=lt_dlclose(mod->module_handle); #else result=dlclose(mod->module_handle); #endif /* mark the module as being unloaded */ mod->is_currently_loaded=FALSE; #ifdef DEBUG printf("Module '%s' unloaded successfully.\n",mod->filename); #endif snprintf(temp_buffer,sizeof(temp_buffer),"Event broker module '%s' deinitialized successfully.\n",mod->filename); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_all_logs(temp_buffer,NSLOG_INFO_MESSAGE); return OK; } /****************************************************************************/ /****************************************************************************/ /* INFO FUNCTIONS */ /****************************************************************************/ /****************************************************************************/ /* sets module information */ int neb_set_module_info(void *handle, int type, char *data){ nebmodule *mod; if(handle==NULL) return NEBERROR_NOMODULE; /* check type */ if(type<0 || type>=NEBMODULE_MODINFO_NUMITEMS) return NEBERROR_MODINFOBOUNDS; /* get the module */ mod=(nebmodule *)handle; /* free any previously allocated memory */ free(mod->info[type]); /* allocate memory for the new data */ if(data==NULL) mod->info[type]=NULL; else{ mod->info[type]=strdup(data); if(mod->info[type]==NULL) return NEBERROR_NOMEM; } return OK; } /****************************************************************************/ /****************************************************************************/ /* CALLBACK FUNCTIONS */ /****************************************************************************/ /****************************************************************************/ /* allows a module to register a callback function */ int neb_register_callback(int callback_type, void *mod_handle, int priority, int (*callback_func)(int,void *)){ nebmodule *temp_module; nebcallback *new_callback; nebcallback *temp_callback; nebcallback *last_callback; if(callback_func==NULL) return NEBERROR_NOCALLBACKFUNC; if(neb_callback_list==NULL) return NEBERROR_NOCALLBACKLIST; if(mod_handle==NULL) return NEBERROR_NOMODULEHANDLE; /* make sure the callback type is within bounds */ if(callback_type<0 || callback_type>=NEBCALLBACK_NUMITEMS) return NEBERROR_CALLBACKBOUNDS; /* make sure module handle is valid */ for(temp_module=neb_module_list;temp_module;temp_module=temp_module->next){ if((void *)temp_module->module_handle==(void *)mod_handle) break; } if(temp_module==NULL) return NEBERROR_BADMODULEHANDLE; /* allocate memory */ new_callback=(nebcallback *)malloc(sizeof(nebcallback)); if(new_callback==NULL) return NEBERROR_NOMEM; new_callback->priority=priority; new_callback->module_handle=(void *)mod_handle; new_callback->callback_func=(void *)callback_func; /* add new function to callback list, sorted by priority (first come, first served for same priority) */ new_callback->next=NULL; if(neb_callback_list[callback_type]==NULL) neb_callback_list[callback_type]=new_callback; else{ last_callback=NULL; for(temp_callback=neb_callback_list[callback_type];temp_callback!=NULL;temp_callback=temp_callback->next){ if(temp_callback->priority>new_callback->priority) break; last_callback=temp_callback; } if(last_callback==NULL) neb_callback_list[callback_type]=new_callback; else{ if(temp_callback==NULL) last_callback->next=new_callback; else{ new_callback->next=temp_callback; last_callback->next=new_callback; } } } return OK; } /* dregisters all callback functions for a given module */ int neb_deregister_module_callbacks(nebmodule *mod){ nebcallback *temp_callback; nebcallback *next_callback; int callback_type; if(mod==NULL) return NEBERROR_NOMODULE; if(neb_callback_list==NULL) return OK; for(callback_type=0;callback_typenext; if((void *)temp_callback->module_handle==(void *)mod->module_handle) neb_deregister_callback(callback_type,temp_callback->callback_func); } } return OK; } /* allows a module to deregister a callback function */ int neb_deregister_callback(int callback_type, int (*callback_func)(int,void *)){ nebcallback *temp_callback; nebcallback *last_callback; nebcallback *next_callback=NULL; if(callback_func==NULL) return NEBERROR_NOCALLBACKFUNC; if(neb_callback_list==NULL) return NEBERROR_NOCALLBACKLIST; /* make sure the callback type is within bounds */ if(callback_type<0 || callback_type>=NEBCALLBACK_NUMITEMS) return NEBERROR_CALLBACKBOUNDS; /* find the callback to remove */ for(temp_callback=last_callback=neb_callback_list[callback_type];temp_callback!=NULL;temp_callback=next_callback){ next_callback=temp_callback->next; /* we found it */ if(temp_callback->callback_func==callback_func) break; last_callback=temp_callback; } /* we couldn't find the callback */ if(temp_callback==NULL) return NEBERROR_CALLBACKNOTFOUND; else{ /* only one item in the list */ if (temp_callback!=last_callback->next) neb_callback_list[callback_type]=NULL; else last_callback->next=next_callback; free(temp_callback); } return OK; } /* make callbacks to modules */ int neb_make_callbacks(int callback_type, void *data){ nebcallback *temp_callback; int (*callbackfunc)(int,void *); int cbresult; /* make sure callback list is initialized */ if(neb_callback_list==NULL) return ERROR; /* make sure the callback type is within bounds */ if(callback_type<0 || callback_type>=NEBCALLBACK_NUMITEMS) return ERROR; /* make the callbacks... */ for(temp_callback=neb_callback_list[callback_type];temp_callback!=NULL;temp_callback=temp_callback->next){ callbackfunc=temp_callback->callback_func; cbresult=callbackfunc(callback_type,data); #ifdef DEBUG printf("Callback type %d resulted in return code of %d\n",callback_type,cbresult); #endif } return OK; } /* initialize callback list */ int neb_init_callback_list(void){ int x; /* allocate memory for the callback list */ neb_callback_list=(nebcallback **)malloc(NEBCALLBACK_NUMITEMS*sizeof(nebcallback *)); if(neb_callback_list==NULL) return ERROR; /* initialize list pointers */ for(x=0;xnext; free(temp_callback); } neb_callback_list[x]=NULL; } free(neb_callback_list); neb_callback_list=NULL; return OK; } #endif nagios-2.6/base/notifications.c0000664000076500007650000016075110415563215016142 0ustar nagiosnagios/***************************************************************************** * * NOTIFICATIONS.C - Service and host notification functions for Nagios * * Copyright (c) 1999-2006 Ethan Galstad (nagios@nagios.org) * Last Modified: 04-07-2006 * * 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. * *****************************************************************************/ #include "../include/config.h" #include "../include/common.h" #include "../include/objects.h" #include "../include/statusdata.h" #include "../include/nagios.h" #include "../include/broker.h" extern notification *notification_list; extern contact *contact_list; extern serviceescalation *serviceescalation_list; extern hostescalation *hostescalation_list; extern int interval_length; extern int log_notifications; extern int enable_notifications; extern int notification_timeout; extern char *macro_x[MACRO_X_COUNT]; extern char *generic_summary; /******************************************************************/ /***************** SERVICE NOTIFICATION FUNCTIONS *****************/ /******************************************************************/ /* notify contacts about a service problem or recovery */ int service_notification(service *svc, int type, char *ack_author, char *ack_data){ host *temp_host; notification *temp_notification; time_t current_time; struct timeval start_time; struct timeval end_time; int escalated=FALSE; int result=OK; int contacts_notified=0; #ifdef DEBUG0 printf("service_notification() start\n"); #endif /* get the current time */ time(¤t_time); gettimeofday(&start_time,NULL); #ifdef DEBUG4 printf("\nSERVICE NOTIFICATION ATTEMPT: Service '%s' on host '%s'\n",svc->description,svc->host_name); printf("\tType: %d\n",type); printf("\tCurrent time: %s",ctime(¤t_time)); #endif /* find the host this service is associated with */ temp_host=find_host(svc->host_name); /* if we couldn't find the host, return an error */ if(temp_host==NULL){ #ifdef DEBUG4 printf("\tCouldn't find the host associated with this service, so we won't send a notification!\n"); #endif return ERROR; } /* check the viability of sending out a service notification */ if(check_service_notification_viability(svc,type)==ERROR){ #ifdef DEBUG4 printf("\tSending out a notification for this service is not viable at this time.\n"); #endif return OK; } /* if this is just a normal notification... */ if(type==NOTIFICATION_NORMAL){ /* increase the current notification number */ svc->current_notification_number++; #ifdef DEBUG4 printf("\tCurrent notification number: %d\n",svc->current_notification_number); #endif } /* create the contact notification list for this service */ create_notification_list_from_service(svc,&escalated); #ifdef USE_EVENT_BROKER /* send data to event broker */ end_time.tv_sec=0L; end_time.tv_usec=0L; broker_notification_data(NEBTYPE_NOTIFICATION_START,NEBFLAG_NONE,NEBATTR_NONE,SERVICE_NOTIFICATION,type,start_time,end_time,(void *)svc,ack_author,ack_data,escalated,0,NULL); #endif /* we have contacts to notify... */ if(notification_list!=NULL){ /* grab the macro variables */ clear_volatile_macros(); grab_host_macros(temp_host); grab_service_macros(svc); /* if this is an acknowledgement, get the acknowledgement macros */ if(type==NOTIFICATION_ACKNOWLEDGEMENT){ if(macro_x[MACRO_SERVICEACKAUTHOR]!=NULL) free(macro_x[MACRO_SERVICEACKAUTHOR]); if(ack_author==NULL) macro_x[MACRO_SERVICEACKAUTHOR]=NULL; else macro_x[MACRO_SERVICEACKAUTHOR]=strdup(ack_author); if(macro_x[MACRO_SERVICEACKCOMMENT]!=NULL) free(macro_x[MACRO_SERVICEACKCOMMENT]); if(ack_data==NULL) macro_x[MACRO_SERVICEACKCOMMENT]=NULL; else macro_x[MACRO_SERVICEACKCOMMENT]=strdup(ack_data); } /* set the notification type macro */ if(macro_x[MACRO_NOTIFICATIONTYPE]!=NULL) free(macro_x[MACRO_NOTIFICATIONTYPE]); macro_x[MACRO_NOTIFICATIONTYPE]=(char *)malloc(MAX_NOTIFICATIONTYPE_LENGTH); if(macro_x[MACRO_NOTIFICATIONTYPE]!=NULL){ if(type==NOTIFICATION_ACKNOWLEDGEMENT) strcpy(macro_x[MACRO_NOTIFICATIONTYPE],"ACKNOWLEDGEMENT"); else if(type==NOTIFICATION_FLAPPINGSTART) strcpy(macro_x[MACRO_NOTIFICATIONTYPE],"FLAPPINGSTART"); else if(type==NOTIFICATION_FLAPPINGSTOP) strcpy(macro_x[MACRO_NOTIFICATIONTYPE],"FLAPPINGSTOP"); else if(svc->current_state==STATE_OK) strcpy(macro_x[MACRO_NOTIFICATIONTYPE],"RECOVERY"); else strcpy(macro_x[MACRO_NOTIFICATIONTYPE],"PROBLEM"); } /* set the notification number macro */ if(macro_x[MACRO_NOTIFICATIONNUMBER]!=NULL) free(macro_x[MACRO_NOTIFICATIONNUMBER]); macro_x[MACRO_NOTIFICATIONNUMBER]=(char *)malloc(MAX_NOTIFICATIONNUMBER_LENGTH); if(macro_x[MACRO_NOTIFICATIONNUMBER]!=NULL){ snprintf(macro_x[MACRO_NOTIFICATIONNUMBER],MAX_NOTIFICATIONNUMBER_LENGTH-1,"%d",svc->current_notification_number); macro_x[MACRO_NOTIFICATIONNUMBER][MAX_NOTIFICATIONNUMBER_LENGTH-1]='\x0'; } /* notify each contact (duplicates have been removed) */ for(temp_notification=notification_list;temp_notification!=NULL;temp_notification=temp_notification->next){ /* grab the macro variables for this contact */ grab_contact_macros(temp_notification->contact); /* grab summary macros (customized for this contact) */ grab_summary_macros(temp_notification->contact); /* notify this contact */ result=notify_contact_of_service(temp_notification->contact,svc,type,ack_author,ack_data,escalated); /* keep track of how many contacts were notified */ if(result==OK) contacts_notified++; } /* free memory allocated to the notification list */ free_notification_list(); if(type==NOTIFICATION_NORMAL){ /* adjust last/next notification time and notification flags if we notified someone */ if(contacts_notified>0){ /* calculate the next acceptable re-notification time */ svc->next_notification=get_next_service_notification_time(svc,current_time); #ifdef DEBUG4 printf("\tCurrent Time: %s",ctime(¤t_time)); printf("\tNext acceptable notification time: %s",ctime(&svc->next_notification)); #endif /* update the last notification time for this service (this is needed for rescheduling later notifications) */ svc->last_notification=current_time; /* update notifications flags */ if(svc->current_state==STATE_UNKNOWN) svc->notified_on_unknown=TRUE; else if(svc->current_state==STATE_WARNING) svc->notified_on_warning=TRUE; else if(svc->current_state==STATE_CRITICAL) svc->notified_on_critical=TRUE; } /* we didn't end up notifying anyone, so adjust current notification number */ else svc->current_notification_number--; } #ifdef DEBUG4 printf("\tAPPROPRIATE CONTACTS HAVE BEEN NOTIFIED\n"); #endif } /* there were no contacts, so no notification really occurred... */ else{ /* readjust current notification number, since one didn't go out */ if(type==NOTIFICATION_NORMAL) svc->current_notification_number--; #ifdef DEBUG4 printf("\tTHERE WERE NO CONTACTS TO BE NOTIFIED!\n"); #endif } /* get the time we finished */ gettimeofday(&end_time,NULL); #ifdef USE_EVENT_BROKER /* send data to event broker */ broker_notification_data(NEBTYPE_NOTIFICATION_END,NEBFLAG_NONE,NEBATTR_NONE,SERVICE_NOTIFICATION,type,start_time,end_time,(void *)svc,ack_author,ack_data,escalated,contacts_notified,NULL); #endif /* update the status log with the service information */ update_service_status(svc,FALSE); #ifdef DEBUG0 printf("service_notification() end\n"); #endif return OK; } /* checks the viability of sending out a service alert (top level filters) */ int check_service_notification_viability(service *svc, int type){ host *temp_host; time_t current_time; time_t timeperiod_start; #ifdef DEBUG0 printf("check_service_notification_viability() start\n"); #endif /* get current time */ time(¤t_time); /* are notifications enabled? */ if(enable_notifications==FALSE){ #ifdef DEBUG4 printf("\tNotifications are disabled, so service notifications (problems and acknowledments) will not be sent out!\n"); #endif return ERROR; } /* find the host this service is associated with */ temp_host=find_host(svc->host_name); /* if we couldn't find the host, return an error */ if(temp_host==NULL){ #ifdef DEBUG4 printf("\tCouldn't find the host associated with this service, so we won't send a notification!\n"); #endif return ERROR; } /* see if the service can have notifications sent out at this time */ if(check_time_against_period(current_time,svc->notification_period)==ERROR){ #ifdef DEBUG4 printf("\tThis service shouldn't have notifications sent out at this time!\n"); #endif /* calculate the next acceptable notification time, once the next valid time range arrives... */ if(type==NOTIFICATION_NORMAL){ get_next_valid_time(current_time,&timeperiod_start,svc->notification_period); /* looks like there are no valid notification times defined, so schedule the next one far into the future (one year)... */ if(timeperiod_start==(time_t)0) svc->next_notification=(time_t)(current_time+(60*60*24*365)); /* else use the next valid notification time */ else svc->next_notification=timeperiod_start; } return ERROR; } /* are notifications temporarily disabled for this service? */ if(svc->notifications_enabled==FALSE){ #ifdef DEBUG4 printf("\tNotifications are temporarily disabled for this service, so we won't send one out!\n"); #endif return ERROR; } /****************************************/ /*** SPECIAL CASE FOR ACKNOWLEGEMENTS ***/ /****************************************/ /* acknowledgements only have to pass three general filters, although they have another test of their own... */ if(type==NOTIFICATION_ACKNOWLEDGEMENT){ /* don't send an acknowledgement if there isn't a problem... */ if(svc->current_state==STATE_OK){ #ifdef DEBUG4 printf("\tThe service is currently OK, so we won't send an acknowledgement!\n"); #endif return ERROR; } /* acknowledgement viability test passed, so the notification can be sent out */ return OK; } /****************************************/ /*** SPECIAL CASE FOR FLAPPING ALERTS ***/ /****************************************/ /* flapping notifications only have to pass three general filters */ if(type==NOTIFICATION_FLAPPINGSTART || type==NOTIFICATION_FLAPPINGSTOP){ /* don't send a notification if we're not supposed to... */ if(svc->notify_on_flapping==FALSE){ #ifdef DEBUG4 printf("\tWe shouldn't notify about FLAPPING events for this service!\n"); #endif return ERROR; } /* don't send notifications during scheduled downtime */ if(svc->scheduled_downtime_depth>0 || temp_host->scheduled_downtime_depth>0){ #ifdef DEBUG4 printf("\tWe shouldn't notify about FLAPPING events during scheduled downtime!\n"); #endif return ERROR; } /* flapping viability test passed, so the notification can be sent out */ return OK; } /****************************************/ /*** NORMAL NOTIFICATIONS ***************/ /****************************************/ /* has this problem already been acknowledged? */ if(svc->problem_has_been_acknowledged==TRUE){ #ifdef DEBUG4 printf("\tThis service problem has already been acknowledged, so we won't send a notification out!\n"); #endif return ERROR; } /* check service notification dependencies */ if(check_service_dependencies(svc,NOTIFICATION_DEPENDENCY)==DEPENDENCIES_FAILED){ #ifdef DEBUG4 printf("\tService notification dependencies for this service have failed, so we won't sent a notification out!\n"); #endif return ERROR; } /* check host notification dependencies */ if(check_host_dependencies(temp_host,NOTIFICATION_DEPENDENCY)==DEPENDENCIES_FAILED){ #ifdef DEBUG4 printf("\tHost notification dependencies for this service have failed, so we won't sent a notification out!\n"); #endif return ERROR; } /* see if we should notify about problems with this service */ if(svc->current_state==STATE_UNKNOWN && svc->notify_on_unknown==FALSE){ #ifdef DEBUG4 printf("\tWe shouldn't notify about UNKNOWN states for this service!\n"); #endif return ERROR; } if(svc->current_state==STATE_WARNING && svc->notify_on_warning==FALSE){ #ifdef DEBUG4 printf("\tWe shouldn't notify about WARNING states for this service!\n"); #endif return ERROR; } if(svc->current_state==STATE_CRITICAL && svc->notify_on_critical==FALSE){ #ifdef DEBUG4 printf("\tWe shouldn't notify about CRITICAL states for this service!\n"); #endif return ERROR; } if(svc->current_state==STATE_OK){ if(svc->notify_on_recovery==FALSE){ #ifdef DEBUG4 printf("\tWe shouldn't notify about RECOVERY states for this service!\n"); #endif return ERROR; } if(!(svc->notified_on_unknown==TRUE || svc->notified_on_warning==TRUE || svc->notified_on_critical==TRUE)){ #ifdef DEBUG4 printf("\tWe shouldn't notify about this recovery\n"); #endif return ERROR; } } /* if this service is currently flapping, don't send the notification */ if(svc->is_flapping==TRUE){ #ifdef DEBUG4 printf("\tThis service is currently flapping, so we won't send notifications!\n"); #endif return ERROR; } /***** RECOVERY NOTIFICATIONS ARE GOOD TO GO AT THIS POINT *****/ if(svc->current_state==STATE_OK) return OK; /* don't notify contacts about this service problem again if the notification interval is set to 0 */ if(svc->no_more_notifications==TRUE){ #ifdef DEBUG4 printf("\tWe shouldn't re-notify contacts about this service problem!\n"); #endif return ERROR; } /* if the host is down or unreachable, don't notify contacts about service failures */ if(temp_host->current_state!=HOST_UP){ #ifdef DEBUG4 printf("\tThe host is either down or unreachable, so we won't notify contacts about this service!\n"); #endif return ERROR; } /* don't notify if we haven't waited long enough since the last time (and the service is not marked as being volatile) */ if((current_time < svc->next_notification) && svc->is_volatile==FALSE){ #ifdef DEBUG4 printf("\tWe haven't waited long enough to re-notify contacts about this service!\n"); printf("\tNext valid notification time: %s",ctime(&svc->next_notification)); #endif return ERROR; } /* if this service is currently in a scheduled downtime period, don't send the notification */ if(svc->scheduled_downtime_depth>0){ #ifdef DEBUG4 printf("\tThis service is currently in a scheduled downtime, so we won't send notifications!\n"); #endif return ERROR; } /* if this host is currently in a scheduled downtime period, don't send the notification */ if(temp_host->scheduled_downtime_depth>0){ #ifdef DEBUG4 printf("\tThe host this service is associated with is currently in a scheduled downtime, so we won't send notifications!\n"); #endif return ERROR; } #ifdef DEBUG0 printf("check_service_notification_viability() end\n"); #endif return OK; } /* check viability of sending out a service notification to a specific contact (contact-specific filters) */ int check_contact_service_notification_viability(contact *cntct, service *svc, int type){ #ifdef DEBUG0 printf("check_contact_service_notification_viability() start\n"); #endif /* see if the contact can be notified at this time */ if(check_time_against_period(time(NULL),cntct->service_notification_period)==ERROR){ #ifdef DEBUG4 printf("\tThis contact shouldn't be notified at this time!\n"); #endif return ERROR; } /****************************************/ /*** SPECIAL CASE FOR FLAPPING ALERTS ***/ /****************************************/ if(type==NOTIFICATION_FLAPPINGSTART || type==NOTIFICATION_FLAPPINGSTOP){ if(cntct->notify_on_service_flapping==FALSE){ #ifdef DEBUG4 printf("\tWe shouldn't notify this contact about FLAPPING service events!\n"); #endif return ERROR; } return OK; } /*************************************/ /*** ACKS AND NORMAL NOTIFICATIONS ***/ /*************************************/ /* see if we should notify about problems with this service */ if(svc->current_state==STATE_UNKNOWN && cntct->notify_on_service_unknown==FALSE){ #ifdef DEBUG4 printf("\tWe shouldn't notify this contact about UNKNOWN service states!\n"); #endif return ERROR; } if(svc->current_state==STATE_WARNING && cntct->notify_on_service_warning==FALSE){ #ifdef DEBUG4 printf("\tWe shouldn't notify this contact about WARNING service states!\n"); #endif return ERROR; } if(svc->current_state==STATE_CRITICAL && cntct->notify_on_service_critical==FALSE){ #ifdef DEBUG4 printf("\tWe shouldn't notify this contact about CRITICAL service states!\n"); #endif return ERROR; } if(svc->current_state==STATE_OK){ if(cntct->notify_on_service_recovery==FALSE){ #ifdef DEBUG4 printf("\tWe shouldn't notify this contact about RECOVERY service states!\n"); #endif return ERROR; } if(!((svc->notified_on_unknown==TRUE && cntct->notify_on_service_unknown==TRUE) || (svc->notified_on_warning==TRUE && cntct->notify_on_service_warning==TRUE) || (svc->notified_on_critical==TRUE && cntct->notify_on_service_critical==TRUE))){ #ifdef DEBUG4 printf("\tWe shouldn't notify about this recovery\n"); #endif return ERROR; } } #ifdef DEBUG0 printf("check_contact_service_notification_viability() end\n"); #endif return OK; } /* notify a specific contact about a service problem or recovery */ int notify_contact_of_service(contact *cntct, service *svc, int type, char *ack_author, char *ack_data, int escalated){ commandsmember *temp_commandsmember; char command_name[MAX_INPUT_BUFFER]; char *command_name_ptr=NULL; char raw_command[MAX_COMMAND_BUFFER]; char processed_command[MAX_COMMAND_BUFFER]; char temp_buffer[MAX_INPUT_BUFFER]; int early_timeout=FALSE; double exectime; struct timeval start_time,end_time; struct timeval method_start_time,method_end_time; int macro_options=STRIP_ILLEGAL_MACRO_CHARS|ESCAPE_MACRO_CHARS; #ifdef DEBUG0 printf("notify_contact_of_service() start\n"); #endif #ifdef DEBUG4 printf("\tNotify user %s\n",cntct->name); #endif /* check viability of notifying this user */ /* acknowledgements are no longer excluded from this test - added 8/19/02 Tom Bertelson */ if(check_contact_service_notification_viability(cntct,svc,type)==ERROR) return ERROR; /* get start time */ gettimeofday(&start_time,NULL); #ifdef USE_EVENT_BROKER /* send data to event broker */ end_time.tv_sec=0L; end_time.tv_usec=0L; broker_contact_notification_data(NEBTYPE_CONTACTNOTIFICATION_START,NEBFLAG_NONE,NEBATTR_NONE,SERVICE_NOTIFICATION,type,start_time,end_time,(void *)svc,cntct,ack_author,ack_data,escalated,NULL); #endif /* process all the notification commands this user has */ for(temp_commandsmember=cntct->service_notification_commands;temp_commandsmember!=NULL;temp_commandsmember=temp_commandsmember->next){ /* get start time */ gettimeofday(&method_start_time,NULL); #ifdef USE_EVENT_BROKER /* send data to event broker */ method_end_time.tv_sec=0L; method_end_time.tv_usec=0L; broker_contact_notification_method_data(NEBTYPE_CONTACTNOTIFICATIONMETHOD_START,NEBFLAG_NONE,NEBATTR_NONE,SERVICE_NOTIFICATION,type,method_start_time,method_end_time,(void *)svc,cntct,temp_commandsmember->command,ack_author,ack_data,escalated,NULL); #endif /* get the command name */ strncpy(command_name,temp_commandsmember->command,sizeof(command_name)); command_name[sizeof(command_name)-1]='\x0'; command_name_ptr=strtok(command_name,"!"); /* get the raw command line */ get_raw_command_line(temp_commandsmember->command,raw_command,sizeof(raw_command),macro_options); strip(raw_command); /* process any macros contained in the argument */ process_macros(raw_command,processed_command,sizeof(processed_command),macro_options); strip(processed_command); /* run the notification command */ if(strcmp(processed_command,"")){ #ifdef DEBUG4 printf("\tRaw Command: %s\n",raw_command); printf("\tProcessed Command: %s\n",processed_command); #endif /* log the notification to program log file */ if(log_notifications==TRUE){ switch(type){ case NOTIFICATION_ACKNOWLEDGEMENT: snprintf(temp_buffer,sizeof(temp_buffer),"SERVICE NOTIFICATION: %s;%s;%s;ACKNOWLEDGEMENT (%s);%s;%s;%s;%s\n",cntct->name,svc->host_name,svc->description,macro_x[MACRO_SERVICESTATE],command_name_ptr,macro_x[MACRO_SERVICEOUTPUT],macro_x[MACRO_SERVICEACKAUTHOR],macro_x[MACRO_SERVICEACKCOMMENT]); break; case NOTIFICATION_FLAPPINGSTART: snprintf(temp_buffer,sizeof(temp_buffer),"SERVICE NOTIFICATION: %s;%s;%s;FLAPPINGSTART (%s);%s;%s\n",cntct->name,svc->host_name,svc->description,macro_x[MACRO_SERVICESTATE],command_name_ptr,macro_x[MACRO_SERVICEOUTPUT]); break; case NOTIFICATION_FLAPPINGSTOP: snprintf(temp_buffer,sizeof(temp_buffer),"SERVICE NOTIFICATION: %s;%s;%s;FLAPPINGSTOP (%s);%s;%s\n",cntct->name,svc->host_name,svc->description,macro_x[MACRO_SERVICESTATE],command_name_ptr,macro_x[MACRO_SERVICEOUTPUT]); break; default: snprintf(temp_buffer,sizeof(temp_buffer),"SERVICE NOTIFICATION: %s;%s;%s;%s;%s;%s\n",cntct->name,svc->host_name,svc->description,macro_x[MACRO_SERVICESTATE],command_name_ptr,macro_x[MACRO_SERVICEOUTPUT]); break; } temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_all_logs(temp_buffer,NSLOG_SERVICE_NOTIFICATION); } /* run the command */ my_system(processed_command,notification_timeout,&early_timeout,&exectime,NULL,0); /* check to see if the notification command timed out */ if(early_timeout==TRUE){ snprintf(temp_buffer,sizeof(temp_buffer),"Warning: Contact '%s' service notification command '%s' timed out after %d seconds\n",cntct->name,processed_command,DEFAULT_NOTIFICATION_TIMEOUT); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_SERVICE_NOTIFICATION | NSLOG_RUNTIME_WARNING,TRUE); } } /* get end time */ gettimeofday(&method_end_time,NULL); #ifdef USE_EVENT_BROKER /* send data to event broker */ broker_contact_notification_method_data(NEBTYPE_CONTACTNOTIFICATIONMETHOD_END,NEBFLAG_NONE,NEBATTR_NONE,SERVICE_NOTIFICATION,type,method_start_time,method_end_time,(void *)svc,cntct,temp_commandsmember->command,ack_author,ack_data,escalated,NULL); #endif } /* get end time */ gettimeofday(&end_time,NULL); #ifdef USE_EVENT_BROKER /* send data to event broker */ broker_contact_notification_data(NEBTYPE_CONTACTNOTIFICATION_END,NEBFLAG_NONE,NEBATTR_NONE,SERVICE_NOTIFICATION,type,start_time,end_time,(void *)svc,cntct,ack_author,ack_data,escalated,NULL); #endif #ifdef DEBUG0 printf("notify_contact_of_service() end\n"); #endif return OK; } /* checks to see if a service escalation entry is a match for the current service notification */ int is_valid_escalation_for_service_notification(service *svc,serviceescalation *se){ int notification_number; time_t current_time; #ifdef DEBUG0 printf("is_valid_escalation_for_service_notification() start\n"); #endif /* get the current time */ time(¤t_time); /* if this is a recovery, really we check for who got notified about a previous problem */ if(svc->current_state==STATE_OK) notification_number=svc->current_notification_number-1; else notification_number=svc->current_notification_number; /* this entry if it is not for this service */ if(strcmp(svc->host_name,se->host_name) || strcmp(svc->description,se->description)) return FALSE; /* skip this escalation if it happens later */ if(se->first_notification > notification_number) return FALSE; /* skip this escalation if it has already passed */ if(se->last_notification!=0 && se->last_notification < notification_number) return FALSE; /* skip this escalation if it has a timeperiod and the current time isn't valid */ if(se->escalation_period!=NULL && check_time_against_period(current_time,se->escalation_period)==ERROR) return FALSE; /* skip this escalation if the state options don't match */ if(svc->current_state==STATE_OK && se->escalate_on_recovery==FALSE) return FALSE; else if(svc->current_state==STATE_WARNING && se->escalate_on_warning==FALSE) return FALSE; else if(svc->current_state==STATE_UNKNOWN && se->escalate_on_unknown==FALSE) return FALSE; else if(svc->current_state==STATE_CRITICAL && se->escalate_on_critical==FALSE) return FALSE; #ifdef DEBUG0 printf("is_valid_escalation_for_service_notification() end\n"); #endif return TRUE; } /* checks to see whether a service notification should be escalation */ int should_service_notification_be_escalated(service *svc){ serviceescalation *temp_se; #ifdef DEBUG0 printf("should_service_notification_be_escalated() start\n"); #endif /* search the service escalation list */ for(temp_se=serviceescalation_list;temp_se!=NULL;temp_se=temp_se->next){ /* we found a matching entry, so escalate this notification! */ if(is_valid_escalation_for_service_notification(svc,temp_se)==TRUE){ #ifdef DEBUG4 printf("\tService notification WILL BE escalated\n"); #endif return TRUE; } } #ifdef DEBUG4 printf("\tService notification will NOT be escalated\n"); #endif #ifdef DEBUG0 printf("should_service_notification_be_escalated() end\n"); #endif return FALSE; } /* given a service, create a list of contacts to be notified, removing duplicates */ int create_notification_list_from_service(service *svc, int *escalated){ serviceescalation *temp_se; contactgroupsmember *temp_group; contactgroup *temp_contactgroup; contact *temp_contact; #ifdef DEBUG0 printf("create_notification_list_from_service() end\n"); #endif /* should this notification be escalated? */ if(should_service_notification_be_escalated(svc)==TRUE){ /* set the escalation flag */ *escalated=TRUE; /* search all the escalation entries for valid matches */ for(temp_se=serviceescalation_list;temp_se!=NULL;temp_se=temp_se->next){ /* skip this entry if it isn't appropriate */ if(is_valid_escalation_for_service_notification(svc,temp_se)==FALSE) continue; /* find each contact group in this escalation entry */ for(temp_group=temp_se->contact_groups;temp_group!=NULL;temp_group=temp_group->next){ temp_contactgroup=find_contactgroup(temp_group->group_name); if(temp_contactgroup==NULL) continue; /* check all contacts */ for(temp_contact=contact_list;temp_contact!=NULL;temp_contact=temp_contact->next){ if(is_contact_member_of_contactgroup(temp_contactgroup,temp_contact)==TRUE) add_notification(temp_contact); } } } } /* no escalation is necessary - just continue normally... */ else{ /* set the escalation flag */ *escalated=FALSE; /* find all contacts for this service */ for(temp_contact=contact_list;temp_contact!=NULL;temp_contact=temp_contact->next){ if(is_contact_for_service(svc,temp_contact)==TRUE) add_notification(temp_contact); } } #ifdef DEBUG0 printf("create_notification_list_from_service() end\n"); #endif return OK; } /******************************************************************/ /******************* HOST NOTIFICATION FUNCTIONS ******************/ /******************************************************************/ /* notify all contacts for a host that the entire host is down or up */ int host_notification(host *hst, int type, char *ack_author, char *ack_data){ notification *temp_notification; time_t current_time; struct timeval start_time; struct timeval end_time; int escalated=FALSE; int result=OK; int contacts_notified=0; #ifdef DEBUG0 printf("host_notification() start\n"); #endif /* get the current time */ time(¤t_time); gettimeofday(&start_time,NULL); #ifdef DEBUG4 printf("\nHOST NOTIFICATION ATTEMPT: Host '%s'\n",hst->name); printf("\tType: %d\n",type); printf("\tCurrent time: %s",ctime(¤t_time)); #endif /* check viability of sending out a host notification */ if(check_host_notification_viability(hst,type)==ERROR){ #ifdef DEBUG4 printf("\tSending out a notification for this host is not viable at this time.\n"); #endif return OK; } /* if this is just a normal notification... */ if(type==NOTIFICATION_NORMAL){ /* increment the current notification number */ hst->current_notification_number++; #ifdef DEBUG4 printf("\tCurrent notification number: %d\n",hst->current_notification_number); #endif } /* create the contact notification list for this host */ create_notification_list_from_host(hst,&escalated); #ifdef USE_EVENT_BROKER /* send data to event broker */ end_time.tv_sec=0L; end_time.tv_usec=0L; broker_notification_data(NEBTYPE_NOTIFICATION_START,NEBFLAG_NONE,NEBATTR_NONE,HOST_NOTIFICATION,type,start_time,end_time,(void *)hst,ack_author,ack_data,escalated,0,NULL); #endif /* there are contacts to be notified... */ if(notification_list!=NULL){ /* grab the macro variables */ clear_volatile_macros(); grab_host_macros(hst); /* if this is an acknowledgement, get the acknowledgement macros */ if(type==NOTIFICATION_ACKNOWLEDGEMENT){ if(macro_x[MACRO_HOSTACKAUTHOR]!=NULL) free(macro_x[MACRO_HOSTACKAUTHOR]); if(ack_author==NULL) macro_x[MACRO_HOSTACKAUTHOR]=NULL; else macro_x[MACRO_HOSTACKAUTHOR]=strdup(ack_author); if(macro_x[MACRO_HOSTACKCOMMENT]!=NULL) free(macro_x[MACRO_HOSTACKCOMMENT]); if(ack_data==NULL) macro_x[MACRO_HOSTACKCOMMENT]=NULL; else macro_x[MACRO_HOSTACKCOMMENT]=strdup(ack_data); } /* set the notification type macro */ if(macro_x[MACRO_NOTIFICATIONTYPE]!=NULL) free(macro_x[MACRO_NOTIFICATIONTYPE]); macro_x[MACRO_NOTIFICATIONTYPE]=(char *)malloc(MAX_NOTIFICATIONTYPE_LENGTH); if(macro_x[MACRO_NOTIFICATIONTYPE]!=NULL){ if(type==NOTIFICATION_ACKNOWLEDGEMENT) strcpy(macro_x[MACRO_NOTIFICATIONTYPE],"ACKNOWLEDGEMENT"); else if(type==NOTIFICATION_FLAPPINGSTART) strcpy(macro_x[MACRO_NOTIFICATIONTYPE],"FLAPPINGSTART"); else if(type==NOTIFICATION_FLAPPINGSTOP) strcpy(macro_x[MACRO_NOTIFICATIONTYPE],"FLAPPINGSTOP"); else if(hst->current_state==HOST_UP) strcpy(macro_x[MACRO_NOTIFICATIONTYPE],"RECOVERY"); else strcpy(macro_x[MACRO_NOTIFICATIONTYPE],"PROBLEM"); } /* set the notification number macro */ if(macro_x[MACRO_NOTIFICATIONNUMBER]!=NULL) free(macro_x[MACRO_NOTIFICATIONNUMBER]); macro_x[MACRO_NOTIFICATIONNUMBER]=(char *)malloc(MAX_NOTIFICATIONNUMBER_LENGTH); if(macro_x[MACRO_NOTIFICATIONNUMBER]!=NULL){ snprintf(macro_x[MACRO_NOTIFICATIONNUMBER],MAX_NOTIFICATIONNUMBER_LENGTH-1,"%d",hst->current_notification_number); macro_x[MACRO_NOTIFICATIONNUMBER][MAX_NOTIFICATIONNUMBER_LENGTH-1]='\x0'; } /* notify each contact (duplicates have been removed) */ for(temp_notification=notification_list;temp_notification!=NULL;temp_notification=temp_notification->next){ /* grab the macro variables for this contact */ grab_contact_macros(temp_notification->contact); /* grab summary macros (customized for this contact) */ grab_summary_macros(temp_notification->contact); /* notify this contact */ result=notify_contact_of_host(temp_notification->contact,hst,type,ack_author,ack_data,escalated); /* keep track of how many contacts were notified */ if(result==OK) contacts_notified++; } /* free memory allocated to the notification list */ free_notification_list(); if(type==NOTIFICATION_NORMAL){ /* adjust last/next notification time and notification flags if we notified someone */ if(contacts_notified>0){ /* calculate the next acceptable re-notification time */ hst->next_host_notification=get_next_host_notification_time(hst,current_time); #ifdef DEBUG4 printf("\tCurrent Time: %s",ctime(¤t_time)); printf("\tNext acceptable notification time: %s",ctime(&hst->next_host_notification)); #endif /* update the last notification time for this host (this is needed for scheduling the next problem notification) */ hst->last_host_notification=current_time; /* update notifications flags */ if(hst->current_state==HOST_DOWN) hst->notified_on_down=TRUE; else if(hst->current_state==HOST_UNREACHABLE) hst->notified_on_unreachable=TRUE; } /* we didn't end up notifying anyone, so adjust current notification number */ else hst->current_notification_number--; } #ifdef DEBUG4 printf("\tAPPROPRIATE CONTACTS HAVE BEEN NOTIFIED\n"); #endif } /* there were no contacts, so no notification really occurred... */ else{ /* adjust notification number, since no notification actually went out */ if(type==NOTIFICATION_NORMAL) hst->current_notification_number--; #ifdef DEBUG4 printf("\tTHERE WERE NO CONTACTS TO BE NOTIFIED!\n"); #endif } /* get the time we finished */ gettimeofday(&end_time,NULL); #ifdef USE_EVENT_BROKER /* send data to event broker */ broker_notification_data(NEBTYPE_NOTIFICATION_END,NEBFLAG_NONE,NEBATTR_NONE,HOST_NOTIFICATION,type,start_time,end_time,(void *)hst,ack_author,ack_data,escalated,contacts_notified,NULL); #endif /* update the status log with the host info */ update_host_status(hst,FALSE); #ifdef DEBUG0 printf("host_notification() end\n"); #endif return OK; } /* checks viability of sending a host notification */ int check_host_notification_viability(host *hst, int type){ time_t current_time; time_t timeperiod_start; #ifdef DEBUG0 printf("check_host_notification_viability() start\n"); #endif /* get current time */ time(¤t_time); /* are notifications enabled? */ if(enable_notifications==FALSE){ #ifdef DEBUG4 printf("\tNotifications are disabled, so host notifications (problems or acknowledgements) will not be sent out!\n"); #endif return ERROR; } /* see if the host can have notifications sent out at this time */ if(check_time_against_period(current_time,hst->notification_period)==ERROR){ #ifdef DEBUG4 printf("\tThis host shouldn't have notifications sent out at this time!\n"); #endif /* if this is a normal notification, calculate the next acceptable notification time, once the next valid time range arrives... */ if(type==NOTIFICATION_NORMAL){ get_next_valid_time(current_time,&timeperiod_start,hst->notification_period); /* it looks like there is no notification time defined, so schedule next one far into the future (one year)... */ if(timeperiod_start==(time_t)0) hst->next_host_notification=(time_t)(current_time+(60*60*24*365)); /* else use the next valid notification time */ else hst->next_host_notification=timeperiod_start; } return ERROR; } /* are notifications temporarily disabled for this host? */ if(hst->notifications_enabled==FALSE){ #ifdef DEBUG4 printf("\tNotifications are temporarily disabled for this host, so we won't send one out!\n"); #endif return ERROR; } /****************************************/ /*** SPECIAL CASE FOR ACKNOWLEGEMENTS ***/ /****************************************/ /* acknowledgements only have to pass three general filters, although they have another test of their own... */ if(type==NOTIFICATION_ACKNOWLEDGEMENT){ /* don't send an acknowledgement if there isn't a problem... */ if(hst->current_state==HOST_UP){ #ifdef DEBUG4 printf("\tThe host is currently UP, so we won't send an acknowledgement!\n"); #endif return ERROR; } /* acknowledgement viability test passed, so the notification can be sent out */ return OK; } /*****************************************/ /*** SPECIAL CASE FOR FLAPPING ALERTS ***/ /*****************************************/ /* flapping notifications only have to pass three general filters */ if(type==NOTIFICATION_FLAPPINGSTART || type==NOTIFICATION_FLAPPINGSTOP){ /* don't send a notification if we're not supposed to... */ if(hst->notify_on_flapping==FALSE){ #ifdef DEBUG4 printf("\tWe shouldn't notify about FLAPPING events for this host!\n"); #endif return ERROR; } /* don't send notifications during scheduled downtime */ if(hst->scheduled_downtime_depth>0){ #ifdef DEBUG4 printf("\tWe shouldn't notify about FLAPPING events during scheduled downtime!\n"); #endif return ERROR; } /* flapping viability test passed, so the notification can be sent out */ return OK; } /****************************************/ /*** NORMAL NOTIFICATIONS ***************/ /****************************************/ /* has this problem already been acknowledged? */ if(hst->problem_has_been_acknowledged==TRUE){ #ifdef DEBUG4 printf("\tThis host problem has already been acknowledged, so we won't send a notification out!\n"); #endif return ERROR; } /* check notification dependencies */ if(check_host_dependencies(hst,NOTIFICATION_DEPENDENCY)==DEPENDENCIES_FAILED){ #ifdef DEBUG4 printf("\tNotification dependencies for this host have failed, so we won't sent a notification out!\n"); #endif return ERROR; } /* see if we should notify about problems with this host */ if(hst->current_state==HOST_UNREACHABLE && hst->notify_on_unreachable==FALSE){ #ifdef DEBUG4 printf("\tWe shouldn't notify about UNREACHABLE status for this host!\n"); #endif return ERROR; } if(hst->current_state==HOST_DOWN && hst->notify_on_down==FALSE){ #ifdef DEBUG4 printf("\tWe shouldn't notify about DOWN states for this host!\n"); #endif return ERROR; } if(hst->current_state==HOST_UP){ if(hst->notify_on_recovery==FALSE){ #ifdef DEBUG4 printf("\tWe shouldn't notify about RECOVERY states for this host!\n"); #endif return ERROR; } if(!(hst->notified_on_down==TRUE || hst->notified_on_unreachable==TRUE)){ #ifdef DEBUG4 printf("\tWe shouldn't notify about this recovery\n"); #endif return ERROR; } } /* if this host is currently flapping, don't send the notification */ if(hst->is_flapping==TRUE){ #ifdef DEBUG4 printf("\tThis host is currently flapping, so we won't send notifications!\n"); #endif return ERROR; } /***** RECOVERY NOTIFICATIONS ARE GOOD TO GO AT THIS POINT *****/ if(hst->current_state==HOST_UP) return OK; /* if this host is currently in a scheduled downtime period, don't send the notification */ if(hst->scheduled_downtime_depth>0){ #ifdef DEBUG4 printf("\tThis host is currently in a scheduled downtime, so we won't send notifications!\n"); #endif return ERROR; } /* check if we shouldn't renotify contacts about the host problem */ if(hst->no_more_notifications==TRUE){ #ifdef DEBUG4 printf("\tWe shouldn't re-notify contacts about this host problem!!\n"); #endif return ERROR; } /* check if its time to re-notify the contacts about the host... */ if(current_time < hst->next_host_notification){ #ifdef DEBUG4 printf("\tIts not yet time to re-notify the contacts about this host problem...\n"); printf("\tNext acceptable notification time: %s",ctime(&hst->next_host_notification)); #endif return ERROR; } #ifdef DEBUG0 printf("check_host_notification_viability() end\n"); #endif return OK; } /* checks the viability of notifying a specific contact about a host */ int check_contact_host_notification_viability(contact *cntct, host *hst, int type){ #ifdef DEBUG0 printf("check_contact_host_notification_viability() start\n"); #endif /* see if the contact can be notified at this time */ if(check_time_against_period(time(NULL),cntct->host_notification_period)==ERROR){ #ifdef DEBUG4 printf("\tThis contact shouldn't be notified at this time!\n"); #endif return ERROR; } /****************************************/ /*** SPECIAL CASE FOR FLAPPING ALERTS ***/ /****************************************/ if(type==NOTIFICATION_FLAPPINGSTART || type==NOTIFICATION_FLAPPINGSTOP){ if(cntct->notify_on_host_flapping==FALSE){ #ifdef DEBUG4 printf("\tWe shouldn't notify this contact about FLAPPING host events!\n"); #endif return ERROR; } return OK; } /*************************************/ /*** ACKS AND NORMAL NOTIFICATIONS ***/ /*************************************/ /* see if we should notify about problems with this host */ if(hst->current_state==HOST_DOWN && cntct->notify_on_host_down==FALSE){ #ifdef DEBUG4 printf("\tWe shouldn't notify this contact about DOWN states!\n"); #endif return ERROR; } if(hst->current_state==HOST_UNREACHABLE && cntct->notify_on_host_unreachable==FALSE){ #ifdef DEBUG4 printf("\tWe shouldn't notify this contact about UNREACHABLE states!\n"); #endif return ERROR; } if(hst->current_state==HOST_UP){ if(cntct->notify_on_host_recovery==FALSE){ #ifdef DEBUG4 printf("\tWe shouldn't notify this contact about RECOVERY states!\n"); #endif return ERROR; } if(!((hst->notified_on_down==TRUE && cntct->notify_on_host_down==TRUE) || (hst->notified_on_unreachable==TRUE && cntct->notify_on_host_unreachable==TRUE))){ #ifdef DEBUG4 printf("\tWe shouldn't notify about this recovery\n"); #endif return ERROR; } } #ifdef DEBUG0 printf("check_contact_host_notification_viability() end\n"); #endif return OK; } /* notify a specific contact that an entire host is down or up */ int notify_contact_of_host(contact *cntct, host *hst, int type, char *ack_author, char *ack_data, int escalated){ commandsmember *temp_commandsmember; char command_name[MAX_INPUT_BUFFER]; char *command_name_ptr; char temp_buffer[MAX_INPUT_BUFFER]; char raw_command[MAX_COMMAND_BUFFER]; char processed_command[MAX_COMMAND_BUFFER]; int early_timeout=FALSE; double exectime; struct timeval start_time; struct timeval end_time; struct timeval method_start_time; struct timeval method_end_time; int macro_options=STRIP_ILLEGAL_MACRO_CHARS|ESCAPE_MACRO_CHARS; #ifdef DEBUG0 printf("notify_contact_of_host() start\n"); #endif #ifdef DEBUG4 printf("\tNotify user %s\n",cntct->name); #endif /* check viability of notifying this user about the host */ /* acknowledgements are no longer excluded from this test - added 8/19/02 Tom Bertelson */ if(check_contact_host_notification_viability(cntct,hst,type)==ERROR) return ERROR; /* get start time */ gettimeofday(&start_time,NULL); #ifdef USE_EVENT_BROKER /* send data to event broker */ end_time.tv_sec=0L; end_time.tv_usec=0L; broker_contact_notification_data(NEBTYPE_CONTACTNOTIFICATION_START,NEBFLAG_NONE,NEBATTR_NONE,HOST_NOTIFICATION,type,start_time,end_time,(void *)hst,cntct,ack_author,ack_data,escalated,NULL); #endif /* process all the notification commands this user has */ for(temp_commandsmember=cntct->host_notification_commands;temp_commandsmember!=NULL;temp_commandsmember=temp_commandsmember->next){ /* get start time */ gettimeofday(&method_start_time,NULL); #ifdef USE_EVENT_BROKER /* send data to event broker */ method_end_time.tv_sec=0L; method_end_time.tv_usec=0L; broker_contact_notification_method_data(NEBTYPE_CONTACTNOTIFICATIONMETHOD_START,NEBFLAG_NONE,NEBATTR_NONE,HOST_NOTIFICATION,type,method_start_time,method_end_time,(void *)hst,cntct,temp_commandsmember->command,ack_author,ack_data,escalated,NULL); #endif /* get the command name */ strncpy(command_name,temp_commandsmember->command,sizeof(command_name)); command_name[sizeof(command_name)-1]='\x0'; command_name_ptr=strtok(command_name,"!"); /* get the raw command line */ get_raw_command_line(temp_commandsmember->command,raw_command,sizeof(raw_command),macro_options); strip(raw_command); /* process any macros contained in the argument */ process_macros(raw_command,processed_command,sizeof(processed_command),macro_options); strip(processed_command); /* run the notification command */ if(strcmp(processed_command,"")){ #ifdef DEBUG4 printf("\tRaw Command: %s\n",raw_command); printf("\tProcessed Command: %s\n",processed_command); #endif /* log the notification to program log file */ if(log_notifications==TRUE){ switch(type){ case NOTIFICATION_ACKNOWLEDGEMENT: snprintf(temp_buffer,sizeof(temp_buffer),"HOST NOTIFICATION: %s;%s;ACKNOWLEDGEMENT (%s);%s;%s;%s;%s\n",cntct->name,hst->name,macro_x[MACRO_HOSTSTATE],command_name_ptr,macro_x[MACRO_HOSTOUTPUT],macro_x[MACRO_HOSTACKAUTHOR],macro_x[MACRO_HOSTACKCOMMENT]); break; case NOTIFICATION_FLAPPINGSTART: snprintf(temp_buffer,sizeof(temp_buffer),"HOST NOTIFICATION: %s;%s;FLAPPINGSTART (%s);%s;%s\n",cntct->name,hst->name,macro_x[MACRO_HOSTSTATE],command_name_ptr,macro_x[MACRO_HOSTOUTPUT]); break; case NOTIFICATION_FLAPPINGSTOP: snprintf(temp_buffer,sizeof(temp_buffer),"HOST NOTIFICATION: %s;%s;FLAPPINGSTOP (%s);%s;%s\n",cntct->name,hst->name,macro_x[MACRO_HOSTSTATE],command_name_ptr,macro_x[MACRO_HOSTOUTPUT]); break; default: snprintf(temp_buffer,sizeof(temp_buffer),"HOST NOTIFICATION: %s;%s;%s;%s;%s\n",cntct->name,hst->name,macro_x[MACRO_HOSTSTATE],command_name_ptr,macro_x[MACRO_HOSTOUTPUT]); break; } temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_all_logs(temp_buffer,NSLOG_HOST_NOTIFICATION); } /* run the command */ my_system(processed_command,notification_timeout,&early_timeout,&exectime,NULL,0); /* check to see if the notification timed out */ if(early_timeout==TRUE){ snprintf(temp_buffer,sizeof(temp_buffer),"Warning: Contact '%s' host notification command '%s' timed out after %d seconds\n",cntct->name,processed_command,DEFAULT_NOTIFICATION_TIMEOUT); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_HOST_NOTIFICATION | NSLOG_RUNTIME_WARNING,TRUE); } } /* get end time */ gettimeofday(&method_end_time,NULL); #ifdef USE_EVENT_BROKER /* send data to event broker */ broker_contact_notification_method_data(NEBTYPE_CONTACTNOTIFICATIONMETHOD_END,NEBFLAG_NONE,NEBATTR_NONE,HOST_NOTIFICATION,type,method_start_time,method_end_time,(void *)hst,cntct,temp_commandsmember->command,ack_author,ack_data,escalated,NULL); #endif } /* get end time */ gettimeofday(&end_time,NULL); #ifdef USE_EVENT_BROKER /* send data to event broker */ broker_contact_notification_data(NEBTYPE_CONTACTNOTIFICATION_END,NEBFLAG_NONE,NEBATTR_NONE,HOST_NOTIFICATION,type,start_time,end_time,(void *)hst,cntct,ack_author,ack_data,escalated,NULL); #endif #ifdef DEBUG0 printf("notify_contact_of_host() end\n"); #endif return OK; } /* checks to see if a host escalation entry is a match for the current host notification */ int is_valid_host_escalation_for_host_notification(host *hst, hostescalation *he){ host *temp_host; int notification_number; time_t current_time; #ifdef DEBUG0 printf("is_valid_host_escalation_for_host_notification() start\n"); #endif /* get the current time */ time(¤t_time); /* if this is a recovery, really we check for who got notified about a previous problem */ if(hst->current_state==HOST_UP) notification_number=hst->current_notification_number-1; else notification_number=hst->current_notification_number; /* find the host this escalation entry is associated with */ temp_host=find_host(he->host_name); if(temp_host==NULL || temp_host!=hst) return FALSE; /* skip this escalation if it happens later */ if(he->first_notification > notification_number) return FALSE; /* skip this escalation if it has already passed */ if(he->last_notification!=0 && he->last_notification < notification_number) return FALSE; /* skip this escalation if it has a timeperiod and the current time isn't valid */ if(he->escalation_period!=NULL && check_time_against_period(current_time,he->escalation_period)==ERROR) return FALSE; /* skip this escalation if the state options don't match */ if(hst->current_state==HOST_UP && he->escalate_on_recovery==FALSE) return FALSE; else if(hst->current_state==HOST_DOWN && he->escalate_on_down==FALSE) return FALSE; else if(hst->current_state==HOST_UNREACHABLE && he->escalate_on_unreachable==FALSE) return FALSE; #ifdef DEBUG0 printf("is_valid_host_escalation_for_host_notification() end\n"); #endif return TRUE; } /* checks to see whether a host notification should be escalation */ int should_host_notification_be_escalated(host *hst){ hostescalation *temp_he; #ifdef DEBUG0 printf("should_host_notification_be_escalated() start\n"); #endif /* search the host escalation list */ for(temp_he=hostescalation_list;temp_he!=NULL;temp_he=temp_he->next){ /* we found a matching entry, so escalate this notification! */ if(is_valid_host_escalation_for_host_notification(hst,temp_he)==TRUE) return TRUE; } #ifdef DEBUG0 printf("should_host_notification_be_escalated() end\n"); #endif return FALSE; } /* given a host, create a list of contacts to be notified, removing duplicates */ int create_notification_list_from_host(host *hst, int *escalated){ hostescalation *temp_he; contactgroupsmember *temp_group; contactgroup *temp_contactgroup; contact *temp_contact; #ifdef DEBUG0 printf("create_notification_list_from_host() start\n"); #endif /* see if this notification should be escalated */ if(should_host_notification_be_escalated(hst)==TRUE){ /* set the escalation flag */ *escalated=TRUE; /* check all the host escalation entries */ for(temp_he=hostescalation_list;temp_he!=NULL;temp_he=temp_he->next){ /* see if this escalation if valid for this notification */ if(is_valid_host_escalation_for_host_notification(hst,temp_he)==FALSE) continue; /* find each contact group in this escalation entry */ for(temp_group=temp_he->contact_groups;temp_group!=NULL;temp_group=temp_group->next){ temp_contactgroup=find_contactgroup(temp_group->group_name); if(temp_contactgroup==NULL) continue; /* check all contacts */ for(temp_contact=contact_list;temp_contact!=NULL;temp_contact=temp_contact->next){ if(is_contact_member_of_contactgroup(temp_contactgroup,temp_contact)==TRUE) add_notification(temp_contact); } } } } /* else we shouldn't escalate the notification, so continue as normal... */ else{ /* set the escalation flag */ *escalated=FALSE; /* get all contacts for this host */ for(temp_contact=contact_list;temp_contact!=NULL;temp_contact=temp_contact->next){ if(is_contact_for_host(hst,temp_contact)==TRUE) add_notification(temp_contact); } } #ifdef DEBUG0 printf("create_notification_list_from_host() end\n"); #endif return OK; } /******************************************************************/ /***************** NOTIFICATION TIMING FUNCTIONS ******************/ /******************************************************************/ /* calculates next acceptable re-notification time for a service */ time_t get_next_service_notification_time(service *svc, time_t offset){ time_t next_notification; int interval_to_use; serviceescalation *temp_se; int have_escalated_interval=FALSE; #ifdef DEBUG0 printf("get_next_service_notification_time() start\n"); #endif #ifdef DEBUG4 printf("\tCalculating next valid notification time...\n"); #endif /* default notification interval */ interval_to_use=svc->notification_interval; #ifdef DEBUG4 printf("\t\tDefault interval: %d\n",interval_to_use); #endif /* search all the escalation entries for valid matches for this service (at its current notification number) */ for(temp_se=serviceescalation_list;temp_se!=NULL;temp_se=temp_se->next){ /* interval < 0 means to use non-escalated interval */ if(temp_se->notification_interval<0) continue; /* skip this entry if it isn't appropriate */ if(is_valid_escalation_for_service_notification(svc,temp_se)==FALSE) continue; #ifdef DEBUG4 printf("\t\tFound a valid escalation w/ interval of %d\n",temp_se->notification_interval); #endif /* if we haven't used a notification interval from an escalation yet, use this one */ if(have_escalated_interval==FALSE){ have_escalated_interval=TRUE; interval_to_use=temp_se->notification_interval; } /* else use the shortest of all valid escalation intervals */ else if(temp_se->notification_intervalnotification_interval; #ifdef DEBUG4 printf("\t\tNew interval: %d\n",interval_to_use); #endif } /* if notification interval is 0, we shouldn't send any more problem notifications (unless service is volatile) */ if(interval_to_use==0 && svc->is_volatile==FALSE) svc->no_more_notifications=TRUE; else svc->no_more_notifications=FALSE; #ifdef DEBUG4 printf("\tInterval used for calculating next valid notification time: %d\n",interval_to_use); #endif /* calculate next notification time */ next_notification=offset+(interval_to_use*interval_length); #ifdef DEBUG0 printf("get_next_service_notification_time() end\n"); #endif return next_notification; } /* calculates next acceptable re-notification time for a host */ time_t get_next_host_notification_time(host *hst, time_t offset){ time_t next_notification; int interval_to_use; hostescalation *temp_he; int have_escalated_interval=FALSE; #ifdef DEBUG0 printf("get_next_host_notification_time() start\n"); #endif /* default notification interval */ interval_to_use=hst->notification_interval; /* check all the host escalation entries for valid matches for this host (at its current notification number) */ for(temp_he=hostescalation_list;temp_he!=NULL;temp_he=temp_he->next){ /* interval < 0 means to use non-escalated interval */ if(temp_he->notification_interval<0) continue; /* skip this entry if it isn't appropriate */ if(is_valid_host_escalation_for_host_notification(hst,temp_he)==FALSE) continue; /* if we haven't used a notification interval from an escalation yet, use this one */ if(have_escalated_interval==FALSE){ have_escalated_interval=TRUE; interval_to_use=temp_he->notification_interval; } /* else use the shortest of all valid escalation intervals */ else if(temp_he->notification_intervalnotification_interval; } /* if interval is 0, no more notifications should be sent */ if(interval_to_use==0) hst->no_more_notifications=TRUE; else hst->no_more_notifications=FALSE; /* calculate next notification time */ next_notification=offset+(interval_to_use*interval_length); #ifdef DEBUG0 printf("get_next_host_notification_time() end\n"); #endif return next_notification; } /******************************************************************/ /***************** NOTIFICATION OBJECT FUNCTIONS ******************/ /******************************************************************/ /* given a contact name, find the notification entry for them for the list in memory */ notification * find_notification(char *contact_name){ notification *temp_notification; #ifdef DEBUG0 printf("find_notification() start\n"); #endif if(contact_name==NULL) return NULL; temp_notification=notification_list; while(temp_notification!=NULL){ if(!strcmp(contact_name,temp_notification->contact->name)) return temp_notification; temp_notification=temp_notification->next; } #ifdef DEBUG0 printf("find_notification() end\n"); #endif /* we couldn't find the contact in the notification list */ return NULL; } /* add a new notification to the list in memory */ int add_notification(contact *cntct){ notification *new_notification; notification *temp_notification; #ifdef DEBUG0 printf("add_notification() start\n"); #endif #ifdef DEBUG1 printf("\tAdd contact '%s'\n",cntct->name); #endif /* don't add anything if this contact is already on the notification list */ temp_notification=find_notification(cntct->name); if(temp_notification!=NULL) return OK; /* allocate memory for a new contact in the notification list */ new_notification=malloc(sizeof(notification)); if(new_notification==NULL) return ERROR; /* fill in the contact info */ new_notification->contact=cntct; /* add new notification to head of list */ new_notification->next=notification_list; notification_list=new_notification; #ifdef DEBUG0 printf("add_notification() end\n"); #endif return OK; } nagios-2.6/base/perfdata.c0000664000076500007650000000570010336571237015054 0ustar nagiosnagios/***************************************************************************** * * PERFDATA.C - Performance data routines for Nagios * * Copyright (c) 2000-2004 Ethan Galstad (nagios@nagios.org) * Last Modified: 11-29-2004 * * 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/perfdata.h" /***** IMPLEMENTATION-SPECIFIC HEADER FILES *****/ #ifdef USE_XPDDEFAULT #include "../xdata/xpddefault.h" #endif extern int process_performance_data; /******************************************************************/ /************** INITIALIZATION & CLEANUP FUNCTIONS ****************/ /******************************************************************/ /* initializes performance data */ int initialize_performance_data(char *config_file){ #ifdef USE_XPDDEFAULT xpddefault_initialize_performance_data(config_file); #endif return OK; } /* cleans up performance data */ int cleanup_performance_data(char *config_file){ #ifdef USE_XPDDEFAULT xpddefault_cleanup_performance_data(config_file); #endif return OK; } /******************************************************************/ /****************** PERFORMANCE DATA FUNCTIONS ********************/ /******************************************************************/ /* updates service performance data */ int update_service_performance_data(service *svc){ /* should we be processing performance data for anything? */ if(process_performance_data==FALSE) return OK; /* should we process performance data for this service? */ if(svc->process_performance_data==FALSE) return OK; /* process the performance data! */ #ifdef USE_XPDDEFAULT xpddefault_update_service_performance_data(svc); #endif return OK; } /* updates host performance data */ int update_host_performance_data(host *hst){ /* should we be processing performance data for anything? */ if(process_performance_data==FALSE) return OK; /* should we process performance data for this host? */ if(hst->process_performance_data==FALSE) return OK; /* process the performance data! */ #ifdef USE_XPDDEFAULT xpddefault_update_host_performance_data(hst); #endif return OK; } nagios-2.6/base/sehandlers.c0000664000076500007650000005747310353050230015414 0ustar nagiosnagios/***************************************************************************** * * SEHANDLERS.C - Service and host event and state handlers for Nagios * * Copyright (c) 1999-2004 Ethan Galstad (nagios@nagios.org) * Last Modified: 12-19-2004 * * 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. * *****************************************************************************/ #include "../include/config.h" #include "../include/common.h" #include "../include/statusdata.h" #include "../include/downtime.h" #include "../include/nagios.h" #include "../include/perfdata.h" #include "../include/broker.h" extern int enable_event_handlers; extern int obsess_over_services; extern int obsess_over_hosts; extern int log_event_handlers; extern int log_host_retries; extern int event_handler_timeout; extern int ocsp_timeout; extern int ochp_timeout; extern char *macro_x[MACRO_X_COUNT]; extern char *global_host_event_handler; extern char *global_service_event_handler; extern char *ocsp_command; extern char *ochp_command; extern time_t program_start; /******************************************************************/ /************* OBSESSIVE COMPULSIVE HANDLER FUNCTIONS *************/ /******************************************************************/ /* handles service check results in an obsessive compulsive manner... */ int obsessive_compulsive_service_check_processor(service *svc){ char raw_command_line[MAX_COMMAND_BUFFER]; char processed_command_line[MAX_COMMAND_BUFFER]; char temp_buffer[MAX_INPUT_BUFFER]; host *temp_host; int early_timeout=FALSE; double exectime; int macro_options=STRIP_ILLEGAL_MACRO_CHARS|ESCAPE_MACRO_CHARS; #ifdef DEBUG0 printf("obsessive_compulsive_service_check_processor() start\n"); #endif /* bail out if we shouldn't be obsessing */ if(obsess_over_services==FALSE) return OK; if(svc->obsess_over_service==FALSE) return OK; /* if there is no valid command, exit */ if(ocsp_command==NULL) return ERROR; /* find the associated host */ temp_host=find_host(svc->host_name); /* update service macros */ clear_volatile_macros(); grab_host_macros(temp_host); grab_service_macros(svc); grab_summary_macros(NULL); /* get the raw command line */ get_raw_command_line(ocsp_command,raw_command_line,sizeof(raw_command_line),macro_options); strip(raw_command_line); #ifdef DEBUG3 printf("\tRaw obsessive compulsive service processor command line: %s\n",raw_command_line); #endif /* process any macros in the raw command line */ process_macros(raw_command_line,processed_command_line,(int)sizeof(processed_command_line),macro_options); #ifdef DEBUG3 printf("\tProcessed obsessive compulsive service processor command line: %s\n",processed_command_line); #endif /* run the command */ my_system(processed_command_line,ocsp_timeout,&early_timeout,&exectime,NULL,0); /* check to see if the command timed out */ if(early_timeout==TRUE){ snprintf(temp_buffer,sizeof(temp_buffer),"Warning: OCSP command '%s' for service '%s' on host '%s' timed out after %d seconds\n",processed_command_line,svc->description,svc->host_name,ocsp_timeout); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_RUNTIME_WARNING,TRUE); } #ifdef DEBUG0 printf("obsessive_compulsive_service_check_processor() end\n"); #endif return OK; } /* handles host check results in an obsessive compulsive manner... */ int obsessive_compulsive_host_check_processor(host *hst){ char raw_command_line[MAX_COMMAND_BUFFER]; char processed_command_line[MAX_COMMAND_BUFFER]; char temp_buffer[MAX_INPUT_BUFFER]; int early_timeout=FALSE; double exectime; int macro_options=STRIP_ILLEGAL_MACRO_CHARS|ESCAPE_MACRO_CHARS; #ifdef DEBUG0 printf("obsessive_compulsive_host_check_processor() start\n"); #endif /* bail out if we shouldn't be obsessing */ if(obsess_over_hosts==FALSE) return OK; if(hst->obsess_over_host==FALSE) return OK; /* if there is no valid command, exit */ if(ochp_command==NULL) return ERROR; /* update macros */ clear_volatile_macros(); grab_host_macros(hst); grab_summary_macros(NULL); /* get the raw command line */ get_raw_command_line(ochp_command,raw_command_line,sizeof(raw_command_line),macro_options); strip(raw_command_line); #ifdef DEBUG3 printf("\tRaw obsessive compulsive host processor command line: %s\n",raw_command_line); #endif /* process any macros in the raw command line */ process_macros(raw_command_line,processed_command_line,(int)sizeof(processed_command_line),macro_options); #ifdef DEBUG3 printf("\tProcessed obsessive compulsive host processor command line: %s\n",processed_command_line); #endif /* run the command */ my_system(processed_command_line,ochp_timeout,&early_timeout,&exectime,NULL,0); /* check to see if the command timed out */ if(early_timeout==TRUE){ snprintf(temp_buffer,sizeof(temp_buffer),"Warning: OCHP command '%s' for host '%s' timed out after %d seconds\n",processed_command_line,hst->name,ochp_timeout); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_RUNTIME_WARNING,TRUE); } #ifdef DEBUG0 printf("obsessive_compulsive_host_check_processor() end\n"); #endif return OK; } /******************************************************************/ /**************** SERVICE EVENT HANDLER FUNCTIONS *****************/ /******************************************************************/ /* handles changes in the state of a service */ int handle_service_event(service *svc){ host *temp_host; #ifdef DEBUG0 printf("handle_service_event() start\n"); #endif #ifdef USE_EVENT_BROKER /* send event data to broker */ broker_statechange_data(NEBTYPE_STATECHANGE_END,NEBFLAG_NONE,NEBATTR_NONE,SERVICE_STATECHANGE,(void *)svc,svc->current_state,svc->state_type,svc->current_attempt,svc->max_attempts,NULL); #endif /* bail out if we shouldn't be running event handlers */ if(enable_event_handlers==FALSE) return OK; if(svc->event_handler_enabled==FALSE) return OK; /* find the host */ temp_host=find_host(svc->host_name); /* update service macros */ clear_volatile_macros(); grab_host_macros(temp_host); grab_service_macros(svc); grab_summary_macros(NULL); /* run the global service event handler */ run_global_service_event_handler(svc); /* run the event handler command if there is one */ if(svc->event_handler!=NULL) run_service_event_handler(svc); /* check for external commands - the event handler may have given us some directives... */ check_for_external_commands(); #ifdef DEBUG0 printf("handle_service_event() end\n"); #endif return OK; } /* runs the global service event handler */ int run_global_service_event_handler(service *svc){ char raw_command_line[MAX_COMMAND_BUFFER]; char processed_command_line[MAX_COMMAND_BUFFER]; char command_output[MAX_INPUT_BUFFER]; char temp_buffer[MAX_INPUT_BUFFER]; int early_timeout=FALSE; double exectime=0.0; int result=0; struct timeval start_time; struct timeval end_time; int macro_options=STRIP_ILLEGAL_MACRO_CHARS|ESCAPE_MACRO_CHARS; #ifdef DEBUG0 printf("run_global_service_event_handler() start\n"); #endif /* bail out if we shouldn't be running event handlers */ if(enable_event_handlers==FALSE) return OK; /* a global service event handler command has not been defined */ if(global_service_event_handler==NULL) return ERROR; /* get start time */ gettimeofday(&start_time,NULL); #ifdef USE_EVENT_BROKER /* send event data to broker */ end_time.tv_sec=0L; end_time.tv_usec=0L; broker_event_handler(NEBTYPE_EVENTHANDLER_START,NEBFLAG_NONE,NEBATTR_NONE,GLOBAL_SERVICE_EVENTHANDLER,(void *)svc,svc->current_state,svc->state_type,start_time,end_time,exectime,event_handler_timeout,early_timeout,result,global_service_event_handler,NULL,NULL,NULL); #endif /* get the raw command line */ get_raw_command_line(global_service_event_handler,raw_command_line,sizeof(raw_command_line),macro_options); strip(raw_command_line); #ifdef DEBUG3 printf("\tRaw global service event handler command line: %s\n",raw_command_line); #endif /* process any macros in the raw command line */ process_macros(raw_command_line,processed_command_line,(int)sizeof(processed_command_line),macro_options); #ifdef DEBUG3 printf("\tProcessed global service event handler command line: %s\n",processed_command_line); #endif if(log_event_handlers==TRUE){ snprintf(temp_buffer,sizeof(temp_buffer),"GLOBAL SERVICE EVENT HANDLER: %s;%s;%s;%s;%s;%s\n",svc->host_name,svc->description,macro_x[MACRO_SERVICESTATE],macro_x[MACRO_SERVICESTATETYPE],macro_x[MACRO_SERVICEATTEMPT],global_service_event_handler); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_all_logs(temp_buffer,NSLOG_EVENT_HANDLER); } /* run the command */ result=my_system(processed_command_line,event_handler_timeout,&early_timeout,&exectime,command_output,sizeof(command_output)-1); /* check to see if the event handler timed out */ if(early_timeout==TRUE){ snprintf(temp_buffer,sizeof(temp_buffer),"Warning: Global service event handler command '%s' timed out after %d seconds\n",processed_command_line,event_handler_timeout); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_EVENT_HANDLER | NSLOG_RUNTIME_WARNING,TRUE); } /* get end time */ gettimeofday(&end_time,NULL); #ifdef USE_EVENT_BROKER /* send event data to broker */ broker_event_handler(NEBTYPE_EVENTHANDLER_END,NEBFLAG_NONE,NEBATTR_NONE,GLOBAL_SERVICE_EVENTHANDLER,(void *)svc,svc->current_state,svc->state_type,start_time,end_time,exectime,event_handler_timeout,early_timeout,result,global_service_event_handler,processed_command_line,command_output,NULL); #endif #ifdef DEBUG0 printf("run_global_service_event_handler() end\n"); #endif return OK; } /* runs a service event handler command */ int run_service_event_handler(service *svc){ char raw_command_line[MAX_COMMAND_BUFFER]; char processed_command_line[MAX_COMMAND_BUFFER]; char command_output[MAX_INPUT_BUFFER]; char temp_buffer[MAX_INPUT_BUFFER]; int early_timeout=FALSE; double exectime=0.0; int result=0; struct timeval start_time; struct timeval end_time; int macro_options=STRIP_ILLEGAL_MACRO_CHARS|ESCAPE_MACRO_CHARS; #ifdef DEBUG0 printf("run_service_event_handler() start\n"); #endif /* bail if there's no command */ if(svc->event_handler==NULL) return ERROR; /* get start time */ gettimeofday(&start_time,NULL); #ifdef USE_EVENT_BROKER /* send event data to broker */ end_time.tv_sec=0L; end_time.tv_usec=0L; broker_event_handler(NEBTYPE_EVENTHANDLER_START,NEBFLAG_NONE,NEBATTR_NONE,SERVICE_EVENTHANDLER,(void *)svc,svc->current_state,svc->state_type,start_time,end_time,exectime,event_handler_timeout,early_timeout,result,svc->event_handler,NULL,NULL,NULL); #endif /* get the raw command line */ get_raw_command_line(svc->event_handler,raw_command_line,sizeof(raw_command_line),macro_options); strip(raw_command_line); #ifdef DEBUG3 printf("\tRaw service event handler command line: %s\n",raw_command_line); #endif /* process any macros in the raw command line */ process_macros(raw_command_line,processed_command_line,(int)sizeof(processed_command_line),macro_options); #ifdef DEBUG3 printf("\tProcessed service event handler command line: %s\n",processed_command_line); #endif if(log_event_handlers==TRUE){ snprintf(temp_buffer,sizeof(temp_buffer),"SERVICE EVENT HANDLER: %s;%s;%s;%s;%s;%s\n",svc->host_name,svc->description,macro_x[MACRO_SERVICESTATE],macro_x[MACRO_SERVICESTATETYPE],macro_x[MACRO_SERVICEATTEMPT],svc->event_handler); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_all_logs(temp_buffer,NSLOG_EVENT_HANDLER); } /* run the command */ result=my_system(processed_command_line,event_handler_timeout,&early_timeout,&exectime,command_output,sizeof(command_output)-1); /* check to see if the event handler timed out */ if(early_timeout==TRUE){ snprintf(temp_buffer,sizeof(temp_buffer),"Warning: Service event handler command '%s' timed out after %d seconds\n",processed_command_line,event_handler_timeout); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_EVENT_HANDLER | NSLOG_RUNTIME_WARNING,TRUE); } /* get end time */ gettimeofday(&end_time,NULL); #ifdef USE_EVENT_BROKER /* send event data to broker */ broker_event_handler(NEBTYPE_EVENTHANDLER_END,NEBFLAG_NONE,NEBATTR_NONE,SERVICE_EVENTHANDLER,(void *)svc,svc->current_state,svc->state_type,start_time,end_time,exectime,event_handler_timeout,early_timeout,result,svc->event_handler,processed_command_line,command_output,NULL); #endif #ifdef DEBUG0 printf("run_service_event_handler() end\n"); #endif return OK; } /******************************************************************/ /****************** HOST EVENT HANDLER FUNCTIONS ******************/ /******************************************************************/ /* handles a change in the status of a host */ int handle_host_event(host *hst){ #ifdef DEBUG0 printf("handle_host_event() start\n"); #endif #ifdef USE_EVENT_BROKER /* send event data to broker */ broker_statechange_data(NEBTYPE_STATECHANGE_END,NEBFLAG_NONE,NEBATTR_NONE,HOST_STATECHANGE,(void *)hst,hst->current_state,hst->state_type,hst->current_attempt,hst->max_attempts,NULL); #endif /* bail out if we shouldn't be running event handlers */ if(enable_event_handlers==FALSE) return OK; if(hst->event_handler_enabled==FALSE) return OK; /* update host macros */ clear_volatile_macros(); grab_host_macros(hst); grab_summary_macros(NULL); /* run the global host event handler */ run_global_host_event_handler(hst); /* run the event handler command if there is one */ if(hst->event_handler!=NULL) run_host_event_handler(hst); /* check for external commands - the event handler may have given us some directives... */ check_for_external_commands(); #ifdef DEBUG0 printf("handle_host_event() end\n"); #endif return OK; } /* runs the global host event handler */ int run_global_host_event_handler(host *hst){ char raw_command_line[MAX_COMMAND_BUFFER]; char processed_command_line[MAX_COMMAND_BUFFER]; char command_output[MAX_INPUT_BUFFER]; char temp_buffer[MAX_INPUT_BUFFER]; int early_timeout=FALSE; double exectime=0.0; int result=0; struct timeval start_time; struct timeval end_time; int macro_options=STRIP_ILLEGAL_MACRO_CHARS|ESCAPE_MACRO_CHARS; #ifdef DEBUG0 printf("run_global_host_event_handler() start\n"); #endif /* bail out if we shouldn't be running event handlers */ if(enable_event_handlers==FALSE) return OK; /* no global host event handler command is defined */ if(global_host_event_handler==NULL) return ERROR; /* get start time */ gettimeofday(&start_time,NULL); #ifdef USE_EVENT_BROKER /* send event data to broker */ end_time.tv_sec=0L; end_time.tv_usec=0L; broker_event_handler(NEBTYPE_EVENTHANDLER_START,NEBFLAG_NONE,NEBATTR_NONE,GLOBAL_HOST_EVENTHANDLER,(void *)hst,hst->current_state,hst->state_type,start_time,end_time,exectime,event_handler_timeout,early_timeout,result,global_host_event_handler,NULL,NULL,NULL); #endif /* get the raw command line */ get_raw_command_line(global_host_event_handler,raw_command_line,sizeof(raw_command_line),macro_options); strip(raw_command_line); #ifdef DEBUG3 printf("\tRaw global host event handler command line: %s\n",raw_command_line); #endif /* process any macros in the raw command line */ process_macros(raw_command_line,processed_command_line,(int)sizeof(processed_command_line),macro_options); #ifdef DEBUG3 printf("\tProcessed global host event handler command line: %s\n",processed_command_line); #endif if(log_event_handlers==TRUE){ snprintf(temp_buffer,sizeof(temp_buffer),"GLOBAL HOST EVENT HANDLER: %s;%s;%s;%s;%s\n",hst->name,macro_x[MACRO_HOSTSTATE],macro_x[MACRO_HOSTSTATETYPE],macro_x[MACRO_HOSTATTEMPT],global_host_event_handler); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_all_logs(temp_buffer,NSLOG_EVENT_HANDLER); } /* run the command */ result=my_system(processed_command_line,event_handler_timeout,&early_timeout,&exectime,command_output,sizeof(command_output)-1); /* check for a timeout in the execution of the event handler command */ if(early_timeout==TRUE){ snprintf(temp_buffer,sizeof(temp_buffer),"Warning: Global host event handler command '%s' timed out after %d seconds\n",processed_command_line,event_handler_timeout); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_EVENT_HANDLER | NSLOG_RUNTIME_WARNING,TRUE); } /* get end time */ gettimeofday(&end_time,NULL); #ifdef USE_EVENT_BROKER /* send event data to broker */ broker_event_handler(NEBTYPE_EVENTHANDLER_END,NEBFLAG_NONE,NEBATTR_NONE,GLOBAL_HOST_EVENTHANDLER,(void *)hst,hst->current_state,hst->state_type,start_time,end_time,exectime,event_handler_timeout,early_timeout,result,global_host_event_handler,processed_command_line,command_output,NULL); #endif #ifdef DEBUG0 printf("run_global_host_event_handler() end\n"); #endif return OK; } /* runs a host event handler command */ int run_host_event_handler(host *hst){ char raw_command_line[MAX_COMMAND_BUFFER]; char processed_command_line[MAX_COMMAND_BUFFER]; char command_output[MAX_INPUT_BUFFER]; char temp_buffer[MAX_INPUT_BUFFER]; int early_timeout=FALSE; double exectime=0.0; int result=0; struct timeval start_time; struct timeval end_time; int macro_options=STRIP_ILLEGAL_MACRO_CHARS|ESCAPE_MACRO_CHARS; #ifdef DEBUG0 printf("run_host_event_handler() start\n"); #endif /* bail if there's no command */ if(hst->event_handler==NULL) return ERROR; /* get start time */ gettimeofday(&start_time,NULL); #ifdef USE_EVENT_BROKER /* send event data to broker */ broker_event_handler(NEBTYPE_EVENTHANDLER_START,NEBFLAG_NONE,NEBATTR_NONE,HOST_EVENTHANDLER,(void *)hst,hst->current_state,hst->state_type,start_time,end_time,exectime,event_handler_timeout,early_timeout,result,hst->event_handler,NULL,NULL,NULL); #endif /* get the raw command line */ get_raw_command_line(hst->event_handler,raw_command_line,sizeof(raw_command_line),macro_options); strip(raw_command_line); #ifdef DEBUG3 printf("\tRaw host event handler command line: %s\n",raw_command_line); #endif /* process any macros in the raw command line */ process_macros(raw_command_line,processed_command_line,(int)sizeof(processed_command_line),macro_options); #ifdef DEBUG3 printf("\tProcessed host event handler command line: %s\n",processed_command_line); #endif if(log_event_handlers==TRUE){ snprintf(temp_buffer,sizeof(temp_buffer),"HOST EVENT HANDLER: %s;%s;%s;%s;%s\n",hst->name,macro_x[MACRO_HOSTSTATE],macro_x[MACRO_HOSTSTATETYPE],macro_x[MACRO_HOSTATTEMPT],hst->event_handler); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_all_logs(temp_buffer,NSLOG_EVENT_HANDLER); } /* run the command */ result=my_system(processed_command_line,event_handler_timeout,&early_timeout,&exectime,command_output,sizeof(command_output)-1); /* check to see if the event handler timed out */ if(early_timeout==TRUE){ snprintf(temp_buffer,sizeof(temp_buffer),"Warning: Host event handler command '%s' timed out after %d seconds\n",processed_command_line,event_handler_timeout); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_EVENT_HANDLER | NSLOG_RUNTIME_WARNING,TRUE); } /* get end time */ gettimeofday(&end_time,NULL); #ifdef USE_EVENT_BROKER /* send event data to broker */ broker_event_handler(NEBTYPE_EVENTHANDLER_END,NEBFLAG_NONE,NEBATTR_NONE,HOST_EVENTHANDLER,(void *)hst,hst->current_state,hst->state_type,start_time,end_time,exectime,event_handler_timeout,early_timeout,result,hst->event_handler,processed_command_line,command_output,NULL); #endif #ifdef DEBUG0 printf("run_host_event_handler() end\n"); #endif return OK; } /******************************************************************/ /****************** HOST STATE HANDLER FUNCTIONS ******************/ /******************************************************************/ /* top level host state handler - occurs after every host check (soft/hard and active/passive) */ int handle_host_state(host *hst){ int state_change=FALSE; time_t current_time; #ifdef DEBUG0 printf("handle_host_state() start\n"); #endif /* get current time */ time(¤t_time); /* obsess over this host check */ obsessive_compulsive_host_check_processor(hst); /* update performance data */ update_host_performance_data(hst); /* record latest time for current state */ switch(hst->current_state){ case HOST_UP: hst->last_time_up=current_time; break; case HOST_DOWN: hst->last_time_down=current_time; break; case HOST_UNREACHABLE: hst->last_time_unreachable=current_time; break; default: break; } /* has the host state changed? */ if(hst->last_state!=hst->current_state || (hst->current_state==HOST_UP && hst->state_type==SOFT_STATE)) state_change=TRUE; /* if the host state has changed... */ if(state_change==TRUE){ /* update last state change times */ hst->last_state_change=current_time; if(hst->state_type==HARD_STATE) hst->last_hard_state_change=current_time; /* reset the acknowledgement flag if necessary */ if(hst->acknowledgement_type==ACKNOWLEDGEMENT_NORMAL){ hst->problem_has_been_acknowledged=FALSE; hst->acknowledgement_type=ACKNOWLEDGEMENT_NONE; } else if(hst->acknowledgement_type==ACKNOWLEDGEMENT_STICKY && hst->current_state==HOST_UP){ hst->problem_has_been_acknowledged=FALSE; hst->acknowledgement_type=ACKNOWLEDGEMENT_NONE; } /* reset the next and last notification times */ hst->last_host_notification=(time_t)0; hst->next_host_notification=(time_t)0; /* reset notification suppression option */ hst->no_more_notifications=FALSE; /* the host just recovered, so reset the current host attempt */ /* 11/11/05 EG - moved below */ /* if(hst->current_state==HOST_UP) hst->current_attempt=1; */ /* write the host state change to the main log file */ if(hst->state_type==HARD_STATE || (hst->state_type==SOFT_STATE && log_host_retries==TRUE)) log_host_event(hst); /* check for start of flexible (non-fixed) scheduled downtime */ if(hst->state_type==HARD_STATE) check_pending_flex_host_downtime(hst); /* notify contacts about the recovery or problem if its a "hard" state */ if(hst->state_type==HARD_STATE) host_notification(hst,NOTIFICATION_NORMAL,NULL,NULL); /* handle the host state change */ handle_host_event(hst); /* the host just recovered, so reset the current host attempt */ if(hst->current_state==HOST_UP) hst->current_attempt=1; /* the host recovered, so reset the current notification number and state flags (after the recovery notification has gone out) */ if(hst->current_state==HOST_UP){ hst->current_notification_number=0; hst->notified_on_down=FALSE; hst->notified_on_unreachable=FALSE; } } /* else the host state has not changed */ else{ /* notify contacts if host is still down or unreachable */ if(hst->current_state!=HOST_UP && hst->state_type==HARD_STATE) host_notification(hst,NOTIFICATION_NORMAL,NULL,NULL); /* if we're in a soft state and we should log host retries, do so now... */ if(hst->state_type==SOFT_STATE && log_host_retries==TRUE) log_host_event(hst); } #ifdef DEBUG0 printf("handle_host_state() end\n"); #endif return OK; } nagios-2.6/base/sretention.c0000664000076500007650000000674410336571237015471 0ustar nagiosnagios/***************************************************************************** * * SRETENTION.C - State retention routines for Nagios * * Copyright (c) 1999-2003 Ethan Galstad (nagios@nagios.org) * Last Modified: 08-24-2003 * * 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 "../include/nagios.h" #include "../include/sretention.h" #include "../include/broker.h" extern int retain_state_information; /**** IMPLEMENTATION SPECIFIC HEADER FILES ****/ #ifdef USE_XRDDEFAULT #include "../xdata/xrddefault.h" /* default routines */ #endif /******************************************************************/ /************* TOP-LEVEL STATE INFORMATION FUNCTIONS **************/ /******************************************************************/ /* save all host and service state information */ int save_state_information(char *main_config_file, int autosave){ char buffer[MAX_INPUT_BUFFER]; int result=OK; #ifdef DEBUG0 printf("save_state_information() start\n"); #endif if(retain_state_information==FALSE) return OK; #ifdef USE_EVENT_BROKER /* send data to event broker */ broker_retention_data(NEBTYPE_RETENTIONDATA_STARTSAVE,NEBFLAG_NONE,NEBATTR_NONE,NULL); #endif /********* IMPLEMENTATION-SPECIFIC OUTPUT FUNCTION ********/ #ifdef USE_XRDDEFAULT result=xrddefault_save_state_information(main_config_file); #endif #ifdef USE_EVENT_BROKER /* send data to event broker */ broker_retention_data(NEBTYPE_RETENTIONDATA_ENDSAVE,NEBFLAG_NONE,NEBATTR_NONE,NULL); #endif if(result==ERROR) return ERROR; if(autosave==TRUE){ snprintf(buffer,sizeof(buffer),"Auto-save of retention data completed successfully.\n"); buffer[sizeof(buffer)-1]='\x0'; write_to_all_logs(buffer,NSLOG_PROCESS_INFO); } #ifdef DEBUG0 printf("save_state_information() end\n"); #endif return OK; } /* reads in initial host and state information */ int read_initial_state_information(char *main_config_file){ int result=OK; #ifdef DEBUG0 printf("read_initial_state_information() start\n"); #endif if(retain_state_information==FALSE) return OK; #ifdef USE_EVENT_BROKER /* send data to event broker */ broker_retention_data(NEBTYPE_RETENTIONDATA_STARTLOAD,NEBFLAG_NONE,NEBATTR_NONE,NULL); #endif /********* IMPLEMENTATION-SPECIFIC INPUT FUNCTION ********/ #ifdef USE_XRDDEFAULT result=xrddefault_read_state_information(main_config_file); #endif #ifdef USE_EVENT_BROKER /* send data to event broker */ broker_retention_data(NEBTYPE_RETENTIONDATA_ENDLOAD,NEBFLAG_NONE,NEBATTR_NONE,NULL); #endif if(result==ERROR) return ERROR; #ifdef DEBUG0 printf("read_initial_state_information() end\n"); #endif return OK; } nagios-2.6/base/utils.c0000664000076500007650000046373310520507414014433 0ustar nagiosnagios/***************************************************************************** * * UTILS.C - Miscellaneous utility functions for Nagios * * Copyright (c) 1999-2006 Ethan Galstad (nagios@nagios.org) * Last Modified: 10-27-2006 * * 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. * *****************************************************************************/ #include "../include/config.h" #include "../include/common.h" #include "../include/objects.h" #include "../include/statusdata.h" #include "../include/comments.h" #include "../include/nagios.h" #include "../include/broker.h" #include "../include/nebmods.h" #include "../include/nebmodules.h" #ifdef EMBEDDEDPERL #include "../include/epn_nagios.h" static PerlInterpreter *my_perl = NULL; int use_embedded_perl=TRUE; #endif char *my_strtok_buffer=NULL; char *original_my_strtok_buffer=NULL; extern char *config_file; extern char *log_file; extern char *command_file; extern char *temp_file; extern char *lock_file; extern char *log_archive_path; extern char *auth_file; extern char *p1_file; extern char *nagios_user; extern char *nagios_group; extern char *macro_x[MACRO_X_COUNT]; extern char *macro_x_names[MACRO_X_COUNT]; extern char *macro_argv[MAX_COMMAND_ARGUMENTS]; extern char *macro_user[MAX_USER_MACROS]; extern char *macro_contactaddress[MAX_CONTACT_ADDRESSES]; extern char *macro_ondemand; extern char *global_host_event_handler; extern char *global_service_event_handler; extern char *ocsp_command; extern char *ochp_command; extern char *illegal_object_chars; extern char *illegal_output_chars; extern int use_regexp_matches; extern int use_true_regexp_matching; extern int sigshutdown; extern int sigrestart; extern int daemon_mode; extern int daemon_dumps_core; extern int use_syslog; extern int log_notifications; extern int log_service_retries; extern int log_host_retries; extern int log_event_handlers; extern int log_external_commands; extern int log_passive_checks; extern unsigned long logging_options; extern unsigned long syslog_options; extern int service_check_timeout; extern int host_check_timeout; extern int event_handler_timeout; extern int notification_timeout; extern int ocsp_timeout; extern int ochp_timeout; extern int log_initial_states; extern double sleep_time; extern int interval_length; extern int service_inter_check_delay_method; extern int host_inter_check_delay_method; extern int service_interleave_factor_method; extern int max_host_check_spread; extern int max_service_check_spread; extern int command_check_interval; extern int service_check_reaper_interval; extern int service_freshness_check_interval; extern int host_freshness_check_interval; extern int auto_rescheduling_interval; extern int auto_rescheduling_window; extern int check_external_commands; extern int check_orphaned_services; extern int check_service_freshness; extern int check_host_freshness; extern int auto_reschedule_checks; extern int use_aggressive_host_checking; extern int soft_state_dependencies; extern int retain_state_information; extern int retention_update_interval; extern int use_retained_program_state; extern int use_retained_scheduling_info; extern int retention_scheduling_horizon; extern unsigned long modified_host_process_attributes; extern unsigned long modified_service_process_attributes; extern int log_rotation_method; extern time_t last_command_check; extern time_t last_command_status_update; extern time_t last_log_rotation; extern int verify_config; extern int test_scheduling; extern service_message svc_msg; extern int ipc_pipe[2]; extern int max_parallel_service_checks; extern int currently_running_service_checks; extern int enable_notifications; extern int execute_service_checks; extern int accept_passive_service_checks; extern int execute_host_checks; extern int accept_passive_host_checks; extern int enable_event_handlers; extern int obsess_over_services; extern int obsess_over_hosts; extern int enable_failure_prediction; extern int process_performance_data; extern int aggregate_status_updates; extern int status_update_interval; extern int time_change_threshold; extern unsigned long event_broker_options; extern int process_performance_data; extern int enable_flap_detection; extern double low_service_flap_threshold; extern double high_service_flap_threshold; extern double low_host_flap_threshold; extern double high_host_flap_threshold; extern int date_format; extern contact *contact_list; extern contactgroup *contactgroup_list; extern host *host_list; extern hostgroup *hostgroup_list; extern service *service_list; extern servicegroup *servicegroup_list; extern timed_event *event_list_high; extern timed_event *event_list_low; extern notification *notification_list; extern command *command_list; extern timeperiod *timeperiod_list; extern int command_file_fd; extern FILE *command_file_fp; extern int command_file_created; char my_system_output[MAX_INPUT_BUFFER]; #ifdef HAVE_TZNAME #ifdef CYGWIN extern char *_tzname[2] __declspec(dllimport); #else extern char *tzname[2]; #endif #endif extern service_message svc_msg; extern pthread_t worker_threads[TOTAL_WORKER_THREADS]; extern circular_buffer external_command_buffer; extern circular_buffer service_result_buffer; extern circular_buffer event_broker_buffer; /* from GNU defines errno as a macro, since it's a per-thread variable */ #ifndef errno extern int errno; #endif /******************************************************************/ /************************ MACRO FUNCTIONS *************************/ /******************************************************************/ /* replace macros in notification commands with their values */ int process_macros(char *input_buffer, char *output_buffer, int buffer_length, int options){ char *temp_buffer; int in_macro; int x; int arg_index=0; int user_index=0; int address_index=0; char *selected_macro=NULL; int clean_macro=FALSE; int found_macro_x=FALSE; #ifdef DEBUG0 printf("process_macros() start\n"); #endif if(output_buffer==NULL || buffer_length<=0) return ERROR; strcpy(output_buffer,""); if(input_buffer==NULL) return ERROR; in_macro=FALSE; /*#define TEST_MACROS 1*/ #ifdef TEST_MACROS printf("**** BEGIN MACRO PROCESSING ***********\n"); printf("Processing: '%s'\n",input_buffer); printf("Buffer length: %d\n",buffer_length); #endif for(temp_buffer=my_strtok(input_buffer,"$");temp_buffer!=NULL;temp_buffer=my_strtok(NULL,"$")){ #ifdef TEST_MACROS printf(" Processing part: '%s'\n",temp_buffer); #endif selected_macro=NULL; found_macro_x=FALSE; clean_macro=FALSE; if(in_macro==FALSE){ if(strlen(output_buffer)+strlen(temp_buffer)=16 && x<=19){ clean_macro=TRUE; options&=STRIP_ILLEGAL_MACRO_CHARS|ESCAPE_MACRO_CHARS; } break; } } /* we already have a macro... */ if(found_macro_x==TRUE) x=0; /* on-demand host macros */ else if(strstr(temp_buffer,"HOST") && strstr(temp_buffer,":")){ grab_on_demand_macro(temp_buffer); selected_macro=macro_ondemand; /* output/perfdata macros get cleaned */ if(strstr(temp_buffer,"HOSTOUTPUT:")==temp_buffer || strstr(temp_buffer,"HOSTPERFDATA:")){ clean_macro=TRUE; options&=STRIP_ILLEGAL_MACRO_CHARS|ESCAPE_MACRO_CHARS; } } /* on-demand service macros */ else if(strstr(temp_buffer,"SERVICE") && strstr(temp_buffer,":")){ grab_on_demand_macro(temp_buffer); selected_macro=macro_ondemand; /* output/perfdata macros get cleaned */ if(strstr(temp_buffer,"SERVICEOUTPUT:")==temp_buffer || strstr(temp_buffer,"SERVICEPERFDATA:")){ clean_macro=TRUE; options&=STRIP_ILLEGAL_MACRO_CHARS|ESCAPE_MACRO_CHARS; } } /* argv macros */ else if(strstr(temp_buffer,"ARG")==temp_buffer){ arg_index=atoi(temp_buffer+3); if(arg_index>=1 && arg_index<=MAX_COMMAND_ARGUMENTS) selected_macro=macro_argv[arg_index-1]; else selected_macro=NULL; } /* user macros */ else if(strstr(temp_buffer,"USER")==temp_buffer){ user_index=atoi(temp_buffer+4); if(user_index>=1 && user_index<=MAX_USER_MACROS) selected_macro=macro_user[user_index-1]; else selected_macro=NULL; } /* contact address macros */ else if(strstr(temp_buffer,"CONTACTADDRESS")==temp_buffer){ address_index=atoi(temp_buffer+14); if(address_index>=1 && address_index<=MAX_CONTACT_ADDRESSES) selected_macro=macro_contactaddress[address_index-1]; else selected_macro=NULL; } /* an escaped $ is done by specifying two $$ next to each other */ else if(!strcmp(temp_buffer,"")){ #ifdef TEST_MACROS printf(" Escaped $. Running output (%d): '%s'\n",strlen(output_buffer),output_buffer); #endif strncat(output_buffer,"$",buffer_length-strlen(output_buffer)-1); } /* a non-macro, just some user-defined string between two $s */ else{ #ifdef TEST_MACROS printf(" Non-macro. Running output (%d): '%s'\n",strlen(output_buffer),output_buffer); #endif strncat(output_buffer,"$",buffer_length-strlen(output_buffer)-1); output_buffer[buffer_length-1]='\x0'; strncat(output_buffer,temp_buffer,buffer_length-strlen(output_buffer)-1); output_buffer[buffer_length-1]='\x0'; strncat(output_buffer,"$",buffer_length-strlen(output_buffer)-1); } /* insert macro */ if(selected_macro!=NULL){ /* URL encode the macro */ if(options & URL_ENCODE_MACRO_CHARS) selected_macro=get_url_encoded_string(selected_macro); /* some macros are cleaned... */ if(clean_macro==TRUE || ((options & STRIP_ILLEGAL_MACRO_CHARS) || (options & ESCAPE_MACRO_CHARS))) strncat(output_buffer,(selected_macro==NULL)?"":clean_macro_chars(selected_macro,options),buffer_length-strlen(output_buffer)-1); /* others are not cleaned */ else strncat(output_buffer,(selected_macro==NULL)?"":selected_macro,buffer_length-strlen(output_buffer)-1); /* free memory if necessary */ if(options & URL_ENCODE_MACRO_CHARS) free(selected_macro); #ifdef TEST_MACROS printf(" Just finished macro. Running output (%d): '%s'\n",strlen(output_buffer),output_buffer); #endif } output_buffer[buffer_length-1]='\x0'; } in_macro=FALSE; } } #ifdef TEST_MACROS printf("Done. Final output: '%s'\n",output_buffer); printf("**** END MACRO PROCESSING *************\n"); #endif #ifdef DEBUG0 printf("process_macros() end\n"); #endif return OK; } /* grab macros that are specific to a particular service */ int grab_service_macros(service *svc){ servicegroup *temp_servicegroup; serviceextinfo *temp_serviceextinfo; time_t current_time; unsigned long duration; int days; int hours; int minutes; int seconds; char temp_buffer[MAX_INPUT_BUFFER]; #ifdef DEBUG0 printf("grab_service_macros() start\n"); #endif /* get the service description */ if(macro_x[MACRO_SERVICEDESC]!=NULL) free(macro_x[MACRO_SERVICEDESC]); macro_x[MACRO_SERVICEDESC]=strdup(svc->description); /* get the plugin output */ if(macro_x[MACRO_SERVICEOUTPUT]!=NULL) free(macro_x[MACRO_SERVICEOUTPUT]); if(svc->plugin_output==NULL) macro_x[MACRO_SERVICEOUTPUT]=NULL; else macro_x[MACRO_SERVICEOUTPUT]=strdup(svc->plugin_output); /* get the performance data */ if(macro_x[MACRO_SERVICEPERFDATA]!=NULL) free(macro_x[MACRO_SERVICEPERFDATA]); if(svc->perf_data==NULL) macro_x[MACRO_SERVICEPERFDATA]=NULL; else macro_x[MACRO_SERVICEPERFDATA]=strdup(svc->perf_data); /* get the service check command */ if(macro_x[MACRO_SERVICECHECKCOMMAND]!=NULL) free(macro_x[MACRO_SERVICECHECKCOMMAND]); if(svc->service_check_command==NULL) macro_x[MACRO_SERVICECHECKCOMMAND]=NULL; else macro_x[MACRO_SERVICECHECKCOMMAND]=strdup(svc->service_check_command); /* grab the service check type */ if(macro_x[MACRO_SERVICECHECKTYPE]!=NULL) free(macro_x[MACRO_SERVICECHECKTYPE]); macro_x[MACRO_SERVICECHECKTYPE]=(char *)malloc(MAX_CHECKTYPE_LENGTH); if(macro_x[MACRO_SERVICECHECKTYPE]!=NULL) strcpy(macro_x[MACRO_SERVICECHECKTYPE],(svc->check_type==SERVICE_CHECK_PASSIVE)?"PASSIVE":"ACTIVE"); /* grab the service state type macro (this is usually overridden later on) */ if(macro_x[MACRO_SERVICESTATETYPE]!=NULL) free(macro_x[MACRO_SERVICESTATETYPE]); macro_x[MACRO_SERVICESTATETYPE]=(char *)malloc(MAX_STATETYPE_LENGTH); if(macro_x[MACRO_SERVICESTATETYPE]!=NULL) strcpy(macro_x[MACRO_SERVICESTATETYPE],(svc->state_type==HARD_STATE)?"HARD":"SOFT"); /* get the service state */ if(macro_x[MACRO_SERVICESTATE]!=NULL) free(macro_x[MACRO_SERVICESTATE]); macro_x[MACRO_SERVICESTATE]=(char *)malloc(MAX_STATE_LENGTH); if(macro_x[MACRO_SERVICESTATE]!=NULL){ if(svc->current_state==STATE_OK) strcpy(macro_x[MACRO_SERVICESTATE],"OK"); else if(svc->current_state==STATE_WARNING) strcpy(macro_x[MACRO_SERVICESTATE],"WARNING"); else if(svc->current_state==STATE_CRITICAL) strcpy(macro_x[MACRO_SERVICESTATE],"CRITICAL"); else strcpy(macro_x[MACRO_SERVICESTATE],"UNKNOWN"); } /* get the service state id */ if(macro_x[MACRO_SERVICESTATEID]!=NULL) free(macro_x[MACRO_SERVICESTATEID]); macro_x[MACRO_SERVICESTATEID]=(char *)malloc(MAX_STATEID_LENGTH); if(macro_x[MACRO_SERVICESTATEID]!=NULL){ snprintf(macro_x[MACRO_SERVICESTATEID],MAX_STATEID_LENGTH,"%d",svc->current_state); macro_x[MACRO_SERVICESTATEID][MAX_STATEID_LENGTH-1]='\x0'; } /* get the current service check attempt macro */ if(macro_x[MACRO_SERVICEATTEMPT]!=NULL) free(macro_x[MACRO_SERVICEATTEMPT]); macro_x[MACRO_SERVICEATTEMPT]=(char *)malloc(MAX_ATTEMPT_LENGTH); if(macro_x[MACRO_SERVICEATTEMPT]!=NULL){ snprintf(macro_x[MACRO_SERVICEATTEMPT],MAX_ATTEMPT_LENGTH,"%d",svc->current_attempt); macro_x[MACRO_SERVICEATTEMPT][MAX_ATTEMPT_LENGTH-1]='\x0'; } /* get the execution time macro */ if(macro_x[MACRO_SERVICEEXECUTIONTIME]!=NULL) free(macro_x[MACRO_SERVICEEXECUTIONTIME]); macro_x[MACRO_SERVICEEXECUTIONTIME]=(char *)malloc(MAX_EXECUTIONTIME_LENGTH); if(macro_x[MACRO_SERVICEEXECUTIONTIME]!=NULL){ snprintf(macro_x[MACRO_SERVICEEXECUTIONTIME],MAX_EXECUTIONTIME_LENGTH,"%.3f",svc->execution_time); macro_x[MACRO_SERVICEEXECUTIONTIME][MAX_EXECUTIONTIME_LENGTH-1]='\x0'; } /* get the latency macro */ if(macro_x[MACRO_SERVICELATENCY]!=NULL) free(macro_x[MACRO_SERVICELATENCY]); macro_x[MACRO_SERVICELATENCY]=(char *)malloc(MAX_LATENCY_LENGTH); if(macro_x[MACRO_SERVICELATENCY]!=NULL){ snprintf(macro_x[MACRO_SERVICELATENCY],MAX_LATENCY_LENGTH,"%.3f",svc->latency); macro_x[MACRO_SERVICELATENCY][MAX_LATENCY_LENGTH-1]='\x0'; } /* get the last check time macro */ if(macro_x[MACRO_LASTSERVICECHECK]!=NULL) free(macro_x[MACRO_LASTSERVICECHECK]); macro_x[MACRO_LASTSERVICECHECK]=(char *)malloc(MAX_DATETIME_LENGTH); if(macro_x[MACRO_LASTSERVICECHECK]!=NULL){ snprintf(macro_x[MACRO_LASTSERVICECHECK],MAX_DATETIME_LENGTH,"%lu",(unsigned long)svc->last_check); macro_x[MACRO_LASTSERVICECHECK][MAX_DATETIME_LENGTH-1]='\x0'; } /* get the last state change time macro */ if(macro_x[MACRO_LASTSERVICESTATECHANGE]!=NULL) free(macro_x[MACRO_LASTSERVICESTATECHANGE]); macro_x[MACRO_LASTSERVICESTATECHANGE]=(char *)malloc(MAX_DATETIME_LENGTH); if(macro_x[MACRO_LASTSERVICESTATECHANGE]!=NULL){ snprintf(macro_x[MACRO_LASTSERVICESTATECHANGE],MAX_DATETIME_LENGTH,"%lu",(unsigned long)svc->last_state_change); macro_x[MACRO_LASTSERVICESTATECHANGE][MAX_DATETIME_LENGTH-1]='\x0'; } /* get the last time ok macro */ if(macro_x[MACRO_LASTSERVICEOK]!=NULL) free(macro_x[MACRO_LASTSERVICEOK]); macro_x[MACRO_LASTSERVICEOK]=(char *)malloc(MAX_DATETIME_LENGTH); if(macro_x[MACRO_LASTSERVICEOK]!=NULL){ snprintf(macro_x[MACRO_LASTSERVICEOK],MAX_DATETIME_LENGTH,"%lu",(unsigned long)svc->last_time_ok); macro_x[MACRO_LASTSERVICEOK][MAX_DATETIME_LENGTH-1]='\x0'; } /* get the last time warning macro */ if(macro_x[MACRO_LASTSERVICEWARNING]!=NULL) free(macro_x[MACRO_LASTSERVICEWARNING]); macro_x[MACRO_LASTSERVICEWARNING]=(char *)malloc(MAX_DATETIME_LENGTH); if(macro_x[MACRO_LASTSERVICEWARNING]!=NULL){ snprintf(macro_x[MACRO_LASTSERVICEWARNING],MAX_DATETIME_LENGTH,"%lu",(unsigned long)svc->last_time_warning); macro_x[MACRO_LASTSERVICEWARNING][MAX_DATETIME_LENGTH-1]='\x0'; } /* get the last time unknown macro */ if(macro_x[MACRO_LASTSERVICEUNKNOWN]!=NULL) free(macro_x[MACRO_LASTSERVICEUNKNOWN]); macro_x[MACRO_LASTSERVICEUNKNOWN]=(char *)malloc(MAX_DATETIME_LENGTH); if(macro_x[MACRO_LASTSERVICEUNKNOWN]!=NULL){ snprintf(macro_x[MACRO_LASTSERVICEUNKNOWN],MAX_DATETIME_LENGTH,"%lu",(unsigned long)svc->last_time_unknown); macro_x[MACRO_LASTSERVICEUNKNOWN][MAX_DATETIME_LENGTH-1]='\x0'; } /* get the last time critical macro */ if(macro_x[MACRO_LASTSERVICECRITICAL]!=NULL) free(macro_x[MACRO_LASTSERVICECRITICAL]); macro_x[MACRO_LASTSERVICECRITICAL]=(char *)malloc(MAX_DATETIME_LENGTH); if(macro_x[MACRO_LASTSERVICECRITICAL]!=NULL){ snprintf(macro_x[MACRO_LASTSERVICECRITICAL],MAX_DATETIME_LENGTH,"%lu",(unsigned long)svc->last_time_critical); macro_x[MACRO_LASTSERVICECRITICAL][MAX_DATETIME_LENGTH-1]='\x0'; } /* get the service downtime depth */ if(macro_x[MACRO_SERVICEDOWNTIME]!=NULL) free(macro_x[MACRO_SERVICEDOWNTIME]); macro_x[MACRO_SERVICEDOWNTIME]=(char *)malloc(MAX_DOWNTIME_LENGTH); if(macro_x[MACRO_SERVICEDOWNTIME]!=NULL){ snprintf(macro_x[MACRO_SERVICEDOWNTIME],MAX_DOWNTIME_LENGTH,"%d",svc->scheduled_downtime_depth); macro_x[MACRO_SERVICEDOWNTIME][MAX_DOWNTIME_LENGTH-1]='\x0'; } /* get the percent state change */ if(macro_x[MACRO_SERVICEPERCENTCHANGE]!=NULL) free(macro_x[MACRO_SERVICEPERCENTCHANGE]); macro_x[MACRO_SERVICEPERCENTCHANGE]=(char *)malloc(MAX_PERCENTCHANGE_LENGTH); if(macro_x[MACRO_SERVICEPERCENTCHANGE]!=NULL){ snprintf(macro_x[MACRO_SERVICEPERCENTCHANGE],MAX_PERCENTCHANGE_LENGTH,"%.2f",svc->percent_state_change); macro_x[MACRO_SERVICEPERCENTCHANGE][MAX_PERCENTCHANGE_LENGTH-1]='\x0'; } time(¤t_time); duration=(unsigned long)(current_time-svc->last_state_change); /* get the state duration in seconds */ if(macro_x[MACRO_SERVICEDURATIONSEC]!=NULL) free(macro_x[MACRO_SERVICEDURATIONSEC]); macro_x[MACRO_SERVICEDURATIONSEC]=(char *)malloc(MAX_DURATION_LENGTH); if(macro_x[MACRO_SERVICEDURATIONSEC]!=NULL){ snprintf(macro_x[MACRO_SERVICEDURATIONSEC],MAX_DURATION_LENGTH,"%lu",duration); macro_x[MACRO_SERVICEDURATIONSEC][MAX_DURATION_LENGTH-1]='\x0'; } /* get the state duration */ if(macro_x[MACRO_SERVICEDURATION]!=NULL) free(macro_x[MACRO_SERVICEDURATION]); macro_x[MACRO_SERVICEDURATION]=(char *)malloc(MAX_DURATION_LENGTH); if(macro_x[MACRO_SERVICEDURATION]!=NULL){ days=duration/86400; duration-=(days*86400); hours=duration/3600; duration-=(hours*3600); minutes=duration/60; duration-=(minutes*60); seconds=duration; snprintf(macro_x[MACRO_SERVICEDURATION],MAX_DURATION_LENGTH,"%dd %dh %dm %ds",days,hours,minutes,seconds); macro_x[MACRO_SERVICEDURATION][MAX_DURATION_LENGTH-1]='\x0'; } /* find one servicegroup (there may be none or several) this service is associated with */ for(temp_servicegroup=servicegroup_list;temp_servicegroup!=NULL;temp_servicegroup=temp_servicegroup->next){ if(is_service_member_of_servicegroup(temp_servicegroup,svc)==TRUE) break; } /* get the servicegroup name */ if(macro_x[MACRO_SERVICEGROUPNAME]!=NULL) free(macro_x[MACRO_SERVICEGROUPNAME]); macro_x[MACRO_SERVICEGROUPNAME]=NULL; if(temp_servicegroup!=NULL) macro_x[MACRO_SERVICEGROUPNAME]=strdup(temp_servicegroup->group_name); /* get the servicegroup alias */ if(macro_x[MACRO_SERVICEGROUPALIAS]!=NULL) free(macro_x[MACRO_SERVICEGROUPALIAS]); macro_x[MACRO_SERVICEGROUPALIAS]=NULL; if(temp_servicegroup!=NULL) macro_x[MACRO_SERVICEGROUPALIAS]=strdup(temp_servicegroup->alias); if((temp_serviceextinfo=find_serviceextinfo(svc->host_name,svc->description))){ /* get the action url */ if(macro_x[MACRO_SERVICEACTIONURL]!=NULL) free(macro_x[MACRO_SERVICEACTIONURL]); if(temp_serviceextinfo->action_url==NULL) macro_x[MACRO_SERVICEACTIONURL]=NULL; else macro_x[MACRO_SERVICEACTIONURL]=strdup(temp_serviceextinfo->action_url); /* get the notes url */ if(macro_x[MACRO_SERVICENOTESURL]!=NULL) free(macro_x[MACRO_SERVICENOTESURL]); if(temp_serviceextinfo->notes_url==NULL) macro_x[MACRO_SERVICENOTESURL]=NULL; else macro_x[MACRO_SERVICENOTESURL]=strdup(temp_serviceextinfo->notes_url); /* get the notes */ if(macro_x[MACRO_SERVICENOTES]!=NULL) free(macro_x[MACRO_SERVICENOTES]); if(temp_serviceextinfo->notes==NULL) macro_x[MACRO_SERVICENOTES]=NULL; else macro_x[MACRO_SERVICENOTES]=strdup(temp_serviceextinfo->notes); } /* get the date/time macros */ grab_datetime_macros(); strip(macro_x[MACRO_SERVICEOUTPUT]); strip(macro_x[MACRO_SERVICEPERFDATA]); strip(macro_x[MACRO_SERVICECHECKCOMMAND]); strip(macro_x[MACRO_SERVICENOTES]); /* notes and action URL macros may themselves contain macros, so process them... */ if(macro_x[MACRO_SERVICEACTIONURL]!=NULL){ process_macros(macro_x[MACRO_SERVICEACTIONURL],temp_buffer,sizeof(temp_buffer),URL_ENCODE_MACRO_CHARS); free(macro_x[MACRO_SERVICEACTIONURL]); macro_x[MACRO_SERVICEACTIONURL]=strdup(temp_buffer); } if(macro_x[MACRO_SERVICENOTESURL]!=NULL){ process_macros(macro_x[MACRO_SERVICENOTESURL],temp_buffer,sizeof(temp_buffer),URL_ENCODE_MACRO_CHARS); free(macro_x[MACRO_SERVICENOTESURL]); macro_x[MACRO_SERVICENOTESURL]=strdup(temp_buffer); } #ifdef DEBUG0 printf("grab_service_macros() end\n"); #endif return OK; } /* grab macros that are specific to a particular host */ int grab_host_macros(host *hst){ hostgroup *temp_hostgroup; hostextinfo *temp_hostextinfo; time_t current_time; unsigned long duration; int days; int hours; int minutes; int seconds; char temp_buffer[MAX_INPUT_BUFFER]; #ifdef DEBUG0 printf("grab_host_macros() start\n"); #endif /* get the host name */ if(macro_x[MACRO_HOSTNAME]!=NULL) free(macro_x[MACRO_HOSTNAME]); macro_x[MACRO_HOSTNAME]=strdup(hst->name); /* get the host alias */ if(macro_x[MACRO_HOSTALIAS]!=NULL) free(macro_x[MACRO_HOSTALIAS]); macro_x[MACRO_HOSTALIAS]=strdup(hst->alias); /* get the host address */ if(macro_x[MACRO_HOSTADDRESS]!=NULL) free(macro_x[MACRO_HOSTADDRESS]); macro_x[MACRO_HOSTADDRESS]=strdup(hst->address); /* get the host state */ if(macro_x[MACRO_HOSTSTATE]!=NULL) free(macro_x[MACRO_HOSTSTATE]); macro_x[MACRO_HOSTSTATE]=(char *)malloc(MAX_STATE_LENGTH); if(macro_x[MACRO_HOSTSTATE]!=NULL){ if(hst->current_state==HOST_DOWN) strcpy(macro_x[MACRO_HOSTSTATE],"DOWN"); else if(hst->current_state==HOST_UNREACHABLE) strcpy(macro_x[MACRO_HOSTSTATE],"UNREACHABLE"); else strcpy(macro_x[MACRO_HOSTSTATE],"UP"); } /* get the host state id */ if(macro_x[MACRO_HOSTSTATEID]!=NULL) free(macro_x[MACRO_HOSTSTATEID]); macro_x[MACRO_HOSTSTATEID]=(char *)malloc(MAX_STATEID_LENGTH); if(macro_x[MACRO_HOSTSTATEID]!=NULL){ snprintf(macro_x[MACRO_HOSTSTATEID],MAX_STATEID_LENGTH,"%d",hst->current_state); macro_x[MACRO_HOSTSTATEID][MAX_STATEID_LENGTH-1]='\x0'; } /* grab the host check type */ if(macro_x[MACRO_HOSTCHECKTYPE]!=NULL) free(macro_x[MACRO_HOSTCHECKTYPE]); macro_x[MACRO_HOSTCHECKTYPE]=(char *)malloc(MAX_CHECKTYPE_LENGTH); if(macro_x[MACRO_HOSTCHECKTYPE]!=NULL) strcpy(macro_x[MACRO_HOSTCHECKTYPE],(hst->check_type==HOST_CHECK_PASSIVE)?"PASSIVE":"ACTIVE"); /* get the host state type macro */ if(macro_x[MACRO_HOSTSTATETYPE]!=NULL) free(macro_x[MACRO_HOSTSTATETYPE]); macro_x[MACRO_HOSTSTATETYPE]=(char *)malloc(MAX_STATETYPE_LENGTH); if(macro_x[MACRO_HOSTSTATETYPE]!=NULL) strcpy(macro_x[MACRO_HOSTSTATETYPE],(hst->state_type==HARD_STATE)?"HARD":"SOFT"); /* get the plugin output */ if(macro_x[MACRO_HOSTOUTPUT]!=NULL) free(macro_x[MACRO_HOSTOUTPUT]); if(hst->plugin_output==NULL) macro_x[MACRO_HOSTOUTPUT]=NULL; else macro_x[MACRO_HOSTOUTPUT]=strdup(hst->plugin_output); /* get the performance data */ if(macro_x[MACRO_HOSTPERFDATA]!=NULL) free(macro_x[MACRO_HOSTPERFDATA]); if(hst->perf_data==NULL) macro_x[MACRO_HOSTPERFDATA]=NULL; else macro_x[MACRO_HOSTPERFDATA]=strdup(hst->perf_data); /* get the host check command */ if(macro_x[MACRO_HOSTCHECKCOMMAND]!=NULL) free(macro_x[MACRO_HOSTCHECKCOMMAND]); if(hst->host_check_command==NULL) macro_x[MACRO_HOSTCHECKCOMMAND]=NULL; else macro_x[MACRO_HOSTCHECKCOMMAND]=strdup(hst->host_check_command); /* get the host current attempt */ if(macro_x[MACRO_HOSTATTEMPT]!=NULL) free(macro_x[MACRO_HOSTATTEMPT]); macro_x[MACRO_HOSTATTEMPT]=(char *)malloc(MAX_ATTEMPT_LENGTH); if(macro_x[MACRO_HOSTATTEMPT]!=NULL){ snprintf(macro_x[MACRO_HOSTATTEMPT],MAX_ATTEMPT_LENGTH,"%d",hst->current_attempt); macro_x[MACRO_HOSTATTEMPT][MAX_ATTEMPT_LENGTH-1]='\x0'; } /* get the host downtime depth */ if(macro_x[MACRO_HOSTDOWNTIME]!=NULL) free(macro_x[MACRO_HOSTDOWNTIME]); macro_x[MACRO_HOSTDOWNTIME]=(char *)malloc(MAX_DOWNTIME_LENGTH); if(macro_x[MACRO_HOSTDOWNTIME]!=NULL){ snprintf(macro_x[MACRO_HOSTDOWNTIME],MAX_DOWNTIME_LENGTH,"%d",hst->scheduled_downtime_depth); macro_x[MACRO_HOSTDOWNTIME][MAX_DOWNTIME_LENGTH-1]='\x0'; } /* get the percent state change */ if(macro_x[MACRO_HOSTPERCENTCHANGE]!=NULL) free(macro_x[MACRO_HOSTPERCENTCHANGE]); macro_x[MACRO_HOSTPERCENTCHANGE]=(char *)malloc(MAX_PERCENTCHANGE_LENGTH); if(macro_x[MACRO_HOSTPERCENTCHANGE]!=NULL){ snprintf(macro_x[MACRO_HOSTPERCENTCHANGE],MAX_PERCENTCHANGE_LENGTH,"%.2f",hst->percent_state_change); macro_x[MACRO_HOSTPERCENTCHANGE][MAX_PERCENTCHANGE_LENGTH-1]='\x0'; } time(¤t_time); duration=(unsigned long)(current_time-hst->last_state_change); /* get the state duration in seconds */ if(macro_x[MACRO_HOSTDURATIONSEC]!=NULL) free(macro_x[MACRO_HOSTDURATIONSEC]); macro_x[MACRO_HOSTDURATIONSEC]=(char *)malloc(MAX_DURATION_LENGTH); if(macro_x[MACRO_HOSTDURATIONSEC]!=NULL){ snprintf(macro_x[MACRO_HOSTDURATIONSEC],MAX_DURATION_LENGTH,"%lu",duration); macro_x[MACRO_HOSTDURATIONSEC][MAX_DURATION_LENGTH-1]='\x0'; } /* get the state duration */ if(macro_x[MACRO_HOSTDURATION]!=NULL) free(macro_x[MACRO_HOSTDURATION]); macro_x[MACRO_HOSTDURATION]=(char *)malloc(MAX_DURATION_LENGTH); if(macro_x[MACRO_HOSTDURATION]!=NULL){ days=duration/86400; duration-=(days*86400); hours=duration/3600; duration-=(hours*3600); minutes=duration/60; duration-=(minutes*60); seconds=duration; snprintf(macro_x[MACRO_HOSTDURATION],MAX_DURATION_LENGTH,"%dd %dh %dm %ds",days,hours,minutes,seconds); macro_x[MACRO_HOSTDURATION][MAX_DURATION_LENGTH-1]='\x0'; } /* get the execution time macro */ if(macro_x[MACRO_HOSTEXECUTIONTIME]!=NULL) free(macro_x[MACRO_HOSTEXECUTIONTIME]); macro_x[MACRO_HOSTEXECUTIONTIME]=(char *)malloc(MAX_EXECUTIONTIME_LENGTH); if(macro_x[MACRO_HOSTEXECUTIONTIME]!=NULL){ snprintf(macro_x[MACRO_HOSTEXECUTIONTIME],MAX_EXECUTIONTIME_LENGTH,"%.3f",hst->execution_time); macro_x[MACRO_HOSTEXECUTIONTIME][MAX_EXECUTIONTIME_LENGTH-1]='\x0'; } /* get the latency macro */ if(macro_x[MACRO_HOSTLATENCY]!=NULL) free(macro_x[MACRO_HOSTLATENCY]); macro_x[MACRO_HOSTLATENCY]=(char *)malloc(MAX_LATENCY_LENGTH); if(macro_x[MACRO_HOSTLATENCY]!=NULL){ snprintf(macro_x[MACRO_HOSTLATENCY],MAX_LATENCY_LENGTH,"%.3f",hst->latency); macro_x[MACRO_HOSTLATENCY][MAX_LATENCY_LENGTH-1]='\x0'; } /* get the last check time macro */ if(macro_x[MACRO_LASTHOSTCHECK]!=NULL) free(macro_x[MACRO_LASTHOSTCHECK]); macro_x[MACRO_LASTHOSTCHECK]=(char *)malloc(MAX_DATETIME_LENGTH); if(macro_x[MACRO_LASTHOSTCHECK]!=NULL){ snprintf(macro_x[MACRO_LASTHOSTCHECK],MAX_DATETIME_LENGTH,"%lu",(unsigned long)hst->last_check); macro_x[MACRO_LASTHOSTCHECK][MAX_DATETIME_LENGTH-1]='\x0'; } /* get the last state change time macro */ if(macro_x[MACRO_LASTHOSTSTATECHANGE]!=NULL) free(macro_x[MACRO_LASTHOSTSTATECHANGE]); macro_x[MACRO_LASTHOSTSTATECHANGE]=(char *)malloc(MAX_DATETIME_LENGTH); if(macro_x[MACRO_LASTHOSTSTATECHANGE]!=NULL){ snprintf(macro_x[MACRO_LASTHOSTSTATECHANGE],MAX_DATETIME_LENGTH,"%lu",(unsigned long)hst->last_state_change); macro_x[MACRO_LASTHOSTSTATECHANGE][MAX_DATETIME_LENGTH-1]='\x0'; } /* get the last time up macro */ if(macro_x[MACRO_LASTHOSTUP]!=NULL) free(macro_x[MACRO_LASTHOSTUP]); macro_x[MACRO_LASTHOSTUP]=(char *)malloc(MAX_DATETIME_LENGTH); if(macro_x[MACRO_LASTHOSTUP]!=NULL){ snprintf(macro_x[MACRO_LASTHOSTUP],MAX_DATETIME_LENGTH,"%lu",(unsigned long)hst->last_time_up); macro_x[MACRO_LASTHOSTUP][MAX_DATETIME_LENGTH-1]='\x0'; } /* get the last time down macro */ if(macro_x[MACRO_LASTHOSTDOWN]!=NULL) free(macro_x[MACRO_LASTHOSTDOWN]); macro_x[MACRO_LASTHOSTDOWN]=(char *)malloc(MAX_DATETIME_LENGTH); if(macro_x[MACRO_LASTHOSTDOWN]!=NULL){ snprintf(macro_x[MACRO_LASTHOSTDOWN],MAX_DATETIME_LENGTH,"%lu",(unsigned long)hst->last_time_down); macro_x[MACRO_LASTHOSTDOWN][MAX_DATETIME_LENGTH-1]='\x0'; } /* get the last time unreachable macro */ if(macro_x[MACRO_LASTHOSTUNREACHABLE]!=NULL) free(macro_x[MACRO_LASTHOSTUNREACHABLE]); macro_x[MACRO_LASTHOSTUNREACHABLE]=(char *)malloc(MAX_DATETIME_LENGTH); if(macro_x[MACRO_LASTHOSTUNREACHABLE]!=NULL){ snprintf(macro_x[MACRO_LASTHOSTUNREACHABLE],MAX_DATETIME_LENGTH,"%lu",(unsigned long)hst->last_time_unreachable); macro_x[MACRO_LASTHOSTUNREACHABLE][MAX_DATETIME_LENGTH-1]='\x0'; } /* find one hostgroup (there may be none or several) this host is associated with */ for(temp_hostgroup=hostgroup_list;temp_hostgroup!=NULL;temp_hostgroup=temp_hostgroup->next){ if(is_host_member_of_hostgroup(temp_hostgroup,hst)==TRUE) break; } /* get the hostgroup name */ if(macro_x[MACRO_HOSTGROUPNAME]!=NULL) free(macro_x[MACRO_HOSTGROUPNAME]); macro_x[MACRO_HOSTGROUPNAME]=NULL; if(temp_hostgroup!=NULL) macro_x[MACRO_HOSTGROUPNAME]=strdup(temp_hostgroup->group_name); /* get the hostgroup alias */ if(macro_x[MACRO_HOSTGROUPALIAS]!=NULL) free(macro_x[MACRO_HOSTGROUPALIAS]); macro_x[MACRO_HOSTGROUPALIAS]=NULL; if(temp_hostgroup!=NULL) macro_x[MACRO_HOSTGROUPALIAS]=strdup(temp_hostgroup->alias); if((temp_hostextinfo=find_hostextinfo(hst->name))){ /* get the action url */ if(macro_x[MACRO_HOSTACTIONURL]!=NULL) free(macro_x[MACRO_HOSTACTIONURL]); if(temp_hostextinfo->action_url==NULL) macro_x[MACRO_HOSTACTIONURL]=NULL; else macro_x[MACRO_HOSTACTIONURL]=strdup(temp_hostextinfo->action_url); /* get the notes url */ if(macro_x[MACRO_HOSTNOTESURL]!=NULL) free(macro_x[MACRO_HOSTNOTESURL]); if(temp_hostextinfo->notes_url==NULL) macro_x[MACRO_HOSTNOTESURL]=NULL; else macro_x[MACRO_HOSTNOTESURL]=strdup(temp_hostextinfo->notes_url); /* get the notes */ if(macro_x[MACRO_HOSTNOTES]!=NULL) free(macro_x[MACRO_HOSTNOTES]); if(temp_hostextinfo->notes==NULL) macro_x[MACRO_HOSTNOTES]=NULL; else macro_x[MACRO_HOSTNOTES]=strdup(temp_hostextinfo->notes); } /* get the date/time macros */ grab_datetime_macros(); strip(macro_x[MACRO_HOSTOUTPUT]); strip(macro_x[MACRO_HOSTPERFDATA]); strip(macro_x[MACRO_HOSTCHECKCOMMAND]); strip(macro_x[MACRO_HOSTNOTES]); /* notes and action URL macros may themselves contain macros, so process them... */ if(macro_x[MACRO_HOSTACTIONURL]!=NULL){ process_macros(macro_x[MACRO_HOSTACTIONURL],temp_buffer,sizeof(temp_buffer),URL_ENCODE_MACRO_CHARS); free(macro_x[MACRO_HOSTACTIONURL]); macro_x[MACRO_HOSTACTIONURL]=strdup(temp_buffer); } if(macro_x[MACRO_HOSTNOTESURL]!=NULL){ process_macros(macro_x[MACRO_HOSTNOTESURL],temp_buffer,sizeof(temp_buffer),URL_ENCODE_MACRO_CHARS); free(macro_x[MACRO_HOSTNOTESURL]); macro_x[MACRO_HOSTNOTESURL]=strdup(temp_buffer); } #ifdef DEBUG0 printf("grab_host_macros() end\n"); #endif return OK; } /* grab an on-demand host or service macro */ int grab_on_demand_macro(char *str){ char *macro=NULL; char *first_arg=NULL; char *second_arg=NULL; char result_buffer[MAX_INPUT_BUFFER]; int result_buffer_len, delimiter_len; host *temp_host; hostgroup *temp_hostgroup; hostgroupmember *temp_hostgroupmember; service *temp_service; servicegroup *temp_servicegroup; servicegroupmember *temp_servicegroupmember; char *ptr; int return_val=ERROR; #ifdef DEBUG0 printf("grab_on_demand_macro() start\n"); #endif /* clear the on-demand macro */ if(macro_ondemand!=NULL){ free(macro_ondemand); macro_ondemand=NULL; } /* get the first argument */ macro=strdup(str); if(macro==NULL) return ERROR; /* get the host name */ ptr=strchr(macro,':'); if(ptr==NULL){ free(macro); return ERROR; } /* terminate the macro name at the first arg's delimiter */ ptr[0]='\x0'; first_arg=ptr+1; /* get the second argument (if present) */ ptr=strchr(first_arg,':'); if(ptr!=NULL){ /* terminate the first arg at the second arg's delimiter */ ptr[0]='\x0'; second_arg=ptr+1; } /* process the macro */ if(strstr(macro,"HOST")){ /* process a host macro */ if(second_arg==NULL){ temp_host=find_host(first_arg); return_val=grab_on_demand_host_macro(temp_host,macro); } /* process a host macro containing a hostgroup */ else{ temp_hostgroup=find_hostgroup(first_arg); if(temp_hostgroup==NULL){ free(macro); return ERROR; } return_val=OK; /* start off assuming there's no error */ result_buffer[0]='\0'; result_buffer[sizeof(result_buffer)-1]='\0'; result_buffer_len=0; delimiter_len=strlen(second_arg); /* process each host in the hostgroup */ temp_hostgroupmember=temp_hostgroup->members; if(temp_hostgroupmember==NULL){ macro_ondemand=strdup(""); free(macro); return OK; } while(1){ temp_host=find_host(temp_hostgroupmember->host_name); if(grab_on_demand_host_macro(temp_host,macro)==OK){ strncat(result_buffer,macro_ondemand,sizeof(result_buffer)-result_buffer_len-1); result_buffer_len+=strlen(macro_ondemand); if(result_buffer_len>sizeof(result_buffer)-1){ return_val=ERROR; break; } temp_hostgroupmember=temp_hostgroupmember->next; if(temp_hostgroupmember==NULL) break; strncat(result_buffer,second_arg,sizeof(result_buffer)-result_buffer_len-1); result_buffer_len+=delimiter_len; if(result_buffer_len>sizeof(result_buffer)-1){ return_val=ERROR; break; } } else{ return_val=ERROR; temp_hostgroupmember=temp_hostgroupmember->next; if(temp_hostgroupmember==NULL) break; } free(macro_ondemand); macro_ondemand=NULL; } free(macro_ondemand); macro_ondemand=strdup(result_buffer); } } else if(strstr(macro,"SERVICE")){ /* second args will either be service description or delimiter */ if(second_arg==NULL){ free(macro); return ERROR; } /* process a service macro */ temp_service=find_service(first_arg, second_arg); if(temp_service!=NULL) return_val=grab_on_demand_service_macro(temp_service,macro); /* process a service macro containing a servicegroup */ else{ temp_servicegroup=find_servicegroup(first_arg); if(temp_servicegroup==NULL){ free(macro); return ERROR; } return_val=OK; /* start off assuming there's no error */ result_buffer[0]='\0'; result_buffer[sizeof(result_buffer)-1]='\0'; result_buffer_len=0; delimiter_len=strlen(second_arg); /* process each service in the servicegroup */ temp_servicegroupmember=temp_servicegroup->members; if(temp_servicegroupmember==NULL){ macro_ondemand=strdup(""); free(macro); return OK; } while(1){ temp_service=find_service(temp_servicegroupmember->host_name,temp_servicegroupmember->service_description); if(grab_on_demand_service_macro(temp_service,macro)==OK){ strncat(result_buffer,macro_ondemand,sizeof(result_buffer)-result_buffer_len-1); result_buffer_len+=strlen(macro_ondemand); if(result_buffer_len>sizeof(result_buffer)-1){ return_val=ERROR; break; } temp_servicegroupmember=temp_servicegroupmember->next; if(temp_servicegroupmember==NULL) break; strncat(result_buffer,second_arg,sizeof(result_buffer)-result_buffer_len-1); result_buffer_len+=delimiter_len; if(result_buffer_len>sizeof(result_buffer)-1){ return_val=ERROR; break; } } else{ return_val=ERROR; temp_servicegroupmember=temp_servicegroupmember->next; if(temp_servicegroupmember==NULL) break; } free(macro_ondemand); macro_ondemand=NULL; } free(macro_ondemand); macro_ondemand=strdup(result_buffer); } } else return_val=ERROR; free(macro); #ifdef DEBUG0 printf("grab_on_demand_macro() end\n"); #endif return return_val; } /* grab an on-demand host macro */ int grab_on_demand_host_macro(host *hst, char *macro){ hostgroup *temp_hostgroup; hostextinfo *temp_hostextinfo; char temp_buffer[MAX_INPUT_BUFFER]; time_t current_time; unsigned long duration; int days; int hours; int minutes; int seconds; #ifdef DEBUG0 printf("grab_on_demand_host_macro() start\n"); #endif if(hst==NULL || macro==NULL) return ERROR; /* initialize the macro */ macro_ondemand=NULL; time(¤t_time); duration=(unsigned long)(current_time-hst->last_state_change); /* find one hostgroup (there may be none or several) this host is associated with */ for(temp_hostgroup=hostgroup_list;temp_hostgroup!=NULL;temp_hostgroup=temp_hostgroup->next){ if(is_host_member_of_hostgroup(temp_hostgroup,hst)==TRUE) break; } /* get the host alias */ if(!strcmp(macro,"HOSTALIAS")) macro_ondemand=strdup(hst->alias); /* get the host address */ else if(!strcmp(macro,"HOSTADDRESS")) macro_ondemand=strdup(hst->address); /* get the host state */ else if(!strcmp(macro,"HOSTSTATE")){ macro_ondemand=(char *)malloc(MAX_STATE_LENGTH); if(macro_ondemand!=NULL){ if(hst->current_state==HOST_DOWN) strcpy(macro_ondemand,"DOWN"); else if(hst->current_state==HOST_UNREACHABLE) strcpy(macro_ondemand,"UNREACHABLE"); else strcpy(macro_ondemand,"UP"); } } /* get the host state id */ else if(!strcmp(macro,"HOSTSTATEID")){ macro_ondemand=(char *)malloc(MAX_STATEID_LENGTH); if(macro_ondemand!=NULL){ snprintf(macro_ondemand,MAX_STATEID_LENGTH,"%d",hst->current_state); macro_ondemand[MAX_STATEID_LENGTH-1]='\x0'; } } /* grab the host check type */ else if(!strcmp(macro,"HOSTCHECKTYPE")){ macro_ondemand=(char *)malloc(MAX_CHECKTYPE_LENGTH); if(macro_ondemand!=NULL) strcpy(macro_ondemand,(hst->check_type==HOST_CHECK_PASSIVE)?"PASSIVE":"ACTIVE"); } /* get the host state type macro */ else if(!strcmp(macro,"HOSTSTATETYPE")){ macro_ondemand=(char *)malloc(MAX_STATETYPE_LENGTH); if(macro_ondemand!=NULL) strcpy(macro_ondemand,(hst->state_type==HARD_STATE)?"HARD":"SOFT"); } /* get the plugin output */ else if(!strcmp(macro,"HOSTOUTPUT")){ if(hst->plugin_output==NULL) macro_ondemand=NULL; else{ macro_ondemand=strdup(hst->plugin_output); strip(macro_ondemand); } } /* get the performance data */ else if(!strcmp(macro,"HOSTPERFDATA")){ if(hst->perf_data==NULL) macro_ondemand=NULL; else{ macro_ondemand=strdup(hst->perf_data); strip(macro_ondemand); } } /* get the host current attempt */ else if(!strcmp(macro,"HOSTATTEMPT")){ macro_ondemand=(char *)malloc(MAX_ATTEMPT_LENGTH); if(macro_ondemand!=NULL){ snprintf(macro_ondemand,MAX_ATTEMPT_LENGTH,"%d",hst->current_attempt); macro_ondemand[MAX_ATTEMPT_LENGTH-1]='\x0'; } } /* get the host downtime depth */ else if(!strcmp(macro,"HOSTDOWNTIME")){ macro_ondemand=(char *)malloc(MAX_DOWNTIME_LENGTH); if(macro_ondemand!=NULL){ snprintf(macro_ondemand,MAX_DOWNTIME_LENGTH,"%d",hst->scheduled_downtime_depth); macro_ondemand[MAX_ATTEMPT_LENGTH-1]='\x0'; } } /* get the percent state change */ else if(!strcmp(macro,"HOSTPERCENTCHANGE")){ macro_ondemand=(char *)malloc(MAX_PERCENTCHANGE_LENGTH); if(macro_ondemand!=NULL){ snprintf(macro_ondemand,MAX_PERCENTCHANGE_LENGTH,"%.2f",hst->percent_state_change); macro_ondemand[MAX_PERCENTCHANGE_LENGTH-1]='\x0'; } } /* get the state duration in seconds */ else if(!strcmp(macro,"HOSTDURATIONSEC")){ macro_ondemand=(char *)malloc(MAX_DURATION_LENGTH); if(macro_ondemand!=NULL){ snprintf(macro_ondemand,MAX_DURATION_LENGTH,"%lu",duration); macro_ondemand[MAX_DURATION_LENGTH-1]='\x0'; } } /* get the state duration */ else if(!strcmp(macro,"HOSTDURATION")){ macro_ondemand=(char *)malloc(MAX_DURATION_LENGTH); if(macro_ondemand!=NULL){ days=duration/86400; duration-=(days*86400); hours=duration/3600; duration-=(hours*3600); minutes=duration/60; duration-=(minutes*60); seconds=duration; snprintf(macro_ondemand,MAX_DURATION_LENGTH,"%dd %dh %dm %ds",days,hours,minutes,seconds); macro_ondemand[MAX_DURATION_LENGTH-1]='\x0'; } } /* get the execution time macro */ else if(!strcmp(macro,"HOSTEXECUTIONTIME")){ macro_ondemand=(char *)malloc(MAX_EXECUTIONTIME_LENGTH); if(macro_ondemand!=NULL){ snprintf(macro_ondemand,MAX_EXECUTIONTIME_LENGTH,"%.3f",hst->execution_time); macro_ondemand[MAX_EXECUTIONTIME_LENGTH-1]='\x0'; } } /* get the latency macro */ else if(!strcmp(macro,"HOSTLATENCY")){ macro_ondemand=(char *)malloc(MAX_LATENCY_LENGTH); if(macro_ondemand!=NULL){ snprintf(macro_ondemand,MAX_LATENCY_LENGTH,"%.3f",hst->latency); macro_ondemand[MAX_LATENCY_LENGTH-1]='\x0'; } } /* get the last check time macro */ else if(!strcmp(macro,"LASTHOSTCHECK")){ macro_ondemand=(char *)malloc(MAX_DATETIME_LENGTH); if(macro_ondemand!=NULL){ snprintf(macro_ondemand,MAX_DATETIME_LENGTH,"%lu",(unsigned long)hst->last_check); macro_ondemand[MAX_DATETIME_LENGTH-1]='\x0'; } } /* get the last state change time macro */ else if(!strcmp(macro,"LASTHOSTSTATECHANGE")){ macro_ondemand=(char *)malloc(MAX_DATETIME_LENGTH); if(macro_ondemand!=NULL){ snprintf(macro_ondemand,MAX_DATETIME_LENGTH,"%lu",(unsigned long)hst->last_state_change); macro_ondemand[MAX_DATETIME_LENGTH-1]='\x0'; } } /* get the last time up macro */ else if(!strcmp(macro,"LASTHOSTUP")){ macro_ondemand=(char *)malloc(MAX_DATETIME_LENGTH); if(macro_ondemand!=NULL){ snprintf(macro_ondemand,MAX_DATETIME_LENGTH,"%lu",(unsigned long)hst->last_time_up); macro_ondemand[MAX_DATETIME_LENGTH-1]='\x0'; } } /* get the last time down macro */ else if(!strcmp(macro,"LASTHOSTDOWN")){ macro_ondemand=(char *)malloc(MAX_DATETIME_LENGTH); if(macro_ondemand!=NULL){ snprintf(macro_ondemand,MAX_DATETIME_LENGTH,"%lu",(unsigned long)hst->last_time_down); macro_ondemand[MAX_DATETIME_LENGTH-1]='\x0'; } } /* get the last time unreachable macro */ else if(!strcmp(macro,"LASTHOSTUNREACHABLE")){ macro_ondemand=(char *)malloc(MAX_DATETIME_LENGTH); if(macro_ondemand!=NULL){ snprintf(macro_ondemand,MAX_DATETIME_LENGTH,"%lu",(unsigned long)hst->last_time_unreachable); macro_ondemand[MAX_DATETIME_LENGTH-1]='\x0'; } } /* get the hostgroup name */ else if(!strcmp(macro,"HOSTGROUPNAME")){ if(temp_hostgroup!=NULL) macro_ondemand=strdup(temp_hostgroup->group_name); } /* get the hostgroup alias */ else if(!strcmp(macro,"HOSTGROUPALIAS")){ if(temp_hostgroup!=NULL) macro_ondemand=strdup(temp_hostgroup->alias); } /* extended info */ else if(!strcmp(macro,"HOSTACTIONURL") || !strcmp(macro,"HOSTNOTESURL") || !strcmp(macro,"HOSTNOTES")){ /* find the extended info entry */ if((temp_hostextinfo=find_hostextinfo(hst->name))){ /* action url */ if(!strcmp(macro,"HOSTACTIONURL")){ if(temp_hostextinfo->action_url) macro_ondemand=strdup(temp_hostextinfo->action_url); /* action URL macros may themselves contain macros, so process them... */ if(macro_ondemand!=NULL){ process_macros(macro_ondemand,temp_buffer,sizeof(temp_buffer),URL_ENCODE_MACRO_CHARS); free(macro_ondemand); macro_ondemand=strdup(temp_buffer); } } /* notes url */ if(!strcmp(macro,"HOSTNOTESURL")){ if(temp_hostextinfo->notes_url) macro_ondemand=strdup(temp_hostextinfo->notes_url); /* action URL macros may themselves contain macros, so process them... */ if(macro_ondemand!=NULL){ process_macros(macro_ondemand,temp_buffer,sizeof(temp_buffer),URL_ENCODE_MACRO_CHARS); free(macro_ondemand); macro_ondemand=strdup(temp_buffer); } } /* notes */ if(!strcmp(macro,"HOSTNOTES")){ if(temp_hostextinfo->notes) macro_ondemand=strdup(temp_hostextinfo->notes); } } } else return ERROR; #ifdef DEBUG0 printf("grab_on_demand_host_macro() end\n"); #endif return OK; } /* grab an on-demand service macro */ int grab_on_demand_service_macro(service *svc, char *macro){ servicegroup *temp_servicegroup; serviceextinfo *temp_serviceextinfo; char temp_buffer[MAX_INPUT_BUFFER]; time_t current_time; unsigned long duration; int days; int hours; int minutes; int seconds; #ifdef DEBUG0 printf("grab_on_demand_service_macro() start\n"); #endif if(svc==NULL || macro==NULL) return ERROR; /* initialize the macro */ macro_ondemand=NULL; time(¤t_time); duration=(unsigned long)(current_time-svc->last_state_change); /* find one servicegroup (there may be none or several) this service is associated with */ for(temp_servicegroup=servicegroup_list;temp_servicegroup!=NULL;temp_servicegroup=temp_servicegroup->next){ if(is_service_member_of_servicegroup(temp_servicegroup,svc)==TRUE) break; } /* get the plugin output */ if(!strcmp(macro,"SERVICEOUTPUT")){ if(svc->plugin_output==NULL) macro_ondemand=NULL; else{ macro_ondemand=strdup(svc->plugin_output); strip(macro_ondemand); } } /* get the performance data */ else if(!strcmp(macro,"SERVICEPERFDATA")){ if(svc->perf_data==NULL) macro_ondemand=NULL; else{ macro_ondemand=strdup(svc->perf_data); strip(macro_ondemand); } } /* grab the servuce check type */ else if(!strcmp(macro,"SERVICECHECKTYPE")){ macro_ondemand=(char *)malloc(MAX_CHECKTYPE_LENGTH); if(macro_ondemand!=NULL) strcpy(macro_ondemand,(svc->check_type==SERVICE_CHECK_PASSIVE)?"PASSIVE":"ACTIVE"); } /* grab the service state type macro (this is usually overridden later on) */ else if(!strcmp(macro,"SERVICESTATETYPE")){ macro_ondemand=(char *)malloc(MAX_STATETYPE_LENGTH); if(macro_ondemand!=NULL) strcpy(macro_ondemand,(svc->state_type==HARD_STATE)?"HARD":"SOFT"); } /* get the service state */ else if(!strcmp(macro,"SERVICESTATE")){ macro_ondemand=(char *)malloc(MAX_STATE_LENGTH); if(macro_ondemand!=NULL){ if(svc->current_state==STATE_OK) strcpy(macro_ondemand,"OK"); else if(svc->current_state==STATE_WARNING) strcpy(macro_ondemand,"WARNING"); else if(svc->current_state==STATE_CRITICAL) strcpy(macro_ondemand,"CRITICAL"); else strcpy(macro_ondemand,"UNKNOWN"); } } /* get the service state id */ else if(!strcmp(macro,"SERVICESTATEID")){ macro_ondemand=(char *)malloc(MAX_STATEID_LENGTH); if(macro_ondemand!=NULL){ snprintf(macro_ondemand,MAX_STATEID_LENGTH,"%d",svc->current_state); macro_ondemand[MAX_STATEID_LENGTH-1]='\x0'; } } /* get the current service check attempt macro */ else if(!strcmp(macro,"SERVICEATTEMPT")){ macro_ondemand=(char *)malloc(MAX_ATTEMPT_LENGTH); if(macro_ondemand!=NULL){ snprintf(macro_ondemand,MAX_ATTEMPT_LENGTH,"%d",svc->current_attempt); macro_ondemand[MAX_ATTEMPT_LENGTH-1]='\x0'; } } /* get the execution time macro */ else if(!strcmp(macro,"SERVICEEXECUTIONTIME")){ macro_ondemand=(char *)malloc(MAX_EXECUTIONTIME_LENGTH); if(macro_ondemand!=NULL){ snprintf(macro_ondemand,MAX_EXECUTIONTIME_LENGTH,"%.3f",svc->execution_time); macro_ondemand[MAX_EXECUTIONTIME_LENGTH-1]='\x0'; } } /* get the latency macro */ else if(!strcmp(macro,"SERVICELATENCY")){ macro_ondemand=(char *)malloc(MAX_LATENCY_LENGTH); if(macro_ondemand!=NULL){ snprintf(macro_ondemand,MAX_LATENCY_LENGTH,"%.3f",svc->latency); macro_ondemand[MAX_LATENCY_LENGTH-1]='\x0'; } } /* get the last check time macro */ else if(!strcmp(macro,"LASTSERVICECHECK")){ macro_ondemand=(char *)malloc(MAX_DATETIME_LENGTH); if(macro_ondemand!=NULL){ snprintf(macro_ondemand,MAX_DATETIME_LENGTH,"%lu",(unsigned long)svc->last_check); macro_ondemand[MAX_DATETIME_LENGTH-1]='\x0'; } } /* get the last state change time macro */ else if(!strcmp(macro,"LASTSERVICESTATECHANGE")){ macro_ondemand=(char *)malloc(MAX_DATETIME_LENGTH); if(macro_ondemand!=NULL){ snprintf(macro_ondemand,MAX_DATETIME_LENGTH,"%lu",(unsigned long)svc->last_state_change); macro_ondemand[MAX_DATETIME_LENGTH-1]='\x0'; } } /* get the last time ok macro */ else if(!strcmp(macro,"LASTSERVICEOK")){ macro_ondemand=(char *)malloc(MAX_DATETIME_LENGTH); if(macro_ondemand!=NULL){ snprintf(macro_ondemand,MAX_DATETIME_LENGTH,"%lu",(unsigned long)svc->last_time_ok); macro_ondemand[MAX_DATETIME_LENGTH-1]='\x0'; } } /* get the last time warning macro */ else if(!strcmp(macro,"LASTSERVICEWARNING")){ macro_ondemand=(char *)malloc(MAX_DATETIME_LENGTH); if(macro_ondemand!=NULL){ snprintf(macro_ondemand,MAX_DATETIME_LENGTH,"%lu",(unsigned long)svc->last_time_warning); macro_ondemand[MAX_DATETIME_LENGTH-1]='\x0'; } } /* get the last time unknown macro */ else if(!strcmp(macro,"LASTSERVICEUNKNOWN")){ macro_ondemand=(char *)malloc(MAX_DATETIME_LENGTH); if(macro_ondemand!=NULL){ snprintf(macro_ondemand,MAX_DATETIME_LENGTH,"%lu",(unsigned long)svc->last_time_unknown); macro_ondemand[MAX_DATETIME_LENGTH-1]='\x0'; } } /* get the last time critical macro */ else if(!strcmp(macro,"LASTSERVICECRITICAL")){ macro_ondemand=(char *)malloc(MAX_DATETIME_LENGTH); if(macro_ondemand!=NULL){ snprintf(macro_ondemand,MAX_DATETIME_LENGTH,"%lu",(unsigned long)svc->last_time_critical); macro_ondemand[MAX_DATETIME_LENGTH-1]='\x0'; } } /* get the service downtime depth */ else if(!strcmp(macro,"SERVICEDOWNTIME")){ macro_ondemand=(char *)malloc(MAX_DOWNTIME_LENGTH); if(macro_ondemand!=NULL){ snprintf(macro_ondemand,MAX_DOWNTIME_LENGTH,"%d",svc->scheduled_downtime_depth); macro_ondemand[MAX_DOWNTIME_LENGTH-1]='\x0'; } } /* get the percent state change */ else if(!strcmp(macro,"SERVICEPERCENTCHANGE")){ macro_ondemand=(char *)malloc(MAX_PERCENTCHANGE_LENGTH); if(macro_ondemand!=NULL){ snprintf(macro_ondemand,MAX_PERCENTCHANGE_LENGTH,"%.2f",svc->percent_state_change); macro_ondemand[MAX_PERCENTCHANGE_LENGTH-1]='\x0'; } } /* get the state duration in seconds */ else if(!strcmp(macro,"SERVICEDURATIONSEC")){ macro_ondemand=(char *)malloc(MAX_DURATION_LENGTH); if(macro_ondemand!=NULL){ snprintf(macro_ondemand,MAX_DURATION_LENGTH,"%lu",duration); macro_ondemand[MAX_DURATION_LENGTH-1]='\x0'; } } /* get the state duration */ else if(!strcmp(macro,"SERVICEDURATION")){ macro_ondemand=(char *)malloc(MAX_DURATION_LENGTH); if(macro_ondemand!=NULL){ days=duration/86400; duration-=(days*86400); hours=duration/3600; duration-=(hours*3600); minutes=duration/60; duration-=(minutes*60); seconds=duration; snprintf(macro_ondemand,MAX_DURATION_LENGTH,"%dd %dh %dm %ds",days,hours,minutes,seconds); macro_ondemand[MAX_DURATION_LENGTH-1]='\x0'; } } /* get the servicegroup name */ else if(!strcmp(macro,"SERVICEGROUPNAME")){ if(temp_servicegroup!=NULL) macro_ondemand=strdup(temp_servicegroup->group_name); } /* get the servicegroup alias */ else if(!strcmp(macro,"SERVICEGROUPALIAS")){ if(temp_servicegroup!=NULL) macro_ondemand=strdup(temp_servicegroup->alias); } /* extended info */ else if(!strcmp(macro,"SERVICEACTIONURL") || !strcmp(macro,"SERVICENOTESURL") || !strcmp(macro,"SERVICENOTES")){ /* find the extended info entry */ if((temp_serviceextinfo=find_serviceextinfo(svc->host_name,svc->description))){ /* action url */ if(!strcmp(macro,"SERVICEACTIONURL")){ if(temp_serviceextinfo->action_url) macro_ondemand=strdup(temp_serviceextinfo->action_url); /* action URL macros may themselves contain macros, so process them... */ if(macro_ondemand!=NULL){ process_macros(macro_ondemand,temp_buffer,sizeof(temp_buffer),URL_ENCODE_MACRO_CHARS); free(macro_ondemand); macro_ondemand=strdup(temp_buffer); } } /* notes url */ if(!strcmp(macro,"SERVICENOTESURL")){ if(temp_serviceextinfo->notes_url) macro_ondemand=strdup(temp_serviceextinfo->notes_url); /* action URL macros may themselves contain macros, so process them... */ if(macro_ondemand!=NULL){ process_macros(macro_ondemand,temp_buffer,sizeof(temp_buffer),URL_ENCODE_MACRO_CHARS); free(macro_ondemand); macro_ondemand=strdup(temp_buffer); } } /* notes */ if(!strcmp(macro,"SERVICENOTES")){ if(temp_serviceextinfo->notes) macro_ondemand=strdup(temp_serviceextinfo->notes); } } } else return ERROR; #ifdef DEBUG0 printf("grab_on_demand_service_macro() end\n"); #endif return OK; } /* grab macros that are specific to a particular contact */ int grab_contact_macros(contact *cntct){ int x; #ifdef DEBUG0 printf("grab_contact_macros() start\n"); #endif /* get the name */ if(macro_x[MACRO_CONTACTNAME]!=NULL) free(macro_x[MACRO_CONTACTNAME]); macro_x[MACRO_CONTACTNAME]=strdup(cntct->name); /* get the alias */ if(macro_x[MACRO_CONTACTALIAS]!=NULL) free(macro_x[MACRO_CONTACTALIAS]); macro_x[MACRO_CONTACTALIAS]=strdup(cntct->alias); /* get the email address */ if(macro_x[MACRO_CONTACTEMAIL]!=NULL) free(macro_x[MACRO_CONTACTEMAIL]); if(cntct->email==NULL) macro_x[MACRO_CONTACTEMAIL]=NULL; else macro_x[MACRO_CONTACTEMAIL]=strdup(cntct->email); /* get the pager number */ if(macro_x[MACRO_CONTACTPAGER]!=NULL) free(macro_x[MACRO_CONTACTPAGER]); if(cntct->pager==NULL) macro_x[MACRO_CONTACTPAGER]=NULL; else macro_x[MACRO_CONTACTPAGER]=strdup(cntct->pager); /* get misc contact addresses */ for(x=0;xaddress[x]==NULL) macro_contactaddress[x]=NULL; else macro_contactaddress[x]=strdup(cntct->address[x]); } /* get the date/time macros */ grab_datetime_macros(); strip(macro_x[MACRO_CONTACTNAME]); strip(macro_x[MACRO_CONTACTALIAS]); strip(macro_x[MACRO_CONTACTEMAIL]); strip(macro_x[MACRO_CONTACTPAGER]); for(x=0;xnext){ /* filter totals based on contact if necessary */ if(temp_contact!=NULL) authorized=is_contact_for_host(temp_host,temp_contact); if(authorized==TRUE){ problem=TRUE; if(temp_host->current_state==HOST_UP && temp_host->has_been_checked==TRUE) hosts_up++; else if(temp_host->current_state==HOST_DOWN){ if(temp_host->scheduled_downtime_depth>0) problem=FALSE; if(temp_host->problem_has_been_acknowledged==TRUE) problem=FALSE; if(temp_host->checks_enabled==FALSE) problem=FALSE; if(problem==TRUE) hosts_down_unhandled++; hosts_down++; } else if(temp_host->current_state==HOST_UNREACHABLE){ if(temp_host->scheduled_downtime_depth>0) problem=FALSE; if(temp_host->problem_has_been_acknowledged==TRUE) problem=FALSE; if(temp_host->checks_enabled==FALSE) problem=FALSE; if(problem==TRUE) hosts_down_unhandled++; hosts_unreachable++; } } } host_problems=hosts_down+hosts_unreachable; host_problems_unhandled=hosts_down_unhandled+hosts_unreachable_unhandled; /* get service totals */ for(temp_service=service_list;temp_service!=NULL;temp_service=temp_service->next){ /* filter totals based on contact if necessary */ if(temp_contact!=NULL) authorized=is_contact_for_service(temp_service,temp_contact); if(authorized==TRUE){ problem=TRUE; if(temp_service->current_state==STATE_OK && temp_service->has_been_checked==TRUE) services_ok++; else if(temp_service->current_state==STATE_WARNING){ temp_host=find_host(temp_service->host_name); if(temp_host!=NULL && (temp_host->current_state==HOST_DOWN || temp_host->current_state==HOST_UNREACHABLE)) problem=FALSE; if(temp_service->scheduled_downtime_depth>0) problem=FALSE; if(temp_service->problem_has_been_acknowledged==TRUE) problem=FALSE; if(temp_service->checks_enabled==FALSE) problem=FALSE; if(problem==TRUE) services_warning_unhandled++; services_warning++; } else if(temp_service->current_state==STATE_UNKNOWN){ temp_host=find_host(temp_service->host_name); if(temp_host!=NULL && (temp_host->current_state==HOST_DOWN || temp_host->current_state==HOST_UNREACHABLE)) problem=FALSE; if(temp_service->scheduled_downtime_depth>0) problem=FALSE; if(temp_service->problem_has_been_acknowledged==TRUE) problem=FALSE; if(temp_service->checks_enabled==FALSE) problem=FALSE; if(problem==TRUE) services_unknown_unhandled++; services_unknown++; } else if(temp_service->current_state==STATE_CRITICAL){ temp_host=find_host(temp_service->host_name); if(temp_host!=NULL && (temp_host->current_state==HOST_DOWN || temp_host->current_state==HOST_UNREACHABLE)) problem=FALSE; if(temp_service->scheduled_downtime_depth>0) problem=FALSE; if(temp_service->problem_has_been_acknowledged==TRUE) problem=FALSE; if(temp_service->checks_enabled==FALSE) problem=FALSE; if(problem==TRUE) services_critical_unhandled++; services_critical++; } } } service_problems=services_warning+services_critical+services_unknown; service_problems_unhandled=services_warning_unhandled+services_critical_unhandled+services_unknown_unhandled; /* get total hosts up */ if(macro_x[MACRO_TOTALHOSTSUP]!=NULL) free(macro_x[MACRO_TOTALHOSTSUP]); macro_x[MACRO_TOTALHOSTSUP]=(char *)malloc(MAX_TOTALS_LENGTH); if(macro_x[MACRO_TOTALHOSTSUP]!=NULL){ snprintf(macro_x[MACRO_TOTALHOSTSUP],MAX_TOTALS_LENGTH,"%d",hosts_up); macro_x[MACRO_TOTALHOSTSUP][MAX_TOTALS_LENGTH-1]='\x0'; } /* get total hosts down */ if(macro_x[MACRO_TOTALHOSTSDOWN]!=NULL) free(macro_x[MACRO_TOTALHOSTSDOWN]); macro_x[MACRO_TOTALHOSTSDOWN]=(char *)malloc(MAX_TOTALS_LENGTH); if(macro_x[MACRO_TOTALHOSTSDOWN]!=NULL){ snprintf(macro_x[MACRO_TOTALHOSTSDOWN],MAX_TOTALS_LENGTH,"%d",hosts_down); macro_x[MACRO_TOTALHOSTSDOWN][MAX_TOTALS_LENGTH-1]='\x0'; } /* get total hosts unreachable */ if(macro_x[MACRO_TOTALHOSTSUNREACHABLE]!=NULL) free(macro_x[MACRO_TOTALHOSTSUNREACHABLE]); macro_x[MACRO_TOTALHOSTSUNREACHABLE]=(char *)malloc(MAX_TOTALS_LENGTH); if(macro_x[MACRO_TOTALHOSTSUNREACHABLE]!=NULL){ snprintf(macro_x[MACRO_TOTALHOSTSUNREACHABLE],MAX_TOTALS_LENGTH,"%d",hosts_unreachable); macro_x[MACRO_TOTALHOSTSUNREACHABLE][MAX_TOTALS_LENGTH-1]='\x0'; } /* get total unhandled hosts down */ if(macro_x[MACRO_TOTALHOSTSDOWNUNHANDLED]!=NULL) free(macro_x[MACRO_TOTALHOSTSDOWNUNHANDLED]); macro_x[MACRO_TOTALHOSTSDOWNUNHANDLED]=(char *)malloc(MAX_TOTALS_LENGTH); if(macro_x[MACRO_TOTALHOSTSDOWNUNHANDLED]!=NULL){ snprintf(macro_x[MACRO_TOTALHOSTSDOWNUNHANDLED],MAX_TOTALS_LENGTH,"%d",hosts_down_unhandled); macro_x[MACRO_TOTALHOSTSDOWNUNHANDLED][MAX_TOTALS_LENGTH-1]='\x0'; } /* get total unhandled hosts unreachable */ if(macro_x[MACRO_TOTALHOSTSUNREACHABLEUNHANDLED]!=NULL) free(macro_x[MACRO_TOTALHOSTSUNREACHABLEUNHANDLED]); macro_x[MACRO_TOTALHOSTSUNREACHABLEUNHANDLED]=(char *)malloc(MAX_TOTALS_LENGTH); if(macro_x[MACRO_TOTALHOSTSUNREACHABLEUNHANDLED]!=NULL){ snprintf(macro_x[MACRO_TOTALHOSTSUNREACHABLEUNHANDLED],MAX_TOTALS_LENGTH,"%d",hosts_unreachable_unhandled); macro_x[MACRO_TOTALHOSTSUNREACHABLEUNHANDLED][MAX_TOTALS_LENGTH-1]='\x0'; } /* get total host problems */ if(macro_x[MACRO_TOTALHOSTPROBLEMS]!=NULL) free(macro_x[MACRO_TOTALHOSTPROBLEMS]); macro_x[MACRO_TOTALHOSTPROBLEMS]=(char *)malloc(MAX_TOTALS_LENGTH); if(macro_x[MACRO_TOTALHOSTPROBLEMS]!=NULL){ snprintf(macro_x[MACRO_TOTALHOSTPROBLEMS],MAX_TOTALS_LENGTH,"%d",host_problems); macro_x[MACRO_TOTALHOSTPROBLEMS][MAX_TOTALS_LENGTH-1]='\x0'; } /* get total unhandled host problems */ if(macro_x[MACRO_TOTALHOSTPROBLEMSUNHANDLED]!=NULL) free(macro_x[MACRO_TOTALHOSTPROBLEMSUNHANDLED]); macro_x[MACRO_TOTALHOSTPROBLEMSUNHANDLED]=(char *)malloc(MAX_TOTALS_LENGTH); if(macro_x[MACRO_TOTALHOSTPROBLEMSUNHANDLED]!=NULL){ snprintf(macro_x[MACRO_TOTALHOSTPROBLEMSUNHANDLED],MAX_TOTALS_LENGTH,"%d",host_problems_unhandled); macro_x[MACRO_TOTALHOSTPROBLEMSUNHANDLED][MAX_TOTALS_LENGTH-1]='\x0'; } /* get total services ok */ if(macro_x[MACRO_TOTALSERVICESOK]!=NULL) free(macro_x[MACRO_TOTALSERVICESOK]); macro_x[MACRO_TOTALSERVICESOK]=(char *)malloc(MAX_TOTALS_LENGTH); if(macro_x[MACRO_TOTALSERVICESOK]!=NULL){ snprintf(macro_x[MACRO_TOTALSERVICESOK],MAX_TOTALS_LENGTH,"%d",services_ok); macro_x[MACRO_TOTALSERVICESOK][MAX_TOTALS_LENGTH-1]='\x0'; } /* get total services warning */ if(macro_x[MACRO_TOTALSERVICESWARNING]!=NULL) free(macro_x[MACRO_TOTALSERVICESWARNING]); macro_x[MACRO_TOTALSERVICESWARNING]=(char *)malloc(MAX_TOTALS_LENGTH); if(macro_x[MACRO_TOTALSERVICESWARNING]!=NULL){ snprintf(macro_x[MACRO_TOTALSERVICESWARNING],MAX_TOTALS_LENGTH,"%d",services_warning); macro_x[MACRO_TOTALSERVICESWARNING][MAX_TOTALS_LENGTH-1]='\x0'; } /* get total services critical */ if(macro_x[MACRO_TOTALSERVICESCRITICAL]!=NULL) free(macro_x[MACRO_TOTALSERVICESCRITICAL]); macro_x[MACRO_TOTALSERVICESCRITICAL]=(char *)malloc(MAX_TOTALS_LENGTH); if(macro_x[MACRO_TOTALSERVICESCRITICAL]!=NULL){ snprintf(macro_x[MACRO_TOTALSERVICESCRITICAL],MAX_TOTALS_LENGTH,"%d",services_critical); macro_x[MACRO_TOTALSERVICESCRITICAL][MAX_TOTALS_LENGTH-1]='\x0'; } /* get total services unknown */ if(macro_x[MACRO_TOTALSERVICESUNKNOWN]!=NULL) free(macro_x[MACRO_TOTALSERVICESUNKNOWN]); macro_x[MACRO_TOTALSERVICESUNKNOWN]=(char *)malloc(MAX_TOTALS_LENGTH); if(macro_x[MACRO_TOTALSERVICESUNKNOWN]!=NULL){ snprintf(macro_x[MACRO_TOTALSERVICESUNKNOWN],MAX_TOTALS_LENGTH,"%d",services_unknown); macro_x[MACRO_TOTALSERVICESUNKNOWN][MAX_TOTALS_LENGTH-1]='\x0'; } /* get total unhandled services warning */ if(macro_x[MACRO_TOTALSERVICESWARNINGUNHANDLED]!=NULL) free(macro_x[MACRO_TOTALSERVICESWARNINGUNHANDLED]); macro_x[MACRO_TOTALSERVICESWARNINGUNHANDLED]=(char *)malloc(MAX_TOTALS_LENGTH); if(macro_x[MACRO_TOTALSERVICESWARNINGUNHANDLED]!=NULL){ snprintf(macro_x[MACRO_TOTALSERVICESWARNINGUNHANDLED],MAX_TOTALS_LENGTH,"%d",services_warning_unhandled); macro_x[MACRO_TOTALSERVICESWARNINGUNHANDLED][MAX_TOTALS_LENGTH-1]='\x0'; } /* get total unhandled services critical */ if(macro_x[MACRO_TOTALSERVICESCRITICALUNHANDLED]!=NULL) free(macro_x[MACRO_TOTALSERVICESCRITICALUNHANDLED]); macro_x[MACRO_TOTALSERVICESCRITICALUNHANDLED]=(char *)malloc(MAX_TOTALS_LENGTH); if(macro_x[MACRO_TOTALSERVICESCRITICALUNHANDLED]!=NULL){ snprintf(macro_x[MACRO_TOTALSERVICESCRITICALUNHANDLED],MAX_TOTALS_LENGTH,"%d",services_critical_unhandled); macro_x[MACRO_TOTALSERVICESCRITICALUNHANDLED][MAX_TOTALS_LENGTH-1]='\x0'; } /* get total unhandled services unknown */ if(macro_x[MACRO_TOTALSERVICESUNKNOWNUNHANDLED]!=NULL) free(macro_x[MACRO_TOTALSERVICESUNKNOWNUNHANDLED]); macro_x[MACRO_TOTALSERVICESUNKNOWNUNHANDLED]=(char *)malloc(MAX_TOTALS_LENGTH); if(macro_x[MACRO_TOTALSERVICESUNKNOWNUNHANDLED]!=NULL){ snprintf(macro_x[MACRO_TOTALSERVICESUNKNOWNUNHANDLED],MAX_TOTALS_LENGTH,"%d",services_unknown_unhandled); macro_x[MACRO_TOTALSERVICESUNKNOWNUNHANDLED][MAX_TOTALS_LENGTH-1]='\x0'; } /* get total service problems */ if(macro_x[MACRO_TOTALSERVICEPROBLEMS]!=NULL) free(macro_x[MACRO_TOTALSERVICEPROBLEMS]); macro_x[MACRO_TOTALSERVICEPROBLEMS]=(char *)malloc(MAX_TOTALS_LENGTH); if(macro_x[MACRO_TOTALSERVICEPROBLEMS]!=NULL){ snprintf(macro_x[MACRO_TOTALSERVICEPROBLEMS],MAX_TOTALS_LENGTH,"%d",service_problems); macro_x[MACRO_TOTALSERVICEPROBLEMS][MAX_TOTALS_LENGTH-1]='\x0'; } /* get total unhandled service problems */ if(macro_x[MACRO_TOTALSERVICEPROBLEMSUNHANDLED]!=NULL) free(macro_x[MACRO_TOTALSERVICEPROBLEMSUNHANDLED]); macro_x[MACRO_TOTALSERVICEPROBLEMSUNHANDLED]=(char *)malloc(MAX_TOTALS_LENGTH); if(macro_x[MACRO_TOTALSERVICEPROBLEMSUNHANDLED]!=NULL){ snprintf(macro_x[MACRO_TOTALSERVICEPROBLEMSUNHANDLED],MAX_TOTALS_LENGTH,"%d",service_problems_unhandled); macro_x[MACRO_TOTALSERVICEPROBLEMSUNHANDLED][MAX_TOTALS_LENGTH-1]='\x0'; } #ifdef DEBUG0 printf("grab_summary_macros() end\n"); #endif return OK; } /* updates date/time macros */ int grab_datetime_macros(void){ time_t t; #ifdef DEBUG0 printf("grab_datetime_macros() start\n"); #endif /* get the current time */ time(&t); /* get the current date/time (long format macro) */ if(macro_x[MACRO_LONGDATETIME]==NULL) macro_x[MACRO_LONGDATETIME]=(char *)malloc(MAX_DATETIME_LENGTH); if(macro_x[MACRO_LONGDATETIME]!=NULL) get_datetime_string(&t,macro_x[MACRO_LONGDATETIME],MAX_DATETIME_LENGTH,LONG_DATE_TIME); /* get the current date/time (short format macro) */ if(macro_x[MACRO_SHORTDATETIME]==NULL) macro_x[MACRO_SHORTDATETIME]=(char *)malloc(MAX_DATETIME_LENGTH); if(macro_x[MACRO_SHORTDATETIME]!=NULL) get_datetime_string(&t,macro_x[MACRO_SHORTDATETIME],MAX_DATETIME_LENGTH,SHORT_DATE_TIME); /* get the short format date macro */ if(macro_x[MACRO_DATE]==NULL) macro_x[MACRO_DATE]=(char *)malloc(MAX_DATETIME_LENGTH); if(macro_x[MACRO_DATE]!=NULL) get_datetime_string(&t,macro_x[MACRO_DATE],MAX_DATETIME_LENGTH,SHORT_DATE); /* get the short format time macro */ if(macro_x[MACRO_TIME]==NULL) macro_x[MACRO_TIME]=(char *)malloc(MAX_DATETIME_LENGTH); if(macro_x[MACRO_TIME]!=NULL) get_datetime_string(&t,macro_x[MACRO_TIME],MAX_DATETIME_LENGTH,SHORT_TIME); /* get the time_t format time macro */ if(macro_x[MACRO_TIMET]==NULL) macro_x[MACRO_TIMET]=(char *)malloc(MAX_DATETIME_LENGTH); if(macro_x[MACRO_TIMET]!=NULL){ snprintf(macro_x[MACRO_TIMET],MAX_DATETIME_LENGTH,"%lu",(unsigned long)t); macro_x[MACRO_TIMET][MAX_DATETIME_LENGTH-1]='\x0'; } strip(macro_x[MACRO_LONGDATETIME]); strip(macro_x[MACRO_SHORTDATETIME]); strip(macro_x[MACRO_DATE]); strip(macro_x[MACRO_TIME]); strip(macro_x[MACRO_TIMET]); #ifdef DEBUG0 printf("grab_datetime_macros() end\n"); #endif return OK; } /* clear argv macros - used in commands */ int clear_argv_macros(void){ int x; #ifdef DEBUG0 printf("clear_argv_macros() start\n"); #endif /* command argument macros */ for(x=0;x=16 && x<=19) set_macro_environment_var(macro_x_names[x],clean_macro_chars(macro_x[x],STRIP_ILLEGAL_MACRO_CHARS|ESCAPE_MACRO_CHARS),set); /* others don't */ else set_macro_environment_var(macro_x_names[x],macro_x[x],set); } #ifdef DEBUG0 printf("set_macrox_environment_vars() end\n"); #endif return OK; } /* sets or unsets argv macro environment variables */ int set_argv_macro_environment_vars(int set){ char macro_name[MAX_INPUT_BUFFER]; int x; #ifdef DEBUG0 printf("set_argv_macro_environment_vars() start\n"); #endif /* set each of the argv macro environment variables */ for(x=0;x3) result=STATE_UNKNOWN; /* try and read the results from the command output (retry if we encountered a signal) */ do{ bytes_read=read(fd[0],buffer,sizeof(buffer)-1); }while(bytes_read==-1 && errno==EINTR); buffer[sizeof(buffer)-1]='\x0'; if(output!=NULL){ strncpy(output,buffer,output_length); output[output_length-1]='\x0'; } if(bytes_read==-1 && output!=NULL) strcpy(output,""); /* if there was a critical return code and no output AND the command time exceeded the timeout thresholds, assume a timeout */ if(result==STATE_CRITICAL && bytes_read==-1 && (end_time.tv_sec-start_time.tv_sec)>=timeout){ /* set the early timeout flag */ *early_timeout=TRUE; /* try to kill the command that timed out by sending termination signal to child process group */ kill((pid_t)(-pid),SIGTERM); sleep(1); kill((pid_t)(-pid),SIGKILL); } #ifdef USE_EVENT_BROKER /* send data to event broker */ broker_system_command(NEBTYPE_SYSTEM_COMMAND_END,NEBFLAG_NONE,NEBATTR_NONE,start_time,end_time,*exectime,timeout,*early_timeout,result,cmd,output,NULL); #endif /* close the pipe for reading */ close(fd[0]); } #ifdef DEBUG1 printf("my_system() end\n"); #endif return result; } /* given a "raw" command, return the "expanded" or "whole" command line */ void get_raw_command_line(char *cmd, char *raw_command, int buffer_length, int macro_options){ char temp_arg[MAX_COMMAND_BUFFER]; char arg_buffer[MAX_COMMAND_BUFFER]; command *temp_command; int x,y; int arg_index; #ifdef DEBUG0 printf("get_raw_command_line() start\n"); #endif #ifdef DEBUG1 printf("\tInput: %s\n",cmd); #endif /* clear the argv macros */ clear_argv_macros(); /* make sure we've got all the requirements */ if(cmd==NULL || raw_command==NULL || buffer_length<=0){ #ifdef DEBUG1 printf("\tWe don't have enough data to get the raw command line!\n"); #endif return; } /* initialize the command */ strcpy(raw_command,""); /* clear the old command arguments */ for(x=0;xcommand_line,buffer_length); raw_command[buffer_length-1]='\x0'; strip(raw_command); /* skip the command name (we're about to get the arguments)... */ for(arg_index=0;;arg_index++){ if(cmd[arg_index]=='!' || cmd[arg_index]=='\x0') break; } /* get the command arguments */ for(x=0;xtm_sec=0; t->tm_min=0; t->tm_hour=0; midnight_today=(unsigned long)mktime(t); for(temp_range=temp_period->days[t->tm_wday];temp_range!=NULL;temp_range=temp_range->next){ /* if the user-specified time falls in this range, return with a positive result */ if(check_time>=(time_t)(midnight_today+temp_range->range_start) && check_time<=(time_t)(midnight_today+temp_range->range_end)) return OK; } #ifdef DEBUG0 printf("check_time_against_period() end\n"); #endif return ERROR; } /* given a preferred time, get the next valid time within a time period */ void get_next_valid_time(time_t preferred_time,time_t *valid_time, char *period_name){ timeperiod *temp_period; timerange *temp_timerange; unsigned long midnight_today; struct tm *t; int today; int weekday; unsigned long earliest_next_valid_time=0L; time_t this_time_range_start; int has_looped=FALSE; int days_into_the_future; #ifdef DEBUG0 printf("get_next_valid_time() start\n"); #endif #ifdef DEBUG1 printf("\tPreferred Time: %lu --> %s",(unsigned long)preferred_time,ctime(&preferred_time)); #endif /* if the preferred time is valid today, go with it */ if(check_time_against_period(preferred_time,period_name)==OK) *valid_time=preferred_time; /* else find the next available time */ else{ /* find the time period - if we can't find it, go with the preferred time */ temp_period=find_timeperiod(period_name); if(temp_period==NULL){ *valid_time=preferred_time; return; } t=localtime((time_t *)&preferred_time); /* calculate the start of the day (midnight, 00:00 hours) */ t->tm_sec=0; t->tm_min=0; t->tm_hour=0; midnight_today=(unsigned long)mktime(t); today=t->tm_wday; has_looped=FALSE; /* check a one week rotation of time */ for(weekday=today,days_into_the_future=0;;weekday++,days_into_the_future++){ if(weekday>=7){ weekday-=7; has_looped=TRUE; } /* check all time ranges for this day of the week */ for(temp_timerange=temp_period->days[weekday];temp_timerange!=NULL;temp_timerange=temp_timerange->next){ /* calculate the time for the start of this time range */ this_time_range_start=(time_t)(midnight_today+(days_into_the_future*3600*24)+temp_timerange->range_start); /* we're looking for the earliest possible start time for this day */ if((earliest_next_valid_time==(time_t)0 || (this_time_range_start < earliest_next_valid_time)) && (this_time_range_start >= (time_t)preferred_time)) earliest_next_valid_time=this_time_range_start; } /* break out of the loop if we have checked an entire week already */ if(has_looped==TRUE && weekday >= today) break; } /* if we couldn't find a time period (there must be none defined) */ if(earliest_next_valid_time==(time_t)0) *valid_time=(time_t)preferred_time; /* else use the calculated time */ else *valid_time=earliest_next_valid_time; } #ifdef DEBUG1 printf("\tNext Valid Time: %lu --> %s",(unsigned long)*valid_time,ctime(valid_time)); #endif #ifdef DEBUG0 printf("get_next_valid_time() end\n"); #endif return; } /* given a date/time in time_t format, produce a corresponding date/time string, including timezone */ void get_datetime_string(time_t *raw_time,char *buffer,int buffer_length, int type){ time_t t; struct tm *tm_ptr; int hour; int minute; int second; int month; int day; int year; char *weekdays[7]={"Sun","Mon","Tue","Wed","Thu","Fri","Sat"}; char *months[12]={"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sept","Oct","Nov","Dec"}; #ifdef HAVE_TM_ZONE # define tzone tm_ptr->tm_zone #else # define tzone (tm_ptr->tm_isdst)?tzname[1]:tzname[0] #endif if(raw_time==NULL) time(&t); else t=*raw_time; tm_ptr=localtime(&t); hour=tm_ptr->tm_hour; minute=tm_ptr->tm_min; second=tm_ptr->tm_sec; month=tm_ptr->tm_mon+1; day=tm_ptr->tm_mday; year=tm_ptr->tm_year+1900; /* ctime() style date/time */ if(type==LONG_DATE_TIME) snprintf(buffer,buffer_length,"%s %s %d %02d:%02d:%02d %s %d",weekdays[tm_ptr->tm_wday],months[tm_ptr->tm_mon],day,hour,minute,second,tzone,year); /* short date/time */ else if(type==SHORT_DATE_TIME){ if(date_format==DATE_FORMAT_EURO) snprintf(buffer,buffer_length,"%02d-%02d-%04d %02d:%02d:%02d",day,month,year,hour,minute,second); else if(date_format==DATE_FORMAT_ISO8601 || date_format==DATE_FORMAT_STRICT_ISO8601) snprintf(buffer,buffer_length,"%04d-%02d-%02d%c%02d:%02d:%02d",year,month,day,(date_format==DATE_FORMAT_STRICT_ISO8601)?'T':' ',hour,minute,second); else snprintf(buffer,buffer_length,"%02d-%02d-%04d %02d:%02d:%02d",month,day,year,hour,minute,second); } /* short date */ else if(type==SHORT_DATE){ if(date_format==DATE_FORMAT_EURO) snprintf(buffer,buffer_length,"%02d-%02d-%04d",day,month,year); else if(date_format==DATE_FORMAT_ISO8601 || date_format==DATE_FORMAT_STRICT_ISO8601) snprintf(buffer,buffer_length,"%04d-%02d-%02d",year,month,day); else snprintf(buffer,buffer_length,"%02d-%02d-%04d",month,day,year); } /* short time */ else snprintf(buffer,buffer_length,"%02d:%02d:%02d",hour,minute,second); buffer[buffer_length-1]='\x0'; /* don't mess up other functions that might want to call a variable 'tzone' */ #undef tzone return; } /* get the next time to schedule a log rotation */ time_t get_next_log_rotation_time(void){ time_t current_time; struct tm *t; int is_dst_now=FALSE; time_t run_time; #ifdef DEBUG0 printf("get_next_log_rotation_time() start\n"); #endif time(¤t_time); t=localtime(¤t_time); t->tm_min=0; t->tm_sec=0; is_dst_now=(t->tm_isdst>0)?TRUE:FALSE; switch(log_rotation_method){ case LOG_ROTATION_HOURLY: t->tm_hour++; run_time=mktime(t); break; case LOG_ROTATION_DAILY: t->tm_mday++; t->tm_hour=0; run_time=mktime(t); break; case LOG_ROTATION_WEEKLY: t->tm_mday+=(7-t->tm_wday); t->tm_hour=0; run_time=mktime(t); break; case LOG_ROTATION_MONTHLY: default: t->tm_mon++; t->tm_mday=1; t->tm_hour=0; run_time=mktime(t); break; } if(is_dst_now==TRUE && t->tm_isdst==0) run_time+=3600; else if(is_dst_now==FALSE && t->tm_isdst>0) run_time-=3600; #ifdef DEBUG1 printf("\tNext Log Rotation Time: %s",ctime(&run_time)); #endif #ifdef DEBUG0 printf("get_next_log_rotation_time() end\n"); #endif return run_time; } /******************************************************************/ /******************** SIGNAL HANDLER FUNCTIONS ********************/ /******************************************************************/ /* trap signals so we can exit gracefully */ void setup_sighandler(void){ #ifdef DEBUG0 printf("setup_sighandler() start\n"); #endif /* reset the shutdown flag */ sigshutdown=FALSE; /* remove buffering from stderr, stdin, and stdout */ setbuf(stdin,(char *)NULL); setbuf(stdout,(char *)NULL); setbuf(stderr,(char *)NULL); /* initialize signal handling */ signal(SIGPIPE,SIG_IGN); signal(SIGQUIT,sighandler); signal(SIGTERM,sighandler); signal(SIGHUP,sighandler); #if !defined(DEBUG0) && !defined(DEBUG1) && !defined(DEBUG2) && !defined(DEBUG3) && !defined(DEBUG4) && !defined(DEBUG5) if(daemon_dumps_core==FALSE || daemon_mode==FALSE) signal(SIGSEGV,sighandler); #endif #ifdef DEBUG0 printf("setup_sighandler() end\n"); #endif return; } /* reset signal handling... */ void reset_sighandler(void){ #ifdef DEBUG0 printf("reset_sighandler() start\n"); #endif /* set signal handling to default actions */ signal(SIGQUIT,SIG_DFL); signal(SIGTERM,SIG_DFL); signal(SIGHUP,SIG_DFL); signal(SIGSEGV,SIG_DFL); signal(SIGPIPE,SIG_DFL); #ifdef DEBUG0 printf("reset_sighandler() end\n"); #endif return; } /* handle signals */ void sighandler(int sig){ static char *sigs[]={"EXIT","HUP","INT","QUIT","ILL","TRAP","ABRT","BUS","FPE","KILL","USR1","SEGV","USR2","PIPE","ALRM","TERM","STKFLT","CHLD","CONT","STOP","TSTP","TTIN","TTOU","URG","XCPU","XFSZ","VTALRM","PROF","WINCH","IO","PWR","UNUSED","ZERR","DEBUG",(char *)NULL}; int i; char temp_buffer[MAX_INPUT_BUFFER]; /* if shutdown is already true, we're in a signal trap loop! */ if(sigshutdown==TRUE) exit(ERROR); if(sig<0) sig=-sig; for(i=0;sigs[i]!=(char *)NULL;i++); sig%=i; /* we received a SIGHUP, so restart... */ if(sig==SIGHUP){ sigrestart=TRUE; sprintf(temp_buffer,"Caught SIGHUP, restarting...\n"); write_to_all_logs(temp_buffer,NSLOG_PROCESS_INFO); #ifdef DEBUG2 printf("%s\n",temp_buffer); #endif } /* else begin shutting down... */ else if(sig<16){ sigshutdown=TRUE; sprintf(temp_buffer,"Caught SIG%s, shutting down...\n",sigs[sig]); write_to_all_logs(temp_buffer,NSLOG_PROCESS_INFO); #ifdef DEBUG2 printf("%s\n",temp_buffer); #endif #ifdef REMOVED_06202006 /* remove the lock file if we're in daemon mode */ if(daemon_mode==TRUE) unlink(lock_file); /* close and delete the external command file FIFO */ close_command_file(); #endif } return; } /* handle timeouts when executing service checks */ void service_check_sighandler(int sig){ struct timeval end_time; /* get the current time */ gettimeofday(&end_time,NULL); /* write plugin check results to message queue */ strncpy(svc_msg.output,"(Service Check Timed Out)",sizeof(svc_msg.output)-1); svc_msg.output[sizeof(svc_msg.output)-1]='\x0'; #ifdef SERVICE_CHECK_TIMEOUTS_RETURN_UNKNOWN svc_msg.return_code=STATE_UNKNOWN; #else svc_msg.return_code=STATE_CRITICAL; #endif svc_msg.exited_ok=TRUE; svc_msg.check_type=SERVICE_CHECK_ACTIVE; svc_msg.finish_time=end_time; svc_msg.early_timeout=TRUE; write_svc_message(&svc_msg); /* close write end of IPC pipe */ close(ipc_pipe[1]); /* try to kill the command that timed out by sending termination signal to our process group */ /* we also kill ourselves while doing this... */ kill((pid_t)0,SIGKILL); /* force the child process (service check) to exit... */ exit(STATE_CRITICAL); } /* handle timeouts when executing commands via my_system() */ void my_system_sighandler(int sig){ /* force the child process to exit... */ exit(STATE_CRITICAL); } /******************************************************************/ /************************ DAEMON FUNCTIONS ************************/ /******************************************************************/ int daemon_init(void){ pid_t pid=-1; int pidno; int lockfile; int val=0; char buf[256]; struct flock lock; char temp_buffer[MAX_INPUT_BUFFER]; char *homedir=NULL; #ifdef RLIMIT_CORE struct rlimit limit; #endif /* change working directory. scuttle home if we're dumping core */ homedir=getenv("HOME"); if(daemon_dumps_core==TRUE && homedir!=NULL) chdir(homedir); else chdir("/"); umask(S_IWGRP|S_IWOTH); lockfile=open(lock_file,O_RDWR | O_CREAT, S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH); if(lockfile<0){ strcpy(temp_buffer,""); if(errno==EISDIR) snprintf(temp_buffer,sizeof(temp_buffer)-1,"%s is a directory\n",lock_file); else if(errno==EACCES) snprintf(temp_buffer,sizeof(temp_buffer)-1,"You do not have permission to write to %s\n",lock_file); else if(errno==ENAMETOOLONG) snprintf(temp_buffer,sizeof(temp_buffer)-1,"The filename is too long: %s\n",lock_file); else if(errno==ENOENT) snprintf(temp_buffer,sizeof(temp_buffer)-1,"%s does not exist (ENOENT)\n",lock_file); else if(errno==ENOTDIR) snprintf(temp_buffer,sizeof(temp_buffer)-1,"%s does not exist (ENOTDIR)\n",lock_file); else if(errno==ENXIO) snprintf(temp_buffer,sizeof(temp_buffer)-1,"Cannot write to special file\n"); else if(errno==ENODEV) snprintf(temp_buffer,sizeof(temp_buffer)-1,"Cannot write to device\n"); else if(errno==EROFS) snprintf(temp_buffer,sizeof(temp_buffer)-1,"%s is on a read-only file system\n",lock_file); else if(errno==ETXTBSY) snprintf(temp_buffer,sizeof(temp_buffer)-1,"%s is a currently running program\n",lock_file); else if(errno==EFAULT) snprintf(temp_buffer,sizeof(temp_buffer)-1,"%s is outside address space\n",lock_file); else if(errno==ELOOP) snprintf(temp_buffer,sizeof(temp_buffer)-1,"Too many symbolic links\n"); else if(errno==ENOSPC) snprintf(temp_buffer,sizeof(temp_buffer)-1,"No space on device\n"); else if(errno==ENOMEM) snprintf(temp_buffer,sizeof(temp_buffer)-1,"Insufficient kernel memory\n"); else if(errno==EMFILE) snprintf(temp_buffer,sizeof(temp_buffer)-1,"Too many files open in process\n"); else if(errno==ENFILE) snprintf(temp_buffer,sizeof(temp_buffer)-1,"Too many files open on system\n"); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_RUNTIME_ERROR,TRUE); snprintf(temp_buffer,sizeof(temp_buffer),"Bailing out due to errors encountered while attempting to daemonize... (PID=%d)",(int)getpid()); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_PROCESS_INFO | NSLOG_RUNTIME_ERROR,TRUE); cleanup(); exit(ERROR); } /* see if we can read the contents of the lockfile */ if((val=read(lockfile,buf,(size_t)10))<0){ write_to_logs_and_console("Lockfile exists but cannot be read",NSLOG_RUNTIME_ERROR,TRUE); cleanup(); exit(ERROR); } /* we read something - check the PID */ if(val>0){ if((val=sscanf(buf,"%d",&pidno))<1){ snprintf(temp_buffer,sizeof(temp_buffer)-1,"Lockfile '%s' does not contain a valid PID (%s)",lock_file,buf); write_to_logs_and_console(temp_buffer,NSLOG_RUNTIME_ERROR,TRUE); cleanup(); exit(ERROR); } } /* check for SIGHUP */ if(val==1 && (pid=(pid_t)pidno)==getpid()){ close(lockfile); return OK; } /* exit on errors... */ if((pid=fork())<0) return(ERROR); /* parent process goes away.. */ else if((int)pid!=0) exit(OK); /* child continues... */ /* child becomes session leader... */ setsid(); /* place a file lock on the lock file */ lock.l_type=F_WRLCK; lock.l_start=0; lock.l_whence=SEEK_SET; lock.l_len=0; if(fcntl(lockfile,F_SETLK,&lock)<0){ if(errno==EACCES || errno==EAGAIN){ fcntl(lockfile,F_GETLK,&lock); snprintf(temp_buffer,sizeof(temp_buffer)-1,"Lockfile '%s' is held by PID %d. Bailing out...",lock_file,(int)lock.l_pid); } else snprintf(temp_buffer,sizeof(temp_buffer)-1,"Cannot lock lockfile '%s': %s. Bailing out...",lock_file,strerror(errno)); write_to_logs_and_console(temp_buffer,NSLOG_RUNTIME_ERROR,TRUE); cleanup(); exit(ERROR); } /* prevent daemon from dumping a core file... */ #ifdef RLIMIT_CORE if(daemon_dumps_core==FALSE){ getrlimit(RLIMIT_CORE,&limit); limit.rlim_cur=0; setrlimit(RLIMIT_CORE,&limit); } #endif /* write PID to lockfile... */ lseek(lockfile,0,SEEK_SET); ftruncate(lockfile,0); sprintf(buf,"%d\n",(int)getpid()); write(lockfile,buf,strlen(buf)); /* make sure lock file stays open while program is executing... */ val=fcntl(lockfile,F_GETFD,0); val|=FD_CLOEXEC; fcntl(lockfile,F_SETFD,val); /* close existing stdin, stdout, stderr */ close(0); close(1); close(2); /* THIS HAS TO BE DONE TO AVOID PROBLEMS WITH STDERR BEING REDIRECTED TO SERVICE MESSAGE PIPE! */ /* re-open stdin, stdout, stderr with known values */ open("/dev/null",O_RDONLY); open("/dev/null",O_WRONLY); open("/dev/null",O_WRONLY); #ifdef USE_EVENT_BROKER /* send program data to broker */ broker_program_state(NEBTYPE_PROCESS_DAEMONIZE,NEBFLAG_NONE,NEBATTR_NONE,NULL); #endif return OK; } /******************************************************************/ /*********************** SECURITY FUNCTIONS ***********************/ /******************************************************************/ /* drops privileges */ int drop_privileges(char *user, char *group){ char temp_buffer[MAX_INPUT_BUFFER]; uid_t uid=-1; gid_t gid=-1; struct group *grp; struct passwd *pw; int result=OK; #ifdef DEBUG0 printf("drop_privileges() start\n"); #endif #ifdef DEBUG1 printf("Original UID/GID: %d/%d\n",(int)getuid(),(int)getgid()); #endif /* only drop privileges if we're running as root, so we don't interfere with being debugged while running as some random user */ if(getuid()!=0) return OK; /* set effective group ID */ if(group!=NULL){ /* see if this is a group name */ if(strspn(group,"0123456789")gr_gid); else{ snprintf(temp_buffer,sizeof(temp_buffer)-1,"Warning: Could not get group entry for '%s'",group); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_RUNTIME_WARNING,TRUE); } } /* else we were passed the GID */ else gid=(gid_t)atoi(group); /* set effective group ID if other than current EGID */ if(gid!=getegid()){ if(setgid(gid)==-1){ snprintf(temp_buffer,sizeof(temp_buffer)-1,"Warning: Could not set effective GID=%d",(int)gid); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_RUNTIME_WARNING,TRUE); result=ERROR; } } } /* set effective user ID */ if(user!=NULL){ /* see if this is a user name */ if(strspn(user,"0123456789")pw_uid); else{ snprintf(temp_buffer,sizeof(temp_buffer)-1,"Warning: Could not get passwd entry for '%s'",user); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_RUNTIME_WARNING,TRUE); } } /* else we were passed the UID */ else uid=(uid_t)atoi(user); #ifdef HAVE_INITGROUPS if(uid!=geteuid()){ /* initialize supplementary groups */ if(initgroups(user,gid)==-1){ if(errno==EPERM){ snprintf(temp_buffer,sizeof(temp_buffer)-1,"Warning: Unable to change supplementary groups using initgroups() -- I hope you know what you're doing"); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_RUNTIME_WARNING,TRUE); } else{ snprintf(temp_buffer,sizeof(temp_buffer)-1,"Warning: Possibly root user failed dropping privileges with initgroups()"); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_RUNTIME_WARNING,TRUE); return ERROR; } } } #endif if(setuid(uid)==-1){ snprintf(temp_buffer,sizeof(temp_buffer)-1,"Warning: Could not set effective UID=%d",(int)uid); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_RUNTIME_WARNING,TRUE); result=ERROR; } } #ifdef DEBUG1 printf("New UID/GID: %d/%d\n",(int)getuid(),(int)getgid()); #endif #ifdef DEBUG0 printf("drop_privileges() end\n"); #endif return result; } /******************************************************************/ /************************* IPC FUNCTIONS **************************/ /******************************************************************/ /* reads a service message from the circular buffer */ int read_svc_message(service_message *message){ char buffer[MAX_INPUT_BUFFER]; int result; #ifdef DEBUG0 printf("read_svc_message() start\n"); #endif if(message==NULL) return -1; /* clear the message buffer */ memset((void *)message,0,sizeof(service_message)); /* get a lock on the buffer */ pthread_mutex_lock(&service_result_buffer.buffer_lock); /* handle detected overflows */ if(service_result_buffer.overflow>0){ /* log the warning */ snprintf(buffer,sizeof(buffer)-1,"Warning: Overflow detected in service check result buffer - %lu message(s) lost.\n",service_result_buffer.overflow); buffer[sizeof(buffer)-1]='\x0'; write_to_logs_and_console(buffer,NSLOG_RUNTIME_WARNING,TRUE); /* reset overflow counter */ service_result_buffer.overflow=0; } /* there are no items in the buffer */ if(service_result_buffer.items==0) result=-1; /* return the message from the tail of the buffer */ else{ /* copy message to user-supplied structure */ memcpy(message,((service_message **)service_result_buffer.buffer)[service_result_buffer.tail],sizeof(service_message)); /* free memory allocated for buffer slot */ free(((service_message **)service_result_buffer.buffer)[service_result_buffer.tail]); service_result_buffer.buffer[service_result_buffer.tail]=NULL; /* adjust tail counter and number of items */ service_result_buffer.tail=(service_result_buffer.tail + 1) % SERVICE_BUFFER_SLOTS; service_result_buffer.items--; result=0; } /* release the lock on the buffer */ pthread_mutex_unlock(&service_result_buffer.buffer_lock); #ifdef DEBUG0 printf("read_svc_message() end\n"); #endif return result; } /* writes a service message to the message pipe */ int write_svc_message(service_message *message){ struct timeval tv; int write_result; #ifdef DEBUG0 printf("write_svc_message() start\n"); #endif if(message==NULL) return 0; while(1){ write_result=write(ipc_pipe[1],message,sizeof(service_message)); if(write_result==-1){ /* pipe is full - wait a bit and retry */ if(errno==EAGAIN){ tv.tv_sec=0; tv.tv_usec=250; select(0,NULL,NULL,NULL,&tv); continue; } /* an interrupt occurred - retry */ if(errno==EINTR) continue; /* some other error occurred - bail out */ break; } else break; } #ifdef DEBUG0 printf("write_svc_message() end\n"); #endif return write_result; } /* creates external command file as a named pipe (FIFO) and opens it for reading (non-blocked mode) */ int open_command_file(void){ char buffer[MAX_INPUT_BUFFER]; struct stat st; int result; #ifdef DEBUG0 printf("open_command_file() start\n"); #endif /* if we're not checking external commands, don't do anything */ if(check_external_commands==FALSE) return OK; /* the command file was already created */ if(command_file_created==TRUE) return OK; /* reset umask (group needs write permissions) */ umask(S_IWOTH); /* use existing FIFO if possible */ if(!(stat(command_file,&st)!=-1 && (st.st_mode & S_IFIFO))){ /* create the external command file as a named pipe (FIFO) */ if((result=mkfifo(command_file,S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP))!=0){ snprintf(buffer,sizeof(buffer)-1,"Error: Could not create external command file '%s' as named pipe: (%d) -> %s. If this file already exists and you are sure that another copy of Nagios is not running, you should delete this file.\n",command_file,errno,strerror(errno)); buffer[sizeof(buffer)-1]='\x0'; write_to_logs_and_console(buffer,NSLOG_RUNTIME_ERROR,TRUE); return ERROR; } } /* open the command file for reading (non-blocked) - O_TRUNC flag cannot be used due to errors on some systems */ if((command_file_fd=open(command_file,O_RDONLY | O_NONBLOCK))<0){ snprintf(buffer,sizeof(buffer)-1,"Error: Could not open external command file for reading via open(): (%d) -> %s\n",errno,strerror(errno)); buffer[sizeof(buffer)-1]='\x0'; write_to_logs_and_console(buffer,NSLOG_RUNTIME_ERROR,TRUE); return ERROR; } /* re-open the FIFO for use with fgets() */ if((command_file_fp=fdopen(command_file_fd,"r"))==NULL){ snprintf(buffer,sizeof(buffer)-1,"Error: Could not open external command file for reading via fdopen(): (%d) -> %s\n",errno,strerror(errno)); buffer[sizeof(buffer)-1]='\x0'; write_to_logs_and_console(buffer,NSLOG_RUNTIME_ERROR,TRUE); return ERROR; } /* initialize worker thread */ if(init_command_file_worker_thread()==ERROR){ snprintf(buffer,sizeof(buffer)-1,"Error: Could not initialize command file worker thread.\n"); buffer[sizeof(buffer)-1]='\x0'; write_to_logs_and_console(buffer,NSLOG_RUNTIME_ERROR,TRUE); /* close the command file */ fclose(command_file_fp); /* delete the named pipe */ unlink(command_file); return ERROR; } /* set a flag to remember we already created the file */ command_file_created=TRUE; #ifdef DEBUG0 printf("open_command_file() end\n"); #endif return OK; } /* closes the external command file FIFO and deletes it */ int close_command_file(void){ #ifdef DEBUG0 printf("close_command_file() start\n"); #endif /* if we're not checking external commands, don't do anything */ if(check_external_commands==FALSE) return OK; /* the command file wasn't created or was already cleaned up */ if(command_file_created==FALSE) return OK; /* reset our flag */ command_file_created=FALSE; /* shutdown the worker thread */ shutdown_command_file_worker_thread(); /* close the command file */ fclose(command_file_fp); /* delete the named pipe */ /* if(unlink(command_file)!=0) return ERROR; */ #ifdef DEBUG0 printf("close_command_file() end\n"); #endif return OK; } /******************************************************************/ /************************ STRING FUNCTIONS ************************/ /******************************************************************/ /* strip newline, carriage return, and tab characters from beginning and end of a string */ void strip(char *buffer){ register int x; register int y; register int z; if(buffer==NULL || buffer[0]=='\x0') return; /* strip end of string */ y=(int)strlen(buffer); for(x=y-1;x>=0;x--){ if(buffer[x]==' ' || buffer[x]=='\n' || buffer[x]=='\r' || buffer[x]=='\t' || buffer[x]==13) buffer[x]='\x0'; else break; } /* strip beginning of string (by shifting) */ y=(int)strlen(buffer); for(x=0;x0){ for(z=x;z=0;x--){ ch=(int)name[x]; /* illegal ASCII characters */ if(ch<32 || ch==127) return TRUE; /* REMOVED 3/11/05 to allow for non-english spellings, etc. */ /* illegal extended ASCII characters */ /* if(ch>=166) return TRUE; */ /* illegal user-specified characters */ if(illegal_object_chars!=NULL) for(y=0;illegal_object_chars[y];y++) if(name[x]==illegal_object_chars[y]) return TRUE; } return FALSE; } /* cleans illegal characters in macros before output */ char *clean_macro_chars(char *macro,int options){ register int x,y,z; register int ch; register int len; register int illegal_char; if(macro==NULL) return ""; len=(int)strlen(macro); /* strip illegal characters out of macro */ if(options & STRIP_ILLEGAL_MACRO_CHARS){ for(y=0,x=0;x=166) continue; */ /* illegal user-specified characters */ illegal_char=FALSE; if(illegal_output_chars!=NULL){ for(z=0;illegal_output_chars[z]!='\x0';z++){ if(ch==(int)illegal_output_chars[z]){ illegal_char=TRUE; break; } } } if(illegal_char==FALSE) macro[y++]=macro[x]; } macro[y++]='\x0'; } #ifdef ON_HOLD_FOR_NOW /* escape nasty character in macro */ if(options & ESCAPE_MACRO_CHARS){ } #endif return macro; } /* fix the problem with strtok() skipping empty options between tokens */ char *my_strtok(char *buffer,char *tokens){ char *token_position; char *sequence_head; if(buffer!=NULL){ if(original_my_strtok_buffer!=NULL) free(original_my_strtok_buffer); my_strtok_buffer=(char *)malloc(strlen(buffer)+1); if(my_strtok_buffer==NULL) return NULL; original_my_strtok_buffer=my_strtok_buffer; strcpy(my_strtok_buffer,buffer); } sequence_head=my_strtok_buffer; if(sequence_head[0]=='\x0') return NULL; token_position=strchr(my_strtok_buffer,tokens[0]); if(token_position==NULL){ my_strtok_buffer=strchr(my_strtok_buffer,'\x0'); return sequence_head; } token_position[0]='\x0'; my_strtok_buffer=token_position+1; return sequence_head; } /* fixes compiler problems under Solaris, since strsep() isn't included */ /* this code is taken from the glibc source */ char *my_strsep (char **stringp, const char *delim){ char *begin, *end; begin = *stringp; if (begin == NULL) return NULL; /* A frequent case is when the delimiter string contains only one character. Here we don't need to call the expensive `strpbrk' function and instead work using `strchr'. */ if(delim[0]=='\0' || delim[1]=='\0'){ char ch = delim[0]; if(ch=='\0') end=NULL; else{ if(*begin==ch) end=begin; else end=strchr(begin+1,ch); } } else /* Find the end of the token. */ end = strpbrk (begin, delim); if(end){ /* Terminate the token and set *STRINGP past NUL character. */ *end++='\0'; *stringp=end; } else /* No more delimiters; this is the last token. */ *stringp=NULL; return begin; } /* encodes a string in proper URL format */ char *get_url_encoded_string(char *input){ register int x,y; char *encoded_url_string=NULL; char temp_expansion[4]; /* bail if no input */ if(input==NULL) return NULL; /* allocate enough memory to escape all characters if necessary */ if((encoded_url_string=(char *)malloc((strlen(input)*3)+1))==NULL) return NULL; /* check/encode all characters */ for(x=0,y=0;input[x]!=(char)'\x0';x++){ /* alpha-numeric characters and a few other characters don't get encoded */ if(((char)input[x]>='0' && (char)input[x]<='9') || ((char)input[x]>='A' && (char)input[x]<='Z') || ((char)input[x]>=(char)'a' && (char)input[x]<=(char)'z') || (char)input[x]==(char)'.' || (char)input[x]==(char)'-' || (char)input[x]==(char)'_'){ encoded_url_string[y]=input[x]; y++; } /* spaces are pluses */ else if((char)input[x]<=(char)' '){ encoded_url_string[y]='+'; y++; } /* anything else gets represented by its hex value */ else{ encoded_url_string[y]='\x0'; sprintf(temp_expansion,"%%%02X",(unsigned int)input[x]); strcat(encoded_url_string,temp_expansion); y+=3; } } /* terminate encoded string */ encoded_url_string[y]='\x0'; return encoded_url_string; } /******************************************************************/ /************************* HASH FUNCTIONS *************************/ /******************************************************************/ /* single hash function */ int hashfunc1(const char *name1,int hashslots){ unsigned int i,result; result=0; if(name1) for(i=0;i0) return 1; else if(result<0) return -1; else return strcmp(val1b,val2b); } /******************************************************************/ /************************* FILE FUNCTIONS *************************/ /******************************************************************/ /* renames a file - works across filesystems (Mike Wiacek) */ int my_rename(char *source, char *dest){ char buffer[MAX_INPUT_BUFFER]={0}; int rename_result; int source_fd; int dest_fd; int bytes_read; /* make sure we have something */ if(source==NULL || dest==NULL) return -1; /* first see if we can rename file with standard function */ rename_result=rename(source,dest); /* an error occurred because the source and dest files are on different filesystems */ if(rename_result==-1 && errno==EXDEV){ #ifdef DEBUG2 printf("\tMoving file across file systems.\n"); #endif /* open destination file for writing */ if((dest_fd=open(dest,O_WRONLY|O_TRUNC|O_CREAT|O_APPEND,0644))>0){ /* open source file for reading */ if((source_fd=open(source,O_RDONLY,0644))>0){ while((bytes_read=read(source_fd,buffer,sizeof(buffer)))>0) write(dest_fd,buffer,bytes_read); close(source_fd); close(dest_fd); /* delete the original file */ unlink(source); /* reset result since we successfully copied file */ rename_result=0; } else{ close(dest_fd); return rename_result; } } else return rename_result; } return rename_result; } /* open a file read-only via mmap() */ mmapfile *mmap_fopen(char *filename){ mmapfile *new_mmapfile; int fd; void *mmap_buf; struct stat statbuf; int mode=O_RDONLY; /* allocate memory */ if((new_mmapfile=(mmapfile *)malloc(sizeof(mmapfile)))==NULL) return NULL; /* open the file */ if((fd=open(filename,mode))==-1){ free(new_mmapfile); return NULL; } /* get file info */ if((fstat(fd,&statbuf))==-1){ close(fd); free(new_mmapfile); return NULL; } /* mmap() the file - allocate one extra byte for processing zero-byte files */ if((mmap_buf=(void *)mmap(0,statbuf.st_size+1,PROT_READ,MAP_PRIVATE,fd,0))==MAP_FAILED){ close(fd); free(new_mmapfile); return NULL; } /* populate struct info for later use */ /*new_mmapfile->path=strdup(filename);*/ new_mmapfile->path=NULL; new_mmapfile->fd=fd; new_mmapfile->file_size=(unsigned long)(statbuf.st_size); new_mmapfile->current_position=0L; new_mmapfile->current_line=0L; new_mmapfile->mmap_buf=mmap_buf; return new_mmapfile; } /* close a file originally opened via mmap() */ int mmap_fclose(mmapfile *temp_mmapfile){ if(temp_mmapfile==NULL) return ERROR; /* un-mmap() the file */ munmap(temp_mmapfile->mmap_buf,temp_mmapfile->file_size); /* close the file */ close(temp_mmapfile->fd); /* free memory */ if(temp_mmapfile->path!=NULL) free(temp_mmapfile->path); free(temp_mmapfile); return OK; } /* gets one line of input from an mmap()'ed file */ char *mmap_fgets(mmapfile *temp_mmapfile){ char *buf=NULL; unsigned long x=0L; int len=0; if(temp_mmapfile==NULL) return NULL; /* we've reached the end of the file */ if(temp_mmapfile->current_position>=temp_mmapfile->file_size) return NULL; /* find the end of the string (or buffer) */ for(x=temp_mmapfile->current_position;xfile_size;x++){ if(*((char *)(temp_mmapfile->mmap_buf)+x)=='\n'){ x++; break; } } /* calculate length of line we just read */ len=(int)(x-temp_mmapfile->current_position); /* allocate memory for the new line */ if((buf=(char *)malloc(len+1))==NULL) return NULL; /* copy string to newly allocated memory and terminate the string */ memcpy(buf,((char *)(temp_mmapfile->mmap_buf)+temp_mmapfile->current_position),len); buf[len]='\x0'; /* update the current position */ temp_mmapfile->current_position=x; /* increment the current line */ temp_mmapfile->current_line++; return buf; } /* gets one line of input from an mmap()'ed file (may be contained on more than one line in the source file) */ char *mmap_fgets_multiline(mmapfile *temp_mmapfile){ char *buf=NULL; char *tempbuf=NULL; int len; int len2; if(temp_mmapfile==NULL) return NULL; while(1){ free(tempbuf); if((tempbuf=mmap_fgets(temp_mmapfile))==NULL) break; if(buf==NULL){ len=strlen(tempbuf); if((buf=(char *)malloc(len+1))==NULL) break; memcpy(buf,tempbuf,len); buf[len]='\x0'; } else{ len=strlen(tempbuf); len2=strlen(buf); if((buf=(char *)realloc(buf,len+len2+1))==NULL) break; strcat(buf,tempbuf); len+=len2; buf[len]='\x0'; } /* we shouldn't continue to the next line... */ if(!(len>0 && buf[len-1]=='\\' && (len==1 || buf[len-2]!='\\'))) break; } free(tempbuf); return buf; } /******************************************************************/ /******************** EMBEDDED PERL FUNCTIONS *********************/ /******************************************************************/ /* initializes embedded perl interpreter */ int init_embedded_perl(char **env){ #ifdef EMBEDDEDPERL char *embedding[] = { "", "" }; int exitstatus = 0; char buffer[MAX_INPUT_BUFFER]; int argc = 2; struct stat stat_buf; /* make sure the P1 file exists... */ if(p1_file==NULL || stat(p1_file,&stat_buf)!=0){ use_embedded_perl=FALSE; snprintf(buffer,sizeof(buffer),"Error: p1.pl file required for embedded Perl interpreter is missing!\n"); buffer[sizeof(buffer)-1]='\x0'; write_to_logs_and_console(buffer,NSLOG_RUNTIME_ERROR,TRUE); } else{ embedding[1]=p1_file; use_embedded_perl=TRUE; PERL_SYS_INIT3(&argc,&embedding,&env); if((my_perl=perl_alloc())==NULL){ use_embedded_perl=FALSE; snprintf(buffer,sizeof(buffer),"Error: Could not allocate memory for embedded Perl interpreter!\n"); buffer[sizeof(buffer)-1]='\x0'; write_to_logs_and_console(buffer,NSLOG_RUNTIME_ERROR,TRUE); } } /* a fatal error occurred... */ if(use_embedded_perl==FALSE){ snprintf(buffer,sizeof(buffer),"Bailing out due to errors encountered while initializing the embedded Perl interpreter. (PID=%d)\n",(int)getpid()); buffer[sizeof(buffer)-1]='\x0'; write_to_logs_and_console(buffer,NSLOG_PROCESS_INFO | NSLOG_RUNTIME_ERROR,TRUE); cleanup(); exit(ERROR); } perl_construct(my_perl); exitstatus=perl_parse(my_perl,xs_init,2,embedding,env); if(!exitstatus) exitstatus=perl_run(my_perl); #endif return OK; } /* closes embedded perl interpreter */ int deinit_embedded_perl(void){ #ifdef EMBEDDEDPERL PL_perl_destruct_level=0; perl_destruct(my_perl); perl_free(my_perl); PERL_SYS_TERM(); #endif return OK; } /******************************************************************/ /************************ THREAD FUNCTIONS ************************/ /******************************************************************/ /* initializes service result worker thread */ int init_service_result_worker_thread(void){ int result; sigset_t newmask; /* initialize circular buffer */ service_result_buffer.head=0; service_result_buffer.tail=0; service_result_buffer.items=0; service_result_buffer.overflow=0L; service_result_buffer.buffer=(void **)malloc(SERVICE_BUFFER_SLOTS*sizeof(service_message **)); if(service_result_buffer.buffer==NULL) return ERROR; /* initialize mutex */ pthread_mutex_init(&service_result_buffer.buffer_lock,NULL); /* new thread should block all signals */ sigfillset(&newmask); pthread_sigmask(SIG_BLOCK,&newmask,NULL); /* create worker thread */ result=pthread_create(&worker_threads[SERVICE_WORKER_THREAD],NULL,service_result_worker_thread,NULL); /* main thread should unblock all signals */ pthread_sigmask(SIG_UNBLOCK,&newmask,NULL); #ifdef DEBUG1 printf("SERVICE CHECK THREAD: %lu\n",(unsigned long)worker_threads[SERVICE_WORKER_THREAD]); #endif if(result) return ERROR; return OK; } /* shutdown the service result worker thread */ int shutdown_service_result_worker_thread(void){ /* tell the worker thread to exit */ pthread_cancel(worker_threads[SERVICE_WORKER_THREAD]); /* wait for the worker thread to exit */ pthread_join(worker_threads[SERVICE_WORKER_THREAD],NULL); return OK; } /* clean up resources used by service result worker thread */ void cleanup_service_result_worker_thread(void *arg){ int x; /* release memory allocated to circular buffer */ for(x=service_result_buffer.tail;x!=service_result_buffer.head;x=(x+1) % SERVICE_BUFFER_SLOTS){ free(((service_message **)service_result_buffer.buffer)[x]); ((service_message **)service_result_buffer.buffer)[x]=NULL; } free(service_result_buffer.buffer); return; } /* initializes command file worker thread */ int init_command_file_worker_thread(void){ int result; sigset_t newmask; /* initialize circular buffer */ external_command_buffer.head=0; external_command_buffer.tail=0; external_command_buffer.items=0; external_command_buffer.overflow=0L; external_command_buffer.buffer=(void **)malloc(COMMAND_BUFFER_SLOTS*sizeof(char **)); if(external_command_buffer.buffer==NULL) return ERROR; /* initialize mutex */ pthread_mutex_init(&external_command_buffer.buffer_lock,NULL); /* new thread should block all signals */ sigfillset(&newmask); pthread_sigmask(SIG_BLOCK,&newmask,NULL); /* create worker thread */ result=pthread_create(&worker_threads[COMMAND_WORKER_THREAD],NULL,command_file_worker_thread,NULL); /* main thread should unblock all signals */ pthread_sigmask(SIG_UNBLOCK,&newmask,NULL); #ifdef DEBUG1 printf("COMMAND FILE THREAD: %lu\n",(unsigned long)worker_threads[COMMAND_WORKER_THREAD]); #endif if(result) return ERROR; return OK; } /* shutdown command file worker thread */ int shutdown_command_file_worker_thread(void){ /* tell the worker thread to exit */ pthread_cancel(worker_threads[COMMAND_WORKER_THREAD]); /* wait for the worker thread to exit */ pthread_join(worker_threads[COMMAND_WORKER_THREAD],NULL); return OK; } /* clean up resources used by command file worker thread */ void cleanup_command_file_worker_thread(void *arg){ int x; /* release memory allocated to circular buffer */ for(x=external_command_buffer.tail;x!=external_command_buffer.head;x=(x+1) % COMMAND_BUFFER_SLOTS){ free(((char **)external_command_buffer.buffer)[x]); ((char **)external_command_buffer.buffer)[x]=NULL; } free(external_command_buffer.buffer); return; } /* service worker thread - artificially increases buffer of IPC pipe */ void * service_result_worker_thread(void *arg){ struct pollfd pfd; int pollval; struct timeval tv; int read_result; int bytes_to_read; int write_offset; int buffer_items; service_message message; service_message *new_message; /* specify cleanup routine */ pthread_cleanup_push(cleanup_service_result_worker_thread,NULL); /* set cancellation info */ pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,NULL); pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED,NULL); while(1){ /* should we shutdown? */ pthread_testcancel(); /* wait for data to arrive */ /* select seems to not work, so we have to use poll instead */ pfd.fd=ipc_pipe[0]; pfd.events=POLLIN; pollval=poll(&pfd,1,500); /* loop if no data */ if(pollval==0) continue; /* check for errors */ if(pollval==-1){ switch(errno){ case EBADF: write_to_log("service_result_worker_thread(): poll(): EBADF",logging_options,NULL); break; case ENOMEM: write_to_log("service_result_worker_thread(): poll(): ENOMEM",logging_options,NULL); break; case EFAULT: write_to_log("service_result_worker_thread(): poll(): EFAULT",logging_options,NULL); break; case EINTR: /* this can happen when running under a debugger like gdb */ /* write_to_log("service_result_worker_thread(): poll(): EINTR (impossible)",logging_options,NULL); */ break; default: write_to_log("service_result_worker_thread(): poll(): Unknown errno value.",logging_options,NULL); break; } continue; } /* should we shutdown? */ pthread_testcancel(); /* get number of items in the buffer */ pthread_mutex_lock(&service_result_buffer.buffer_lock); buffer_items=service_result_buffer.items; pthread_mutex_unlock(&service_result_buffer.buffer_lock); /* process data in the pipe (one message max) if there's some free space in the circular buffer */ if(buffer_items=0){ /* allocate memory for the message */ new_message=(service_message *)malloc(sizeof(service_message)); if(new_message==NULL) break; /* copy the data we read to the message buffer */ memcpy(new_message,&message,sizeof(service_message)); /* obtain a lock for writing to the buffer */ pthread_mutex_lock(&service_result_buffer.buffer_lock); /* handle overflow conditions */ /* NOTE: This should never happen (see check above) - child processes will instead block trying to write messages to the pipe... */ if(service_result_buffer.items==SERVICE_BUFFER_SLOTS){ /* record overflow */ service_result_buffer.overflow++; /* update tail pointer */ service_result_buffer.tail=(service_result_buffer.tail + 1) % SERVICE_BUFFER_SLOTS; } /* save the data to the buffer */ ((service_message **)service_result_buffer.buffer)[service_result_buffer.head]=new_message; /* increment the head counter and items */ service_result_buffer.head=(service_result_buffer.head + 1) % SERVICE_BUFFER_SLOTS; if(service_result_buffer.itemsnext; free(this_event); this_event=next_event; } /* reset the event pointer */ event_list_high=NULL; /* free memory for the low priority event list */ this_event=event_list_low; while(this_event!=NULL){ next_event=this_event->next; free(this_event); this_event=next_event; } /* reset the event pointer */ event_list_low=NULL; #ifdef DEBUG1 printf("\tevent lists freed\n"); #endif /* free memory used by my_strtok() function */ if(original_my_strtok_buffer!=NULL) free(original_my_strtok_buffer); /* reset the my_strtok() buffers */ original_my_strtok_buffer=NULL; my_strtok_buffer=NULL; #ifdef DEBUG1 printf("\tmy_strtok() buffers freed\n"); #endif /* free memory for global event handlers */ if(global_host_event_handler!=NULL){ free(global_host_event_handler); global_host_event_handler=NULL; } if(global_service_event_handler!=NULL){ free(global_service_event_handler); global_service_event_handler=NULL; } #ifdef DEBUG1 printf("\tglobal event handlers freed\n"); #endif /* free any notification list that may have been overlooked */ free_notification_list(); #ifdef DEBUG1 printf("\tnotification_list freed\n"); #endif /* free obsessive compulsive commands */ if(ocsp_command!=NULL){ free(ocsp_command); ocsp_command=NULL; } if(ochp_command!=NULL){ free(ochp_command); ochp_command=NULL; } /* free memory associated with macros */ for(x=0;xnext; free((void *)temp_notification); temp_notification=next_notification; } /* reset notification list pointer */ notification_list=NULL; #ifdef DEBUG0 printf("free_notification_list() end\n"); #endif return; } /* reset all system-wide variables, so when we've receive a SIGHUP we can restart cleanly */ int reset_variables(void){ int x; #ifdef DEBUG0 printf("reset_variables() start\n"); #endif log_file=(char *)strdup(DEFAULT_LOG_FILE); temp_file=(char *)strdup(DEFAULT_TEMP_FILE); command_file=(char *)strdup(DEFAULT_COMMAND_FILE); lock_file=(char *)strdup(DEFAULT_LOCK_FILE); auth_file=(char *)strdup(DEFAULT_AUTH_FILE); p1_file=(char *)strdup(DEFAULT_P1_FILE); log_archive_path=(char *)strdup(DEFAULT_LOG_ARCHIVE_PATH); nagios_user=(char *)strdup(DEFAULT_NAGIOS_USER); nagios_group=(char *)strdup(DEFAULT_NAGIOS_GROUP); use_regexp_matches=FALSE; use_true_regexp_matching=FALSE; use_syslog=DEFAULT_USE_SYSLOG; log_service_retries=DEFAULT_LOG_SERVICE_RETRIES; log_host_retries=DEFAULT_LOG_HOST_RETRIES; log_initial_states=DEFAULT_LOG_INITIAL_STATES; log_notifications=DEFAULT_NOTIFICATION_LOGGING; log_event_handlers=DEFAULT_LOG_EVENT_HANDLERS; log_external_commands=DEFAULT_LOG_EXTERNAL_COMMANDS; log_passive_checks=DEFAULT_LOG_PASSIVE_CHECKS; logging_options=NSLOG_RUNTIME_ERROR | NSLOG_RUNTIME_WARNING | NSLOG_VERIFICATION_ERROR | NSLOG_VERIFICATION_WARNING | NSLOG_CONFIG_ERROR | NSLOG_CONFIG_WARNING | NSLOG_PROCESS_INFO | NSLOG_HOST_NOTIFICATION | NSLOG_SERVICE_NOTIFICATION | NSLOG_EVENT_HANDLER | NSLOG_EXTERNAL_COMMAND | NSLOG_PASSIVE_CHECK | NSLOG_HOST_UP | NSLOG_HOST_DOWN | NSLOG_HOST_UNREACHABLE | NSLOG_SERVICE_OK | NSLOG_SERVICE_WARNING | NSLOG_SERVICE_UNKNOWN | NSLOG_SERVICE_CRITICAL | NSLOG_INFO_MESSAGE; syslog_options=NSLOG_RUNTIME_ERROR | NSLOG_RUNTIME_WARNING | NSLOG_VERIFICATION_ERROR | NSLOG_VERIFICATION_WARNING | NSLOG_CONFIG_ERROR | NSLOG_CONFIG_WARNING | NSLOG_PROCESS_INFO | NSLOG_HOST_NOTIFICATION | NSLOG_SERVICE_NOTIFICATION | NSLOG_EVENT_HANDLER | NSLOG_EXTERNAL_COMMAND | NSLOG_PASSIVE_CHECK | NSLOG_HOST_UP | NSLOG_HOST_DOWN | NSLOG_HOST_UNREACHABLE | NSLOG_SERVICE_OK | NSLOG_SERVICE_WARNING | NSLOG_SERVICE_UNKNOWN | NSLOG_SERVICE_CRITICAL | NSLOG_INFO_MESSAGE; service_check_timeout=DEFAULT_SERVICE_CHECK_TIMEOUT; host_check_timeout=DEFAULT_HOST_CHECK_TIMEOUT; event_handler_timeout=DEFAULT_EVENT_HANDLER_TIMEOUT; notification_timeout=DEFAULT_NOTIFICATION_TIMEOUT; ocsp_timeout=DEFAULT_OCSP_TIMEOUT; ochp_timeout=DEFAULT_OCHP_TIMEOUT; sleep_time=DEFAULT_SLEEP_TIME; interval_length=DEFAULT_INTERVAL_LENGTH; service_inter_check_delay_method=ICD_SMART; host_inter_check_delay_method=ICD_SMART; service_interleave_factor_method=ILF_SMART; max_service_check_spread=DEFAULT_SERVICE_CHECK_SPREAD; max_host_check_spread=DEFAULT_HOST_CHECK_SPREAD; use_aggressive_host_checking=DEFAULT_AGGRESSIVE_HOST_CHECKING; soft_state_dependencies=FALSE; retain_state_information=FALSE; retention_update_interval=DEFAULT_RETENTION_UPDATE_INTERVAL; use_retained_program_state=TRUE; use_retained_scheduling_info=FALSE; retention_scheduling_horizon=DEFAULT_RETENTION_SCHEDULING_HORIZON; modified_host_process_attributes=MODATTR_NONE; modified_service_process_attributes=MODATTR_NONE; command_check_interval=DEFAULT_COMMAND_CHECK_INTERVAL; service_check_reaper_interval=DEFAULT_SERVICE_REAPER_INTERVAL; service_freshness_check_interval=DEFAULT_FRESHNESS_CHECK_INTERVAL; host_freshness_check_interval=DEFAULT_FRESHNESS_CHECK_INTERVAL; auto_rescheduling_interval=DEFAULT_AUTO_RESCHEDULING_INTERVAL; auto_rescheduling_window=DEFAULT_AUTO_RESCHEDULING_WINDOW; check_external_commands=DEFAULT_CHECK_EXTERNAL_COMMANDS; check_orphaned_services=DEFAULT_CHECK_ORPHANED_SERVICES; check_service_freshness=DEFAULT_CHECK_SERVICE_FRESHNESS; check_host_freshness=DEFAULT_CHECK_HOST_FRESHNESS; auto_reschedule_checks=DEFAULT_AUTO_RESCHEDULE_CHECKS; log_rotation_method=LOG_ROTATION_NONE; last_command_check=0L; last_command_status_update=0L; last_log_rotation=0L; max_parallel_service_checks=DEFAULT_MAX_PARALLEL_SERVICE_CHECKS; currently_running_service_checks=0; enable_notifications=TRUE; execute_service_checks=TRUE; accept_passive_service_checks=TRUE; execute_host_checks=TRUE; accept_passive_service_checks=TRUE; enable_event_handlers=TRUE; obsess_over_services=FALSE; obsess_over_hosts=FALSE; enable_failure_prediction=TRUE; aggregate_status_updates=TRUE; status_update_interval=DEFAULT_STATUS_UPDATE_INTERVAL; event_broker_options=BROKER_NOTHING; time_change_threshold=DEFAULT_TIME_CHANGE_THRESHOLD; enable_flap_detection=DEFAULT_ENABLE_FLAP_DETECTION; low_service_flap_threshold=DEFAULT_LOW_SERVICE_FLAP_THRESHOLD; high_service_flap_threshold=DEFAULT_HIGH_SERVICE_FLAP_THRESHOLD; low_host_flap_threshold=DEFAULT_LOW_HOST_FLAP_THRESHOLD; high_host_flap_threshold=DEFAULT_HIGH_HOST_FLAP_THRESHOLD; process_performance_data=DEFAULT_PROCESS_PERFORMANCE_DATA; date_format=DATE_FORMAT_US; for(x=0;x (b)) ? (a) : (b)) #endif #ifndef min #define min(a,b) (((a) < (b)) ? (a) : (b)) #endif /* output types */ #define HTML_OUTPUT 0 #define CSV_OUTPUT 1 /* archived state types */ #define AS_CURRENT_STATE -1 /* special case for initial assumed state */ #define AS_NO_DATA 0 #define AS_PROGRAM_END 1 #define AS_PROGRAM_START 2 #define AS_HOST_UP 3 #define AS_HOST_DOWN 4 #define AS_HOST_UNREACHABLE 5 #define AS_SVC_OK 6 #define AS_SVC_UNKNOWN 7 #define AS_SVC_WARNING 8 #define AS_SVC_CRITICAL 9 #define AS_SVC_DOWNTIME_START 10 #define AS_SVC_DOWNTIME_END 11 #define AS_HOST_DOWNTIME_START 12 #define AS_HOST_DOWNTIME_END 13 #define AS_SOFT_STATE 1 #define AS_HARD_STATE 2 /* display types */ #define DISPLAY_NO_AVAIL 0 #define DISPLAY_HOSTGROUP_AVAIL 1 #define DISPLAY_HOST_AVAIL 2 #define DISPLAY_SERVICE_AVAIL 3 #define DISPLAY_SERVICEGROUP_AVAIL 4 /* subject types */ #define HOST_SUBJECT 0 #define SERVICE_SUBJECT 1 /* standard report times */ #define TIMEPERIOD_CUSTOM 0 #define TIMEPERIOD_TODAY 1 #define TIMEPERIOD_YESTERDAY 2 #define TIMEPERIOD_THISWEEK 3 #define TIMEPERIOD_LASTWEEK 4 #define TIMEPERIOD_THISMONTH 5 #define TIMEPERIOD_LASTMONTH 6 #define TIMEPERIOD_THISQUARTER 7 #define TIMEPERIOD_LASTQUARTER 8 #define TIMEPERIOD_THISYEAR 9 #define TIMEPERIOD_LASTYEAR 10 #define TIMEPERIOD_LAST24HOURS 11 #define TIMEPERIOD_LAST7DAYS 12 #define TIMEPERIOD_LAST31DAYS 13 #define MIN_TIMESTAMP_SPACING 10 #define MAX_ARCHIVE_SPREAD 65 #define MAX_ARCHIVE 65 #define MAX_ARCHIVE_BACKTRACKS 60 authdata current_authdata; typedef struct archived_state_struct{ time_t time_stamp; int entry_type; int state_type; char *state_info; int processed_state; struct archived_state_struct *misc_ptr; struct archived_state_struct *next; }archived_state; typedef struct avail_subject_struct{ int type; char *host_name; char *service_description; archived_state *as_list; /* archived state list */ archived_state *as_list_tail; archived_state *sd_list; /* scheduled downtime list */ int last_known_state; time_t earliest_time; time_t latest_time; int earliest_state; int latest_state; unsigned long time_up; unsigned long time_down; unsigned long time_unreachable; unsigned long time_ok; unsigned long time_warning; unsigned long time_unknown; unsigned long time_critical; unsigned long scheduled_time_up; unsigned long scheduled_time_down; unsigned long scheduled_time_unreachable; unsigned long scheduled_time_ok; unsigned long scheduled_time_warning; unsigned long scheduled_time_unknown; unsigned long scheduled_time_critical; unsigned long scheduled_time_indeterminate; unsigned long time_indeterminate_nodata; unsigned long time_indeterminate_notrunning; struct avail_subject_struct *next; }avail_subject; avail_subject *subject_list=NULL; time_t t1; time_t t2; int display_type=DISPLAY_NO_AVAIL; int timeperiod_type=TIMEPERIOD_LAST24HOURS; int show_log_entries=FALSE; int full_log_entries=FALSE; int show_scheduled_downtime=TRUE; int start_second=0; int start_minute=0; int start_hour=0; int start_day=1; int start_month=1; int start_year=2000; int end_second=0; int end_minute=0; int end_hour=24; int end_day=1; int end_month=1; int end_year=2000; int get_date_parts=FALSE; int select_hostgroups=FALSE; int select_hosts=FALSE; int select_servicegroups=FALSE; int select_services=FALSE; int select_output_format=FALSE; int compute_time_from_parts=FALSE; int show_all_hostgroups=FALSE; int show_all_hosts=FALSE; int show_all_servicegroups=FALSE; int show_all_services=FALSE; int assume_initial_states=TRUE; int assume_state_retention=TRUE; int assume_states_during_notrunning=TRUE; int initial_assumed_host_state=AS_NO_DATA; int initial_assumed_service_state=AS_NO_DATA; int include_soft_states=FALSE; char *hostgroup_name=""; char *host_name=""; char *servicegroup_name=""; char *svc_description=""; void create_subject_list(void); void add_subject(int,char *,char *); avail_subject *find_subject(int,char *,char *); void compute_availability(void); void compute_subject_availability(avail_subject *,time_t); void compute_subject_availability_times(int,int,time_t,time_t,time_t,avail_subject *,archived_state *); void compute_subject_downtime(avail_subject *,time_t); void compute_subject_downtime_times(time_t,time_t,avail_subject *,archived_state *); void compute_subject_downtime_part_times(time_t,time_t,int,avail_subject *); void display_hostgroup_availability(void); void display_specific_hostgroup_availability(hostgroup *); void display_servicegroup_availability(void); void display_specific_servicegroup_availability(servicegroup *); void display_host_availability(void); void display_service_availability(void); void write_log_entries(avail_subject *); void get_running_average(double *,double,int); void host_report_url(char *,char *); void service_report_url(char *,char *,char *); void compute_report_times(void); int convert_host_state_to_archived_state(int); int convert_service_state_to_archived_state(int); void add_global_archived_state(int,int,time_t,char *); void add_archived_state(int,int,time_t,char *,avail_subject *); void add_scheduled_downtime(int,time_t,avail_subject *); void free_availability_data(void); void free_archived_state_list(archived_state *); void read_archived_state_data(void); void scan_log_file_for_archived_state_data(char *); void convert_timeperiod_to_times(int); unsigned long calculate_total_time(time_t,time_t); void document_header(int); void document_footer(void); int process_cgivars(void); int backtrack_archives=2; int earliest_archive=0; int embedded=FALSE; int display_header=TRUE; timeperiod *current_timeperiod=NULL; int output_format=HTML_OUTPUT; int main(int argc, char **argv){ int result=OK; char temp_buffer[MAX_INPUT_BUFFER]; char start_timestring[MAX_DATETIME_LENGTH]; char end_timestring[MAX_DATETIME_LENGTH]; host *temp_host; service *temp_service; int is_authorized=TRUE; time_t report_start_time; time_t report_end_time; int days, hours, minutes, seconds; hostgroup *temp_hostgroup; servicegroup *temp_servicegroup; timeperiod *temp_timeperiod; time_t t3; time_t current_time; struct tm *t; char *firsthostpointer; /* reset internal CGI variables */ reset_cgi_vars(); /* read the CGI configuration file */ result=read_cgi_config_file(get_cgi_config_location()); if(result==ERROR){ document_header(FALSE); cgi_config_file_error(get_cgi_config_location()); document_footer(); return ERROR; } /* read the main configuration file */ result=read_main_config_file(main_config_file); if(result==ERROR){ document_header(FALSE); main_config_file_error(main_config_file); document_footer(); return ERROR; } /* read all object configuration data */ result=read_all_object_configuration_data(main_config_file,READ_ALL_OBJECT_DATA); if(result==ERROR){ document_header(FALSE); object_data_error(); document_footer(); return ERROR; } /* read all status data */ result=read_all_status_data(get_cgi_config_location(),READ_ALL_STATUS_DATA); if(result==ERROR){ document_header(FALSE); status_data_error(); document_footer(); return ERROR; } /* initialize time period to last 24 hours */ time(¤t_time); t2=current_time; t1=(time_t)(current_time-(60*60*24)); /* default number of backtracked archives */ switch(log_rotation_method){ case LOG_ROTATION_MONTHLY: backtrack_archives=1; break; case LOG_ROTATION_WEEKLY: backtrack_archives=2; break; case LOG_ROTATION_DAILY: backtrack_archives=4; break; case LOG_ROTATION_HOURLY: backtrack_archives=8; break; default: backtrack_archives=2; break; } /* get the arguments passed in the URL */ process_cgivars(); document_header(TRUE); /* get authentication information */ get_authentication_information(¤t_authdata); if(compute_time_from_parts==TRUE) compute_report_times(); /* make sure times are sane, otherwise swap them */ if(t2current_time){ t2=current_time; if(t1>t2) t1=t2-(60*60*24); } if(display_header==TRUE){ /* begin top table */ printf("\n"); printf("\n"); /* left column of the first row */ printf("\n"); /* center column of top row */ printf("\n"); /* right hand column of top row */ printf("\n"); /* end of top table */ printf("\n"); printf("
\n"); switch(display_type){ case DISPLAY_HOST_AVAIL: snprintf(temp_buffer,sizeof(temp_buffer)-1,"Host Availability Report"); break; case DISPLAY_SERVICE_AVAIL: snprintf(temp_buffer,sizeof(temp_buffer)-1,"Service Availability Report"); break; case DISPLAY_HOSTGROUP_AVAIL: snprintf(temp_buffer,sizeof(temp_buffer)-1,"Hostgroup Availability Report"); break; case DISPLAY_SERVICEGROUP_AVAIL: snprintf(temp_buffer,sizeof(temp_buffer)-1,"Servicegroup Availability Report"); break; default: snprintf(temp_buffer,sizeof(temp_buffer)-1,"Availability Report"); break; } temp_buffer[sizeof(temp_buffer)-1]='\x0'; display_info_table(temp_buffer,FALSE,¤t_authdata); if(((display_type==DISPLAY_HOST_AVAIL && show_all_hosts==FALSE) || (display_type==DISPLAY_SERVICE_AVAIL && show_all_services==FALSE)) && get_date_parts==FALSE){ printf("\n"); printf("\n"); printf("\n"); } printf("\n"); if(display_type!=DISPLAY_NO_AVAIL && get_date_parts==FALSE){ printf("
\n"); if(display_type==DISPLAY_HOST_AVAIL){ if(show_all_hosts==TRUE) printf("All Hosts"); else printf("Host '%s'",host_name); } else if(display_type==DISPLAY_SERVICE_AVAIL){ if(show_all_services==TRUE) printf("All Services"); else printf("Service '%s' On Host '%s'",svc_description,host_name); } else if(display_type==DISPLAY_HOSTGROUP_AVAIL){ if(show_all_hostgroups==TRUE) printf("All Hostgroups"); else printf("Hostgroup '%s'",hostgroup_name); } else if(display_type==DISPLAY_SERVICEGROUP_AVAIL){ if(show_all_servicegroups==TRUE) printf("All Servicegroups"); else printf("Servicegroup '%s'",servicegroup_name); } printf("
\n"); printf("
\n"); printf("Availability Report\n",url_images_path,TRENDS_ICON); printf("
\n"); get_time_string(&t1,start_timestring,sizeof(start_timestring)-1,SHORT_DATE_TIME); get_time_string(&t2,end_timestring,sizeof(end_timestring)-1,SHORT_DATE_TIME); printf("
%s to %s
\n",start_timestring,end_timestring); get_time_breakdown((time_t)(t2-t1),&days,&hours,&minutes,&seconds); printf("
Duration: %dd %dh %dm %ds
\n",days,hours,minutes,seconds); } printf("
\n"); printf("\n"); if(display_type!=DISPLAY_NO_AVAIL && get_date_parts==FALSE){ printf("\n",AVAIL_CGI); printf("\n",(unsigned long)t1); printf("\n",(unsigned long)t2); if(show_log_entries==TRUE) printf("\n"); if(full_log_entries==TRUE) printf("\n"); if(display_type==DISPLAY_HOSTGROUP_AVAIL) printf("\n",hostgroup_name); if(display_type==DISPLAY_HOST_AVAIL || display_type==DISPLAY_SERVICE_AVAIL) printf("\n",host_name); if(display_type==DISPLAY_SERVICE_AVAIL) printf("\n",svc_description); if(display_type==DISPLAY_SERVICEGROUP_AVAIL) printf("\n",servicegroup_name); printf("\n",(assume_initial_states==TRUE)?"yes":"no"); printf("\n",(assume_state_retention==TRUE)?"yes":"no"); printf("\n",(assume_states_during_notrunning==TRUE)?"yes":"no"); printf("\n",(include_soft_states==TRUE)?"yes":"no"); printf("\n",(display_type==DISPLAY_SERVICE_AVAIL)?"service":"host",(display_type==DISPLAY_HOST_AVAIL || display_type==DISPLAY_HOSTGROUP_AVAIL || display_type==DISPLAY_SERVICEGROUP_AVAIL)?"First assumed service state":""); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); } /* display context-sensitive help */ printf("\n"); printf("
First assumed %s state:%s
\n"); if(display_type==DISPLAY_HOST_AVAIL || display_type==DISPLAY_HOSTGROUP_AVAIL || display_type==DISPLAY_SERVICEGROUP_AVAIL){ printf("\n"); } else{ printf("",initial_assumed_host_state); printf("\n"); } printf("\n"); if(display_type==DISPLAY_HOST_AVAIL || display_type==DISPLAY_HOSTGROUP_AVAIL || display_type==DISPLAY_SERVICEGROUP_AVAIL){ printf("\n"); } printf("
Report period:Backtracked archives:
\n"); printf("\n"); printf("\n"); printf("\n",backtrack_archives); printf("
\n"); printf("\n"); printf("
\n"); if(get_date_parts==TRUE) display_context_help(CONTEXTHELP_AVAIL_MENU5); else if(select_hostgroups==TRUE) display_context_help(CONTEXTHELP_AVAIL_MENU2); else if(select_hosts==TRUE) display_context_help(CONTEXTHELP_AVAIL_MENU3); else if(select_services==TRUE) display_context_help(CONTEXTHELP_AVAIL_MENU4); else if(display_type==DISPLAY_HOSTGROUP_AVAIL) display_context_help(CONTEXTHELP_AVAIL_HOSTGROUP); else if(display_type==DISPLAY_HOST_AVAIL) display_context_help(CONTEXTHELP_AVAIL_HOST); else if(display_type==DISPLAY_SERVICE_AVAIL) display_context_help(CONTEXTHELP_AVAIL_SERVICE); else if(display_type==DISPLAY_SERVICEGROUP_AVAIL) display_context_help(CONTEXTHELP_AVAIL_SERVICEGROUP); else display_context_help(CONTEXTHELP_AVAIL_MENU1); printf("
\n"); printf("
\n"); } /* step 3 - ask user for report date range */ if(get_date_parts==TRUE){ time(¤t_time); t=localtime(¤t_time); start_day=1; start_year=t->tm_year+1900; end_day=t->tm_mday; end_year=t->tm_year+1900; printf("

Step 3: Select Report Options

\n"); printf("

\n"); printf("
\n",AVAIL_CGI); printf("\n"); if(display_type==DISPLAY_HOSTGROUP_AVAIL) printf("\n",hostgroup_name); if(display_type==DISPLAY_HOST_AVAIL || display_type==DISPLAY_SERVICE_AVAIL) printf("\n",host_name); if(display_type==DISPLAY_SERVICE_AVAIL) printf("\n",svc_description); if(display_type==DISPLAY_SERVICEGROUP_AVAIL) printf("\n",servicegroup_name); printf("\n"); printf(""); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf(""); printf("\n"); printf("\n"); printf("\n"); printf(""); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf(""); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); if(display_type!=DISPLAY_SERVICE_AVAIL){ printf("\n"); printf("\n"); } printf("\n"); printf("\n"); printf("\n"); printf("\n"); if((display_type==DISPLAY_HOST_AVAIL && show_all_hosts==TRUE) || (display_type==DISPLAY_SERVICE_AVAIL && show_all_services==TRUE)){ printf(""); printf("\n"); printf("\n"); printf("\n"); } printf("\n"); printf("
Report Period:\n"); printf("\n"); printf("
If Custom Report Period...
Start Date (Inclusive):"); printf("\n "); printf(" ",start_day); printf("",start_year); printf("\n"); printf("\n"); printf("\n"); printf("
End Date (Inclusive):"); printf("\n "); printf(" ",end_day); printf("",end_year); printf("\n"); printf("\n"); printf("\n"); printf("

Report time Period:\n"); printf("\n"); printf("

Assume Initial States:\n"); printf("\n"); printf("
Assume State Retention:\n"); printf("\n"); printf("
Assume States During Program Downtime:\n"); printf("\n"); printf("
Include Soft States:\n"); printf("\n"); printf("
First Assumed Host State:\n"); printf("\n"); printf("
First Assumed Service State:\n"); printf("\n"); printf("
Backtracked Archives (To Scan For Initial States):\n"); printf("\n",backtrack_archives); printf("
Output in CSV Format:"); printf("\n"); printf("
\n"); printf("
\n"); printf("

\n"); } /* step 2 - the user wants to select a hostgroup */ else if(select_hostgroups==TRUE){ printf("

Step 2: Select Hostgroup

\n"); printf("

\n"); printf("
\n",AVAIL_CGI); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("
Hostgroup(s):\n"); printf("\n"); printf("
\n"); printf("
\n"); printf("

\n"); } /* step 2 - the user wants to select a host */ else if(select_hosts==TRUE){ printf("

Step 2: Select Host

\n"); printf("

\n"); printf("
\n",AVAIL_CGI); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("
Host(s):\n"); printf("\n"); printf("
\n"); printf("
\n"); printf("

\n"); printf("
Tip: If you want to have the option of getting the availability data in CSV format, select '** ALL HOSTS **' from the pull-down menu.\n"); } /* step 2 - the user wants to select a servicegroup */ else if(select_servicegroups==TRUE){ printf("

Step 2: Select Servicegroup

\n"); printf("

\n"); printf("
\n",AVAIL_CGI); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("
Servicegroup(s):\n"); printf("\n"); printf("
\n"); printf("
\n"); printf("

\n"); } /* step 2 - the user wants to select a service */ else if(select_services==TRUE){ printf("\n"); printf("

Step 2: Select Service

\n"); printf("

\n"); printf("
\n",AVAIL_CGI); printf("\n"); printf("\n",(firsthostpointer==NULL)?"unknown":firsthostpointer); printf("\n"); printf("\n"); printf("\n"); printf("
Service(s):\n"); printf("\n"); printf("
\n"); printf("
\n"); printf("

\n"); printf("
Tip: If you want to have the option of getting the availability data in CSV format, select '** ALL SERVICES **' from the pull-down menu.\n"); } /* generate availability report */ else if(display_type!=DISPLAY_NO_AVAIL){ /* check authorization */ is_authorized=TRUE; if((display_type==DISPLAY_HOST_AVAIL && show_all_hosts==FALSE) || (display_type==DISPLAY_SERVICE_AVAIL && show_all_services==FALSE)){ if(display_type==DISPLAY_HOST_AVAIL && show_all_hosts==FALSE) is_authorized=is_authorized_for_host(find_host(host_name),¤t_authdata); else is_authorized=is_authorized_for_service(find_service(host_name,svc_description),¤t_authdata); } if(is_authorized==FALSE) printf("

It appears as though you are not authorized to view information for the specified %s...

\n",(display_type==DISPLAY_HOST_AVAIL)?"host":"service"); else{ time(&report_start_time); /* create list of subjects to collect availability data for */ create_subject_list(); /* read in all necessary archived state data */ read_archived_state_data(); /* compute availability data */ compute_availability(); time(&report_end_time); if(output_format==HTML_OUTPUT){ get_time_breakdown((time_t)(report_end_time-report_start_time),&days,&hours,&minutes,&seconds); printf("
[ Availability report completed in %d min %d sec ]
\n",minutes,seconds); printf("

\n"); } /* display availability data */ if(display_type==DISPLAY_HOST_AVAIL) display_host_availability(); else if(display_type==DISPLAY_SERVICE_AVAIL) display_service_availability(); else if(display_type==DISPLAY_HOSTGROUP_AVAIL) display_hostgroup_availability(); else if(display_type==DISPLAY_SERVICEGROUP_AVAIL) display_servicegroup_availability(); /* free memory allocated to availability data */ free_availability_data(); } } /* step 1 - ask the user what kind of report they want */ else{ printf("

Step 1: Select Report Type

\n"); printf("

\n"); printf("
\n",AVAIL_CGI); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("
Type:\n"); printf("\n"); printf("
\n"); printf("
\n"); printf("

\n"); } document_footer(); /* free all other allocated memory */ free_memory(); return OK; } void document_header(int use_stylesheet){ char date_time[MAX_DATETIME_LENGTH]; time_t current_time; time_t expire_time; printf("Cache-Control: no-store\r\n"); printf("Pragma: no-cache\r\n"); time(¤t_time); get_time_string(¤t_time,date_time,sizeof(date_time),HTTP_DATE_TIME); printf("Last-Modified: %s\r\n",date_time); expire_time=(time_t)0; get_time_string(&expire_time,date_time,sizeof(date_time),HTTP_DATE_TIME); printf("Expires: %s\r\n",date_time); if(output_format==HTML_OUTPUT) printf("Content-type: text/html\r\n\r\n"); else{ printf("Content-type: text/plain\r\n\r\n"); return; } if(embedded==TRUE || output_format==CSV_OUTPUT) return; printf("\n"); printf("\n"); printf("\n"); printf("Nagios Availability\n"); printf("\n"); if(use_stylesheet==TRUE){ printf("\n",url_stylesheets_path,COMMON_CSS); printf("\n",url_stylesheets_path,AVAIL_CSS); } printf("\n"); printf("\n"); /* include user SSI header */ include_ssi_files(AVAIL_CGI,SSI_HEADER); return; } void document_footer(void){ if(output_format!=HTML_OUTPUT) return; if(embedded==TRUE) return; /* include user SSI footer */ include_ssi_files(AVAIL_CGI,SSI_FOOTER); printf("\n"); printf("\n"); return; } int process_cgivars(void){ char **variables; int error=FALSE; int x; variables=getcgivars(); for(x=0;variables[x]!=NULL;x++){ /* do some basic length checking on the variable identifier to prevent buffer overflows */ if(strlen(variables[x])>=MAX_INPUT_BUFFER-1){ x++; continue; } /* we found the hostgroup argument */ else if(!strcmp(variables[x],"hostgroup")){ x++; if(variables[x]==NULL){ error=TRUE; break; } hostgroup_name=(char *)malloc(strlen(variables[x])+1); if(hostgroup_name==NULL) hostgroup_name=""; else strcpy(hostgroup_name,variables[x]); display_type=DISPLAY_HOSTGROUP_AVAIL; show_all_hostgroups=(strcmp(hostgroup_name,"all"))?FALSE:TRUE; } /* we found the servicegroup argument */ else if(!strcmp(variables[x],"servicegroup")){ x++; if(variables[x]==NULL){ error=TRUE; break; } servicegroup_name=(char *)malloc(strlen(variables[x])+1); if(servicegroup_name==NULL) servicegroup_name=""; else strcpy(servicegroup_name,variables[x]); display_type=DISPLAY_SERVICEGROUP_AVAIL; show_all_servicegroups=(strcmp(servicegroup_name,"all"))?FALSE:TRUE; } /* we found the host argument */ else if(!strcmp(variables[x],"host")){ x++; if(variables[x]==NULL){ error=TRUE; break; } host_name=(char *)malloc(strlen(variables[x])+1); if(host_name==NULL) host_name=""; else strcpy(host_name,variables[x]); display_type=DISPLAY_HOST_AVAIL; show_all_hosts=(strcmp(host_name,"all"))?FALSE:TRUE; } /* we found the service description argument */ else if(!strcmp(variables[x],"service")){ x++; if(variables[x]==NULL){ error=TRUE; break; } svc_description=(char *)malloc(strlen(variables[x])+1); if(svc_description==NULL) svc_description=""; else strcpy(svc_description,variables[x]); display_type=DISPLAY_SERVICE_AVAIL; show_all_services=(strcmp(svc_description,"all"))?FALSE:TRUE; } /* we found first time argument */ else if(!strcmp(variables[x],"t1")){ x++; if(variables[x]==NULL){ error=TRUE; break; } t1=(time_t)strtoul(variables[x],NULL,10); timeperiod_type=TIMEPERIOD_CUSTOM; compute_time_from_parts=FALSE; } /* we found first time argument */ else if(!strcmp(variables[x],"t2")){ x++; if(variables[x]==NULL){ error=TRUE; break; } t2=(time_t)strtoul(variables[x],NULL,10); timeperiod_type=TIMEPERIOD_CUSTOM; compute_time_from_parts=FALSE; } /* we found the assume initial states option */ else if(!strcmp(variables[x],"assumeinitialstates")){ x++; if(variables[x]==NULL){ error=TRUE; break; } if(!strcmp(variables[x],"yes")) assume_initial_states=TRUE; else assume_initial_states=FALSE; } /* we found the assume state during program not running option */ else if(!strcmp(variables[x],"assumestatesduringnotrunning")){ x++; if(variables[x]==NULL){ error=TRUE; break; } if(!strcmp(variables[x],"yes")) assume_states_during_notrunning=TRUE; else assume_states_during_notrunning=FALSE; } /* we found the initial assumed host state option */ else if(!strcmp(variables[x],"initialassumedhoststate")){ x++; if(variables[x]==NULL){ error=TRUE; break; } initial_assumed_host_state=atoi(variables[x]); } /* we found the initial assumed service state option */ else if(!strcmp(variables[x],"initialassumedservicestate")){ x++; if(variables[x]==NULL){ error=TRUE; break; } initial_assumed_service_state=atoi(variables[x]); } /* we found the assume state retention option */ else if(!strcmp(variables[x],"assumestateretention")){ x++; if(variables[x]==NULL){ error=TRUE; break; } if(!strcmp(variables[x],"yes")) assume_state_retention=TRUE; else assume_state_retention=FALSE; } /* we found the include soft states option */ else if(!strcmp(variables[x],"includesoftstates")){ x++; if(variables[x]==NULL){ error=TRUE; break; } if(!strcmp(variables[x],"yes")) include_soft_states=TRUE; else include_soft_states=FALSE; } /* we found the backtrack archives argument */ else if(!strcmp(variables[x],"backtrack")){ x++; if(variables[x]==NULL){ error=TRUE; break; } backtrack_archives=atoi(variables[x]); if(backtrack_archives<0) backtrack_archives=0; if(backtrack_archives>MAX_ARCHIVE_BACKTRACKS) backtrack_archives=MAX_ARCHIVE_BACKTRACKS; #ifdef DEBUG printf("BACKTRACK ARCHIVES: %d\n",backtrack_archives); #endif } /* we found the standard timeperiod argument */ else if(!strcmp(variables[x],"timeperiod")){ x++; if(variables[x]==NULL){ error=TRUE; break; } if(!strcmp(variables[x],"today")) timeperiod_type=TIMEPERIOD_TODAY; else if(!strcmp(variables[x],"yesterday")) timeperiod_type=TIMEPERIOD_YESTERDAY; else if(!strcmp(variables[x],"thisweek")) timeperiod_type=TIMEPERIOD_THISWEEK; else if(!strcmp(variables[x],"lastweek")) timeperiod_type=TIMEPERIOD_LASTWEEK; else if(!strcmp(variables[x],"thismonth")) timeperiod_type=TIMEPERIOD_THISMONTH; else if(!strcmp(variables[x],"lastmonth")) timeperiod_type=TIMEPERIOD_LASTMONTH; else if(!strcmp(variables[x],"thisquarter")) timeperiod_type=TIMEPERIOD_THISQUARTER; else if(!strcmp(variables[x],"lastquarter")) timeperiod_type=TIMEPERIOD_LASTQUARTER; else if(!strcmp(variables[x],"thisyear")) timeperiod_type=TIMEPERIOD_THISYEAR; else if(!strcmp(variables[x],"lastyear")) timeperiod_type=TIMEPERIOD_LASTYEAR; else if(!strcmp(variables[x],"last24hours")) timeperiod_type=TIMEPERIOD_LAST24HOURS; else if(!strcmp(variables[x],"last7days")) timeperiod_type=TIMEPERIOD_LAST7DAYS; else if(!strcmp(variables[x],"last31days")) timeperiod_type=TIMEPERIOD_LAST31DAYS; else if(!strcmp(variables[x],"custom")) timeperiod_type=TIMEPERIOD_CUSTOM; else continue; convert_timeperiod_to_times(timeperiod_type); compute_time_from_parts=FALSE; } /* we found the embed option */ else if(!strcmp(variables[x],"embedded")) embedded=TRUE; /* we found the noheader option */ else if(!strcmp(variables[x],"noheader")) display_header=FALSE; /* we found the CSV output option */ else if(!strcmp(variables[x],"csvoutput")){ display_header=FALSE; output_format=CSV_OUTPUT; } /* we found the log entries option */ else if(!strcmp(variables[x],"show_log_entries")) show_log_entries=TRUE; /* we found the full log entries option */ else if(!strcmp(variables[x],"full_log_entries")) full_log_entries=TRUE; /* we found the get date parts option */ else if(!strcmp(variables[x],"get_date_parts")) get_date_parts=TRUE; /* we found the report type selection option */ else if(!strcmp(variables[x],"report_type")){ x++; if(variables[x]==NULL){ error=TRUE; break; } if(!strcmp(variables[x],"hostgroups")) select_hostgroups=TRUE; else if(!strcmp(variables[x],"servicegroups")) select_servicegroups=TRUE; else if(!strcmp(variables[x],"hosts")) select_hosts=TRUE; else select_services=TRUE; } /* we found time argument */ else if(!strcmp(variables[x],"smon")){ x++; if(variables[x]==NULL){ error=TRUE; break; } if(timeperiod_type!=TIMEPERIOD_CUSTOM) continue; start_month=atoi(variables[x]); timeperiod_type=TIMEPERIOD_CUSTOM; compute_time_from_parts=TRUE; } /* we found time argument */ else if(!strcmp(variables[x],"sday")){ x++; if(variables[x]==NULL){ error=TRUE; break; } if(timeperiod_type!=TIMEPERIOD_CUSTOM) continue; start_day=atoi(variables[x]); timeperiod_type=TIMEPERIOD_CUSTOM; compute_time_from_parts=TRUE; } /* we found time argument */ else if(!strcmp(variables[x],"syear")){ x++; if(variables[x]==NULL){ error=TRUE; break; } if(timeperiod_type!=TIMEPERIOD_CUSTOM) continue; start_year=atoi(variables[x]); timeperiod_type=TIMEPERIOD_CUSTOM; compute_time_from_parts=TRUE; } /* we found time argument */ else if(!strcmp(variables[x],"smin")){ x++; if(variables[x]==NULL){ error=TRUE; break; } if(timeperiod_type!=TIMEPERIOD_CUSTOM) continue; start_minute=atoi(variables[x]); timeperiod_type=TIMEPERIOD_CUSTOM; compute_time_from_parts=TRUE; } /* we found time argument */ else if(!strcmp(variables[x],"ssec")){ x++; if(variables[x]==NULL){ error=TRUE; break; } if(timeperiod_type!=TIMEPERIOD_CUSTOM) continue; start_second=atoi(variables[x]); timeperiod_type=TIMEPERIOD_CUSTOM; compute_time_from_parts=TRUE; } /* we found time argument */ else if(!strcmp(variables[x],"shour")){ x++; if(variables[x]==NULL){ error=TRUE; break; } if(timeperiod_type!=TIMEPERIOD_CUSTOM) continue; start_hour=atoi(variables[x]); timeperiod_type=TIMEPERIOD_CUSTOM; compute_time_from_parts=TRUE; } /* we found time argument */ else if(!strcmp(variables[x],"emon")){ x++; if(variables[x]==NULL){ error=TRUE; break; } if(timeperiod_type!=TIMEPERIOD_CUSTOM) continue; end_month=atoi(variables[x]); timeperiod_type=TIMEPERIOD_CUSTOM; compute_time_from_parts=TRUE; } /* we found time argument */ else if(!strcmp(variables[x],"eday")){ x++; if(variables[x]==NULL){ error=TRUE; break; } if(timeperiod_type!=TIMEPERIOD_CUSTOM) continue; end_day=atoi(variables[x]); timeperiod_type=TIMEPERIOD_CUSTOM; compute_time_from_parts=TRUE; } /* we found time argument */ else if(!strcmp(variables[x],"eyear")){ x++; if(variables[x]==NULL){ error=TRUE; break; } if(timeperiod_type!=TIMEPERIOD_CUSTOM) continue; end_year=atoi(variables[x]); timeperiod_type=TIMEPERIOD_CUSTOM; compute_time_from_parts=TRUE; } /* we found time argument */ else if(!strcmp(variables[x],"emin")){ x++; if(variables[x]==NULL){ error=TRUE; break; } if(timeperiod_type!=TIMEPERIOD_CUSTOM) continue; end_minute=atoi(variables[x]); timeperiod_type=TIMEPERIOD_CUSTOM; compute_time_from_parts=TRUE; } /* we found time argument */ else if(!strcmp(variables[x],"esec")){ x++; if(variables[x]==NULL){ error=TRUE; break; } if(timeperiod_type!=TIMEPERIOD_CUSTOM) continue; end_second=atoi(variables[x]); timeperiod_type=TIMEPERIOD_CUSTOM; compute_time_from_parts=TRUE; } /* we found time argument */ else if(!strcmp(variables[x],"ehour")){ x++; if(variables[x]==NULL){ error=TRUE; break; } if(timeperiod_type!=TIMEPERIOD_CUSTOM) continue; end_hour=atoi(variables[x]); timeperiod_type=TIMEPERIOD_CUSTOM; compute_time_from_parts=TRUE; } /* we found the show scheduled downtime option */ else if(!strcmp(variables[x],"showscheduleddowntime")){ x++; if(variables[x]==NULL){ error=TRUE; break; } if(!strcmp(variables[x],"yes")) show_scheduled_downtime=TRUE; else show_scheduled_downtime=FALSE; } /* we found the report timeperiod option */ else if(!strcmp(variables[x],"rpttimeperiod")){ timeperiod *temp_timeperiod; x++; if(variables[x]==NULL){ error=TRUE; break; } for(temp_timeperiod=timeperiod_list;temp_timeperiod!=NULL;temp_timeperiod=temp_timeperiod->next){ if(!strcmp(url_encode(temp_timeperiod->name),variables[x])){ current_timeperiod=temp_timeperiod; break; } } } } /* free memory allocated to the CGI variables */ free_cgivars(variables); return error; } /* computes availability data for all subjects */ void compute_availability(void){ avail_subject *temp_subject; time_t current_time; time(¤t_time); for(temp_subject=subject_list;temp_subject!=NULL;temp_subject=temp_subject->next){ compute_subject_availability(temp_subject,current_time); compute_subject_downtime(temp_subject,current_time); } return; } /* computes availability data for a given subject */ void compute_subject_availability(avail_subject *subject, time_t current_time){ archived_state *temp_as; archived_state *last_as; time_t a; time_t b; int current_state=AS_NO_DATA; int have_some_real_data=FALSE; hoststatus *hststatus=NULL; servicestatus *svcstatus=NULL; int first_real_state=AS_NO_DATA; time_t initial_assumed_time; int initial_assumed_state=AS_NO_DATA; int error; /* if left hand of graph is after current time, we can't do anything at all.... */ if(t1>current_time) return; /* get current state of host or service if possible */ if(subject->type==HOST_SUBJECT) hststatus=find_hoststatus(subject->host_name); else svcstatus=find_servicestatus(subject->host_name,subject->service_description); /************************************/ /* INSERT CURRENT STATE (IF WE CAN) */ /************************************/ /* if current time DOES NOT fall within graph bounds, so we can't do anything as far as assuming current state */ /* if we don't have any data, assume current state (if possible) */ if(subject->as_list==NULL && current_time>t1 && current_time<=t2){ /* we don't have any historical information, but the current time falls within the reporting period, so use */ /* the current status of the host/service as the starting data */ if(subject->type==HOST_SUBJECT){ if(hststatus!=NULL){ if(hststatus->status==HOST_DOWN) subject->last_known_state=AS_HOST_DOWN; else if(hststatus->status==HOST_UNREACHABLE) subject->last_known_state=AS_HOST_UNREACHABLE; else if(hststatus->status==HOST_UP) subject->last_known_state=AS_HOST_UP; else subject->last_known_state=AS_NO_DATA; if(subject->last_known_state!=AS_NO_DATA){ /* add a dummy archived state item, so something can get graphed */ add_archived_state(subject->last_known_state,AS_HARD_STATE,t1,"Current Host State Assumed (Faked Log Entry)",subject); /* use the current state as the last known real state */ first_real_state=subject->last_known_state; } } } else{ if(svcstatus!=NULL){ if(svcstatus->status==SERVICE_OK) subject->last_known_state=AS_SVC_OK; else if(svcstatus->status==SERVICE_WARNING) subject->last_known_state=AS_SVC_WARNING; else if(svcstatus->status==SERVICE_CRITICAL) subject->last_known_state=AS_SVC_CRITICAL; else if(svcstatus->status==SERVICE_UNKNOWN) subject->last_known_state=AS_SVC_UNKNOWN; else subject->last_known_state=AS_NO_DATA; if(subject->last_known_state!=AS_NO_DATA){ /* add a dummy archived state item, so something can get graphed */ add_archived_state(subject->last_known_state,AS_HARD_STATE,t1,"Current Service State Assumed (Faked Log Entry)",subject); /* use the current state as the last known real state */ first_real_state=subject->last_known_state; } } } } /******************************************/ /* INSERT FIRST ASSUMED STATE (IF WE CAN) */ /******************************************/ if((subject->type==HOST_SUBJECT && initial_assumed_host_state!=AS_NO_DATA) || (subject->type==SERVICE_SUBJECT && initial_assumed_service_state!=AS_NO_DATA)){ /* see if its okay to assume initial state for this subject */ error=FALSE; if(subject->type==SERVICE_SUBJECT){ if(initial_assumed_service_state!=AS_SVC_OK && initial_assumed_service_state!=AS_SVC_WARNING && initial_assumed_service_state!=AS_SVC_UNKNOWN && initial_assumed_service_state!=AS_SVC_CRITICAL && initial_assumed_service_state!=AS_CURRENT_STATE) error=TRUE; else initial_assumed_state=initial_assumed_service_state; if(initial_assumed_service_state==AS_CURRENT_STATE && svcstatus==NULL) error=TRUE; } else{ if(initial_assumed_host_state!=AS_HOST_UP && initial_assumed_host_state!=AS_HOST_DOWN && initial_assumed_host_state!=AS_HOST_UNREACHABLE && initial_assumed_host_state!=AS_CURRENT_STATE) error=TRUE; else initial_assumed_state=initial_assumed_host_state; if(initial_assumed_host_state==AS_CURRENT_STATE && hststatus==NULL) error=TRUE; } /* get the current state if applicable */ if(((subject->type==HOST_SUBJECT && initial_assumed_host_state==AS_CURRENT_STATE) || (subject->type==SERVICE_SUBJECT && initial_assumed_service_state==AS_CURRENT_STATE)) && error==FALSE){ if(subject->type==SERVICE_SUBJECT){ switch(svcstatus->status){ case SERVICE_OK: initial_assumed_state=AS_SVC_OK; break; case SERVICE_WARNING: initial_assumed_state=AS_SVC_WARNING; break; case SERVICE_UNKNOWN: initial_assumed_state=AS_SVC_UNKNOWN; break; case SERVICE_CRITICAL: initial_assumed_state=AS_SVC_CRITICAL; break; default: error=TRUE; break; } } else{ switch(hststatus->status){ case HOST_DOWN: initial_assumed_state=AS_HOST_DOWN; break; case HOST_UNREACHABLE: initial_assumed_state=AS_HOST_UNREACHABLE; break; case HOST_UP: initial_assumed_state=AS_HOST_UP; break; default: error=TRUE; break; } } } if(error==FALSE){ /* add this assumed state entry before any entries in the list and <= t1 */ if(subject->as_list==NULL) initial_assumed_time=t1; else if(subject->as_list->time_stamp>t1) initial_assumed_time=t1; else initial_assumed_time=subject->as_list->time_stamp-1; if(subject->type==HOST_SUBJECT) add_archived_state(initial_assumed_state,AS_HARD_STATE,initial_assumed_time,"First Host State Assumed (Faked Log Entry)",subject); else add_archived_state(initial_assumed_state,AS_HARD_STATE,initial_assumed_time,"First Service State Assumed (Faked Log Entry)",subject); } } /**************************************/ /* BAIL OUT IF WE DON'T HAVE ANYTHING */ /**************************************/ have_some_real_data=FALSE; for(temp_as=subject->as_list;temp_as!=NULL;temp_as=temp_as->next){ if(temp_as->entry_type!=AS_NO_DATA && temp_as->entry_type!=AS_PROGRAM_START && temp_as->entry_type!=AS_PROGRAM_END){ have_some_real_data=TRUE; break; } } if(have_some_real_data==FALSE) return; last_as=NULL; subject->earliest_time=t2; subject->latest_time=t1; #ifdef DEBUG printf("--- BEGINNING/MIDDLE SECTION ---
\n"); #endif /**********************************/ /* BEGINNING/MIDDLE SECTION */ /**********************************/ for(temp_as=subject->as_list;temp_as!=NULL;temp_as=temp_as->next){ /* keep this as last known state if this is the first entry or if it occurs before the starting point of the graph */ if((temp_as->time_stamp<=t1 || temp_as==subject->as_list) && (temp_as->entry_type!=AS_NO_DATA && temp_as->entry_type!=AS_PROGRAM_END && temp_as->entry_type!=AS_PROGRAM_START)){ subject->last_known_state=temp_as->entry_type; #ifdef DEBUG printf("SETTING LAST KNOWN STATE=%d
\n",subject->last_known_state); #endif } /* skip this entry if it occurs before the starting point of the graph */ if(temp_as->time_stamp<=t1){ #ifdef DEBUG printf("SKIPPING PRE-EVENT: %d @ %lu
\n",temp_as->entry_type,temp_as->time_stamp); #endif last_as=temp_as; continue; } /* graph this span if we're not on the first item */ if(last_as!=NULL){ a=last_as->time_stamp; b=temp_as->time_stamp; /* we've already passed the last time displayed in the graph */ if(a>t2) break; /* only graph this data if its on the graph */ else if(b>t1){ /* clip last time if it exceeds graph limits */ if(b>t2) b=t2; /* clip first time if it precedes graph limits */ if(aearliest_time){ subject->earliest_time=a; subject->earliest_state=last_as->entry_type; } /* save this time if its the latest we've graphed */ if(b>subject->latest_time){ subject->latest_time=b; subject->latest_state=last_as->entry_type; } /* compute availability times for this chunk */ compute_subject_availability_times(last_as->entry_type,temp_as->entry_type,last_as->time_stamp,a,b,subject,temp_as); /* return if we've reached the end of the graph limits */ if(b>=t2){ last_as=temp_as; break; } } } /* keep track of the last item */ last_as=temp_as; } #ifdef DEBUG printf("--- END SECTION ---
\n"); #endif /**********************************/ /* END SECTION */ /**********************************/ if(last_as!=NULL){ /* don't process an entry that is beyond the limits of the graph */ if(last_as->time_stampt2) b=t2; a=last_as->time_stamp; if(atype==HOST_SUBJECT) current_state=AS_HOST_UP; else current_state=AS_SVC_OK; /* compute availability times for last state */ compute_subject_availability_times(last_as->entry_type,current_state,last_as->time_stamp,a,b,subject,last_as); } } return; } /* computes availability times */ void compute_subject_availability_times(int first_state,int last_state,time_t real_start_time,time_t start_time,time_t end_time,avail_subject *subject, archived_state *as){ int start_state; int end_state; unsigned long state_duration; struct tm *t; unsigned long midnight_today; int weekday; timerange *temp_timerange; unsigned long temp_duration; unsigned long temp_end; unsigned long temp_start; unsigned long start; unsigned long end; #ifdef DEBUG if(subject->type==HOST_SUBJECT) printf("HOST '%s'...\n",subject->host_name); else printf("SERVICE '%s' ON HOST '%s'...\n",subject->service_description,subject->host_name); printf("COMPUTING %d->%d FROM %lu to %lu (%lu seconds) FOR %s
\n",first_state,last_state,start_time,end_time,(end_time-start_time),(subject->type==HOST_SUBJECT)?"HOST":"SERVICE"); #endif /* clip times if necessary */ if(start_timet2) end_time=t2; /* make sure this is a valid time */ if(start_time>t2) return; if(end_timetm_sec=0; t->tm_min=0; t->tm_hour=0; midnight_today=(unsigned long)mktime(t); weekday=t->tm_wday; while(midnight_todaymidnight_today) temp_start=start_time-midnight_today; #ifdef DEBUG printf("Matching: %ld -> %ld. (%ld -> %ld)
\n",temp_start, temp_end, midnight_today+temp_start, midnight_today+temp_end); #endif /* check all time ranges for this day of the week */ for(temp_timerange=current_timeperiod->days[weekday];temp_timerange!=NULL;temp_timerange=temp_timerange->next){ #ifdef DEBUG printf("
  • Matching in timerange[%d]: %d -> %d (%ld -> %ld)
    \n",weekday,temp_timerange->range_start,temp_timerange->range_end,temp_start,temp_end); #endif start=max(temp_timerange->range_start,temp_start); end=min(temp_timerange->range_end,temp_end); if(startMatched time: %ld -> %ld = %d
    \n",start, end, temp_duration); #endif } #ifdef DEBUG else printf("
  • Ignored time: %ld -> %ld
    \n",start, end); #endif } state_duration+=temp_duration; temp_start=0; midnight_today+=86400; if(++weekday>6) weekday=0; } } /* no report timeperiod was selected (assume 24x7) */ else{ /* calculate time in this state */ state_duration=(unsigned long)(end_time-start_time); } /* can't graph if we don't have data... */ if(first_state==AS_NO_DATA || last_state==AS_NO_DATA){ subject->time_indeterminate_nodata+=state_duration; return; } if(first_state==AS_PROGRAM_START && (last_state==AS_PROGRAM_END || last_state==AS_PROGRAM_START)){ if(assume_initial_states==FALSE){ subject->time_indeterminate_nodata+=state_duration; return; } } if(first_state==AS_PROGRAM_END){ /* added 7/24/03 */ if(assume_states_during_notrunning==TRUE){ first_state=subject->last_known_state; } else{ subject->time_indeterminate_notrunning+=state_duration; return; } } /* special case if first entry was program start */ if(first_state==AS_PROGRAM_START){ if(assume_initial_states==TRUE){ if(assume_state_retention==TRUE) start_state=subject->last_known_state; else{ if(subject->type==HOST_SUBJECT) start_state=AS_HOST_UP; else start_state=AS_SVC_OK; } } else return; } else{ start_state=first_state; subject->last_known_state=first_state; } /* special case if last entry was program stop */ if(last_state==AS_PROGRAM_END) end_state=first_state; else end_state=last_state; /* save "processed state" info */ as->processed_state=start_state; #ifdef DEBUG printf("PASSED TIME CHECKS, CLIPPED VALUES: START=%lu, END=%lu\n",start_time,end_time); #endif /* add time in this state to running totals */ switch(start_state){ case AS_HOST_UP: subject->time_up+=state_duration; break; case AS_HOST_DOWN: subject->time_down+=state_duration; break; case AS_HOST_UNREACHABLE: subject->time_unreachable+=state_duration; break; case AS_SVC_OK: subject->time_ok+=state_duration; break; case AS_SVC_WARNING: subject->time_warning+=state_duration; break; case AS_SVC_UNKNOWN: subject->time_unknown+=state_duration; break; case AS_SVC_CRITICAL: subject->time_critical+=state_duration; break; default: break; } return; } /* computes downtime data for a given subject */ void compute_subject_downtime(avail_subject *subject, time_t current_time){ archived_state *temp_sd; time_t start_time; time_t end_time; int host_downtime_depth=0; int service_downtime_depth=0; int process_chunk=FALSE; #ifdef DEBUG2 printf("COMPUTE_SUBJECT_DOWNTIME\n"); #endif /* if left hand of graph is after current time, we can't do anything at all.... */ if(t1>current_time) return; /* no scheduled downtime data for subject... */ if(subject->sd_list==NULL) return; /* all data we have occurs after last time on graph... */ if(subject->sd_list->time_stamp>=t2) return; /* initialize pointer */ temp_sd=subject->sd_list; /* special case if first entry is the end of scheduled downtime */ if((temp_sd->entry_type==AS_HOST_DOWNTIME_END || temp_sd->entry_type==AS_SVC_DOWNTIME_END) && temp_sd->time_stamp>t1){ #ifdef DEBUG2 printf("\tSPECIAL DOWNTIME CASE\n"); #endif start_time=t1; end_time=(temp_sd->time_stamp>t2)?t2:temp_sd->time_stamp; compute_subject_downtime_times(start_time,end_time,subject,NULL); temp_sd=temp_sd->next; } /* process all periods of scheduled downtime */ for(;temp_sd!=NULL;temp_sd=temp_sd->next){ /* we've passed graph bounds... */ if(temp_sd->time_stamp>=t2) break; if(temp_sd->entry_type==AS_HOST_DOWNTIME_START) host_downtime_depth++; else if(temp_sd->entry_type==AS_HOST_DOWNTIME_END) host_downtime_depth--; else if(temp_sd->entry_type==AS_SVC_DOWNTIME_START) service_downtime_depth++; else if(temp_sd->entry_type==AS_SVC_DOWNTIME_END) service_downtime_depth--; else continue; process_chunk=FALSE; if(temp_sd->entry_type==AS_HOST_DOWNTIME_START || temp_sd->entry_type==AS_SVC_DOWNTIME_START) process_chunk=TRUE; else if(subject->type==SERVICE_SUBJECT && (host_downtime_depth>0 || service_downtime_depth>0)) process_chunk=TRUE; /* process this specific "chunk" of scheduled downtime */ if(process_chunk==TRUE){ start_time=temp_sd->time_stamp; end_time=(temp_sd->next==NULL)?current_time:temp_sd->next->time_stamp; /* check time sanity */ if(end_time<=t1) continue; if(start_time>=t2) continue; if(start_time>=end_time) continue; /* clip time values */ if(start_timet2) end_time=t2; compute_subject_downtime_times(start_time,end_time,subject,temp_sd); } } return; } /* computes downtime times */ void compute_subject_downtime_times(time_t start_time, time_t end_time, avail_subject *subject, archived_state *sd){ archived_state *temp_as=NULL; time_t part_start_time=0L; time_t part_subject_state=0L; int save_status=0; int saved_status=0; int saved_stamp=0; int calc_temp=0; int count=0; archived_state *temp_before=NULL; archived_state *last=NULL; #ifdef DEBUG2 printf("

    ENTERING COMPUTE_SUBJECT_DOWNTIME_TIMES: start=%lu, end=%lu, t1=%lu, t2=%lu

    ",start_time,end_time,t1,t2); #endif /* times are weird, so bail out... */ if(start_time>end_time) return; if(start_timet2) return; /* find starting point in archived state list */ if(sd==NULL){ #ifdef DEBUG2 printf("

    TEMP_AS=SUBJECT->AS_LIST

    "); #endif temp_as=subject->as_list; } else if(sd->misc_ptr==NULL){ #ifdef DEBUG2 printf("

    TEMP_AS=SUBJECT->AS_LIST

    "); #endif temp_as=subject->as_list; } else if(sd->misc_ptr->next==NULL){ #ifdef DEBUG2 printf("

    TEMP_AS=SD->MISC_PTR

    "); #endif temp_as=sd->misc_ptr; } else{ #ifdef DEBUG2 printf("

    TEMP_AS=SD->MISC_PTR->NEXT

    "); #endif temp_as=sd->misc_ptr->next; } /* initialize values */ part_start_time=start_time; if(temp_as==NULL) part_subject_state=AS_NO_DATA; else if(temp_as->processed_state==AS_PROGRAM_START || temp_as->processed_state==AS_PROGRAM_END || temp_as->processed_state==AS_NO_DATA){ #ifdef DEBUG2 printf("

    ENTRY TYPE #1: %d

    ",temp_as->entry_type); #endif part_subject_state=AS_NO_DATA; } else{ #ifdef DEBUG2 printf("

    ENTRY TYPE #2: %d

    ",temp_as->entry_type); #endif part_subject_state=temp_as->processed_state; } #ifdef DEBUG2 printf("

    TEMP_AS=%s

    ",(temp_as==NULL)?"NULL":"Not NULL"); printf("

    SD=%s

    ",(sd==NULL)?"NULL":"Not NULL"); #endif /* temp_as now points to first event to possibly "break" this chunk */ for(;temp_as!=NULL;temp_as=temp_as->next){ count++; last=temp_as; if(temp_before==NULL){ if(last->time_stamp>start_time){ if(last->time_stamp>end_time) compute_subject_downtime_part_times(start_time,end_time,part_subject_state,subject); else compute_subject_downtime_part_times(start_time,last->time_stamp,part_subject_state,subject); } temp_before=temp_as; saved_status=temp_as->entry_type; saved_stamp=temp_as->time_stamp; /* check if first time is before schedule downtime */ if(saved_stampentry_type){ /* is outside schedule time, use end schdule downtime */ if(temp_as->time_stamp>end_time){ if(saved_stamptime_stamp,saved_status,subject); else compute_subject_downtime_part_times(saved_stamp,temp_as->time_stamp,saved_status,subject); } saved_status=temp_as->entry_type; saved_stamp=temp_as->time_stamp; } } /* just one entry inside the scheduled downtime */ if(count==0) compute_subject_downtime_part_times(start_time,end_time,part_subject_state,subject); else{ /* is outside scheduled time, use end schdule downtime */ if(last->time_stamp>end_time) compute_subject_downtime_part_times(saved_stamp,end_time,saved_status,subject); else compute_subject_downtime_part_times(saved_stamp,last->time_stamp,saved_status,subject); } return; } /* computes downtime times */ void compute_subject_downtime_part_times(time_t start_time, time_t end_time, int subject_state, avail_subject *subject){ unsigned long state_duration; #ifdef DEBUG2 printf("ENTERING COMPUTE_SUBJECT_DOWNTIME_PART_TIMES\n"); #endif /* times are weird */ if(start_time>end_time) return; state_duration=(unsigned long)(end_time-start_time); switch(subject_state){ case AS_HOST_UP: subject->scheduled_time_up+=state_duration; break; case AS_HOST_DOWN: subject->scheduled_time_down+=state_duration; break; case AS_HOST_UNREACHABLE: subject->scheduled_time_unreachable+=state_duration; break; case AS_SVC_OK: subject->scheduled_time_ok+=state_duration; break; case AS_SVC_WARNING: subject->scheduled_time_warning+=state_duration; break; case AS_SVC_UNKNOWN: subject->scheduled_time_unknown+=state_duration; break; case AS_SVC_CRITICAL: subject->scheduled_time_critical+=state_duration; break; default: subject->scheduled_time_indeterminate+=state_duration; break; } #ifdef DEBUG2 printf("\tSUBJECT DOWNTIME: Host '%s', Service '%s', State=%d, Duration=%lu, Start=%lu\n",subject->host_name,(subject->service_description==NULL)?"NULL":subject->service_description,subject_state,state_duration,start_time); #endif return; } /* convert current host state to archived state value */ int convert_host_state_to_archived_state(int current_status){ if(current_status==HOST_UP) return AS_HOST_UP; if(current_status==HOST_DOWN) return AS_HOST_DOWN; if(current_status==HOST_UNREACHABLE) return AS_HOST_UNREACHABLE; return AS_NO_DATA; } /* convert current service state to archived state value */ int convert_service_state_to_archived_state(int current_status){ if(current_status==SERVICE_OK) return AS_SVC_OK; if(current_status==SERVICE_UNKNOWN) return AS_SVC_UNKNOWN; if(current_status==SERVICE_WARNING) return AS_SVC_WARNING; if(current_status==SERVICE_CRITICAL) return AS_SVC_CRITICAL; return AS_NO_DATA; } /* create list of subjects to collect availability data for */ void create_subject_list(void){ hostgroup *temp_hostgroup; hostgroupmember *temp_hgmember; servicegroup *temp_servicegroup; servicegroupmember *temp_sgmember; host *temp_host; service *temp_service; char *last_host_name=""; /* we're displaying one or more hosts */ if(display_type==DISPLAY_HOST_AVAIL && host_name!=""){ /* we're only displaying a specific host (and summaries for all services associated with it) */ if(show_all_hosts==FALSE){ add_subject(HOST_SUBJECT,host_name,NULL); for(temp_service=service_list;temp_service!=NULL;temp_service=temp_service->next){ if(!strcmp(temp_service->host_name,host_name)) add_subject(SERVICE_SUBJECT,host_name,temp_service->description); } } /* we're displaying all hosts */ else{ for(temp_host=host_list;temp_host!=NULL;temp_host=temp_host->next) add_subject(HOST_SUBJECT,temp_host->name,NULL); } } /* we're displaying a specific service */ else if(display_type==DISPLAY_SERVICE_AVAIL && svc_description!=""){ /* we're only displaying a specific service */ if(show_all_services==FALSE) add_subject(SERVICE_SUBJECT,host_name,svc_description); /* we're displaying all services */ else{ for(temp_service=service_list;temp_service!=NULL;temp_service=temp_service->next) add_subject(SERVICE_SUBJECT,temp_service->host_name,temp_service->description); } } /* we're displaying one or more hostgroups (the host members of the groups) */ else if(display_type==DISPLAY_HOSTGROUP_AVAIL && hostgroup_name!=""){ /* we're displaying all hostgroups */ if(show_all_hostgroups==TRUE){ for(temp_hostgroup=hostgroup_list;temp_hostgroup!=NULL;temp_hostgroup=temp_hostgroup->next){ for(temp_hgmember=temp_hostgroup->members;temp_hgmember!=NULL;temp_hgmember=temp_hgmember->next) add_subject(HOST_SUBJECT,temp_hgmember->host_name,NULL); } } /* we're only displaying a specific hostgroup */ else{ temp_hostgroup=find_hostgroup(hostgroup_name); if(temp_hostgroup!=NULL){ for(temp_hgmember=temp_hostgroup->members;temp_hgmember!=NULL;temp_hgmember=temp_hgmember->next) add_subject(HOST_SUBJECT,temp_hgmember->host_name,NULL); } } } /* we're displaying one or more servicegroups (the host and service members of the groups) */ else if(display_type==DISPLAY_SERVICEGROUP_AVAIL && servicegroup_name!=""){ /* we're displaying all servicegroups */ if(show_all_servicegroups==TRUE){ for(temp_servicegroup=servicegroup_list;temp_servicegroup!=NULL;temp_servicegroup=temp_servicegroup->next){ for(temp_sgmember=temp_servicegroup->members;temp_sgmember!=NULL;temp_sgmember=temp_sgmember->next){ add_subject(SERVICE_SUBJECT,temp_sgmember->host_name,temp_sgmember->service_description); if(strcmp(last_host_name,temp_sgmember->host_name)) add_subject(HOST_SUBJECT,temp_sgmember->host_name,NULL); last_host_name=temp_sgmember->host_name; } } } /* we're only displaying a specific servicegroup */ else{ temp_servicegroup=find_servicegroup(servicegroup_name); if(temp_servicegroup!=NULL){ for(temp_sgmember=temp_servicegroup->members;temp_sgmember!=NULL;temp_sgmember=temp_sgmember->next){ add_subject(SERVICE_SUBJECT,temp_sgmember->host_name,temp_sgmember->service_description); if(strcmp(last_host_name,temp_sgmember->host_name)) add_subject(HOST_SUBJECT,temp_sgmember->host_name,NULL); last_host_name=temp_sgmember->host_name; } } } } return; } /* adds a subject */ void add_subject(int subject_type, char *hn, char *sd){ avail_subject *last_subject=NULL; avail_subject *temp_subject=NULL; avail_subject *new_subject=NULL; int is_authorized=FALSE; /* bail if we've already added the subject */ if(find_subject(subject_type,hn,sd)) return; /* see if the user is authorized to see data for this host or service */ if(subject_type==HOST_SUBJECT) is_authorized=is_authorized_for_host(find_host(hn),¤t_authdata); else is_authorized=is_authorized_for_service(find_service(hn,sd),¤t_authdata); if(is_authorized==FALSE) return; /* allocate memory for the new entry */ new_subject=(avail_subject *)malloc(sizeof(avail_subject)); if(new_subject==NULL) return; /* allocate memory for the host name */ if(hn!=NULL){ new_subject->host_name=(char *)malloc(strlen(hn)+1); if(new_subject->host_name!=NULL) strcpy(new_subject->host_name,hn); } else new_subject->host_name=NULL; /* allocate memory for the service description */ if(sd!=NULL){ new_subject->service_description=(char *)malloc(strlen(sd)+1); if(new_subject->service_description!=NULL) strcpy(new_subject->service_description,sd); } else new_subject->service_description=NULL; new_subject->type=subject_type; new_subject->earliest_state=AS_NO_DATA; new_subject->latest_state=AS_NO_DATA; new_subject->time_up=0L; new_subject->time_down=0L; new_subject->time_unreachable=0L; new_subject->time_ok=0L; new_subject->time_warning=0L; new_subject->time_unknown=0L; new_subject->time_critical=0L; new_subject->scheduled_time_up=0L; new_subject->scheduled_time_down=0L; new_subject->scheduled_time_unreachable=0L; new_subject->scheduled_time_ok=0L; new_subject->scheduled_time_warning=0L; new_subject->scheduled_time_unknown=0L; new_subject->scheduled_time_critical=0L; new_subject->scheduled_time_indeterminate=0L; new_subject->time_indeterminate_nodata=0L; new_subject->time_indeterminate_notrunning=0L; new_subject->as_list=NULL; new_subject->as_list_tail=NULL; new_subject->sd_list=NULL; new_subject->last_known_state=AS_NO_DATA; /* add the new entry to the list in memory, sorted by host name */ last_subject=subject_list; for(temp_subject=subject_list;temp_subject!=NULL;temp_subject=temp_subject->next){ if(strcmp(new_subject->host_name,temp_subject->host_name)<0){ new_subject->next=temp_subject; if(temp_subject==subject_list) subject_list=new_subject; else last_subject->next=new_subject; break; } else last_subject=temp_subject; } if(subject_list==NULL){ new_subject->next=NULL; subject_list=new_subject; } else if(temp_subject==NULL){ new_subject->next=NULL; last_subject->next=new_subject; } return; } /* finds a specific subject */ avail_subject *find_subject(int type, char *hn, char *sd){ avail_subject *temp_subject; if(hn==NULL) return NULL; if(type==SERVICE_SUBJECT && sd==NULL) return NULL; for(temp_subject=subject_list;temp_subject!=NULL;temp_subject=temp_subject->next){ if(temp_subject->type!=type) continue; if(strcmp(hn,temp_subject->host_name)) continue; if(type==SERVICE_SUBJECT && strcmp(sd,temp_subject->service_description)) continue; return temp_subject; } return NULL; } /* adds an archived state entry to all subjects */ void add_global_archived_state(int entry_type, int state_type, time_t time_stamp, char *state_info){ avail_subject *temp_subject; for(temp_subject=subject_list;temp_subject!=NULL;temp_subject=temp_subject->next) add_archived_state(entry_type,state_type,time_stamp,state_info,temp_subject); return; } /* adds an archived state entry to a specific subject */ void add_archived_state(int entry_type, int state_type, time_t time_stamp, char *state_info, avail_subject *subject){ archived_state *last_as=NULL; archived_state *temp_as=NULL; archived_state *new_as=NULL; /* allocate memory for the new entry */ new_as=(archived_state *)malloc(sizeof(archived_state)); if(new_as==NULL) return; /* allocate memory for the state info */ if(state_info!=NULL){ new_as->state_info=(char *)malloc(strlen(state_info)+1); if(new_as->state_info!=NULL) strcpy(new_as->state_info,state_info); } else new_as->state_info=NULL; /* initialize the "processed state" value - this gets modified later for most entries */ if(entry_type!=AS_PROGRAM_START && entry_type!=AS_PROGRAM_END && entry_type!=AS_NO_DATA) new_as->processed_state=entry_type; else new_as->processed_state=AS_NO_DATA; new_as->entry_type=entry_type; new_as->state_type=state_type; new_as->time_stamp=time_stamp; new_as->misc_ptr=NULL; /* add the new entry to the list in memory, sorted by time (more recent entries should appear towards end of list) */ last_as=subject->as_list; for(temp_as=subject->as_list;temp_as!=NULL;temp_as=temp_as->next){ if(new_as->time_stamptime_stamp){ new_as->next=temp_as; if(temp_as==subject->as_list) subject->as_list=new_as; else last_as->next=new_as; break; } else last_as=temp_as; } if(subject->as_list==NULL){ new_as->next=NULL; subject->as_list=new_as; } else if(temp_as==NULL){ new_as->next=NULL; last_as->next=new_as; } /* update "tail" of the list - not really the tail, just last item added */ subject->as_list_tail=new_as; return; } /* adds a scheduled downtime entry to a specific subject */ void add_scheduled_downtime(int state_type, time_t time_stamp, avail_subject *subject){ archived_state *last_sd=NULL; archived_state *temp_sd=NULL; archived_state *new_sd=NULL; /* allocate memory for the new entry */ new_sd=(archived_state *)malloc(sizeof(archived_state)); if(new_sd==NULL) return; new_sd->state_info=NULL; new_sd->processed_state=state_type; new_sd->entry_type=state_type; new_sd->time_stamp=time_stamp; new_sd->misc_ptr=subject->as_list_tail; /* add the new entry to the list in memory, sorted by time (more recent entries should appear towards end of list) */ last_sd=subject->sd_list; for(temp_sd=subject->sd_list;temp_sd!=NULL;temp_sd=temp_sd->next){ if(new_sd->time_stamp<=temp_sd->time_stamp){ new_sd->next=temp_sd; if(temp_sd==subject->sd_list) subject->sd_list=new_sd; else last_sd->next=new_sd; break; } else last_sd=temp_sd; } if(subject->sd_list==NULL){ new_sd->next=NULL; subject->sd_list=new_sd; } else if(temp_sd==NULL){ new_sd->next=NULL; last_sd->next=new_sd; } return; } /* frees memory allocated to all availability data */ void free_availability_data(void){ avail_subject *this_subject; avail_subject *next_subject; for(this_subject=subject_list;this_subject!=NULL;){ next_subject=this_subject->next; if(this_subject->host_name!=NULL) free(this_subject->host_name); if(this_subject->service_description!=NULL) free(this_subject->service_description); free_archived_state_list(this_subject->as_list); free_archived_state_list(this_subject->sd_list); free(this_subject); this_subject=next_subject; } return; } /* frees memory allocated to the archived state list */ void free_archived_state_list(archived_state *as_list){ archived_state *this_as=NULL; archived_state *next_as=NULL; for(this_as=as_list;this_as!=NULL;){ next_as=this_as->next; if(this_as->state_info!=NULL) free(this_as->state_info); free(this_as); this_as=next_as; } as_list=NULL; return; } /* reads log files for archived state data */ void read_archived_state_data(void){ char filename[MAX_FILENAME_LENGTH]; int oldest_archive=0; int newest_archive=0; int current_archive=0; /* determine oldest archive to use when scanning for data (include backtracked archives as well) */ oldest_archive=determine_archive_to_use_from_time(t1); if(log_rotation_method!=LOG_ROTATION_NONE) oldest_archive+=backtrack_archives; /* determine most recent archive to use when scanning for data */ newest_archive=determine_archive_to_use_from_time(t2); if(oldest_archivenext){ if(temp_subject->type!=SERVICE_SUBJECT) continue; if(strcmp(temp_subject->host_name,entry_host_name)) continue; if(show_scheduled_downtime==FALSE) continue; if(strstr(input,";STARTED;")) add_scheduled_downtime(AS_HOST_DOWNTIME_START,time_stamp,temp_subject); else add_scheduled_downtime(AS_HOST_DOWNTIME_END,time_stamp,temp_subject); } } } } /* free memory and close the file */ free(input); free(input2); mmap_fclose(thefile); return; } void convert_timeperiod_to_times(int type){ time_t current_time; struct tm *t; /* get the current time */ time(¤t_time); t=localtime(¤t_time); t->tm_sec=0; t->tm_min=0; t->tm_hour=0; switch(type){ case TIMEPERIOD_LAST24HOURS: t1=current_time-(60*60*24); t2=current_time; break; case TIMEPERIOD_TODAY: t1=mktime(t); t2=current_time; break; case TIMEPERIOD_YESTERDAY: t1=(time_t)(mktime(t)-(60*60*24)); t2=(time_t)mktime(t); break; case TIMEPERIOD_THISWEEK: t1=(time_t)(mktime(t)-(60*60*24*t->tm_wday)); t2=current_time; break; case TIMEPERIOD_LASTWEEK: t1=(time_t)(mktime(t)-(60*60*24*t->tm_wday)-(60*60*24*7)); t2=(time_t)(mktime(t)-(60*60*24*t->tm_wday)); break; case TIMEPERIOD_THISMONTH: t->tm_mday=1; t1=mktime(t); t2=current_time; break; case TIMEPERIOD_LASTMONTH: t->tm_mday=1; t2=mktime(t); if(t->tm_mon==0){ t->tm_mon=11; t->tm_year--; } else t->tm_mon--; t1=mktime(t); break; case TIMEPERIOD_THISQUARTER: /* not implemented */ break; case TIMEPERIOD_LASTQUARTER: /* not implemented */ break; case TIMEPERIOD_THISYEAR: t->tm_mon=0; t->tm_mday=1; t1=mktime(t); t2=current_time; break; case TIMEPERIOD_LASTYEAR: t->tm_mon=0; t->tm_mday=1; t2=mktime(t); t->tm_year--; t1=mktime(t); break; case TIMEPERIOD_LAST7DAYS: t2=current_time; t1=current_time-(7*24*60*60); break; case TIMEPERIOD_LAST31DAYS: t2=current_time; t1=current_time-(31*24*60*60); break; default: break; } return; } void compute_report_times(void){ time_t current_time; struct tm *st; struct tm *et; /* get the current time */ time(¤t_time); st=localtime(¤t_time); st->tm_sec=start_second; st->tm_min=start_minute; st->tm_hour=start_hour; st->tm_mday=start_day; st->tm_mon=start_month-1; st->tm_year=start_year-1900; t1=mktime(st); et=localtime(¤t_time); et->tm_sec=end_second; et->tm_min=end_minute; et->tm_hour=end_hour; et->tm_mday=end_day; et->tm_mon=end_month-1; et->tm_year=end_year-1900; t2=mktime(et); } /* writes log entries to screen */ void write_log_entries(avail_subject *subject){ archived_state *temp_as; archived_state *temp_sd; time_t current_time; char start_date_time[MAX_DATETIME_LENGTH]; char end_date_time[MAX_DATETIME_LENGTH]; char duration[20]; char *bgclass=""; char *ebgclass=""; char *entry_type=""; char *state_type=""; int days; int hours; int minutes; int seconds; int odd=0; if(output_format!=HTML_OUTPUT) return; if(show_log_entries==FALSE) return; if(subject==NULL) return; time(¤t_time); /* inject all scheduled downtime entries into the main list for display purposes */ for(temp_sd=subject->sd_list;temp_sd!=NULL;temp_sd=temp_sd->next){ switch(temp_sd->entry_type){ case AS_SVC_DOWNTIME_START: case AS_HOST_DOWNTIME_START: entry_type="Start of scheduled downtime"; break; case AS_SVC_DOWNTIME_END: case AS_HOST_DOWNTIME_END: entry_type="End of scheduled downtime"; break; default: entry_type="?"; break; } add_archived_state(temp_sd->entry_type,AS_NO_DATA,temp_sd->time_stamp,entry_type,subject); } printf("

    \n"); printf("
    %s Log Entries:
    \n",(subject->type==HOST_SUBJECT)?"Host":"Service"); printf("
    "); if(full_log_entries==TRUE){ full_log_entries=FALSE; if(subject->type==HOST_SUBJECT) host_report_url(subject->host_name,"[ View condensed log entries ]"); else service_report_url(subject->host_name,subject->service_description,"[ View condensed log entries ]"); full_log_entries=TRUE; } else{ full_log_entries=TRUE; if(subject->type==HOST_SUBJECT) host_report_url(subject->host_name,"[ View full log entries ]"); else service_report_url(subject->host_name,subject->service_description,"[ View full log entries ]"); full_log_entries=FALSE; } printf("
    \n"); printf("
    \n"); printf("\n"); printf("\n"); /* write all archived state entries */ for(temp_as=subject->as_list;temp_as!=NULL;temp_as=temp_as->next){ if(temp_as->state_type==AS_HARD_STATE) state_type=" (HARD)"; else if(temp_as->state_type==AS_SOFT_STATE) state_type=" (SOFT)"; else state_type=""; switch(temp_as->entry_type){ case AS_NO_DATA: if(full_log_entries==FALSE) continue; entry_type="NO DATA"; ebgclass="INDETERMINATE"; break; case AS_PROGRAM_END: if(full_log_entries==FALSE) continue; entry_type="PROGRAM END"; ebgclass="INDETERMINATE"; break; case AS_PROGRAM_START: if(full_log_entries==FALSE) continue; entry_type="PROGRAM (RE)START"; ebgclass="INDETERMINATE"; break; case AS_HOST_UP: entry_type="HOST UP"; ebgclass="UP"; break; case AS_HOST_DOWN: entry_type="HOST DOWN"; ebgclass="DOWN"; break; case AS_HOST_UNREACHABLE: entry_type="HOST UNREACHABLE"; ebgclass="UNREACHABLE"; break; case AS_SVC_OK: entry_type="SERVICE OK"; ebgclass="OK"; break; case AS_SVC_UNKNOWN: entry_type="SERVICE UNKNOWN"; ebgclass="UNKNOWN"; break; case AS_SVC_WARNING: entry_type="SERVICE WARNING"; ebgclass="WARNING"; break; case AS_SVC_CRITICAL: entry_type="SERVICE CRITICAL"; ebgclass="CRITICAL"; break; case AS_SVC_DOWNTIME_START: entry_type="SERVICE DOWNTIME START"; ebgclass="INDETERMINATE"; break; case AS_SVC_DOWNTIME_END: entry_type="SERVICE DOWNTIME END"; ebgclass="INDETERMINATE"; break; case AS_HOST_DOWNTIME_START: entry_type="HOST DOWNTIME START"; ebgclass="INDETERMINATE"; break; case AS_HOST_DOWNTIME_END: entry_type="HOST DOWNTIME END"; ebgclass="INDETERMINATE"; break; default: if(full_log_entries==FALSE) continue; entry_type="?"; ebgclass="INDETERMINATE"; } get_time_string(&(temp_as->time_stamp),start_date_time,sizeof(start_date_time)-1,SHORT_DATE_TIME); if(temp_as->next==NULL){ get_time_string(&t2,end_date_time,sizeof(end_date_time)-1,SHORT_DATE_TIME); get_time_breakdown((time_t)(t2-temp_as->time_stamp),&days,&hours,&minutes,&seconds); snprintf(duration,sizeof(duration)-1,"%dd %dh %dm %ds+",days,hours,minutes,seconds); } else{ get_time_string(&(temp_as->next->time_stamp),end_date_time,sizeof(end_date_time)-1,SHORT_DATE_TIME); get_time_breakdown((time_t)(temp_as->next->time_stamp-temp_as->time_stamp),&days,&hours,&minutes,&seconds); snprintf(duration,sizeof(duration)-1,"%dd %dh %dm %ds",days,hours,minutes,seconds); } if(odd){ bgclass="Odd"; odd=0; } else{ bgclass="Even"; odd=1; } printf("",bgclass); printf("",bgclass,start_date_time); printf("",bgclass,end_date_time); printf("",bgclass,duration); printf("",ebgclass,entry_type,state_type); printf("",bgclass,(temp_as->state_info==NULL)?"":temp_as->state_info); printf("\n"); } printf("
    Event Start TimeEvent End TimeEvent DurationEvent/State TypeEvent/State Information
    %s%s%s%s%s%s
    \n"); printf("
    \n"); return; } /* display hostgroup availability */ void display_hostgroup_availability(void){ hostgroup *temp_hostgroup; /* display data for a specific hostgroup */ if(show_all_hostgroups==FALSE){ temp_hostgroup=find_hostgroup(hostgroup_name); display_specific_hostgroup_availability(temp_hostgroup); } /* display data for all hostgroups */ else{ for(temp_hostgroup=hostgroup_list;temp_hostgroup!=NULL;temp_hostgroup=temp_hostgroup->next) display_specific_hostgroup_availability(temp_hostgroup); } return; } /* display availability for a specific hostgroup */ void display_specific_hostgroup_availability(hostgroup *hg){ unsigned long total_time; unsigned long time_determinate; unsigned long time_indeterminate; avail_subject *temp_subject; double percent_time_up=0.0; double percent_time_down=0.0; double percent_time_unreachable=0.0; double percent_time_up_known=0.0; double percent_time_down_known=0.0; double percent_time_unreachable_known=0.0; double percent_time_indeterminate=0.0; double average_percent_time_up=0.0; double average_percent_time_up_known=0.0; double average_percent_time_down=0.0; double average_percent_time_down_known=0.0; double average_percent_time_unreachable=0.0; double average_percent_time_unreachable_known=0.0; double average_percent_time_indeterminate=0.0; int current_subject=0; char *bgclass=""; int odd=1; host *temp_host; if(hg==NULL) return; /* the user isn't authorized to view this hostgroup */ if(is_authorized_for_hostgroup(hg,¤t_authdata)==FALSE) return; /* calculate total time during period based on timeperiod used for reporting */ total_time=calculate_total_time(t1,t2); printf("

    \n"); printf("
    Hostgroup '%s' Host State Breakdowns:
    \n",hg->group_name); printf("
    \n"); printf("\n"); printf("\n"); for(temp_subject=subject_list;temp_subject!=NULL;temp_subject=temp_subject->next){ if(temp_subject->type!=HOST_SUBJECT) continue; temp_host=find_host(temp_subject->host_name); if(temp_host==NULL) continue; if(is_host_member_of_hostgroup(hg,temp_host)==FALSE) continue; current_subject++; /* reset variables */ percent_time_up=0.0; percent_time_down=0.0; percent_time_unreachable=0.0; percent_time_indeterminate=0.0; percent_time_up_known=0.0; percent_time_down_known=0.0; percent_time_unreachable_known=0.0; time_determinate=temp_subject->time_up+temp_subject->time_down+temp_subject->time_unreachable; time_indeterminate=total_time-time_determinate; if(total_time>0){ percent_time_up=(double)(((double)temp_subject->time_up*100.0)/(double)total_time); percent_time_down=(double)(((double)temp_subject->time_down*100.0)/(double)total_time); percent_time_unreachable=(double)(((double)temp_subject->time_unreachable*100.0)/(double)total_time); percent_time_indeterminate=(double)(((double)time_indeterminate*100.0)/(double)total_time); if(time_determinate>0){ percent_time_up_known=(double)(((double)temp_subject->time_up*100.0)/(double)time_determinate); percent_time_down_known=(double)(((double)temp_subject->time_down*100.0)/(double)time_determinate); percent_time_unreachable_known=(double)(((double)temp_subject->time_unreachable*100.0)/(double)time_determinate); } } if(odd){ odd=0; bgclass="Odd"; } else{ odd=1; bgclass="Even"; } printf("\n",percent_time_up,percent_time_up_known,percent_time_down,percent_time_down_known,percent_time_unreachable,percent_time_unreachable_known,bgclass,percent_time_indeterminate); get_running_average(&average_percent_time_up,percent_time_up,current_subject); get_running_average(&average_percent_time_up_known,percent_time_up_known,current_subject); get_running_average(&average_percent_time_down,percent_time_down,current_subject); get_running_average(&average_percent_time_down_known,percent_time_down_known,current_subject); get_running_average(&average_percent_time_unreachable,percent_time_unreachable,current_subject); get_running_average(&average_percent_time_unreachable_known,percent_time_unreachable_known,current_subject); get_running_average(&average_percent_time_indeterminate,percent_time_indeterminate,current_subject); } /* average statistics */ if(odd){ odd=0; bgclass="Odd"; } else{ odd=1; bgclass="Even"; } printf("",bgclass,bgclass,average_percent_time_up,average_percent_time_up_known,average_percent_time_down,average_percent_time_down_known,average_percent_time_unreachable,average_percent_time_unreachable_known,bgclass,average_percent_time_indeterminate); printf("
    Host%% Time Up%% Time Down%% Time Unreachable%% Time Undetermined
    ",bgclass,bgclass); host_report_url(temp_subject->host_name,temp_subject->host_name); printf("%2.3f%% (%2.3f%%)%2.3f%% (%2.3f%%)%2.3f%% (%2.3f%%)%2.3f%%
    Average%2.3f%% (%2.3f%%)%2.3f%% (%2.3f%%)%2.3f%% (%2.3f%%)%2.3f%%
    \n"); printf("
    \n"); return; } /* display servicegroup availability */ void display_servicegroup_availability(void){ servicegroup *temp_servicegroup; /* display data for a specific servicegroup */ if(show_all_servicegroups==FALSE){ temp_servicegroup=find_servicegroup(servicegroup_name); display_specific_servicegroup_availability(temp_servicegroup); } /* display data for all servicegroups */ else{ for(temp_servicegroup=servicegroup_list;temp_servicegroup!=NULL;temp_servicegroup=temp_servicegroup->next) display_specific_servicegroup_availability(temp_servicegroup); } return; } /* display availability for a specific servicegroup */ void display_specific_servicegroup_availability(servicegroup *sg){ unsigned long total_time; unsigned long time_determinate; unsigned long time_indeterminate; avail_subject *temp_subject; double percent_time_up=0.0; double percent_time_down=0.0; double percent_time_unreachable=0.0; double percent_time_up_known=0.0; double percent_time_down_known=0.0; double percent_time_unreachable_known=0.0; double percent_time_indeterminate=0.0; double percent_time_ok=0.0; double percent_time_warning=0.0; double percent_time_unknown=0.0; double percent_time_critical=0.0; double percent_time_ok_known=0.0; double percent_time_warning_known=0.0; double percent_time_unknown_known=0.0; double percent_time_critical_known=0.0; double average_percent_time_up=0.0; double average_percent_time_up_known=0.0; double average_percent_time_down=0.0; double average_percent_time_down_known=0.0; double average_percent_time_unreachable=0.0; double average_percent_time_unreachable_known=0.0; double average_percent_time_ok=0.0; double average_percent_time_ok_known=0.0; double average_percent_time_unknown=0.0; double average_percent_time_unknown_known=0.0; double average_percent_time_warning=0.0; double average_percent_time_warning_known=0.0; double average_percent_time_critical=0.0; double average_percent_time_critical_known=0.0; double average_percent_time_indeterminate=0.0; int current_subject=0; char *bgclass=""; int odd=1; host *temp_host; service *temp_service; char last_host[MAX_INPUT_BUFFER]; if(sg==NULL) return; /* the user isn't authorized to view this servicegroup */ if(is_authorized_for_servicegroup(sg,¤t_authdata)==FALSE) return; /* calculate total time during period based on timeperiod used for reporting */ total_time=calculate_total_time(t1,t2); printf("

    \n"); printf("
    Servicegroup '%s' Host State Breakdowns:
    \n",sg->group_name); printf("
    \n"); printf("\n"); printf("\n"); for(temp_subject=subject_list;temp_subject!=NULL;temp_subject=temp_subject->next){ if(temp_subject->type!=HOST_SUBJECT) continue; temp_host=find_host(temp_subject->host_name); if(temp_host==NULL) continue; if(is_host_member_of_servicegroup(sg,temp_host)==FALSE) continue; current_subject++; /* reset variables */ percent_time_up=0.0; percent_time_down=0.0; percent_time_unreachable=0.0; percent_time_indeterminate=0.0; percent_time_up_known=0.0; percent_time_down_known=0.0; percent_time_unreachable_known=0.0; time_determinate=temp_subject->time_up+temp_subject->time_down+temp_subject->time_unreachable; time_indeterminate=total_time-time_determinate; if(total_time>0){ percent_time_up=(double)(((double)temp_subject->time_up*100.0)/(double)total_time); percent_time_down=(double)(((double)temp_subject->time_down*100.0)/(double)total_time); percent_time_unreachable=(double)(((double)temp_subject->time_unreachable*100.0)/(double)total_time); percent_time_indeterminate=(double)(((double)time_indeterminate*100.0)/(double)total_time); if(time_determinate>0){ percent_time_up_known=(double)(((double)temp_subject->time_up*100.0)/(double)time_determinate); percent_time_down_known=(double)(((double)temp_subject->time_down*100.0)/(double)time_determinate); percent_time_unreachable_known=(double)(((double)temp_subject->time_unreachable*100.0)/(double)time_determinate); } } if(odd){ odd=0; bgclass="Odd"; } else{ odd=1; bgclass="Even"; } printf("\n",percent_time_up,percent_time_up_known,percent_time_down,percent_time_down_known,percent_time_unreachable,percent_time_unreachable_known,bgclass,percent_time_indeterminate); get_running_average(&average_percent_time_up,percent_time_up,current_subject); get_running_average(&average_percent_time_up_known,percent_time_up_known,current_subject); get_running_average(&average_percent_time_down,percent_time_down,current_subject); get_running_average(&average_percent_time_down_known,percent_time_down_known,current_subject); get_running_average(&average_percent_time_unreachable,percent_time_unreachable,current_subject); get_running_average(&average_percent_time_unreachable_known,percent_time_unreachable_known,current_subject); get_running_average(&average_percent_time_indeterminate,percent_time_indeterminate,current_subject); } /* average statistics */ if(odd){ odd=0; bgclass="Odd"; } else{ odd=1; bgclass="Even"; } printf("",bgclass,bgclass,average_percent_time_up,average_percent_time_up_known,average_percent_time_down,average_percent_time_down_known,average_percent_time_unreachable,average_percent_time_unreachable_known,bgclass,average_percent_time_indeterminate); printf("
    Host%% Time Up%% Time Down%% Time Unreachable%% Time Undetermined
    ",bgclass,bgclass); host_report_url(temp_subject->host_name,temp_subject->host_name); printf("%2.3f%% (%2.3f%%)%2.3f%% (%2.3f%%)%2.3f%% (%2.3f%%)%2.3f%%
    Average%2.3f%% (%2.3f%%)%2.3f%% (%2.3f%%)%2.3f%% (%2.3f%%)%2.3f%%
    \n"); printf("
    \n"); printf("
    \n"); printf("
    Servicegroup '%s' Service State Breakdowns:
    \n",sg->group_name); printf("
    \n"); printf("\n"); printf("\n"); current_subject=0; average_percent_time_indeterminate=0.0; for(temp_subject=subject_list;temp_subject!=NULL;temp_subject=temp_subject->next){ if(temp_subject->type!=SERVICE_SUBJECT) continue; temp_service=find_service(temp_subject->host_name,temp_subject->service_description); if(temp_service==NULL) continue; if(is_service_member_of_servicegroup(sg,temp_service)==FALSE) continue; current_subject++; time_determinate=temp_subject->time_ok+temp_subject->time_warning+temp_subject->time_unknown+temp_subject->time_critical; time_indeterminate=total_time-time_determinate; /* adjust indeterminate time due to insufficient data (not all was caught) */ temp_subject->time_indeterminate_nodata=time_indeterminate-temp_subject->time_indeterminate_notrunning; /* initialize values */ percent_time_ok=0.0; percent_time_warning=0.0; percent_time_unknown=0.0; percent_time_critical=0.0; percent_time_indeterminate=0.0; percent_time_ok_known=0.0; percent_time_warning_known=0.0; percent_time_unknown_known=0.0; percent_time_critical_known=0.0; if(total_time>0){ percent_time_ok=(double)(((double)temp_subject->time_ok*100.0)/(double)total_time); percent_time_warning=(double)(((double)temp_subject->time_warning*100.0)/(double)total_time); percent_time_unknown=(double)(((double)temp_subject->time_unknown*100.0)/(double)total_time); percent_time_critical=(double)(((double)temp_subject->time_critical*100.0)/(double)total_time); percent_time_indeterminate=(double)(((double)time_indeterminate*100.0)/(double)total_time); if(time_determinate>0){ percent_time_ok_known=(double)(((double)temp_subject->time_ok*100.0)/(double)time_determinate); percent_time_warning_known=(double)(((double)temp_subject->time_warning*100.0)/(double)time_determinate); percent_time_unknown_known=(double)(((double)temp_subject->time_unknown*100.0)/(double)time_determinate); percent_time_critical_known=(double)(((double)temp_subject->time_critical*100.0)/(double)time_determinate); } } if(odd){ odd=0; bgclass="Odd"; } else{ odd=1; bgclass="Even"; } printf("\n",percent_time_ok,percent_time_ok_known,percent_time_warning,percent_time_warning_known,percent_time_unknown,percent_time_unknown_known,percent_time_critical,percent_time_critical_known,bgclass,percent_time_indeterminate); strncpy(last_host,temp_subject->host_name,sizeof(last_host)-1); last_host[sizeof(last_host)-1]='\x0'; get_running_average(&average_percent_time_ok,percent_time_ok,current_subject); get_running_average(&average_percent_time_ok_known,percent_time_ok_known,current_subject); get_running_average(&average_percent_time_unknown,percent_time_unknown,current_subject); get_running_average(&average_percent_time_unknown_known,percent_time_unknown_known,current_subject); get_running_average(&average_percent_time_warning,percent_time_warning,current_subject); get_running_average(&average_percent_time_warning_known,percent_time_warning_known,current_subject); get_running_average(&average_percent_time_critical,percent_time_critical,current_subject); get_running_average(&average_percent_time_critical_known,percent_time_critical_known,current_subject); get_running_average(&average_percent_time_indeterminate,percent_time_indeterminate,current_subject); } /* display average stats */ if(odd){ odd=0; bgclass="Odd"; } else{ odd=1; bgclass="Even"; } printf("\n",bgclass,bgclass,average_percent_time_ok,average_percent_time_ok_known,average_percent_time_warning,average_percent_time_warning_known,average_percent_time_unknown,average_percent_time_unknown_known,average_percent_time_critical,average_percent_time_critical_known,bgclass,average_percent_time_indeterminate); printf("
    HostService%% Time OK%% Time Warning%% Time Unknown%% Time Critical%% Time Undetermined
    ",bgclass,bgclass); if(strcmp(temp_subject->host_name,last_host)) host_report_url(temp_subject->host_name,temp_subject->host_name); printf("",bgclass); service_report_url(temp_subject->host_name,temp_subject->service_description,temp_subject->service_description); printf("%2.3f%% (%2.3f%%)%2.3f%% (%2.3f%%)%2.3f%% (%2.3f%%)%2.3f%% (%2.3f%%)%2.3f%%
    Average%2.3f%% (%2.3f%%)%2.3f%% (%2.3f%%)%2.3f%% (%2.3f%%)%2.3f%% (%2.3f%%)%2.3f%%
    \n"); printf("
    \n"); return; } /* display host availability */ void display_host_availability(void){ unsigned long total_time; unsigned long time_determinate; unsigned long time_indeterminate; avail_subject *temp_subject; host *temp_host; service *temp_service; int days, hours, minutes, seconds; char time_indeterminate_string[48]; char time_determinate_string[48]; char total_time_string[48]; double percent_time_ok=0.0; double percent_time_warning=0.0; double percent_time_unknown=0.0; double percent_time_critical=0.0; double percent_time_indeterminate=0.0; double percent_time_ok_known=0.0; double percent_time_warning_known=0.0; double percent_time_unknown_known=0.0; double percent_time_critical_known=0.0; char time_up_string[48]; char time_down_string[48]; char time_unreachable_string[48]; double percent_time_up=0.0; double percent_time_down=0.0; double percent_time_unreachable=0.0; double percent_time_up_known=0.0; double percent_time_down_known=0.0; double percent_time_unreachable_known=0.0; double percent_time_up_scheduled=0.0; double percent_time_up_unscheduled=0.0; double percent_time_down_scheduled=0.0; double percent_time_down_unscheduled=0.0; double percent_time_unreachable_scheduled=0.0; double percent_time_unreachable_unscheduled=0.0; double percent_time_up_scheduled_known=0.0; double percent_time_up_unscheduled_known=0.0; double percent_time_down_scheduled_known=0.0; double percent_time_down_unscheduled_known=0.0; double percent_time_unreachable_scheduled_known=0.0; double percent_time_unreachable_unscheduled_known=0.0; char time_up_scheduled_string[48]; char time_up_unscheduled_string[48]; char time_down_scheduled_string[48]; char time_down_unscheduled_string[48]; char time_unreachable_scheduled_string[48]; char time_unreachable_unscheduled_string[48]; char time_indeterminate_scheduled_string[48]; char time_indeterminate_unscheduled_string[48]; double percent_time_indeterminate_scheduled=0.0; double percent_time_indeterminate_unscheduled=0.0; char time_indeterminate_notrunning_string[48]; char time_indeterminate_nodata_string[48]; double percent_time_indeterminate_notrunning=0.0; double percent_time_indeterminate_nodata=0.0; double average_percent_time_up=0.0; double average_percent_time_up_known=0.0; double average_percent_time_down=0.0; double average_percent_time_down_known=0.0; double average_percent_time_unreachable=0.0; double average_percent_time_unreachable_known=0.0; double average_percent_time_indeterminate=0.0; double average_percent_time_ok=0.0; double average_percent_time_ok_known=0.0; double average_percent_time_unknown=0.0; double average_percent_time_unknown_known=0.0; double average_percent_time_warning=0.0; double average_percent_time_warning_known=0.0; double average_percent_time_critical=0.0; double average_percent_time_critical_known=0.0; int current_subject=0; char *bgclass=""; int odd=1; /* calculate total time during period based on timeperiod used for reporting */ total_time=calculate_total_time(t1,t2); #ifdef DEBUG printf("Total time: '%ld' seconds
    \n",total_time); #endif /* show data for a specific host */ if(show_all_hosts==FALSE){ temp_subject=find_subject(HOST_SUBJECT,host_name,NULL); if(temp_subject==NULL) return; temp_host=find_host(temp_subject->host_name); if(temp_host==NULL) return; /* the user isn't authorized to view this host */ if(is_authorized_for_host(temp_host,¤t_authdata)==FALSE) return; time_determinate=temp_subject->time_up+temp_subject->time_down+temp_subject->time_unreachable; time_indeterminate=total_time-time_determinate; /* adjust indeterminate time due to insufficient data (not all was caught) */ temp_subject->time_indeterminate_nodata=time_indeterminate-temp_subject->time_indeterminate_notrunning; /* up times */ get_time_breakdown(temp_subject->time_up,&days,&hours,&minutes,&seconds); snprintf(time_up_string,sizeof(time_up_string)-1,"%dd %dh %dm %ds",days,hours,minutes,seconds); get_time_breakdown(temp_subject->scheduled_time_up,&days,&hours,&minutes,&seconds); snprintf(time_up_scheduled_string,sizeof(time_up_scheduled_string)-1,"%dd %dh %dm %ds",days,hours,minutes,seconds); get_time_breakdown(temp_subject->time_up-temp_subject->scheduled_time_up,&days,&hours,&minutes,&seconds); snprintf(time_up_unscheduled_string,sizeof(time_up_unscheduled_string)-1,"%dd %dh %dm %ds",days,hours,minutes,seconds); /* down times */ get_time_breakdown(temp_subject->time_down,&days,&hours,&minutes,&seconds); snprintf(time_down_string,sizeof(time_down_string)-1,"%dd %dh %dm %ds",days,hours,minutes,seconds); get_time_breakdown(temp_subject->scheduled_time_down,&days,&hours,&minutes,&seconds); snprintf(time_down_scheduled_string,sizeof(time_down_scheduled_string)-1,"%dd %dh %dm %ds",days,hours,minutes,seconds); get_time_breakdown(temp_subject->time_down-temp_subject->scheduled_time_down,&days,&hours,&minutes,&seconds); snprintf(time_down_unscheduled_string,sizeof(time_down_unscheduled_string)-1,"%dd %dh %dm %ds",days,hours,minutes,seconds); /* unreachable times */ get_time_breakdown(temp_subject->time_unreachable,&days,&hours,&minutes,&seconds); snprintf(time_unreachable_string,sizeof(time_unreachable_string)-1,"%dd %dh %dm %ds",days,hours,minutes,seconds); get_time_breakdown(temp_subject->scheduled_time_unreachable,&days,&hours,&minutes,&seconds); snprintf(time_unreachable_scheduled_string,sizeof(time_unreachable_scheduled_string)-1,"%dd %dh %dm %ds",days,hours,minutes,seconds); get_time_breakdown(temp_subject->time_unreachable-temp_subject->scheduled_time_unreachable,&days,&hours,&minutes,&seconds); snprintf(time_unreachable_unscheduled_string,sizeof(time_unreachable_unscheduled_string)-1,"%dd %dh %dm %ds",days,hours,minutes,seconds); /* indeterminate times */ get_time_breakdown(time_indeterminate,&days,&hours,&minutes,&seconds); snprintf(time_indeterminate_string,sizeof(time_indeterminate_string)-1,"%dd %dh %dm %ds",days,hours,minutes,seconds); get_time_breakdown(temp_subject->scheduled_time_indeterminate,&days,&hours,&minutes,&seconds); snprintf(time_indeterminate_scheduled_string,sizeof(time_indeterminate_scheduled_string)-1,"%dd %dh %dm %ds",days,hours,minutes,seconds); get_time_breakdown(time_indeterminate-temp_subject->scheduled_time_indeterminate,&days,&hours,&minutes,&seconds); snprintf(time_indeterminate_unscheduled_string,sizeof(time_indeterminate_unscheduled_string)-1,"%dd %dh %dm %ds",days,hours,minutes,seconds); get_time_breakdown(temp_subject->time_indeterminate_notrunning,&days,&hours,&minutes,&seconds); snprintf(time_indeterminate_notrunning_string,sizeof(time_indeterminate_notrunning_string)-1,"%dd %dh %dm %ds",days,hours,minutes,seconds); get_time_breakdown(temp_subject->time_indeterminate_nodata,&days,&hours,&minutes,&seconds); snprintf(time_indeterminate_nodata_string,sizeof(time_indeterminate_nodata_string)-1,"%dd %dh %dm %ds",days,hours,minutes,seconds); get_time_breakdown(time_determinate,&days,&hours,&minutes,&seconds); snprintf(time_determinate_string,sizeof(time_determinate_string)-1,"%dd %dh %dm %ds",days,hours,minutes,seconds); get_time_breakdown(total_time,&days,&hours,&minutes,&seconds); snprintf(total_time_string,sizeof(total_time_string)-1,"%dd %dh %dm %ds",days,hours,minutes,seconds); if(total_time>0){ percent_time_up=(double)(((double)temp_subject->time_up*100.0)/(double)total_time); percent_time_up_scheduled=(double)(((double)temp_subject->scheduled_time_up*100.0)/(double)total_time); percent_time_up_unscheduled=percent_time_up-percent_time_up_scheduled; percent_time_down=(double)(((double)temp_subject->time_down*100.0)/(double)total_time); percent_time_down_scheduled=(double)(((double)temp_subject->scheduled_time_down*100.0)/(double)total_time); percent_time_down_unscheduled=percent_time_down-percent_time_down_scheduled; percent_time_unreachable=(double)(((double)temp_subject->time_unreachable*100.0)/(double)total_time); percent_time_unreachable_scheduled=(double)(((double)temp_subject->scheduled_time_unreachable*100.0)/(double)total_time); percent_time_unreachable_unscheduled=percent_time_unreachable-percent_time_unreachable_scheduled; percent_time_indeterminate=(double)(((double)time_indeterminate*100.0)/(double)total_time); percent_time_indeterminate_scheduled=(double)(((double)temp_subject->scheduled_time_indeterminate*100.0)/(double)total_time); percent_time_indeterminate_unscheduled=percent_time_indeterminate-percent_time_indeterminate_scheduled; percent_time_indeterminate_notrunning=(double)(((double)temp_subject->time_indeterminate_notrunning*100.0)/(double)total_time); percent_time_indeterminate_nodata=(double)(((double)temp_subject->time_indeterminate_nodata*100.0)/(double)total_time); if(time_determinate>0){ percent_time_up_known=(double)(((double)temp_subject->time_up*100.0)/(double)time_determinate); percent_time_up_scheduled_known=(double)(((double)temp_subject->scheduled_time_up*100.0)/(double)time_determinate); percent_time_up_unscheduled_known=percent_time_up_known-percent_time_up_scheduled_known; percent_time_down_known=(double)(((double)temp_subject->time_down*100.0)/(double)time_determinate); percent_time_down_scheduled_known=(double)(((double)temp_subject->scheduled_time_down*100.0)/(double)time_determinate); percent_time_down_unscheduled_known=percent_time_down_known-percent_time_down_scheduled_known; percent_time_unreachable_known=(double)(((double)temp_subject->time_unreachable*100.0)/(double)time_determinate); percent_time_unreachable_scheduled_known=(double)(((double)temp_subject->scheduled_time_unreachable*100.0)/(double)time_determinate); percent_time_unreachable_unscheduled_known=percent_time_unreachable_known-percent_time_unreachable_scheduled_known; } } printf("
    Host State Breakdowns:
    \n"); #ifdef USE_TRENDS printf("

    \n"); printf("",t1,t2,(include_soft_states==TRUE)?"yes":"no",(assume_state_retention==TRUE)?"yes":"no",(assume_initial_states==TRUE)?"yes":"no",(assume_states_during_notrunning==TRUE)?"yes":"no",initial_assumed_host_state,backtrack_archives); printf("Host State Trends",t1,t2,(include_soft_states==TRUE)?"yes":"no",(assume_state_retention==TRUE)?"yes":"no",(assume_initial_states==TRUE)?"yes":"no",(assume_states_during_notrunning==TRUE)?"yes":"no",initial_assumed_host_state,backtrack_archives); printf("
    \n"); printf("

    \n"); #endif printf("
    \n"); printf("\n"); printf("\n"); /* up times */ printf(""); printf("\n",time_up_unscheduled_string,percent_time_up,percent_time_up_known); printf("\n",time_up_scheduled_string,percent_time_up_scheduled,percent_time_up_scheduled_known); printf("\n",time_up_string,percent_time_up,percent_time_up_known); /* down times */ printf(""); printf("\n",time_down_unscheduled_string,percent_time_down_unscheduled,percent_time_down_known); printf("\n",time_down_scheduled_string,percent_time_down_scheduled,percent_time_down_scheduled_known); printf("\n",time_down_string,percent_time_down,percent_time_down_known); /* unreachable times */ printf(""); printf("\n",time_unreachable_unscheduled_string,percent_time_unreachable,percent_time_unreachable_known); printf("\n",time_unreachable_scheduled_string,percent_time_unreachable_scheduled,percent_time_unreachable_scheduled_known); printf("\n",time_unreachable_string,percent_time_unreachable,percent_time_unreachable_known); /* indeterminate times */ printf(""); printf("\n",time_indeterminate_notrunning_string,percent_time_indeterminate_notrunning); printf("\n",time_indeterminate_nodata_string,percent_time_indeterminate_nodata); printf("\n",time_indeterminate_string,percent_time_indeterminate); printf("\n"); printf("\n",total_time_string); printf("
    StateType / ReasonTime%% Total Time%% Known Time
    UPUnscheduled%s%2.3f%%%2.3f%%
    Scheduled%s%2.3f%%%2.3f%%
    Total%s%2.3f%%%2.3f%%
    DOWNUnscheduled%s%2.3f%%%2.3f%%
    Scheduled%s%2.3f%%%2.3f%%
    Total%s%2.3f%%%2.3f%%
    UNREACHABLEUnscheduled%s%2.3f%%%2.3f%%
    Scheduled%s%2.3f%%%2.3f%%
    Total%s%2.3f%%%2.3f%%
    UndeterminedNagios Not Running%s%2.3f%%
    Insufficient Data%s%2.3f%%
    Total%s%2.3f%%
    AllTotal%s100.000%%100.000%%
    \n"); printf("
    \n"); /* display state breakdowns for all services on this host */ printf("

    \n"); printf("
    State Breakdowns For Host Services:
    \n"); printf("
    \n"); printf("\n"); printf("\n"); for(temp_subject=subject_list;temp_subject!=NULL;temp_subject=temp_subject->next){ if(temp_subject->type!=SERVICE_SUBJECT) continue; temp_service=find_service(temp_subject->host_name,temp_subject->service_description); if(temp_service==NULL) continue; /* the user isn't authorized to view this service */ if(is_authorized_for_service(temp_service,¤t_authdata)==FALSE) continue; current_subject++; if(odd){ odd=0; bgclass="Odd"; } else{ odd=1; bgclass="Even"; } /* reset variables */ percent_time_ok=0.0; percent_time_warning=0.0; percent_time_unknown=0.0; percent_time_critical=0.0; percent_time_indeterminate=0.0; percent_time_ok_known=0.0; percent_time_warning_known=0.0; percent_time_unknown_known=0.0; percent_time_critical_known=0.0; time_determinate=temp_subject->time_ok+temp_subject->time_warning+temp_subject->time_unknown+temp_subject->time_critical; time_indeterminate=total_time-time_determinate; if(total_time>0){ percent_time_ok=(double)(((double)temp_subject->time_ok*100.0)/(double)total_time); percent_time_warning=(double)(((double)temp_subject->time_warning*100.0)/(double)total_time); percent_time_unknown=(double)(((double)temp_subject->time_unknown*100.0)/(double)total_time); percent_time_critical=(double)(((double)temp_subject->time_critical*100.0)/(double)total_time); percent_time_indeterminate=(double)(((double)time_indeterminate*100.0)/(double)total_time); if(time_determinate>0){ percent_time_ok_known=(double)(((double)temp_subject->time_ok*100.0)/(double)time_determinate); percent_time_warning_known=(double)(((double)temp_subject->time_warning*100.0)/(double)time_determinate); percent_time_unknown_known=(double)(((double)temp_subject->time_unknown*100.0)/(double)time_determinate); percent_time_critical_known=(double)(((double)temp_subject->time_critical*100.0)/(double)time_determinate); } } printf("\n",percent_time_ok,percent_time_ok_known,percent_time_warning,percent_time_warning_known,percent_time_unknown,percent_time_unknown_known,percent_time_critical,percent_time_critical_known,bgclass,percent_time_indeterminate); get_running_average(&average_percent_time_ok,percent_time_ok,current_subject); get_running_average(&average_percent_time_ok_known,percent_time_ok_known,current_subject); get_running_average(&average_percent_time_unknown,percent_time_unknown,current_subject); get_running_average(&average_percent_time_unknown_known,percent_time_unknown_known,current_subject); get_running_average(&average_percent_time_warning,percent_time_warning,current_subject); get_running_average(&average_percent_time_warning_known,percent_time_warning_known,current_subject); get_running_average(&average_percent_time_critical,percent_time_critical,current_subject); get_running_average(&average_percent_time_critical_known,percent_time_critical_known,current_subject); get_running_average(&average_percent_time_indeterminate,percent_time_indeterminate,current_subject); } /* display average stats */ if(odd){ odd=0; bgclass="Odd"; } else{ odd=1; bgclass="Even"; } printf("\n",bgclass,bgclass,average_percent_time_ok,average_percent_time_ok_known,average_percent_time_warning,average_percent_time_warning_known,average_percent_time_unknown,average_percent_time_unknown_known,average_percent_time_critical,average_percent_time_critical_known,bgclass,average_percent_time_indeterminate); printf("
    Service%% Time OK%% Time Warning%% Time Unknown%% Time Critical%% Time Undetermined
    ",bgclass,bgclass); service_report_url(temp_subject->host_name,temp_subject->service_description,temp_subject->service_description); printf("%2.3f%% (%2.3f%%)%2.3f%% (%2.3f%%)%2.3f%% (%2.3f%%)%2.3f%% (%2.3f%%)%2.3f%%
    Average%2.3f%% (%2.3f%%)%2.3f%% (%2.3f%%)%2.3f%% (%2.3f%%)%2.3f%% (%2.3f%%)%2.3f%%
    \n"); printf("
    \n"); /* write log entries for the host */ temp_subject=find_subject(HOST_SUBJECT,host_name,NULL); write_log_entries(temp_subject); } /* display data for all hosts */ else{ if(output_format==HTML_OUTPUT){ printf("

    \n"); printf("
    Host State Breakdowns:
    \n"); printf("
    \n"); printf("\n"); printf("\n"); } else if(output_format==CSV_OUTPUT){ printf("HOST_NAME,"); printf(" TIME_UP_SCHEDULED, PERCENT_TIME_UP_SCHEDULED, PERCENT_KNOWN_TIME_UP_SCHEDULED, TIME_UP_UNSCHEDULED, PERCENT_TIME_UP_UNSCHEDULED, PERCENT_KNOWN_TIME_UP_UNSCHEDULED, TOTAL_TIME_UP, PERCENT_TOTAL_TIME_UP, PERCENT_KNOWN_TIME_UP,"); printf(" TIME_DOWN_SCHEDULED, PERCENT_TIME_DOWN_SCHEDULED, PERCENT_KNOWN_TIME_DOWN_SCHEDULED, TIME_DOWN_UNSCHEDULED, PERCENT_TIME_DOWN_UNSCHEDULED, PERCENT_KNOWN_TIME_DOWN_UNSCHEDULED, TOTAL_TIME_DOWN, PERCENT_TOTAL_TIME_DOWN, PERCENT_KNOWN_TIME_DOWN,"); printf(" TIME_UNREACHABLE_SCHEDULED, PERCENT_TIME_UNREACHABLE_SCHEDULED, PERCENT_KNOWN_TIME_UNREACHABLE_SCHEDULED, TIME_UNREACHABLE_UNSCHEDULED, PERCENT_TIME_UNREACHABLE_UNSCHEDULED, PERCENT_KNOWN_TIME_UNREACHABLE_UNSCHEDULED, TOTAL_TIME_UNREACHABLE, PERCENT_TOTAL_TIME_UNREACHABLE, PERCENT_KNOWN_TIME_UNREACHABLE,"); printf(" TIME_UNDETERMINED_NOT_RUNNING, PERCENT_TIME_UNDETERMINED_NOT_RUNNING, TIME_UNDETERMINED_NO_DATA, PERCENT_TIME_UNDETERMINED_NO_DATA, TOTAL_TIME_UNDETERMINED, PERCENT_TOTAL_TIME_UNDETERMINED\n"); } for(temp_subject=subject_list;temp_subject!=NULL;temp_subject=temp_subject->next){ if(temp_subject->type!=HOST_SUBJECT) continue; temp_host=find_host(temp_subject->host_name); if(temp_host==NULL) continue; /* the user isn't authorized to view this host */ if(is_authorized_for_host(temp_host,¤t_authdata)==FALSE) continue; current_subject++; time_determinate=temp_subject->time_up+temp_subject->time_down+temp_subject->time_unreachable; time_indeterminate=total_time-time_determinate; /* adjust indeterminate time due to insufficient data (not all was caught) */ temp_subject->time_indeterminate_nodata=time_indeterminate-temp_subject->time_indeterminate_notrunning; /* initialize values */ percent_time_up=0.0; percent_time_up_scheduled=0.0; percent_time_up_unscheduled=0.0; percent_time_down=0.0; percent_time_down_scheduled=0.0; percent_time_down_unscheduled=0.0; percent_time_unreachable=0.0; percent_time_unreachable_scheduled=0.0; percent_time_unreachable_unscheduled=0.0; percent_time_indeterminate=0.0; percent_time_indeterminate_scheduled=0.0; percent_time_indeterminate_unscheduled=0.0; percent_time_indeterminate_notrunning=0.0; percent_time_indeterminate_nodata=0.0; percent_time_up_known=0.0; percent_time_up_scheduled_known=0.0; percent_time_up_unscheduled_known=0.0; percent_time_down_known=0.0; percent_time_down_scheduled_known=0.0; percent_time_down_unscheduled_known=0.0; percent_time_unreachable_known=0.0; percent_time_unreachable_scheduled_known=0.0; percent_time_unreachable_unscheduled_known=0.0; if(total_time>0){ percent_time_up=(double)(((double)temp_subject->time_up*100.0)/(double)total_time); percent_time_up_scheduled=(double)(((double)temp_subject->scheduled_time_up*100.0)/(double)total_time); percent_time_up_unscheduled=percent_time_up-percent_time_up_scheduled; percent_time_down=(double)(((double)temp_subject->time_down*100.0)/(double)total_time); percent_time_down_scheduled=(double)(((double)temp_subject->scheduled_time_down*100.0)/(double)total_time); percent_time_down_unscheduled=percent_time_down-percent_time_down_scheduled; percent_time_unreachable=(double)(((double)temp_subject->time_unreachable*100.0)/(double)total_time); percent_time_unreachable_scheduled=(double)(((double)temp_subject->scheduled_time_unreachable*100.0)/(double)total_time); percent_time_unreachable_unscheduled=percent_time_unreachable-percent_time_unreachable_scheduled; percent_time_indeterminate=(double)(((double)time_indeterminate*100.0)/(double)total_time); percent_time_indeterminate_scheduled=(double)(((double)temp_subject->scheduled_time_indeterminate*100.0)/(double)total_time); percent_time_indeterminate_unscheduled=percent_time_indeterminate-percent_time_indeterminate_scheduled; percent_time_indeterminate_notrunning=(double)(((double)temp_subject->time_indeterminate_notrunning*100.0)/(double)total_time); percent_time_indeterminate_nodata=(double)(((double)temp_subject->time_indeterminate_nodata*100.0)/(double)total_time); if(time_determinate>0){ percent_time_up_known=(double)(((double)temp_subject->time_up*100.0)/(double)time_determinate); percent_time_up_scheduled_known=(double)(((double)temp_subject->scheduled_time_up*100.0)/(double)time_determinate); percent_time_up_unscheduled_known=percent_time_up_known-percent_time_up_scheduled_known; percent_time_down_known=(double)(((double)temp_subject->time_down*100.0)/(double)time_determinate); percent_time_down_scheduled_known=(double)(((double)temp_subject->scheduled_time_down*100.0)/(double)time_determinate); percent_time_down_unscheduled_known=percent_time_down_known-percent_time_down_scheduled_known; percent_time_unreachable_known=(double)(((double)temp_subject->time_unreachable*100.0)/(double)time_determinate); percent_time_unreachable_scheduled_known=(double)(((double)temp_subject->scheduled_time_unreachable*100.0)/(double)time_determinate); percent_time_unreachable_unscheduled_known=percent_time_unreachable_known-percent_time_unreachable_scheduled_known; } } if(output_format==HTML_OUTPUT){ if(odd){ odd=0; bgclass="Odd"; } else{ odd=1; bgclass="Even"; } printf("\n",percent_time_up,percent_time_up_known,percent_time_down,percent_time_down_known,percent_time_unreachable,percent_time_unreachable_known,bgclass,percent_time_indeterminate); } else if(output_format==CSV_OUTPUT){ /* host name */ printf("\"%s\",",temp_subject->host_name); /* up times */ printf(" %lu, %2.3f%%, %2.3f%%, %lu, %2.3f%%, %2.3f%%, %lu, %2.3f%%, %2.3f%%,",temp_subject->scheduled_time_up,percent_time_up_scheduled,percent_time_up_scheduled_known,temp_subject->time_up-temp_subject->scheduled_time_up,percent_time_up_unscheduled,percent_time_up_unscheduled_known,temp_subject->time_up,percent_time_up,percent_time_up_known); /* down times */ printf(" %lu, %2.3f%%, %2.3f%%, %lu, %2.3f%%, %2.3f%%, %lu, %2.3f%%, %2.3f%%,",temp_subject->scheduled_time_down,percent_time_down_scheduled,percent_time_down_scheduled_known,temp_subject->time_down-temp_subject->scheduled_time_down,percent_time_down_unscheduled,percent_time_down_unscheduled_known,temp_subject->time_down,percent_time_down,percent_time_down_known); /* unreachable times */ printf(" %lu, %2.3f%%, %2.3f%%, %lu, %2.3f%%, %2.3f%%, %lu, %2.3f%%, %2.3f%%,",temp_subject->scheduled_time_unreachable,percent_time_unreachable_scheduled,percent_time_unreachable_scheduled_known,temp_subject->time_unreachable-temp_subject->scheduled_time_unreachable,percent_time_unreachable_unscheduled,percent_time_unreachable_unscheduled_known,temp_subject->time_unreachable,percent_time_unreachable,percent_time_unreachable_known); /* indeterminate times */ printf(" %lu, %2.3f%%, %lu, %2.3f%%, %lu, %2.3f%%\n",temp_subject->time_indeterminate_notrunning,percent_time_indeterminate_notrunning,temp_subject->time_indeterminate_nodata,percent_time_indeterminate_nodata,time_indeterminate,percent_time_indeterminate); } get_running_average(&average_percent_time_up,percent_time_up,current_subject); get_running_average(&average_percent_time_up_known,percent_time_up_known,current_subject); get_running_average(&average_percent_time_down,percent_time_down,current_subject); get_running_average(&average_percent_time_down_known,percent_time_down_known,current_subject); get_running_average(&average_percent_time_unreachable,percent_time_unreachable,current_subject); get_running_average(&average_percent_time_unreachable_known,percent_time_unreachable_known,current_subject); get_running_average(&average_percent_time_indeterminate,percent_time_indeterminate,current_subject); } if(output_format==HTML_OUTPUT){ /* average statistics */ if(odd){ odd=0; bgclass="Odd"; } else{ odd=1; bgclass="Even"; } printf("",bgclass,bgclass,average_percent_time_up,average_percent_time_up_known,average_percent_time_down,average_percent_time_down_known,average_percent_time_unreachable,average_percent_time_unreachable_known,bgclass,average_percent_time_indeterminate); printf("
    Host%% Time Up%% Time Down%% Time Unreachable%% Time Undetermined
    ",bgclass,bgclass); host_report_url(temp_subject->host_name,temp_subject->host_name); printf("%2.3f%% (%2.3f%%)%2.3f%% (%2.3f%%)%2.3f%% (%2.3f%%)%2.3f%%
    Average%2.3f%% (%2.3f%%)%2.3f%% (%2.3f%%)%2.3f%% (%2.3f%%)%2.3f%%
    \n"); printf("
    \n"); } } return; } /* display service availability */ void display_service_availability(void){ unsigned long total_time; unsigned long time_determinate; unsigned long time_indeterminate; avail_subject *temp_subject; service *temp_service; int days, hours, minutes, seconds; char time_ok_string[48]; char time_warning_string[48]; char time_unknown_string[48]; char time_critical_string[48]; char time_indeterminate_string[48]; char time_determinate_string[48]; char total_time_string[48]; double percent_time_ok=0.0; double percent_time_warning=0.0; double percent_time_unknown=0.0; double percent_time_critical=0.0; double percent_time_indeterminate=0.0; double percent_time_ok_known=0.0; double percent_time_warning_known=0.0; double percent_time_unknown_known=0.0; double percent_time_critical_known=0.0; char time_critical_scheduled_string[48]; char time_critical_unscheduled_string[48]; double percent_time_critical_scheduled=0.0; double percent_time_critical_unscheduled=0.0; double percent_time_critical_scheduled_known=0.0; double percent_time_critical_unscheduled_known=0.0; char time_unknown_scheduled_string[48]; char time_unknown_unscheduled_string[48]; double percent_time_unknown_scheduled=0.0; double percent_time_unknown_unscheduled=0.0; double percent_time_unknown_scheduled_known=0.0; double percent_time_unknown_unscheduled_known=0.0; char time_warning_scheduled_string[48]; char time_warning_unscheduled_string[48]; double percent_time_warning_scheduled=0.0; double percent_time_warning_unscheduled=0.0; double percent_time_warning_scheduled_known=0.0; double percent_time_warning_unscheduled_known=0.0; char time_ok_scheduled_string[48]; char time_ok_unscheduled_string[48]; double percent_time_ok_scheduled=0.0; double percent_time_ok_unscheduled=0.0; double percent_time_ok_scheduled_known=0.0; double percent_time_ok_unscheduled_known=0.0; double average_percent_time_ok=0.0; double average_percent_time_ok_known=0.0; double average_percent_time_unknown=0.0; double average_percent_time_unknown_known=0.0; double average_percent_time_warning=0.0; double average_percent_time_warning_known=0.0; double average_percent_time_critical=0.0; double average_percent_time_critical_known=0.0; double average_percent_time_indeterminate=0.0; int current_subject=0; char time_indeterminate_scheduled_string[48]; char time_indeterminate_unscheduled_string[48]; double percent_time_indeterminate_scheduled=0.0; double percent_time_indeterminate_unscheduled=0.0; char time_indeterminate_notrunning_string[48]; char time_indeterminate_nodata_string[48]; double percent_time_indeterminate_notrunning=0.0; double percent_time_indeterminate_nodata=0.0; int odd=1; char *bgclass=""; char last_host[128]=""; /* calculate total time during period based on timeperiod used for reporting */ total_time=calculate_total_time(t1,t2); /* we're only getting data for one service */ if(show_all_services==FALSE){ temp_subject=find_subject(SERVICE_SUBJECT,host_name,svc_description); if(temp_subject==NULL) return; temp_service=find_service(temp_subject->host_name,temp_subject->service_description); if(temp_service==NULL) return; /* the user isn't authorized to view this service */ if(is_authorized_for_service(temp_service,¤t_authdata)==FALSE) return; time_determinate=temp_subject->time_ok+temp_subject->time_warning+temp_subject->time_unknown+temp_subject->time_critical; time_indeterminate=total_time-time_determinate; /* adjust indeterminate time due to insufficient data (not all was caught) */ temp_subject->time_indeterminate_nodata=time_indeterminate-temp_subject->time_indeterminate_notrunning; /* ok states */ get_time_breakdown(temp_subject->time_ok,&days,&hours,&minutes,&seconds); snprintf(time_ok_string,sizeof(time_ok_string)-1,"%dd %dh %dm %ds",days,hours,minutes,seconds); get_time_breakdown(temp_subject->scheduled_time_ok,&days,&hours,&minutes,&seconds); snprintf(time_ok_scheduled_string,sizeof(time_ok_scheduled_string)-1,"%dd %dh %dm %ds",days,hours,minutes,seconds); get_time_breakdown(temp_subject->time_ok-temp_subject->scheduled_time_ok,&days,&hours,&minutes,&seconds); snprintf(time_ok_unscheduled_string,sizeof(time_ok_unscheduled_string)-1,"%dd %dh %dm %ds",days,hours,minutes,seconds); /* warning states */ get_time_breakdown(temp_subject->time_warning,&days,&hours,&minutes,&seconds); snprintf(time_warning_string,sizeof(time_warning_string)-1,"%dd %dh %dm %ds",days,hours,minutes,seconds); get_time_breakdown(temp_subject->scheduled_time_warning,&days,&hours,&minutes,&seconds); snprintf(time_warning_scheduled_string,sizeof(time_warning_scheduled_string)-1,"%dd %dh %dm %ds",days,hours,minutes,seconds); get_time_breakdown(temp_subject->time_warning-temp_subject->scheduled_time_warning,&days,&hours,&minutes,&seconds); snprintf(time_warning_unscheduled_string,sizeof(time_warning_unscheduled_string)-1,"%dd %dh %dm %ds",days,hours,minutes,seconds); /* unknown states */ get_time_breakdown(temp_subject->time_unknown,&days,&hours,&minutes,&seconds); snprintf(time_unknown_string,sizeof(time_unknown_string)-1,"%dd %dh %dm %ds",days,hours,minutes,seconds); get_time_breakdown(temp_subject->scheduled_time_unknown,&days,&hours,&minutes,&seconds); snprintf(time_unknown_scheduled_string,sizeof(time_unknown_scheduled_string)-1,"%dd %dh %dm %ds",days,hours,minutes,seconds); get_time_breakdown(temp_subject->time_unknown-temp_subject->scheduled_time_unknown,&days,&hours,&minutes,&seconds); snprintf(time_unknown_unscheduled_string,sizeof(time_unknown_unscheduled_string)-1,"%dd %dh %dm %ds",days,hours,minutes,seconds); /* critical states */ get_time_breakdown(temp_subject->time_critical,&days,&hours,&minutes,&seconds); snprintf(time_critical_string,sizeof(time_critical_string)-1,"%dd %dh %dm %ds",days,hours,minutes,seconds); get_time_breakdown(temp_subject->scheduled_time_critical,&days,&hours,&minutes,&seconds); snprintf(time_critical_scheduled_string,sizeof(time_critical_scheduled_string)-1,"%dd %dh %dm %ds",days,hours,minutes,seconds); get_time_breakdown(temp_subject->time_critical-temp_subject->scheduled_time_critical,&days,&hours,&minutes,&seconds); snprintf(time_critical_unscheduled_string,sizeof(time_critical_unscheduled_string)-1,"%dd %dh %dm %ds",days,hours,minutes,seconds); /* indeterminate time */ get_time_breakdown(time_indeterminate,&days,&hours,&minutes,&seconds); snprintf(time_indeterminate_string,sizeof(time_indeterminate_string)-1,"%dd %dh %dm %ds",days,hours,minutes,seconds); get_time_breakdown(temp_subject->scheduled_time_indeterminate,&days,&hours,&minutes,&seconds); snprintf(time_indeterminate_scheduled_string,sizeof(time_indeterminate_scheduled_string)-1,"%dd %dh %dm %ds",days,hours,minutes,seconds); get_time_breakdown(time_indeterminate-temp_subject->scheduled_time_indeterminate,&days,&hours,&minutes,&seconds); snprintf(time_indeterminate_unscheduled_string,sizeof(time_indeterminate_unscheduled_string)-1,"%dd %dh %dm %ds",days,hours,minutes,seconds); get_time_breakdown(temp_subject->time_indeterminate_notrunning,&days,&hours,&minutes,&seconds); snprintf(time_indeterminate_notrunning_string,sizeof(time_indeterminate_notrunning_string)-1,"%dd %dh %dm %ds",days,hours,minutes,seconds); get_time_breakdown(temp_subject->time_indeterminate_nodata,&days,&hours,&minutes,&seconds); snprintf(time_indeterminate_nodata_string,sizeof(time_indeterminate_nodata_string)-1,"%dd %dh %dm %ds",days,hours,minutes,seconds); get_time_breakdown(time_determinate,&days,&hours,&minutes,&seconds); snprintf(time_determinate_string,sizeof(time_determinate_string)-1,"%dd %dh %dm %ds",days,hours,minutes,seconds); get_time_breakdown(total_time,&days,&hours,&minutes,&seconds); snprintf(total_time_string,sizeof(total_time_string)-1,"%dd %dh %dm %ds",days,hours,minutes,seconds); if(total_time>0){ percent_time_ok=(double)(((double)temp_subject->time_ok*100.0)/(double)total_time); percent_time_ok_scheduled=(double)(((double)temp_subject->scheduled_time_ok*100.0)/(double)total_time); percent_time_ok_unscheduled=percent_time_ok-percent_time_ok_scheduled; percent_time_warning=(double)(((double)temp_subject->time_warning*100.0)/(double)total_time); percent_time_warning_scheduled=(double)(((double)temp_subject->scheduled_time_unknown*100.0)/(double)total_time); percent_time_warning_unscheduled=percent_time_warning-percent_time_warning_scheduled; percent_time_unknown=(double)(((double)temp_subject->time_unknown*100.0)/(double)total_time); percent_time_unknown_scheduled=(double)(((double)temp_subject->scheduled_time_unknown*100.0)/(double)total_time); percent_time_unknown_unscheduled=percent_time_unknown-percent_time_unknown_scheduled; percent_time_critical=(double)(((double)temp_subject->time_critical*100.0)/(double)total_time); percent_time_critical_scheduled=(double)(((double)temp_subject->scheduled_time_critical*100.0)/(double)total_time); percent_time_critical_unscheduled=percent_time_critical-percent_time_critical_scheduled; percent_time_indeterminate=(double)(((double)time_indeterminate*100.0)/(double)total_time); percent_time_indeterminate_scheduled=(double)(((double)temp_subject->scheduled_time_indeterminate*100.0)/(double)total_time); percent_time_indeterminate_unscheduled=percent_time_indeterminate-percent_time_indeterminate_scheduled; percent_time_indeterminate_notrunning=(double)(((double)temp_subject->time_indeterminate_notrunning*100.0)/(double)total_time); percent_time_indeterminate_nodata=(double)(((double)temp_subject->time_indeterminate_nodata*100.0)/(double)total_time); if(time_determinate>0){ percent_time_ok_known=(double)(((double)temp_subject->time_ok*100.0)/(double)time_determinate); percent_time_ok_scheduled_known=(double)(((double)temp_subject->scheduled_time_ok*100.0)/(double)time_determinate); percent_time_ok_unscheduled_known=percent_time_ok_known-percent_time_ok_scheduled_known; percent_time_warning_known=(double)(((double)temp_subject->time_warning*100.0)/(double)time_determinate); percent_time_warning_scheduled_known=(double)(((double)temp_subject->scheduled_time_warning*100.0)/(double)time_determinate); percent_time_warning_unscheduled_known=percent_time_warning_known-percent_time_warning_scheduled_known; percent_time_unknown_known=(double)(((double)temp_subject->time_unknown*100.0)/(double)time_determinate); percent_time_unknown_scheduled_known=(double)(((double)temp_subject->scheduled_time_unknown*100.0)/(double)time_determinate); percent_time_unknown_unscheduled_known=percent_time_unknown_known-percent_time_unknown_scheduled_known; percent_time_critical_known=(double)(((double)temp_subject->time_critical*100.0)/(double)time_determinate); percent_time_critical_scheduled_known=(double)(((double)temp_subject->scheduled_time_critical*100.0)/(double)time_determinate); percent_time_critical_unscheduled_known=percent_time_critical_known-percent_time_critical_scheduled_known; } } printf("
    Service State Breakdowns:
    \n"); #ifdef USE_TRENDS printf("

    \n"); printf("",url_encode(svc_description),t1,t2,(include_soft_states==TRUE)?"yes":"no",(assume_state_retention==TRUE)?"yes":"no",(assume_initial_states==TRUE)?"yes":"no",(assume_states_during_notrunning==TRUE)?"yes":"no",initial_assumed_service_state,backtrack_archives); printf("Service State Trends",url_encode(svc_description),t1,t2,(include_soft_states==TRUE)?"yes":"no",(assume_state_retention==TRUE)?"yes":"no",(assume_initial_states==TRUE)?"yes":"no",(assume_states_during_notrunning==TRUE)?"yes":"no",initial_assumed_service_state,backtrack_archives); printf("
    \n"); printf("

    \n"); #endif printf("
    \n"); printf("\n"); printf("\n"); /* ok states */ printf(""); printf("\n",time_ok_unscheduled_string,percent_time_ok_unscheduled,percent_time_ok_unscheduled_known); printf("\n",time_ok_scheduled_string,percent_time_ok_scheduled,percent_time_ok_scheduled_known); printf("\n",time_ok_string,percent_time_ok,percent_time_ok_known); /* warning states */ printf(""); printf("\n",time_warning_unscheduled_string,percent_time_warning_unscheduled,percent_time_warning_unscheduled_known); printf("\n",time_warning_scheduled_string,percent_time_warning_scheduled,percent_time_warning_scheduled_known); printf("\n",time_warning_string,percent_time_warning,percent_time_warning_known); /* unknown states */ printf(""); printf("\n",time_unknown_unscheduled_string,percent_time_unknown_unscheduled,percent_time_unknown_unscheduled_known); printf("\n",time_unknown_scheduled_string,percent_time_unknown_scheduled,percent_time_unknown_scheduled_known); printf("\n",time_unknown_string,percent_time_unknown,percent_time_unknown_known); /* critical states */ printf(""); printf("\n",time_critical_unscheduled_string,percent_time_critical_unscheduled,percent_time_critical_unscheduled_known); printf("\n",time_critical_scheduled_string,percent_time_critical_scheduled,percent_time_critical_scheduled_known); printf("\n",time_critical_string,percent_time_critical,percent_time_critical_known); printf(""); /* printf("\n",time_indeterminate_unscheduled_string,percent_time_indeterminate_unscheduled); printf("\n",time_indeterminate_scheduled_string,percent_time_indeterminate_scheduled); */ printf("\n",time_indeterminate_notrunning_string,percent_time_indeterminate_notrunning); printf("\n",time_indeterminate_nodata_string,percent_time_indeterminate_nodata); printf("\n",time_indeterminate_string,percent_time_indeterminate); printf("\n"); printf("\n",total_time_string); printf("
    StateType / ReasonTime%% Total Time%% Known Time
    OKUnscheduled%s%2.3f%%%2.3f%%
    Scheduled%s%2.3f%%%2.3f%%
    Total%s%2.3f%%%2.3f%%
    WARNINGUnscheduled%s%2.3f%%%2.3f%%
    Scheduled%s%2.3f%%%2.3f%%
    Total%s%2.3f%%%2.3f%%
    UNKNOWNUnscheduled%s%2.3f%%%2.3f%%
    Scheduled%s%2.3f%%%2.3f%%
    Total%s%2.3f%%%2.3f%%
    CRITICALUnscheduled%s%2.3f%%%2.3f%%
    Scheduled%s%2.3f%%%2.3f%%
    Total%s%2.3f%%%2.3f%%
    UndeterminedUnscheduled%s%2.3f%%
    Scheduled%s%2.3f%%
    Nagios Not Running%s%2.3f%%
    Insufficient Data%s%2.3f%%
    Total%s%2.3f%%
    AllTotal%s100.000%%100.000%%
    \n"); printf("
    \n"); write_log_entries(temp_subject); } /* display data for all services */ else{ if(output_format==HTML_OUTPUT){ printf("
    Service State Breakdowns:
    \n"); printf("
    \n"); printf("\n"); printf("\n"); } else if(output_format==CSV_OUTPUT){ printf("HOST_NAME, SERVICE_DESCRIPTION,"); printf(" TIME_OK_SCHEDULED, PERCENT_TIME_OK_SCHEDULED, PERCENT_KNOWN_TIME_OK_SCHEDULED, TIME_OK_UNSCHEDULED, PERCENT_TIME_OK_UNSCHEDULED, PERCENT_KNOWN_TIME_OK_UNSCHEDULED, TOTAL_TIME_OK, PERCENT_TOTAL_TIME_OK, PERCENT_KNOWN_TIME_OK,"); printf(" TIME_WARNING_SCHEDULED, PERCENT_TIME_WARNING_SCHEDULED, PERCENT_KNOWN_TIME_WARNING_SCHEDULED, TIME_WARNING_UNSCHEDULED, PERCENT_TIME_WARNING_UNSCHEDULED, PERCENT_KNOWN_TIME_WARNING_UNSCHEDULED, TOTAL_TIME_WARNING, PERCENT_TOTAL_TIME_WARNING, PERCENT_KNOWN_TIME_WARNING,"); printf(" TIME_UNKNOWN_SCHEDULED, PERCENT_TIME_UNKNOWN_SCHEDULED, PERCENT_KNOWN_TIME_UNKNOWN_SCHEDULED, TIME_UNKNOWN_UNSCHEDULED, PERCENT_TIME_UNKNOWN_UNSCHEDULED, PERCENT_KNOWN_TIME_UNKNOWN_UNSCHEDULED, TOTAL_TIME_UNKNOWN, PERCENT_TOTAL_TIME_UNKNOWN, PERCENT_KNOWN_TIME_UNKNOWN,"); printf(" TIME_CRITICAL_SCHEDULED, PERCENT_TIME_CRITICAL_SCHEDULED, PERCENT_KNOWN_TIME_CRITICAL_SCHEDULED, TIME_CRITICAL_UNSCHEDULED, PERCENT_TIME_CRITICAL_UNSCHEDULED, PERCENT_KNOWN_TIME_CRITICAL_UNSCHEDULED, TOTAL_TIME_CRITICAL, PERCENT_TOTAL_TIME_CRITICAL, PERCENT_KNOWN_TIME_CRITICAL,"); printf(" TIME_UNDETERMINED_NOT_RUNNING, PERCENT_TIME_UNDETERMINED_NOT_RUNNING, TIME_UNDETERMINED_NO_DATA, PERCENT_TIME_UNDETERMINED_NO_DATA, TOTAL_TIME_UNDETERMINED, PERCENT_TOTAL_TIME_UNDETERMINED\n"); } for(temp_subject=subject_list;temp_subject!=NULL;temp_subject=temp_subject->next){ if(temp_subject->type!=SERVICE_SUBJECT) continue; temp_service=find_service(temp_subject->host_name,temp_subject->service_description); if(temp_service==NULL) continue; /* the user isn't authorized to view this service */ if(is_authorized_for_service(temp_service,¤t_authdata)==FALSE) continue; current_subject++; time_determinate=temp_subject->time_ok+temp_subject->time_warning+temp_subject->time_unknown+temp_subject->time_critical; time_indeterminate=total_time-time_determinate; /* adjust indeterminate time due to insufficient data (not all was caught) */ temp_subject->time_indeterminate_nodata=time_indeterminate-temp_subject->time_indeterminate_notrunning; /* initialize values */ percent_time_ok=0.0; percent_time_ok_scheduled=0.0; percent_time_ok_unscheduled=0.0; percent_time_warning=0.0; percent_time_warning_scheduled=0.0; percent_time_warning_unscheduled=0.0; percent_time_unknown=0.0; percent_time_unknown_scheduled=0.0; percent_time_unknown_unscheduled=0.0; percent_time_critical=0.0; percent_time_critical_scheduled=0.0; percent_time_critical_unscheduled=0.0; percent_time_indeterminate=0.0; percent_time_indeterminate_scheduled=0.0; percent_time_indeterminate_unscheduled=0.0; percent_time_indeterminate_notrunning=0.0; percent_time_indeterminate_nodata=0.0; percent_time_ok_known=0.0; percent_time_ok_scheduled_known=0.0; percent_time_ok_unscheduled_known=0.0; percent_time_warning_known=0.0; percent_time_warning_scheduled_known=0.0; percent_time_warning_unscheduled_known=0.0; percent_time_unknown_known=0.0; percent_time_unknown_scheduled_known=0.0; percent_time_unknown_unscheduled_known=0.0; percent_time_critical_known=0.0; percent_time_critical_scheduled_known=0.0; percent_time_critical_unscheduled_known=0.0; if(total_time>0){ percent_time_ok=(double)(((double)temp_subject->time_ok*100.0)/(double)total_time); percent_time_ok_scheduled=(double)(((double)temp_subject->scheduled_time_ok*100.0)/(double)total_time); percent_time_ok_unscheduled=percent_time_ok-percent_time_ok_scheduled; percent_time_warning=(double)(((double)temp_subject->time_warning*100.0)/(double)total_time); percent_time_warning_scheduled=(double)(((double)temp_subject->scheduled_time_unknown*100.0)/(double)total_time); percent_time_warning_unscheduled=percent_time_warning-percent_time_warning_scheduled; percent_time_unknown=(double)(((double)temp_subject->time_unknown*100.0)/(double)total_time); percent_time_unknown_scheduled=(double)(((double)temp_subject->scheduled_time_unknown*100.0)/(double)total_time); percent_time_unknown_unscheduled=percent_time_unknown-percent_time_unknown_scheduled; percent_time_critical=(double)(((double)temp_subject->time_critical*100.0)/(double)total_time); percent_time_critical_scheduled=(double)(((double)temp_subject->scheduled_time_critical*100.0)/(double)total_time); percent_time_critical_unscheduled=percent_time_critical-percent_time_critical_scheduled; percent_time_indeterminate=(double)(((double)time_indeterminate*100.0)/(double)total_time); percent_time_indeterminate_scheduled=(double)(((double)temp_subject->scheduled_time_indeterminate*100.0)/(double)total_time); percent_time_indeterminate_unscheduled=percent_time_indeterminate-percent_time_indeterminate_scheduled; percent_time_indeterminate_notrunning=(double)(((double)temp_subject->time_indeterminate_notrunning*100.0)/(double)total_time); percent_time_indeterminate_nodata=(double)(((double)temp_subject->time_indeterminate_nodata*100.0)/(double)total_time); if(time_determinate>0){ percent_time_ok_known=(double)(((double)temp_subject->time_ok*100.0)/(double)time_determinate); percent_time_ok_scheduled_known=(double)(((double)temp_subject->scheduled_time_ok*100.0)/(double)time_determinate); percent_time_ok_unscheduled_known=percent_time_ok_known-percent_time_ok_scheduled_known; percent_time_warning_known=(double)(((double)temp_subject->time_warning*100.0)/(double)time_determinate); percent_time_warning_scheduled_known=(double)(((double)temp_subject->scheduled_time_warning*100.0)/(double)time_determinate); percent_time_warning_unscheduled_known=percent_time_warning_known-percent_time_warning_scheduled_known; percent_time_unknown_known=(double)(((double)temp_subject->time_unknown*100.0)/(double)time_determinate); percent_time_unknown_scheduled_known=(double)(((double)temp_subject->scheduled_time_unknown*100.0)/(double)time_determinate); percent_time_unknown_unscheduled_known=percent_time_unknown_known-percent_time_unknown_scheduled_known; percent_time_critical_known=(double)(((double)temp_subject->time_critical*100.0)/(double)time_determinate); percent_time_critical_scheduled_known=(double)(((double)temp_subject->scheduled_time_critical*100.0)/(double)time_determinate); percent_time_critical_unscheduled_known=percent_time_critical_known-percent_time_critical_scheduled_known; } } if(output_format==HTML_OUTPUT){ if(odd){ odd=0; bgclass="Odd"; } else{ odd=1; bgclass="Even"; } printf("\n",percent_time_ok,percent_time_ok_known,percent_time_warning,percent_time_warning_known,percent_time_unknown,percent_time_unknown_known,percent_time_critical,percent_time_critical_known,bgclass,percent_time_indeterminate); } else if(output_format==CSV_OUTPUT){ /* host name and service description */ printf("\"%s\", \"%s\",",temp_subject->host_name,temp_subject->service_description); /* ok times */ printf(" %lu, %2.3f%%, %2.3f%%, %lu, %2.3f%%, %2.3f%%, %lu, %2.3f%%, %2.3f%%,",temp_subject->scheduled_time_ok,percent_time_ok_scheduled,percent_time_ok_scheduled_known,temp_subject->time_ok-temp_subject->scheduled_time_ok,percent_time_ok_unscheduled,percent_time_ok_unscheduled_known,temp_subject->time_ok,percent_time_ok,percent_time_ok_known); /* warning times */ printf(" %lu, %2.3f%%, %2.3f%%, %lu, %2.3f%%, %2.3f%%, %lu, %2.3f%%, %2.3f%%,",temp_subject->scheduled_time_warning,percent_time_warning_scheduled,percent_time_warning_scheduled_known,temp_subject->time_warning-temp_subject->scheduled_time_warning,percent_time_warning_unscheduled,percent_time_warning_unscheduled_known,temp_subject->time_warning,percent_time_warning,percent_time_warning_known); /* unknown times */ printf(" %lu, %2.3f%%, %2.3f%%, %lu, %2.3f%%, %2.3f%%, %lu, %2.3f%%, %2.3f%%,",temp_subject->scheduled_time_unknown,percent_time_unknown_scheduled,percent_time_unknown_scheduled_known,temp_subject->time_unknown-temp_subject->scheduled_time_unknown,percent_time_unknown_unscheduled,percent_time_unknown_unscheduled_known,temp_subject->time_unknown,percent_time_unknown,percent_time_unknown_known); /* critical times */ printf(" %lu, %2.3f%%, %2.3f%%, %lu, %2.3f%%, %2.3f%%, %lu, %2.3f%%, %2.3f%%,",temp_subject->scheduled_time_critical,percent_time_critical_scheduled,percent_time_critical_scheduled_known,temp_subject->time_critical-temp_subject->scheduled_time_critical,percent_time_critical_unscheduled,percent_time_critical_unscheduled_known,temp_subject->time_critical,percent_time_critical,percent_time_critical_known); /* indeterminate times */ printf(" %lu, %2.3f%%, %lu, %2.3f%%, %lu, %2.3f%%\n",temp_subject->time_indeterminate_notrunning,percent_time_indeterminate_notrunning,temp_subject->time_indeterminate_nodata,percent_time_indeterminate_nodata,time_indeterminate,percent_time_indeterminate); } strncpy(last_host,temp_subject->host_name,sizeof(last_host)-1); last_host[sizeof(last_host)-1]='\x0'; get_running_average(&average_percent_time_ok,percent_time_ok,current_subject); get_running_average(&average_percent_time_ok_known,percent_time_ok_known,current_subject); get_running_average(&average_percent_time_unknown,percent_time_unknown,current_subject); get_running_average(&average_percent_time_unknown_known,percent_time_unknown_known,current_subject); get_running_average(&average_percent_time_warning,percent_time_warning,current_subject); get_running_average(&average_percent_time_warning_known,percent_time_warning_known,current_subject); get_running_average(&average_percent_time_critical,percent_time_critical,current_subject); get_running_average(&average_percent_time_critical_known,percent_time_critical_known,current_subject); get_running_average(&average_percent_time_indeterminate,percent_time_indeterminate,current_subject); } if(output_format==HTML_OUTPUT){ /* average statistics */ if(odd){ odd=0; bgclass="Odd"; } else{ odd=1; bgclass="Even"; } printf("\n",bgclass,bgclass,average_percent_time_ok,average_percent_time_ok_known,average_percent_time_warning,average_percent_time_warning_known,average_percent_time_unknown,average_percent_time_unknown_known,average_percent_time_critical,average_percent_time_critical_known,bgclass,average_percent_time_indeterminate); printf("
    HostService%% Time OK%% Time Warning%% Time Unknown%% Time Critical%% Time Undetermined
    ",bgclass,bgclass); if(strcmp(temp_subject->host_name,last_host)) host_report_url(temp_subject->host_name,temp_subject->host_name); printf("",bgclass); service_report_url(temp_subject->host_name,temp_subject->service_description,temp_subject->service_description); printf("%2.3f%% (%2.3f%%)%2.3f%% (%2.3f%%)%2.3f%% (%2.3f%%)%2.3f%% (%2.3f%%)%2.3f%%
    Average%2.3f%% (%2.3f%%)%2.3f%% (%2.3f%%)%2.3f%% (%2.3f%%)%2.3f%% (%2.3f%%)%2.3f%%
    \n"); printf("
    \n"); } } return; } void host_report_url(char *hn, char *label){ printf("%s",label); return; } void service_report_url(char *hn, char *sd, char *label){ printf("%s",label); return; } /* calculates running average */ void get_running_average(double *running_average, double new_value, int current_item){ *running_average=(((*running_average*((double)current_item-1.0))+new_value)/(double)current_item); return; } /* used in reports where a timeperiod is selected */ unsigned long calculate_total_time(time_t start_time, time_t end_time){ struct tm *t; unsigned long midnight_today; int weekday; unsigned long total_time; timerange *temp_timerange; unsigned long temp_duration; unsigned long temp_end; unsigned long temp_start; unsigned long start; unsigned long end; /* attempt to handle the current time_period */ if(current_timeperiod!=NULL){ /* "A day" is 86400 seconds */ t=localtime(&start_time); /* calculate the start of the day (midnight, 00:00 hours) */ t->tm_sec=0; t->tm_min=0; t->tm_hour=0; midnight_today=(unsigned long)mktime(t); weekday=t->tm_wday; total_time=0; while(midnight_todaymidnight_today) temp_start=t1-midnight_today; /* check all time ranges for this day of the week */ for(temp_timerange=current_timeperiod->days[weekday];temp_timerange!=NULL;temp_timerange=temp_timerange->next){ start=max(temp_timerange->range_start,temp_start); end=min(temp_timerange->range_end,temp_end); #ifdef DEBUG printf("
  • Matching in timerange[%d]: %d -> %d (%ld -> %ld) %d -> %d = %ld
    \n",weekday,temp_timerange->range_start,temp_timerange->range_end,temp_start,temp_end,start,end,end-start); #endif if(end>start) temp_duration += end-start; } total_time+=temp_duration; temp_start=0; midnight_today+=86400; if(++weekday>6) weekday=0; } return total_time; } /* no timeperiod was selected */ return end_time-start_time; } nagios-2.6/cgi/cgiauth.c0000664000076500007650000003462310336571237014550 0ustar nagiosnagios/***************************************************************************** * * CGIAUTH.C - Authorization utilities for Nagios CGIs * * Copyright (c) 1999-2005 Ethan Galstad (nagios@nagios.org) * Last Modified: 03-23-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. * *****************************************************************************/ #include "../include/common.h" #include "../include/config.h" #include "../include/objects.h" #include "../include/cgiutils.h" #include "../include/cgiauth.h" extern char main_config_file[MAX_FILENAME_LENGTH]; extern hostgroup *hostgroup_list; extern servicegroup *servicegroup_list; extern int use_authentication; extern int hosts_have_been_read; extern int hostgroups_have_been_read; extern int contactgroups_have_been_read; extern int contacts_have_been_read; extern int services_have_been_read; extern int serviceescalations_have_been_read; extern int hostescalations_have_been_read; /* get current authentication information */ int get_authentication_information(authdata *authinfo){ mmapfile *thefile; char *input=NULL; char *temp_ptr; int needed_options; if(authinfo==NULL) return ERROR; /* make sure we have read in all the configuration information we need for the authentication routines... */ needed_options=0; if(hosts_have_been_read==FALSE) needed_options|=READ_HOSTS; if(hostgroups_have_been_read==FALSE) needed_options|=READ_HOSTGROUPS; if(contactgroups_have_been_read==FALSE) needed_options|=READ_CONTACTGROUPS; if(contacts_have_been_read==FALSE) needed_options|=READ_CONTACTS; if(services_have_been_read==FALSE) needed_options|=READ_SERVICES; if(serviceescalations_have_been_read==FALSE) needed_options|=READ_SERVICEESCALATIONS; if(hostescalations_have_been_read==FALSE) needed_options|=READ_HOSTESCALATIONS; if(needed_options>0) read_all_object_configuration_data(main_config_file,needed_options); /* initial values... */ authinfo->authorized_for_all_hosts=FALSE; authinfo->authorized_for_all_host_commands=FALSE; authinfo->authorized_for_all_services=FALSE; authinfo->authorized_for_all_service_commands=FALSE; authinfo->authorized_for_system_information=FALSE; authinfo->authorized_for_system_commands=FALSE; authinfo->authorized_for_configuration_information=FALSE; /* grab username from the environment... */ temp_ptr=getenv("REMOTE_USER"); if(temp_ptr==NULL){ authinfo->username=""; authinfo->authenticated=FALSE; } else{ authinfo->username=(char *)malloc(strlen(temp_ptr)+1); if(authinfo->username==NULL) authinfo->username=""; else strcpy(authinfo->username,temp_ptr); if(!strcmp(authinfo->username,"")) authinfo->authenticated=FALSE; else authinfo->authenticated=TRUE; } /* read in authorization override vars from config file... */ if((thefile=mmap_fopen(get_cgi_config_location()))!=NULL){ while(1){ /* free memory */ free(input); /* read the next line */ if((input=mmap_fgets(thefile))==NULL) break; strip(input); /* we don't have a username yet, so fake the authentication if we find a default username defined */ if(!strcmp(authinfo->username,"") && strstr(input,"default_user_name=")==input){ temp_ptr=strtok(input,"="); temp_ptr=strtok(NULL,","); authinfo->username=(char *)malloc(strlen(temp_ptr)+1); if(authinfo->username==NULL) authinfo->username=""; else strcpy(authinfo->username,temp_ptr); if(!strcmp(authinfo->username,"")) authinfo->authenticated=FALSE; else authinfo->authenticated=TRUE; } else if(strstr(input,"authorized_for_all_hosts=")==input){ temp_ptr=strtok(input,"="); while((temp_ptr=strtok(NULL,","))){ if(!strcmp(temp_ptr,authinfo->username) || !strcmp(temp_ptr,"*")) authinfo->authorized_for_all_hosts=TRUE; } } else if(strstr(input,"authorized_for_all_services=")==input){ temp_ptr=strtok(input,"="); while((temp_ptr=strtok(NULL,","))){ if(!strcmp(temp_ptr,authinfo->username) || !strcmp(temp_ptr,"*")) authinfo->authorized_for_all_services=TRUE; } } else if(strstr(input,"authorized_for_system_information=")==input){ temp_ptr=strtok(input,"="); while((temp_ptr=strtok(NULL,","))){ if(!strcmp(temp_ptr,authinfo->username) || !strcmp(temp_ptr,"*")) authinfo->authorized_for_system_information=TRUE; } } else if(strstr(input,"authorized_for_configuration_information=")==input){ temp_ptr=strtok(input,"="); while((temp_ptr=strtok(NULL,","))){ if(!strcmp(temp_ptr,authinfo->username) || !strcmp(temp_ptr,"*")) authinfo->authorized_for_configuration_information=TRUE; } } else if(strstr(input,"authorized_for_all_host_commands=")==input){ temp_ptr=strtok(input,"="); while((temp_ptr=strtok(NULL,","))){ if(!strcmp(temp_ptr,authinfo->username) || !strcmp(temp_ptr,"*")) authinfo->authorized_for_all_host_commands=TRUE; } } else if(strstr(input,"authorized_for_all_service_commands=")==input){ temp_ptr=strtok(input,"="); while((temp_ptr=strtok(NULL,","))){ if(!strcmp(temp_ptr,authinfo->username) || !strcmp(temp_ptr,"*")) authinfo->authorized_for_all_service_commands=TRUE; } } else if(strstr(input,"authorized_for_system_commands=")==input){ temp_ptr=strtok(input,"="); while((temp_ptr=strtok(NULL,","))){ if(!strcmp(temp_ptr,authinfo->username) || !strcmp(temp_ptr,"*")) authinfo->authorized_for_system_commands=TRUE; } } } /* free memory and close the file */ free(input); mmap_fclose(thefile); } if(authinfo->authenticated==TRUE) return OK; else return ERROR; } /* check if user is authorized to view information about a particular host */ int is_authorized_for_host(host *hst, authdata *authinfo){ contact *temp_contact; if(hst==NULL) return FALSE; /* if we're not using authentication, fake it */ if(use_authentication==FALSE) return TRUE; /* if this user has not authenticated return error */ if(authinfo->authenticated==FALSE) return FALSE; /* if this user is authorized for all hosts, they are for this one... */ if(is_authorized_for_all_hosts(authinfo)==TRUE) return TRUE; /* find the contact */ temp_contact=find_contact(authinfo->username); /* see if this user is a contact for the host */ if(is_contact_for_host(hst,temp_contact)==TRUE) return TRUE; /* see if this user is an escalated contact for the host */ if(is_escalated_contact_for_host(hst,temp_contact)==TRUE) return TRUE; return FALSE; } /* check if user is authorized to view information about all hosts in a particular hostgroup */ int is_authorized_for_hostgroup(hostgroup *hg, authdata *authinfo){ hostgroupmember *temp_hostgroupmember; host *temp_host; if(hg==NULL) return FALSE; /* CHANGED in 2.0 - user must be authorized for ALL hosts in a hostgroup, not just one */ /* see if user is authorized for all hosts in the hostgroup */ for(temp_hostgroupmember=hg->members;temp_hostgroupmember!=NULL;temp_hostgroupmember=temp_hostgroupmember->next){ temp_host=find_host(temp_hostgroupmember->host_name); if(is_authorized_for_host(temp_host,authinfo)==FALSE) return FALSE; } return TRUE; } /* check if user is authorized to view information about all services in a particular servicegroup */ int is_authorized_for_servicegroup(servicegroup *sg, authdata *authinfo){ servicegroupmember *temp_servicegroupmember; service *temp_service; if(sg==NULL) return FALSE; /* see if user is authorized for all services in the servicegroup */ for(temp_servicegroupmember=sg->members;temp_servicegroupmember!=NULL;temp_servicegroupmember=temp_servicegroupmember->next){ temp_service=find_service(temp_servicegroupmember->host_name,temp_servicegroupmember->service_description); if(is_authorized_for_service(temp_service,authinfo)==FALSE) return FALSE; } return TRUE; } /* check if user is authorized to view information about a particular service */ int is_authorized_for_service(service *svc, authdata *authinfo){ host *temp_host; contact *temp_contact; if(svc==NULL) return FALSE; /* if we're not using authentication, fake it */ if(use_authentication==FALSE) return TRUE; /* if this user has not authenticated return error */ if(authinfo->authenticated==FALSE) return FALSE; /* if this user is authorized for all services, they are for this one... */ if(is_authorized_for_all_services(authinfo)==TRUE) return TRUE; /* find the host */ temp_host=find_host(svc->host_name); if(temp_host==NULL) return FALSE; /* if this user is authorized for this host, they are for all services on it as well... */ if(is_authorized_for_host(temp_host,authinfo)==TRUE) return TRUE; /* find the contact */ temp_contact=find_contact(authinfo->username); /* see if this user is a contact for the service */ if(is_contact_for_service(svc,temp_contact)==TRUE) return TRUE; /* see if this user is an escalated contact for the service */ if(is_escalated_contact_for_service(svc,temp_contact)==TRUE) return TRUE; return FALSE; } /* check if current user is authorized to view information on all hosts */ int is_authorized_for_all_hosts(authdata *authinfo){ /* if we're not using authentication, fake it */ if(use_authentication==FALSE) return TRUE; /* if this user has not authenticated return error */ if(authinfo->authenticated==FALSE) return FALSE; return authinfo->authorized_for_all_hosts; } /* check if current user is authorized to view information on all service */ int is_authorized_for_all_services(authdata *authinfo){ /* if we're not using authentication, fake it */ if(use_authentication==FALSE) return TRUE; /* if this user has not authenticated return error */ if(authinfo->authenticated==FALSE) return FALSE; return authinfo->authorized_for_all_services; } /* check if current user is authorized to view system information */ int is_authorized_for_system_information(authdata *authinfo){ /* if we're not using authentication, fake it */ if(use_authentication==FALSE) return TRUE; /* if this user has not authenticated return error */ if(authinfo->authenticated==FALSE) return FALSE; return authinfo->authorized_for_system_information; } /* check if current user is authorized to view configuration information */ int is_authorized_for_configuration_information(authdata *authinfo){ /* if we're not using authentication, fake it */ if(use_authentication==FALSE) return TRUE; /* if this user has not authenticated return error */ if(authinfo->authenticated==FALSE) return FALSE; return authinfo->authorized_for_configuration_information; } /* check if current user is authorized to issue system commands */ int is_authorized_for_system_commands(authdata *authinfo){ /* if we're not using authentication, fake it */ if(use_authentication==FALSE) return TRUE; /* if this user has not authenticated return error */ if(authinfo->authenticated==FALSE) return FALSE; return authinfo->authorized_for_system_commands; } /* check is the current user is authorized to issue commands relating to a particular service */ int is_authorized_for_service_commands(service *svc, authdata *authinfo){ host *temp_host; contact *temp_contact; if(svc==NULL) return FALSE; /* if we're not using authentication, fake it */ if(use_authentication==FALSE) return TRUE; /* if this user has not authenticated return error */ if(authinfo->authenticated==FALSE) return FALSE; /* the user is authorized if they have rights to the service */ if(is_authorized_for_service(svc,authinfo)==TRUE){ /* find the host */ temp_host=find_host(svc->host_name); if(temp_host==NULL) return FALSE; /* find the contact */ temp_contact=find_contact(authinfo->username); /* see if this user is a contact for the host */ if(is_contact_for_host(temp_host,temp_contact)==TRUE) return TRUE; /* see if this user is an escalated contact for the host */ if(is_escalated_contact_for_host(temp_host,temp_contact)==TRUE) return TRUE; /* this user is a contact for the service, so they have permission... */ if(is_contact_for_service(svc,temp_contact)==TRUE) return TRUE; /* this user is an escalated contact for the service, so they have permission... */ if(is_escalated_contact_for_service(svc,temp_contact)==TRUE) return TRUE; /* this user is not a contact for the host, so they must have been given explicit permissions to all service commands */ if(authinfo->authorized_for_all_service_commands==TRUE) return TRUE; } return FALSE; } /* check is the current user is authorized to issue commands relating to a particular host */ int is_authorized_for_host_commands(host *hst, authdata *authinfo){ contact *temp_contact; if(hst==NULL) return FALSE; /* if we're not using authentication, fake it */ if(use_authentication==FALSE) return TRUE; /* if this user has not authenticated return error */ if(authinfo->authenticated==FALSE) return FALSE; /* the user is authorized if they have rights to the host */ if(is_authorized_for_host(hst,authinfo)==TRUE){ /* find the contact */ temp_contact=find_contact(authinfo->username); /* this user is a contact for the host, so they have permission... */ if(is_contact_for_host(hst,temp_contact)==TRUE) return TRUE; /* this user is an escalated contact for the host, so they have permission... */ if(is_escalated_contact_for_host(hst,temp_contact)==TRUE) return TRUE; /* this user is not a contact for the host, so they must have been given explicit permissions to all host commands */ if(authinfo->authorized_for_all_host_commands==TRUE) return TRUE; } return FALSE; } nagios-2.6/cgi/cgiutils.c0000664000076500007650000016172410526136042014742 0ustar nagiosnagios/*********************************************************************** * * CGIUTILS.C - Common utilities for Nagios CGIs * * Copyright (c) 1999-2006 Ethan Galstad (nagios@nagios.org) * Last Modified: 11-12-2006 * * 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. ***********************************************************************/ #include "../include/config.h" #include "../include/common.h" #include "../include/locations.h" #include "../include/objects.h" #include "../include/statusdata.h" #include "../include/cgiutils.h" char main_config_file[MAX_FILENAME_LENGTH]; char log_file[MAX_FILENAME_LENGTH]; char log_archive_path[MAX_FILENAME_LENGTH]; char command_file[MAX_FILENAME_LENGTH]; char physical_html_path[MAX_FILENAME_LENGTH]; char physical_images_path[MAX_FILENAME_LENGTH]; char physical_ssi_path[MAX_FILENAME_LENGTH]; char url_html_path[MAX_FILENAME_LENGTH]; char url_docs_path[MAX_FILENAME_LENGTH]; char url_context_help_path[MAX_FILENAME_LENGTH]; char url_images_path[MAX_FILENAME_LENGTH]; char url_logo_images_path[MAX_FILENAME_LENGTH]; char url_stylesheets_path[MAX_FILENAME_LENGTH]; char url_media_path[MAX_FILENAME_LENGTH]; char *service_critical_sound=NULL; char *service_warning_sound=NULL; char *service_unknown_sound=NULL; char *host_down_sound=NULL; char *host_unreachable_sound=NULL; char *normal_sound=NULL; char *statusmap_background_image=NULL; char *statuswrl_include=NULL; char *ping_syntax=NULL; char nagios_check_command[MAX_INPUT_BUFFER]=""; char nagios_process_info[MAX_INPUT_BUFFER]=""; int nagios_process_state=STATE_OK; extern time_t program_start; extern int nagios_pid; extern int daemon_mode; extern int enable_notifications; extern int execute_service_checks; extern int accept_passive_service_checks; extern int enable_event_handlers; extern int obsess_over_services; extern int enable_failure_prediction; extern int process_performance_data; extern time_t last_command_check; extern time_t last_log_rotation; int check_external_commands=0; int date_format=DATE_FORMAT_US; int log_rotation_method=LOG_ROTATION_NONE; time_t this_scheduled_log_rotation=0L; time_t last_scheduled_log_rotation=0L; time_t next_scheduled_log_rotation=0L; int use_authentication=TRUE; int interval_length=60; int show_context_help=FALSE; int hosts_have_been_read=FALSE; int hostgroups_have_been_read=FALSE; int servicegroups_have_been_read=FALSE; int contacts_have_been_read=FALSE; int contactgroups_have_been_read=FALSE; int services_have_been_read=FALSE; int timeperiods_have_been_read=FALSE; int commands_have_been_read=FALSE; int servicedependencies_have_been_read=FALSE; int serviceescalations_have_been_read=FALSE; int hostdependencies_have_been_read=FALSE; int hostescalations_have_been_read=FALSE; int hostextinfo_have_been_read=FALSE; int serviceextinfo_have_been_read=FALSE; int host_status_has_been_read=FALSE; int service_status_has_been_read=FALSE; int program_status_has_been_read=FALSE; int refresh_rate=DEFAULT_REFRESH_RATE; int default_statusmap_layout_method=0; int default_statuswrl_layout_method=0; extern hostgroup *hostgroup_list; extern contactgroup *contactgroup_list; extern command *command_list; extern timeperiod *timeperiod_list; extern contact *contact_list; extern serviceescalation *serviceescalation_list; extern hoststatus *hoststatus_list; extern servicestatus *servicestatus_list; lifo *lifo_list=NULL; char *my_strtok_buffer=NULL; char *original_my_strtok_buffer=NULL; char encoded_url_string[MAX_INPUT_BUFFER]; char encoded_html_string[MAX_INPUT_BUFFER]; #ifdef HAVE_TZNAME #ifdef CYGWIN extern char *_tzname[2] __declspec(dllimport); #else extern char *tzname[2]; #endif #endif /********************************************************** ***************** CLEANUP FUNCTIONS ********************** **********************************************************/ /* reset all variables used by the CGIs */ void reset_cgi_vars(void){ strcpy(main_config_file,""); strcpy(physical_html_path,""); strcpy(physical_images_path,""); strcpy(physical_ssi_path,""); strcpy(url_html_path,""); strcpy(url_docs_path,""); strcpy(url_context_help_path,""); strcpy(url_stylesheets_path,""); strcpy(url_media_path,""); strcpy(url_images_path,""); strcpy(log_file,""); strcpy(log_archive_path,DEFAULT_LOG_ARCHIVE_PATH); if(log_archive_path[strlen(log_archive_path)-1]!='/' && strlen(log_archive_path)0) return 1; else if(result<0) return -1; else return strcmp(val1b,val2b); } /********************************************************** ******************* LIFO FUNCTIONS *********************** **********************************************************/ /* reads contents of file into the lifo struct */ int read_file_into_lifo(char *filename){ char *input=NULL; mmapfile *thefile; int lifo_result; if((thefile=mmap_fopen(filename))==NULL) return LIFO_ERROR_FILE; while(1){ free(input); if((input=mmap_fgets(thefile))==NULL) break; lifo_result=push_lifo(input); if(lifo_result!=LIFO_OK){ free_lifo_memory(); free(input); mmap_fclose(thefile); return lifo_result; } } mmap_fclose(thefile); return LIFO_OK; } /* frees all memory allocated to lifo */ void free_lifo_memory(void){ lifo *temp_lifo; lifo *next_lifo; if(lifo_list==NULL) return; temp_lifo=lifo_list; while(temp_lifo!=NULL){ next_lifo=temp_lifo->next; if(temp_lifo->data!=NULL) free((void *)temp_lifo->data); free((void *)temp_lifo); temp_lifo=next_lifo; } return; } /* adds an item to lifo */ int push_lifo(char *buffer){ lifo *temp_lifo; temp_lifo=(lifo *)malloc(sizeof(lifo)); if(temp_lifo==NULL) return LIFO_ERROR_MEMORY; if(buffer==NULL) temp_lifo->data=(char *)strdup(""); else temp_lifo->data=(char *)strdup(buffer); if(temp_lifo->data==NULL){ free(temp_lifo); return LIFO_ERROR_MEMORY; } /* add item to front of lifo... */ temp_lifo->next=lifo_list; lifo_list=temp_lifo; return LIFO_OK; } /* returns/clears an item from lifo */ char *pop_lifo(void){ lifo *temp_lifo; char *buf; if(lifo_list==NULL || lifo_list->data==NULL) return NULL; buf=strdup(lifo_list->data); temp_lifo=lifo_list->next; if(lifo_list->data!=NULL) free((void *)lifo_list->data); free((void *)lifo_list); lifo_list=temp_lifo; return buf; } /********************************************************** *************** MISC UTILITY FUNCTIONS ******************* **********************************************************/ /* strip newline, carriage return, and tab characters from beginning and end of a string */ void strip(char *buffer){ register int x; register int y; register int z; if(buffer==NULL || buffer[0]=='\x0') return; /* strip end of string */ y=(int)strlen(buffer); for(x=y-1;x>=0;x--){ if(buffer[x]==' ' || buffer[x]=='\n' || buffer[x]=='\r' || buffer[x]=='\t' || buffer[x]==13) buffer[x]='\x0'; else break; } /* strip beginning of string (by shifting) */ y=(int)strlen(buffer); for(x=0;x0){ for(z=x;z'){ in_html=FALSE; continue; } /* skip everything inside HTML tags */ else if(in_html==TRUE) continue; /* strip single and double quotes */ else if(buffer[x]=='\'' || buffer[x]=='\"') new_buffer[y++]=' '; /* strip semicolons (replace with colons) */ else if(buffer[x]==';') new_buffer[y++]=':'; /* strip pipe and ampersand */ else if(buffer[x]=='&' || buffer[x]=='|') new_buffer[y++]=' '; /* normal character */ else new_buffer[y++]=buffer[x]; } /* terminate sanitized buffer */ new_buffer[y++]='\x0'; /* copy the sanitized buffer back to the original */ strcpy(buffer,new_buffer); /* free memory allocated to the new buffer */ free(new_buffer); return; } /* get date/time string */ void get_time_string(time_t *raw_time,char *buffer,int buffer_length,int type){ time_t t; struct tm *tm_ptr; int day; int hour; int minute; int second; int year; char *weekdays[7]={"Sun","Mon","Tue","Wed","Thu","Fri","Sat"}; char *months[12]={"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"}; char *tzone=""; if(raw_time==NULL) time(&t); else t=*raw_time; if(type==HTTP_DATE_TIME) tm_ptr=gmtime(&t); else tm_ptr=localtime(&t); hour=tm_ptr->tm_hour; minute=tm_ptr->tm_min; second=tm_ptr->tm_sec; day=tm_ptr->tm_mday; year=tm_ptr->tm_year+1900; #ifdef HAVE_TM_ZONE tzone=(char *)tm_ptr->tm_zone; #else tzone=(tm_ptr->tm_isdst)?tzname[1]:tzname[0]; #endif /* ctime() style */ if(type==LONG_DATE_TIME) snprintf(buffer,buffer_length,"%s %s %d %02d:%02d:%02d %s %d",weekdays[tm_ptr->tm_wday],months[tm_ptr->tm_mon],day,hour,minute,second,tzone,year); /* short style */ else if(type==SHORT_DATE_TIME){ if(date_format==DATE_FORMAT_EURO) snprintf(buffer,buffer_length,"%02d-%02d-%04d %02d:%02d:%02d",tm_ptr->tm_mday,tm_ptr->tm_mon+1,tm_ptr->tm_year+1900,tm_ptr->tm_hour,tm_ptr->tm_min,tm_ptr->tm_sec); else if(date_format==DATE_FORMAT_ISO8601 || date_format==DATE_FORMAT_STRICT_ISO8601) snprintf(buffer,buffer_length,"%04d-%02d-%02d%c%02d:%02d:%02d",tm_ptr->tm_year+1900,tm_ptr->tm_mon+1,tm_ptr->tm_mday,(date_format==DATE_FORMAT_STRICT_ISO8601)?'T':' ',tm_ptr->tm_hour,tm_ptr->tm_min,tm_ptr->tm_sec); else snprintf(buffer,buffer_length,"%02d-%02d-%04d %02d:%02d:%02d",tm_ptr->tm_mon+1,tm_ptr->tm_mday,tm_ptr->tm_year+1900,tm_ptr->tm_hour,tm_ptr->tm_min,tm_ptr->tm_sec); } /* expiration date/time for HTTP headers */ else if(type==HTTP_DATE_TIME) snprintf(buffer,buffer_length,"%s, %02d %s %d %02d:%02d:%02d GMT",weekdays[tm_ptr->tm_wday],day,months[tm_ptr->tm_mon],year,hour,minute,second); buffer[buffer_length-1]='\x0'; return; } /* get time string for an interval of time */ void get_interval_time_string(int time_units,char *buffer,int buffer_length){ unsigned long total_seconds; int hours=0; int minutes=0; int seconds=0; total_seconds=(unsigned long)(time_units*interval_length); hours=(int)total_seconds/3600; total_seconds%=3600; minutes=(int)total_seconds/60; total_seconds%=60; seconds=(int)total_seconds; snprintf(buffer,buffer_length,"%dh %dm %ds",hours,minutes,seconds); buffer[buffer_length-1]='\x0'; return; } /* fix the problem with strtok() skipping empty options between tokens */ char *my_strtok(char *buffer,char *tokens){ char *token_position; char *sequence_head; if(buffer!=NULL){ if(original_my_strtok_buffer!=NULL) free(original_my_strtok_buffer); my_strtok_buffer=malloc(strlen(buffer)+1); if(my_strtok_buffer==NULL) return NULL; original_my_strtok_buffer=my_strtok_buffer; strcpy(my_strtok_buffer,buffer); } sequence_head=my_strtok_buffer; if(sequence_head[0]=='\x0') return NULL; token_position=index(my_strtok_buffer,tokens[0]); if(token_position==NULL){ my_strtok_buffer=index(my_strtok_buffer,'\x0'); return sequence_head; } token_position[0]='\x0'; my_strtok_buffer=token_position+1; return sequence_head; } /* fixes compiler problems under Solaris, since strsep() isn't included */ /* this code is taken from the glibc source */ char *my_strsep (char **stringp, const char *delim){ char *begin, *end; begin = *stringp; if (begin == NULL) return NULL; /* A frequent case is when the delimiter string contains only one character. Here we don't need to call the expensive `strpbrk' function and instead work using `strchr'. */ if(delim[0]=='\0' || delim[1]=='\0'){ char ch = delim[0]; if(ch=='\0') end=NULL; else{ if(*begin==ch) end=begin; else end=strchr(begin+1,ch); } } else /* Find the end of the token. */ end = strpbrk (begin, delim); if(end){ /* Terminate the token and set *STRINGP past NUL character. */ *end++='\0'; *stringp=end; } else /* No more delimiters; this is the last token. */ *stringp=NULL; return begin; } /* open a file read-only via mmap() */ mmapfile *mmap_fopen(char *filename){ mmapfile *new_mmapfile; int fd; void *mmap_buf; struct stat statbuf; int mode=O_RDONLY; /* allocate memory */ if((new_mmapfile=(mmapfile *)malloc(sizeof(mmapfile)))==NULL) return NULL; /* open the file */ if((fd=open(filename,mode))==-1) return NULL; /* get file info */ if((fstat(fd,&statbuf))==-1){ close(fd); free(new_mmapfile); return NULL; } /* mmap() the file */ if((mmap_buf=(void *)mmap(0,statbuf.st_size,PROT_READ,MAP_PRIVATE,fd,0))==MAP_FAILED){ close(fd); free(new_mmapfile); return NULL; } /* populate struct info for later use */ new_mmapfile->path=strdup(filename); new_mmapfile->fd=fd; new_mmapfile->file_size=(unsigned long)(statbuf.st_size); new_mmapfile->current_position=0L; new_mmapfile->current_line=0L; new_mmapfile->mmap_buf=mmap_buf; return new_mmapfile; } /* close a file originally opened via mmap() */ int mmap_fclose(mmapfile *temp_mmapfile){ if(temp_mmapfile==NULL) return ERROR; /* un-mmap() the file */ munmap(temp_mmapfile->mmap_buf,temp_mmapfile->file_size); /* close the file */ close(temp_mmapfile->fd); /* free memory */ free(temp_mmapfile); return OK; } /* gets one line of input from an mmap()'ed file */ char *mmap_fgets(mmapfile *temp_mmapfile){ char *buf=NULL; unsigned long x=0L; int len=0; if(temp_mmapfile==NULL) return NULL; /* we've reached the end of the file */ if(temp_mmapfile->current_position>=temp_mmapfile->file_size) return NULL; /* find the end of the string (or buffer) */ for(x=temp_mmapfile->current_position;xfile_size;x++){ if(*((char *)(temp_mmapfile->mmap_buf)+x)=='\n'){ x++; break; } } /* calculate length of line we just read */ len=(int)(x-temp_mmapfile->current_position); /* allocate memory for the new line */ if((buf=(char *)malloc(len+1))==NULL) return NULL; /* copy string to newly allocated memory and terminate the string */ memcpy(buf,((char *)(temp_mmapfile->mmap_buf)+temp_mmapfile->current_position),len); buf[len]='\x0'; /* update the current position */ temp_mmapfile->current_position=x; /* increment the current line */ temp_mmapfile->current_line++; return buf; } /* gets one line of input from an mmap()'ed file (may be contained on more than one line in the source file) */ char *mmap_fgets_multiline(mmapfile *temp_mmapfile){ char *buf=NULL; char *tempbuf=NULL; int len; int len2; if(temp_mmapfile==NULL) return NULL; while(1){ free(tempbuf); if((tempbuf=mmap_fgets(temp_mmapfile))==NULL) break; if(buf==NULL){ len=strlen(tempbuf); if((buf=(char *)malloc(len+1))==NULL) break; memcpy(buf,tempbuf,len); buf[len]='\x0'; } else{ len=strlen(tempbuf); len2=strlen(buf); if((buf=(char *)realloc(buf,len+len2+1))==NULL) break; strcat(buf,tempbuf); len+=len2; buf[len]='\x0'; } /* we shouldn't continue to the next line... */ if(!(len>0 && buf[len-1]=='\\' && (len==1 || buf[len-2]!='\\'))) break; } free(tempbuf); return buf; } /* get days, hours, minutes, and seconds from a raw time_t format or total seconds */ void get_time_breakdown(unsigned long raw_time,int *days,int *hours,int *minutes,int *seconds){ unsigned long temp_time; int temp_days; int temp_hours; int temp_minutes; int temp_seconds; temp_time=raw_time; temp_days=temp_time/86400; temp_time-=(temp_days * 86400); temp_hours=temp_time/3600; temp_time-=(temp_hours * 3600); temp_minutes=temp_time/60; temp_time-=(temp_minutes * 60); temp_seconds=(int)temp_time; *days=temp_days; *hours=temp_hours; *minutes=temp_minutes; *seconds=temp_seconds; return; } /* encodes a string in proper URL format */ char * url_encode(char *input){ int len,output_len; int x,y; char temp_expansion[4]; len=(int)strlen(input); output_len=(int)sizeof(encoded_url_string); encoded_url_string[0]='\x0'; for(x=0,y=0;x<=len && y='0' && (char)input[x]<='9') || ((char)input[x]>='A' && (char)input[x]<='Z') || ((char)input[x]>=(char)'a' && (char)input[x]<=(char)'z') || (char)input[x]==(char)'.' || (char)input[x]==(char)'-' || (char)input[x]==(char)'_'){ encoded_url_string[y]=input[x]; y++; } /* spaces are pluses */ else if((char)input[x]<=(char)' '){ encoded_url_string[y]='+'; y++; } /* anything else gets represented by its hex value */ else{ encoded_url_string[y]='\x0'; if((int)strlen(encoded_url_string)<(output_len-3)){ sprintf(temp_expansion,"%%%02X",(unsigned int)input[x]); strcat(encoded_url_string,temp_expansion); y+=3; } } } encoded_url_string[sizeof(encoded_url_string)-1]='\x0'; return &encoded_url_string[0]; } /* escapes a string used in HTML */ char * html_encode(char *input){ int len,output_len; int x,y; char temp_expansion[7]; len=(int)strlen(input); output_len=(int)sizeof(encoded_html_string); encoded_html_string[0]='\x0'; for(x=0,y=0;x<=len && y='0' && (char)input[x]<='9') || ((char)input[x]>='A' && (char)input[x]<='Z') || ((char)input[x]>=(char)'a' && (char)input[x]<=(char)'z')){ encoded_html_string[y]=input[x]; y++; } /* spaces are encoded as non-breaking spaces */ else if((char)input[x]<=(char)' '){ encoded_html_string[y]='\x0'; if((int)strlen(encoded_html_string)<(output_len-6)){ strcat(encoded_html_string," "); y+=6; } } /* for simplicity, everything else gets represented by its numeric value */ else{ encoded_html_string[y]='\x0'; sprintf(temp_expansion,"&#%d;",(unsigned int)input[x]); if((int)strlen(encoded_html_string)<(output_len-strlen(temp_expansion))){ strcat(encoded_html_string,temp_expansion); y+=strlen(temp_expansion); } } } encoded_html_string[sizeof(encoded_html_string)-1]='\x0'; return &encoded_html_string[0]; } /* determines the log file we should use (from current time) */ void get_log_archive_to_use(int archive,char *buffer,int buffer_length){ struct tm *t; /* determine the time at which the log was rotated for this archive # */ determine_log_rotation_times(archive); /* if we're not rotating the logs or if we want the current log, use the main one... */ if(log_rotation_method==LOG_ROTATION_NONE || archive<=0){ strncpy(buffer,log_file,buffer_length); buffer[buffer_length-1]='\x0'; return; } t=localtime(&this_scheduled_log_rotation); /* use the time that the log rotation occurred to figure out the name of the log file */ snprintf(buffer,buffer_length,"%snagios-%02d-%02d-%d-%02d.log",log_archive_path,t->tm_mon+1,t->tm_mday,t->tm_year+1900,t->tm_hour); buffer[buffer_length-1]='\x0'; return; } /* determines log archive to use, given a specific time */ int determine_archive_to_use_from_time(time_t target_time){ time_t current_time; int current_archive=0; /* if log rotation is disabled, we don't have archives */ if(log_rotation_method==LOG_ROTATION_NONE) return 0; /* make sure target time is rational */ current_time=time(NULL); if(target_time>=current_time) return 0; /* backtrack through archives to find the one we need for this time */ /* start with archive of 1, subtract one when we find the right time period to compensate for current (non-rotated) log */ for(current_archive=1;;current_archive++){ /* determine time at which the log rotation occurred for this archive number */ determine_log_rotation_times(current_archive); /* if the target time falls within the times encompassed by this archive, we have the right archive! */ if(target_time>=this_scheduled_log_rotation) return current_archive-1; } return 0; } /* determines the log rotation times - past, present, future */ void determine_log_rotation_times(int archive){ struct tm *t; int current_month; int is_dst_now=FALSE; time_t current_time; /* negative archive numbers don't make sense */ /* if archive=0 (current log), this_scheduled_log_rotation time is set to next rotation time */ if(archive<0) return; time(¤t_time); t=localtime(¤t_time); is_dst_now=(t->tm_isdst>0)?TRUE:FALSE; t->tm_min=0; t->tm_sec=0; switch(log_rotation_method){ case LOG_ROTATION_HOURLY: this_scheduled_log_rotation=mktime(t); this_scheduled_log_rotation=(time_t)(this_scheduled_log_rotation-((archive-1)*3600)); last_scheduled_log_rotation=(time_t)(this_scheduled_log_rotation-3600); break; case LOG_ROTATION_DAILY: t->tm_hour=0; this_scheduled_log_rotation=mktime(t); this_scheduled_log_rotation=(time_t)(this_scheduled_log_rotation-((archive-1)*86400)); last_scheduled_log_rotation=(time_t)(this_scheduled_log_rotation-86400); break; case LOG_ROTATION_WEEKLY: t->tm_hour=0; this_scheduled_log_rotation=mktime(t); this_scheduled_log_rotation=(time_t)(this_scheduled_log_rotation-(86400*t->tm_wday)); this_scheduled_log_rotation=(time_t)(this_scheduled_log_rotation-((archive-1)*604800)); last_scheduled_log_rotation=(time_t)(this_scheduled_log_rotation-604800); break; case LOG_ROTATION_MONTHLY: t=localtime(¤t_time); t->tm_mon++; t->tm_mday=1; t->tm_hour=0; t->tm_min=0; t->tm_sec=0; for(current_month=0;current_month<=archive;current_month++){ if(t->tm_mon==0){ t->tm_mon=11; t->tm_year--; } else t->tm_mon--; } last_scheduled_log_rotation=mktime(t); t=localtime(¤t_time); t->tm_mon++; t->tm_mday=1; t->tm_hour=0; t->tm_min=0; t->tm_sec=0; for(current_month=0;current_monthtm_mon==0){ t->tm_mon=11; t->tm_year--; } else t->tm_mon--; } this_scheduled_log_rotation=mktime(t); break; default: break; } /* adjust this rotation time for daylight savings time */ t=localtime(&this_scheduled_log_rotation); if(t->tm_isdst>0 && is_dst_now==FALSE) this_scheduled_log_rotation=(time_t)(this_scheduled_log_rotation-3600); else if(t->tm_isdst==0 && is_dst_now==TRUE) this_scheduled_log_rotation=(time_t)(this_scheduled_log_rotation+3600); /* adjust last rotation time for daylight savings time */ t=localtime(&last_scheduled_log_rotation); if(t->tm_isdst>0 && is_dst_now==FALSE) last_scheduled_log_rotation=(time_t)(last_scheduled_log_rotation-3600); else if(t->tm_isdst==0 && is_dst_now==TRUE) last_scheduled_log_rotation=(time_t)(last_scheduled_log_rotation+3600); return; } /********************************************************** *************** COMMON HTML FUNCTIONS ******************** **********************************************************/ void display_info_table(char *title,int refresh, authdata *current_authdata){ time_t current_time; char date_time[MAX_DATETIME_LENGTH]; int result; /* read program status */ result=read_all_status_data(get_cgi_config_location(),READ_PROGRAM_STATUS); printf("\n"); printf("\n"); printf("
    \n"); printf("
    %s
    \n",title); time(¤t_time); get_time_string(¤t_time,date_time,(int)sizeof(date_time),LONG_DATE_TIME); printf("Last Updated: %s
    \n",date_time); if(refresh==TRUE) printf("Updated every %d seconds
    \n",refresh_rate); printf("Nagios® - www.nagios.org
    \n"); if(current_authdata!=NULL) printf("Logged in as %s
    \n",(!strcmp(current_authdata->username,""))?"?":current_authdata->username); if(nagios_process_state!=STATE_OK) printf("
    Warning: Monitoring process may not be running!
    Click here for more info.
    ",EXTINFO_CGI,DISPLAY_PROCESS_INFO); if(result==ERROR) printf("
    Warning: Could not read program status information!
    "); else{ if(enable_notifications==FALSE) printf("
    - Notifications are disabled
    "); if(execute_service_checks==FALSE) printf("
    - Service checks are disabled
    "); } printf("
    \n"); return; } void display_nav_table(char *url,int archive){ char date_time[MAX_DATETIME_LENGTH]; char archive_file[MAX_INPUT_BUFFER]; char *archive_basename; if(log_rotation_method!=LOG_ROTATION_NONE){ printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); if(archive!=0){ printf("\n"); } else printf("\n",url_images_path,EMPTY_ICON); printf("\n"); printf("\n"); } /* get archive to use */ get_log_archive_to_use(archive,archive_file,sizeof(archive_file)-1); /* cut the pathname for security, and the remaining slash for clarity */ archive_basename=(char *)&archive_file; if(strrchr((char *)&archive_basename,'/')!=NULL) archive_basename=strrchr((char *)&archive_file,'/')+1; /* now it's safe to print the filename */ printf("
    \n",archive_basename); return; } /* prints the additional notes or action url for a host (with macros substituted) */ void print_extra_host_url(char *host_name, char *url){ char input_buffer[MAX_INPUT_BUFFER]=""; char output_buffer[MAX_INPUT_BUFFER]=""; char *temp_buffer; int in_macro=FALSE; host *temp_host; if(host_name==NULL || url==NULL) return; temp_host=find_host(host_name); if(temp_host==NULL){ printf("%s",url); return; } strncpy(input_buffer,url,sizeof(input_buffer)-1); output_buffer[sizeof(input_buffer)-1]='\x0'; for(temp_buffer=my_strtok(input_buffer,"$");temp_buffer!=NULL;temp_buffer=my_strtok(NULL,"$")){ if(in_macro==FALSE){ if(strlen(output_buffer)+strlen(temp_buffer)name),sizeof(output_buffer)-strlen(output_buffer)-1); else if(!strcmp(temp_buffer,"HOSTADDRESS")) strncat(output_buffer,(temp_host->address==NULL)?"":url_encode(temp_host->address),sizeof(output_buffer)-strlen(output_buffer)-1); } in_macro=FALSE; } } printf("%s",output_buffer); return; } /* prints the additional notes or action url for a service (with macros substituted) */ void print_extra_service_url(char *host_name, char *svc_description, char *url){ char input_buffer[MAX_INPUT_BUFFER]=""; char output_buffer[MAX_INPUT_BUFFER]=""; char *temp_buffer; int in_macro=FALSE; service *temp_service; host *temp_host; if(host_name==NULL || svc_description==NULL || url==NULL) return; temp_service=find_service(host_name,svc_description); if(temp_service==NULL){ printf("%s",url); return; } temp_host=find_host(host_name); strncpy(input_buffer,url,sizeof(input_buffer)-1); input_buffer[sizeof(input_buffer)-1]='\x0'; for(temp_buffer=my_strtok(input_buffer,"$");temp_buffer!=NULL;temp_buffer=my_strtok(NULL,"$")){ if(in_macro==FALSE){ if(strlen(output_buffer)+strlen(temp_buffer)host_name),sizeof(output_buffer)-strlen(output_buffer)-1); else if(!strcmp(temp_buffer,"HOSTADDRESS") && temp_host!=NULL) strncat(output_buffer,(temp_host->address==NULL)?"":url_encode(temp_host->address),sizeof(output_buffer)-strlen(output_buffer)-1); else if(!strcmp(temp_buffer,"SERVICEDESC")) strncat(output_buffer,url_encode(temp_service->description),sizeof(output_buffer)-strlen(output_buffer)-1); } in_macro=FALSE; } } printf("%s",output_buffer); return; } /* include user-defined SSI footers or headers */ void include_ssi_files(char *cgi_name, int type){ char common_ssi_file[MAX_INPUT_BUFFER]; char cgi_ssi_file[MAX_INPUT_BUFFER]; char raw_cgi_name[MAX_INPUT_BUFFER]; char *stripped_cgi_name; int x; /* common header or footer */ snprintf(common_ssi_file,sizeof(common_ssi_file)-1,"%scommon-%s.ssi",physical_ssi_path,(type==SSI_HEADER)?"header":"footer"); common_ssi_file[sizeof(common_ssi_file)-1]='\x0'; /* CGI-specific header or footer */ strncpy(raw_cgi_name,cgi_name,sizeof(raw_cgi_name)-1); raw_cgi_name[sizeof(raw_cgi_name)-1]='\x0'; stripped_cgi_name=strtok(raw_cgi_name,"."); snprintf(cgi_ssi_file,sizeof(cgi_ssi_file)-1,"%s%s-%s.ssi",physical_ssi_path,(stripped_cgi_name==NULL)?"":stripped_cgi_name,(type==SSI_HEADER)?"header":"footer"); cgi_ssi_file[sizeof(cgi_ssi_file)-1]='\x0'; for(x=0;x\n"); include_ssi_file(common_ssi_file); include_ssi_file(cgi_ssi_file); } else{ include_ssi_file(cgi_ssi_file); include_ssi_file(common_ssi_file); printf("\n\n"); } return; } /* include user-defined SSI footer or header */ void include_ssi_file(char *filename){ char buffer[MAX_INPUT_BUFFER]; FILE *fp; struct stat stat_result; int call_return; /* if file is executable, we want to run it rather than print it */ call_return=stat(filename,&stat_result); /* file is executable */ if(call_return==0 && (stat_result.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))){ /* must flush output stream first so that output from script shows up in correct place. Other choice is to open program under pipe and copy the data from the program to our output stream. */ fflush(stdout); /* ignore return status from system call. */ call_return=system(filename); return; } /* an error occurred trying to stat() the file */ else if(call_return!=0){ /* Handle error conditions. Assume that standard posix error codes and errno are available. If not, comment this section out. */ switch(errno){ case ENOTDIR: /* - A component of the path is not a directory. */ case ELOOP: /* Too many symbolic links encountered while traversing the path. */ case EFAULT: /* Bad address. */ case ENOMEM: /* Out of memory (i.e. kernel memory). */ case ENAMETOOLONG: /* File name too long. */ printf("
    A stat call returned %d while looking for the file %s.
    ", errno, filename); return; case EACCES: /* Permission denied. -- The file should be accessible by nagios. */ printf("
    A stat call returned a permissions error(%d) while looking for the file %s.
    ", errno, filename); return; case ENOENT: /* A component of the path file_name does not exist, or the path is an empty string. Just return if the file doesn't exist. */ return; default: return; } } fp=fopen(filename,"r"); if(fp==NULL) return; /* print all lines in the SSI file */ while(fgets(buffer,(int)(sizeof(buffer)-1),fp)!=NULL) printf("%s",buffer); fclose(fp); return; } /* displays an error if CGI config file could not be read */ void cgi_config_file_error(char *config_file){ printf("

    Whoops!

    \n"); printf("

    Error: Could not open CGI config file '%s' for reading!

    \n",config_file); printf("

    \n"); printf("Here are some things you should check in order to resolve this error:\n"); printf("

    \n"); printf("

    \n"); printf("

      \n"); printf("
    1. Make sure you've installed a CGI config file in its proper location. See the error message about for details on where the CGI is expecting to find the configuration file. A sample CGI configuration file (named cgi.cfg) can be found in the sample-config/ subdirectory of the Nagios source code distribution.\n"); printf("
    2. Make sure the user your web server is running as has permission to read the CGI config file.\n"); printf("
    \n"); printf("

    \n"); printf("

    \n"); printf("Make sure you read the documentation on installing and configuring Nagios thoroughly before continuing. If all else fails, try sending a message to one of the mailing lists. More information can be found at http://www.nagios.org.\n"); printf("

    \n"); return; } /* displays an error if main config file could not be read */ void main_config_file_error(char *config_file){ printf("

    Whoops!

    \n"); printf("

    Error: Could not open main config file '%s' for reading!

    \n",config_file); printf("

    \n"); printf("Here are some things you should check in order to resolve this error:\n"); printf("

    \n"); printf("

    \n"); printf("

      \n"); printf("
    1. Make sure you've installed a main config file in its proper location. See the error message about for details on where the CGI is expecting to find the configuration file. A sample main configuration file (named nagios.cfg) can be found in the sample-config/ subdirectory of the Nagios source code distribution.\n"); printf("
    2. Make sure the user your web server is running as has permission to read the main config file.\n"); printf("
    \n"); printf("

    \n"); printf("

    \n"); printf("Make sure you read the documentation on installing and configuring Nagios thoroughly before continuing. If all else fails, try sending a message to one of the mailing lists. More information can be found at http://www.nagios.org.\n"); printf("

    \n"); return; } /* displays an error if object data could not be read */ void object_data_error(void){ printf("

    Whoops!

    \n"); printf("

    Error: Could not read object configuration data!

    \n"); printf("

    \n"); printf("Here are some things you should check in order to resolve this error:\n"); printf("

    \n"); printf("

    \n"); printf("

      \n"); printf("
    1. Verify configuration options using the -v command-line option to check for errors.\n"); printf("
    2. Check the Nagios log file for messages relating to startup or status data errors.\n"); printf("
    3. Make sure you've compiled the main program and the CGIs to use the same object data storage options (i.e. default text file or template-based file).\n"); printf("
    \n"); printf("

    \n"); printf("

    \n"); printf("Make sure you read the documentation on installing, configuring and running Nagios thoroughly before continuing. If all else fails, try sending a message to one of the mailing lists. More information can be found at http://www.nagios.org.\n"); printf("

    \n"); return; } /* displays an error if status data could not be read */ void status_data_error(void){ printf("

    Whoops!

    \n"); printf("

    Error: Could not read host and service status information!

    \n"); printf("

    \n"); printf("The most common cause of this error message (especially for new users), is the fact that Nagios is not actually running. If Nagios is indeed not running, this is a normal error message. It simply indicates that the CGIs could not obtain the current status of hosts and services that are being monitored. If you've just installed things, make sure you read the documentation on starting Nagios.\n"); printf("

    \n"); printf("

    \n"); printf("Some other things you should check in order to resolve this error include:\n"); printf("

    \n"); printf("

    \n"); printf("

      \n"); printf("
    1. Check the Nagios log file for messages relating to startup or status data errors.\n"); printf("
    2. Always verify configuration options using the -v command-line option before starting or restarting Nagios!\n"); printf("
    3. Make sure you've compiled the main program and the CGIs to use the same status data storage options (i.e. text file or database). If the main program is storing status data in a text file and the CGIs are trying to read status data from a database, you'll have problems.\n"); printf("
    \n"); printf("

    \n"); printf("

    \n"); printf("Make sure you read the documentation on installing, configuring and running Nagios thoroughly before continuing. If all else fails, try sending a message to one of the mailing lists. More information can be found at http://www.nagios.org.\n"); printf("

    \n"); return; } /* displays context-sensitive help window */ void display_context_help(char *chid){ char *icon=CONTEXT_HELP_ICON1; if(show_context_help==FALSE) return; /* change icon if necessary */ if(!strcmp(chid,CONTEXTHELP_TAC)) icon=CONTEXT_HELP_ICON2; printf("Display context-sensitive help for this screen\n",url_context_help_path,chid,url_context_help_path,chid,url_images_path,icon); return; } nagios-2.6/cgi/cmd.c0000664000076500007650000033254710433352477013676 0ustar nagiosnagios/************************************************************************** * * CMD.C - Nagios Command CGI * * Copyright (c) 1999-2006 Ethan Galstad (nagios@nagios.org) * Last Modified: 05-18-2006 * * 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. *************************************************************************/ #include "../include/config.h" #include "../include/common.h" #include "../include/objects.h" #include "../include/comments.h" #include "../include/downtime.h" #include "../include/cgiutils.h" #include "../include/cgiauth.h" #include "../include/getcgi.h" extern char main_config_file[MAX_FILENAME_LENGTH]; extern char command_file[MAX_FILENAME_LENGTH]; extern char comment_file[MAX_FILENAME_LENGTH]; extern char url_stylesheets_path[MAX_FILENAME_LENGTH]; extern int nagios_process_state; extern int check_external_commands; extern int use_authentication; extern scheduled_downtime *scheduled_downtime_list; extern comment *comment_list; extern int date_format; #define MAX_AUTHOR_LENGTH 64 #define MAX_COMMENT_LENGTH 1024 #define HTML_CONTENT 0 #define WML_CONTENT 1 char *host_name=""; char *hostgroup_name=""; char *servicegroup_name=""; char *service_desc=""; char *comment_author=""; char *comment_data=""; char *start_time_string=""; char *end_time_string=""; unsigned long comment_id=0; unsigned long downtime_id=0; int notification_delay=0; int schedule_delay=0; int persistent_comment=FALSE; int sticky_ack=FALSE; int send_notification=FALSE; int force_check=FALSE; int plugin_state=STATE_OK; char plugin_output[MAX_INPUT_BUFFER]=""; char performance_data[MAX_INPUT_BUFFER]=""; time_t start_time=0L; time_t end_time=0L; int affect_host_and_services=FALSE; int propagate_to_children=FALSE; int fixed=FALSE; unsigned long duration=0L; unsigned long triggered_by=0L; int child_options=0; int command_type=CMD_NONE; int command_mode=CMDMODE_REQUEST; int content_type=HTML_CONTENT; int display_header=TRUE; authdata current_authdata; void show_command_help(int); void request_command_data(int); void commit_command_data(int); int commit_command(int); int write_command_to_file(char *); void clean_comment_data(char *); void document_header(int); void document_footer(void); int process_cgivars(void); int string_to_time(char *,time_t *); int main(void){ int result=OK; /* get the arguments passed in the URL */ process_cgivars(); /* reset internal variables */ reset_cgi_vars(); /* read the CGI configuration file */ result=read_cgi_config_file(get_cgi_config_location()); if(result==ERROR){ document_header(FALSE); if(content_type==WML_CONTENT) printf("

    Error: Could not open CGI config file!

    \n"); else cgi_config_file_error(get_cgi_config_location()); document_footer(); return ERROR; } /* read the main configuration file */ result=read_main_config_file(main_config_file); if(result==ERROR){ document_header(FALSE); if(content_type==WML_CONTENT) printf("

    Error: Could not open main config file!

    \n"); else main_config_file_error(main_config_file); document_footer(); return ERROR; } /* This requires the date_format parameter in the main config file */ if (strcmp(start_time_string,"")) string_to_time(start_time_string,&start_time); if (strcmp(end_time_string,"")) string_to_time(end_time_string,&end_time); /* read all object configuration data */ result=read_all_object_configuration_data(main_config_file,READ_ALL_OBJECT_DATA); if(result==ERROR){ document_header(FALSE); if(content_type==WML_CONTENT) printf("

    Error: Could not read object config data!

    \n"); else object_data_error(); document_footer(); return ERROR; } document_header(TRUE); /* get authentication information */ get_authentication_information(¤t_authdata); if(display_header==TRUE){ /* begin top table */ printf("\n"); printf("\n"); /* left column of the first row */ printf("\n"); /* center column of the first row */ printf("\n"); /* right column of the first row */ printf("\n"); /* end of top table */ printf("\n"); printf("
    \n"); display_info_table("External Command Interface",FALSE,¤t_authdata); printf("\n"); printf("\n"); /* display context-sensitive help */ if(command_mode==CMDMODE_COMMIT) display_context_help(CONTEXTHELP_CMD_COMMIT); else display_context_help(CONTEXTHELP_CMD_INPUT); printf("
    \n"); } /* if no command was specified... */ if(command_type==CMD_NONE){ if(content_type==WML_CONTENT) printf("

    Error: No command specified!

    \n"); else printf("

    Error: No command was specified

    \n"); } /* if this is the first request for a command, present option */ else if(command_mode==CMDMODE_REQUEST) request_command_data(command_type); /* the user wants to commit the command */ else if(command_mode==CMDMODE_COMMIT) commit_command_data(command_type); document_footer(); /* free allocated memory */ free_memory(); free_object_data(); return OK; } void document_header(int use_stylesheet){ if(content_type==WML_CONTENT){ printf("Content-type: text/vnd.wap.wml\r\n\r\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); } else{ printf("Content-type: text/html\r\n\r\n"); printf("\n"); printf("\n"); printf("\n"); printf("External Command Interface\n"); printf("\n"); if(use_stylesheet==TRUE){ printf("\n",url_stylesheets_path,COMMON_CSS); printf("\n",url_stylesheets_path,COMMAND_CSS); } printf("\n"); printf("\n"); /* include user SSI header */ include_ssi_files(COMMAND_CGI,SSI_HEADER); } return; } void document_footer(void){ if(content_type==WML_CONTENT){ printf("\n"); printf("\n"); } else{ /* include user SSI footer */ include_ssi_files(COMMAND_CGI,SSI_FOOTER); printf("\n"); printf("\n"); } return; } int process_cgivars(void){ char **variables; int error=FALSE; int x; variables=getcgivars(); for(x=0;variables[x]!=NULL;x++){ /* do some basic length checking on the variable identifier to prevent buffer overflows */ if(strlen(variables[x])>=MAX_INPUT_BUFFER-1){ x++; continue; } /* we found the command type */ else if(!strcmp(variables[x],"cmd_typ")){ x++; if(variables[x]==NULL){ error=TRUE; break; } command_type=atoi(variables[x]); } /* we found the command mode */ else if(!strcmp(variables[x],"cmd_mod")){ x++; if(variables[x]==NULL){ error=TRUE; break; } command_mode=atoi(variables[x]); } /* we found the comment id */ else if(!strcmp(variables[x],"com_id")){ x++; if(variables[x]==NULL){ error=TRUE; break; } comment_id=strtoul(variables[x],NULL,10); } /* we found the downtime id */ else if(!strcmp(variables[x],"down_id")){ x++; if(variables[x]==NULL){ error=TRUE; break; } downtime_id=strtoul(variables[x],NULL,10); } /* we found the notification delay */ else if(!strcmp(variables[x],"not_dly")){ x++; if(variables[x]==NULL){ error=TRUE; break; } notification_delay=atoi(variables[x]); } /* we found the schedule delay */ else if(!strcmp(variables[x],"sched_dly")){ x++; if(variables[x]==NULL){ error=TRUE; break; } schedule_delay=atoi(variables[x]); } /* we found the comment author */ else if(!strcmp(variables[x],"com_author")){ x++; if(variables[x]==NULL){ error=TRUE; break; } comment_author=(char *)malloc(strlen(variables[x])+1); if(comment_author==NULL) comment_author=""; else strcpy(comment_author,variables[x]); } /* we found the comment data */ else if(!strcmp(variables[x],"com_data")){ x++; if(variables[x]==NULL){ error=TRUE; break; } comment_data=(char *)malloc(strlen(variables[x])+1); if(comment_data==NULL) comment_data=""; else strcpy(comment_data,variables[x]); } /* we found the host name */ else if(!strcmp(variables[x],"host")){ x++; if(variables[x]==NULL){ error=TRUE; break; } host_name=(char *)malloc(strlen(variables[x])+1); if(host_name==NULL) host_name=""; else strcpy(host_name,variables[x]); } /* we found the hostgroup name */ else if(!strcmp(variables[x],"hostgroup")){ x++; if(variables[x]==NULL){ error=TRUE; break; } hostgroup_name=(char *)malloc(strlen(variables[x])+1); if(hostgroup_name==NULL) hostgroup_name=""; else strcpy(hostgroup_name,variables[x]); } /* we found the service name */ else if(!strcmp(variables[x],"service")){ x++; if(variables[x]==NULL){ error=TRUE; break; } service_desc=(char *)malloc(strlen(variables[x])+1); if(service_desc==NULL) service_desc=""; else strcpy(service_desc,variables[x]); } /* we found the servicegroup name */ else if(!strcmp(variables[x],"servicegroup")){ x++; if(variables[x]==NULL){ error=TRUE; break; } servicegroup_name=(char *)malloc(strlen(variables[x])+1); if(servicegroup_name==NULL) servicegroup_name=""; else strcpy(servicegroup_name,variables[x]); } /* we got the persistence option for a comment */ else if(!strcmp(variables[x],"persistent")) persistent_comment=TRUE; /* we got the notification option for an acknowledgement */ else if(!strcmp(variables[x],"send_notification")) send_notification=TRUE; /* we got the acknowledgement type */ else if(!strcmp(variables[x],"sticky_ack")) sticky_ack=TRUE; /* we got the service check force option */ else if(!strcmp(variables[x],"force_check")) force_check=TRUE; /* we got the option to affect host and all its services */ else if(!strcmp(variables[x],"ahas")) affect_host_and_services=TRUE; /* we got the option to propagate to child hosts */ else if(!strcmp(variables[x],"ptc")) propagate_to_children=TRUE; /* we got the option for fixed downtime */ else if(!strcmp(variables[x],"fixed")){ x++; if(variables[x]==NULL){ error=TRUE; break; } fixed=(atoi(variables[x])>0)?TRUE:FALSE; } /* we got the triggered by downtime option */ else if(!strcmp(variables[x],"trigger")){ x++; if(variables[x]==NULL){ error=TRUE; break; } triggered_by=strtoul(variables[x],NULL,10); } /* we got the child options */ else if(!strcmp(variables[x],"childoptions")){ x++; if(variables[x]==NULL){ error=TRUE; break; } child_options=atoi(variables[x]); } /* we found the plugin output */ else if(!strcmp(variables[x],"plugin_output")){ x++; if(variables[x]==NULL){ error=TRUE; break; } /* protect against buffer overflows */ if(strlen(variables[x])>=MAX_INPUT_BUFFER-1){ error=TRUE; break; } else strcpy(plugin_output,variables[x]); } /* we found the performance data */ else if(!strcmp(variables[x],"performance_data")){ x++; if(variables[x]==NULL){ error=TRUE; break; } /* protect against buffer overflows */ if(strlen(variables[x])>=MAX_INPUT_BUFFER-1){ error=TRUE; break; } else strcpy(performance_data,variables[x]); } /* we found the plugin state */ else if(!strcmp(variables[x],"plugin_state")){ x++; if(variables[x]==NULL){ error=TRUE; break; } plugin_state=atoi(variables[x]); } /* we found the hour duration */ else if(!strcmp(variables[x],"hours")){ x++; if(variables[x]==NULL){ error=TRUE; break; } if(atoi(variables[x])<0){ error=TRUE; break; } duration+=(unsigned long)(atoi(variables[x])*3600); } /* we found the minute duration */ else if(!strcmp(variables[x],"minutes")){ x++; if(variables[x]==NULL){ error=TRUE; break; } if(atoi(variables[x])<0){ error=TRUE; break; } duration+=(unsigned long)(atoi(variables[x])*60); } /* we found the start time */ else if(!strcmp(variables[x],"start_time")){ x++; if(variables[x]==NULL){ error=TRUE; break; } start_time_string=(char *)malloc(strlen(variables[x])+1); if(start_time_string==NULL) start_time_string=""; else strcpy(start_time_string,variables[x]); } /* we found the end time */ else if(!strcmp(variables[x],"end_time")){ x++; if(variables[x]==NULL){ error=TRUE; break; } end_time_string=(char *)malloc(strlen(variables[x])+1); if(end_time_string==NULL) end_time_string=""; else strcpy(end_time_string,variables[x]); } /* we found the content type argument */ else if(!strcmp(variables[x],"content")){ x++; if(variables[x]==NULL){ error=TRUE; break; } if(!strcmp(variables[x],"wml")){ content_type=WML_CONTENT; display_header=FALSE; } else content_type=HTML_CONTENT; } } /* free memory allocated to the CGI variables */ free_cgivars(variables); return error; } void request_command_data(int cmd){ time_t t; char start_time[MAX_DATETIME_LENGTH]; char buffer[MAX_INPUT_BUFFER]; contact *temp_contact; scheduled_downtime *temp_downtime; /* get default name to use for comment author */ temp_contact=find_contact(current_authdata.username); if(temp_contact!=NULL && temp_contact->alias!=NULL) comment_author=temp_contact->alias; else comment_author=current_authdata.username; printf("

    You are requesting to "); switch(cmd){ case CMD_ADD_HOST_COMMENT: case CMD_ADD_SVC_COMMENT: printf("add a %s comment",(cmd==CMD_ADD_HOST_COMMENT)?"host":"service"); break; case CMD_DEL_HOST_COMMENT: case CMD_DEL_SVC_COMMENT: printf("delete a %s comment",(cmd==CMD_DEL_HOST_COMMENT)?"host":"service"); break; case CMD_DELAY_HOST_NOTIFICATION: case CMD_DELAY_SVC_NOTIFICATION: printf("delay a %s notification",(cmd==CMD_DELAY_HOST_NOTIFICATION)?"host":"service"); break; case CMD_SCHEDULE_SVC_CHECK: printf("schedule a service check"); break; case CMD_ENABLE_SVC_CHECK: case CMD_DISABLE_SVC_CHECK: printf("%s actice checks of a particular service",(cmd==CMD_ENABLE_SVC_CHECK)?"enable":"disable"); break; case CMD_ENABLE_NOTIFICATIONS: case CMD_DISABLE_NOTIFICATIONS: printf("%s notifications",(cmd==CMD_ENABLE_NOTIFICATIONS)?"enable":"disable"); break; case CMD_SHUTDOWN_PROCESS: case CMD_RESTART_PROCESS: printf("%s the Nagios process",(cmd==CMD_SHUTDOWN_PROCESS)?"shutdown":"restart"); break; case CMD_ENABLE_HOST_SVC_CHECKS: case CMD_DISABLE_HOST_SVC_CHECKS: printf("%s active checks of all services on a host",(cmd==CMD_ENABLE_HOST_SVC_CHECKS)?"enable":"disable"); break; case CMD_SCHEDULE_HOST_SVC_CHECKS: printf("schedule a check of all services for a host"); break; case CMD_DEL_ALL_HOST_COMMENTS: case CMD_DEL_ALL_SVC_COMMENTS: printf("delete all comments for a %s",(cmd==CMD_DEL_ALL_HOST_COMMENTS)?"host":"service"); break; case CMD_ENABLE_SVC_NOTIFICATIONS: case CMD_DISABLE_SVC_NOTIFICATIONS: printf("%s notifications for a service",(cmd==CMD_ENABLE_SVC_NOTIFICATIONS)?"enable":"disable"); break; case CMD_ENABLE_HOST_NOTIFICATIONS: case CMD_DISABLE_HOST_NOTIFICATIONS: printf("%s notifications for a host",(cmd==CMD_ENABLE_HOST_NOTIFICATIONS)?"enable":"disable"); break; case CMD_ENABLE_ALL_NOTIFICATIONS_BEYOND_HOST: case CMD_DISABLE_ALL_NOTIFICATIONS_BEYOND_HOST: printf("%s notifications for all hosts and services beyond a host",(cmd==CMD_ENABLE_ALL_NOTIFICATIONS_BEYOND_HOST)?"enable":"disable"); break; case CMD_ENABLE_HOST_SVC_NOTIFICATIONS: case CMD_DISABLE_HOST_SVC_NOTIFICATIONS: printf("%s notifications for all services on a host",(cmd==CMD_ENABLE_HOST_SVC_NOTIFICATIONS)?"enable":"disable"); break; case CMD_ACKNOWLEDGE_HOST_PROBLEM: case CMD_ACKNOWLEDGE_SVC_PROBLEM: printf("acknowledge a %s problem",(cmd==CMD_ACKNOWLEDGE_HOST_PROBLEM)?"host":"service"); break; case CMD_START_EXECUTING_SVC_CHECKS: case CMD_STOP_EXECUTING_SVC_CHECKS: printf("%s executing active service checks",(cmd==CMD_START_EXECUTING_SVC_CHECKS)?"start":"stop"); break; case CMD_START_ACCEPTING_PASSIVE_SVC_CHECKS: case CMD_STOP_ACCEPTING_PASSIVE_SVC_CHECKS: printf("%s accepting passive service checks",(cmd==CMD_START_ACCEPTING_PASSIVE_SVC_CHECKS)?"start":"stop"); break; case CMD_ENABLE_PASSIVE_SVC_CHECKS: case CMD_DISABLE_PASSIVE_SVC_CHECKS: printf("%s accepting passive service checks for a particular service",(cmd==CMD_ENABLE_PASSIVE_SVC_CHECKS)?"start":"stop"); break; case CMD_ENABLE_EVENT_HANDLERS: case CMD_DISABLE_EVENT_HANDLERS: printf("%s event handlers",(cmd==CMD_ENABLE_EVENT_HANDLERS)?"enable":"disable"); break; case CMD_ENABLE_HOST_EVENT_HANDLER: case CMD_DISABLE_HOST_EVENT_HANDLER: printf("%s the event handler for a particular host",(cmd==CMD_ENABLE_HOST_EVENT_HANDLER)?"enable":"disable"); break; case CMD_ENABLE_SVC_EVENT_HANDLER: case CMD_DISABLE_SVC_EVENT_HANDLER: printf("%s the event handler for a particular service",(cmd==CMD_ENABLE_SVC_EVENT_HANDLER)?"enable":"disable"); break; case CMD_ENABLE_HOST_CHECK: case CMD_DISABLE_HOST_CHECK: printf("%s active checks of a particular host",(cmd==CMD_ENABLE_HOST_CHECK)?"enable":"disable"); break; case CMD_STOP_OBSESSING_OVER_SVC_CHECKS: case CMD_START_OBSESSING_OVER_SVC_CHECKS: printf("%s obsessing over service checks",(cmd==CMD_STOP_OBSESSING_OVER_SVC_CHECKS)?"stop":"start"); break; case CMD_REMOVE_HOST_ACKNOWLEDGEMENT: case CMD_REMOVE_SVC_ACKNOWLEDGEMENT: printf("remove a %s acknowledgement",(cmd==CMD_REMOVE_HOST_ACKNOWLEDGEMENT)?"host":"service"); break; case CMD_SCHEDULE_HOST_DOWNTIME: case CMD_SCHEDULE_SVC_DOWNTIME: printf("schedule downtime for a particular %s",(cmd==CMD_SCHEDULE_HOST_DOWNTIME)?"host":"service"); break; case CMD_PROCESS_HOST_CHECK_RESULT: case CMD_PROCESS_SERVICE_CHECK_RESULT: printf("submit a passive check result for a particular %s",(cmd==CMD_PROCESS_HOST_CHECK_RESULT)?"host":"service"); break; case CMD_ENABLE_HOST_FLAP_DETECTION: case CMD_DISABLE_HOST_FLAP_DETECTION: printf("%s flap detection for a particular host",(cmd==CMD_ENABLE_HOST_FLAP_DETECTION)?"enable":"disable"); break; case CMD_ENABLE_SVC_FLAP_DETECTION: case CMD_DISABLE_SVC_FLAP_DETECTION: printf("%s flap detection for a particular service",(cmd==CMD_ENABLE_SVC_FLAP_DETECTION)?"enable":"disable"); break; case CMD_ENABLE_FLAP_DETECTION: case CMD_DISABLE_FLAP_DETECTION: printf("%s flap detection for hosts and services",(cmd==CMD_ENABLE_FLAP_DETECTION)?"enable":"disable"); break; case CMD_ENABLE_HOSTGROUP_SVC_NOTIFICATIONS: case CMD_DISABLE_HOSTGROUP_SVC_NOTIFICATIONS: printf("%s notifications for all services in a particular hostgroup",(cmd==CMD_ENABLE_HOSTGROUP_SVC_NOTIFICATIONS)?"enable":"disable"); break; case CMD_ENABLE_HOSTGROUP_HOST_NOTIFICATIONS: case CMD_DISABLE_HOSTGROUP_HOST_NOTIFICATIONS: printf("%s notifications for all hosts in a particular hostgroup",(cmd==CMD_ENABLE_HOSTGROUP_HOST_NOTIFICATIONS)?"enable":"disable"); break; case CMD_ENABLE_HOSTGROUP_SVC_CHECKS: case CMD_DISABLE_HOSTGROUP_SVC_CHECKS: printf("%s active checks of all services in a particular hostgroup",(cmd==CMD_ENABLE_HOSTGROUP_SVC_CHECKS)?"enable":"disable"); break; case CMD_DEL_HOST_DOWNTIME: case CMD_DEL_SVC_DOWNTIME: printf("cancel scheduled downtime for a particular %s",(cmd==CMD_DEL_HOST_DOWNTIME)?"host":"service"); break; case CMD_ENABLE_FAILURE_PREDICTION: case CMD_DISABLE_FAILURE_PREDICTION: printf("%s failure prediction for hosts and service",(cmd==CMD_ENABLE_FAILURE_PREDICTION)?"enable":"disable"); break; case CMD_ENABLE_PERFORMANCE_DATA: case CMD_DISABLE_PERFORMANCE_DATA: printf("%s performance data processing for hosts and services",(cmd==CMD_ENABLE_PERFORMANCE_DATA)?"enable":"disable"); break; case CMD_SCHEDULE_HOSTGROUP_HOST_DOWNTIME: printf("schedule downtime for all hosts in a particular hostgroup"); break; case CMD_SCHEDULE_HOSTGROUP_SVC_DOWNTIME: printf("schedule downtime for all services in a particular hostgroup"); break; case CMD_START_EXECUTING_HOST_CHECKS: case CMD_STOP_EXECUTING_HOST_CHECKS: printf("%s executing host checks",(cmd==CMD_START_EXECUTING_HOST_CHECKS)?"start":"stop"); break; case CMD_START_ACCEPTING_PASSIVE_HOST_CHECKS: case CMD_STOP_ACCEPTING_PASSIVE_HOST_CHECKS: printf("%s accepting passive host checks",(cmd==CMD_START_ACCEPTING_PASSIVE_HOST_CHECKS)?"start":"stop"); break; case CMD_ENABLE_PASSIVE_HOST_CHECKS: case CMD_DISABLE_PASSIVE_HOST_CHECKS: printf("%s accepting passive checks for a particular host",(cmd==CMD_ENABLE_PASSIVE_HOST_CHECKS)?"start":"stop"); break; case CMD_START_OBSESSING_OVER_HOST_CHECKS: case CMD_STOP_OBSESSING_OVER_HOST_CHECKS: printf("%s obsessing over host checks",(cmd==CMD_START_OBSESSING_OVER_HOST_CHECKS)?"start":"stop"); break; case CMD_SCHEDULE_HOST_CHECK: printf("schedule a host check"); break; case CMD_START_OBSESSING_OVER_SVC: case CMD_STOP_OBSESSING_OVER_SVC: printf("%s obsessing over a particular service",(cmd==CMD_START_OBSESSING_OVER_SVC)?"start":"stop"); break; case CMD_START_OBSESSING_OVER_HOST: case CMD_STOP_OBSESSING_OVER_HOST: printf("%s obsessing over a particular host",(cmd==CMD_START_OBSESSING_OVER_HOST)?"start":"stop"); break; case CMD_ENABLE_SERVICEGROUP_SVC_NOTIFICATIONS: case CMD_DISABLE_SERVICEGROUP_SVC_NOTIFICATIONS: printf("%s notifications for all services in a particular servicegroup",(cmd==CMD_ENABLE_SERVICEGROUP_SVC_NOTIFICATIONS)?"enable":"disable"); break; case CMD_ENABLE_SERVICEGROUP_HOST_NOTIFICATIONS: case CMD_DISABLE_SERVICEGROUP_HOST_NOTIFICATIONS: printf("%s notifications for all hosts in a particular servicegroup",(cmd==CMD_ENABLE_SERVICEGROUP_HOST_NOTIFICATIONS)?"enable":"disable"); break; case CMD_ENABLE_SERVICEGROUP_SVC_CHECKS: case CMD_DISABLE_SERVICEGROUP_SVC_CHECKS: printf("%s active checks of all services in a particular servicegroup",(cmd==CMD_ENABLE_SERVICEGROUP_SVC_CHECKS)?"enable":"disable"); break; case CMD_SCHEDULE_SERVICEGROUP_HOST_DOWNTIME: printf("schedule downtime for all hosts in a particular servicegroup"); break; case CMD_SCHEDULE_SERVICEGROUP_SVC_DOWNTIME: printf("schedule downtime for all services in a particular servicegroup"); break; default: printf("execute an unknown command. Shame on you!
    "); return; } printf("
  • \n"); printf("

    \n"); printf("

    \n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("
    \n"); printf("
    Command Options
    \n"); printf("\n"); printf("\n"); printf("\n"); printf("
    \n"); printf("
    \n", COMMAND_CGI); printf("\n"); printf("\n",cmd,CMDMODE_COMMIT); switch(cmd){ case CMD_ADD_HOST_COMMENT: case CMD_ACKNOWLEDGE_HOST_PROBLEM: printf("\n"); if(cmd==CMD_ACKNOWLEDGE_HOST_PROBLEM){ printf("\n"); printf("\n"); } printf("\n"); printf("\n"); printf("\n"); break; case CMD_ADD_SVC_COMMENT: case CMD_ACKNOWLEDGE_SVC_PROBLEM: printf("\n"); printf("\n"); printf("\n"); } printf("\n"); printf("\n"); printf("\n"); break; case CMD_DEL_HOST_COMMENT: case CMD_DEL_SVC_COMMENT: printf("\n"); break; case CMD_DELAY_HOST_NOTIFICATION: printf("\n"); printf("\n"); break; case CMD_DELAY_SVC_NOTIFICATION: printf("\n"); printf("\n"); break; case CMD_SCHEDULE_SVC_CHECK: case CMD_SCHEDULE_HOST_CHECK: case CMD_SCHEDULE_HOST_SVC_CHECKS: printf("\n"); if(cmd==CMD_SCHEDULE_SVC_CHECK){ printf("\n"); } time(&t); get_time_string(&t,buffer,sizeof(buffer)-1,SHORT_DATE_TIME); printf("\n"); printf("\n"); break; case CMD_ENABLE_SVC_CHECK: case CMD_DISABLE_SVC_CHECK: case CMD_DEL_ALL_SVC_COMMENTS: case CMD_ENABLE_SVC_NOTIFICATIONS: case CMD_DISABLE_SVC_NOTIFICATIONS: case CMD_ENABLE_PASSIVE_SVC_CHECKS: case CMD_DISABLE_PASSIVE_SVC_CHECKS: case CMD_ENABLE_SVC_EVENT_HANDLER: case CMD_DISABLE_SVC_EVENT_HANDLER: case CMD_REMOVE_SVC_ACKNOWLEDGEMENT: case CMD_ENABLE_SVC_FLAP_DETECTION: case CMD_DISABLE_SVC_FLAP_DETECTION: case CMD_START_OBSESSING_OVER_SVC: case CMD_STOP_OBSESSING_OVER_SVC: printf("\n"); printf("\n"); break; case CMD_ENABLE_HOST_SVC_CHECKS: case CMD_DISABLE_HOST_SVC_CHECKS: case CMD_DEL_ALL_HOST_COMMENTS: case CMD_ENABLE_HOST_NOTIFICATIONS: case CMD_DISABLE_HOST_NOTIFICATIONS: case CMD_ENABLE_ALL_NOTIFICATIONS_BEYOND_HOST: case CMD_DISABLE_ALL_NOTIFICATIONS_BEYOND_HOST: case CMD_ENABLE_HOST_SVC_NOTIFICATIONS: case CMD_DISABLE_HOST_SVC_NOTIFICATIONS: case CMD_ENABLE_HOST_EVENT_HANDLER: case CMD_DISABLE_HOST_EVENT_HANDLER: case CMD_ENABLE_HOST_CHECK: case CMD_DISABLE_HOST_CHECK: case CMD_REMOVE_HOST_ACKNOWLEDGEMENT: case CMD_ENABLE_HOST_FLAP_DETECTION: case CMD_DISABLE_HOST_FLAP_DETECTION: case CMD_ENABLE_PASSIVE_HOST_CHECKS: case CMD_DISABLE_PASSIVE_HOST_CHECKS: case CMD_START_OBSESSING_OVER_HOST: case CMD_STOP_OBSESSING_OVER_HOST: printf("\n"); if(cmd==CMD_ENABLE_HOST_SVC_CHECKS || cmd==CMD_DISABLE_HOST_SVC_CHECKS || cmd==CMD_ENABLE_HOST_SVC_NOTIFICATIONS || cmd==CMD_DISABLE_HOST_SVC_NOTIFICATIONS){ printf("\n"); } if(cmd==CMD_ENABLE_HOST_NOTIFICATIONS || cmd==CMD_DISABLE_HOST_NOTIFICATIONS){ printf("\n"); } break; case CMD_ENABLE_NOTIFICATIONS: case CMD_DISABLE_NOTIFICATIONS: case CMD_SHUTDOWN_PROCESS: case CMD_RESTART_PROCESS: case CMD_START_EXECUTING_SVC_CHECKS: case CMD_STOP_EXECUTING_SVC_CHECKS: case CMD_START_ACCEPTING_PASSIVE_SVC_CHECKS: case CMD_STOP_ACCEPTING_PASSIVE_SVC_CHECKS: case CMD_ENABLE_EVENT_HANDLERS: case CMD_DISABLE_EVENT_HANDLERS: case CMD_START_OBSESSING_OVER_SVC_CHECKS: case CMD_STOP_OBSESSING_OVER_SVC_CHECKS: case CMD_ENABLE_FLAP_DETECTION: case CMD_DISABLE_FLAP_DETECTION: case CMD_ENABLE_FAILURE_PREDICTION: case CMD_DISABLE_FAILURE_PREDICTION: case CMD_ENABLE_PERFORMANCE_DATA: case CMD_DISABLE_PERFORMANCE_DATA: case CMD_START_EXECUTING_HOST_CHECKS: case CMD_STOP_EXECUTING_HOST_CHECKS: case CMD_START_ACCEPTING_PASSIVE_HOST_CHECKS: case CMD_STOP_ACCEPTING_PASSIVE_HOST_CHECKS: case CMD_START_OBSESSING_OVER_HOST_CHECKS: case CMD_STOP_OBSESSING_OVER_HOST_CHECKS: printf(""); break; case CMD_PROCESS_HOST_CHECK_RESULT: case CMD_PROCESS_SERVICE_CHECK_RESULT: printf("\n"); if(cmd==CMD_PROCESS_SERVICE_CHECK_RESULT){ printf("\n"); } printf("\n"); printf("\n"); printf("\n"); break; case CMD_SCHEDULE_HOST_DOWNTIME: case CMD_SCHEDULE_SVC_DOWNTIME: printf("\n"); if(cmd==CMD_SCHEDULE_SVC_DOWNTIME){ printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); time(&t); get_time_string(&t,buffer,sizeof(buffer)-1,SHORT_DATE_TIME); printf("\n"); t+=(unsigned long)7200; get_time_string(&t,buffer,sizeof(buffer)-1,SHORT_DATE_TIME); printf("\n"); printf("\n"); printf("\n"); printf("\n"); if(cmd==CMD_SCHEDULE_HOST_DOWNTIME){ printf("\n"); } printf("\n"); break; case CMD_ENABLE_HOSTGROUP_SVC_NOTIFICATIONS: case CMD_DISABLE_HOSTGROUP_SVC_NOTIFICATIONS: case CMD_ENABLE_HOSTGROUP_HOST_NOTIFICATIONS: case CMD_DISABLE_HOSTGROUP_HOST_NOTIFICATIONS: case CMD_ENABLE_HOSTGROUP_SVC_CHECKS: case CMD_DISABLE_HOSTGROUP_SVC_CHECKS: printf("\n"); if(cmd==CMD_ENABLE_HOSTGROUP_SVC_CHECKS || cmd==CMD_DISABLE_HOSTGROUP_SVC_CHECKS || cmd==CMD_ENABLE_HOSTGROUP_SVC_NOTIFICATIONS || cmd==CMD_DISABLE_HOSTGROUP_SVC_NOTIFICATIONS){ printf("\n"); } break; case CMD_ENABLE_SERVICEGROUP_SVC_NOTIFICATIONS: case CMD_DISABLE_SERVICEGROUP_SVC_NOTIFICATIONS: case CMD_ENABLE_SERVICEGROUP_HOST_NOTIFICATIONS: case CMD_DISABLE_SERVICEGROUP_HOST_NOTIFICATIONS: case CMD_ENABLE_SERVICEGROUP_SVC_CHECKS: case CMD_DISABLE_SERVICEGROUP_SVC_CHECKS: printf("\n"); if(cmd==CMD_ENABLE_SERVICEGROUP_SVC_CHECKS || cmd==CMD_DISABLE_SERVICEGROUP_SVC_CHECKS || cmd==CMD_ENABLE_SERVICEGROUP_SVC_NOTIFICATIONS || cmd==CMD_DISABLE_SERVICEGROUP_SVC_NOTIFICATIONS){ printf("\n"); } break; case CMD_DEL_HOST_DOWNTIME: case CMD_DEL_SVC_DOWNTIME: printf("\n"); break; case CMD_SCHEDULE_HOSTGROUP_HOST_DOWNTIME: case CMD_SCHEDULE_HOSTGROUP_SVC_DOWNTIME: case CMD_SCHEDULE_SERVICEGROUP_HOST_DOWNTIME: case CMD_SCHEDULE_SERVICEGROUP_SVC_DOWNTIME: if(cmd==CMD_SCHEDULE_HOSTGROUP_HOST_DOWNTIME || cmd==CMD_SCHEDULE_HOSTGROUP_SVC_DOWNTIME){ printf("\n"); } else{ printf("\n"); } printf("\n"); printf("\n"); time(&t); get_time_string(&t,buffer,sizeof(buffer)-1,SHORT_DATE_TIME); printf("\n"); t+=(unsigned long)7200; get_time_string(&t,buffer,sizeof(buffer)-1,SHORT_DATE_TIME); printf("\n"); printf("\n"); printf("\n"); if(cmd==CMD_SCHEDULE_HOSTGROUP_SVC_DOWNTIME || cmd==CMD_SCHEDULE_SERVICEGROUP_SVC_DOWNTIME){ printf("\n"); } break; default: printf("\n"); } printf("\n"); printf("\n"); printf("
    Host Name:"); printf("",host_name); printf("
    Sticky Acknowledgement:"); printf(""); printf("
    Send Notification:"); printf(""); printf("
    Persistent%s:",(cmd==CMD_ACKNOWLEDGE_HOST_PROBLEM)?" Comment":""); printf(""); printf("
    Author (Your Name):"); printf("",comment_author); printf("
    Comment:"); printf("",comment_data); printf("
    Host Name:"); printf("",host_name); printf("
    Service:"); printf("",service_desc); if(cmd==CMD_ACKNOWLEDGE_SVC_PROBLEM){ printf("
    Sticky Acknowledgement:"); printf(""); printf("
    Send Notification:"); printf(""); printf("
    Persistent%s:",(cmd==CMD_ACKNOWLEDGE_SVC_PROBLEM)?" Comment":""); printf(""); printf("
    Author (Your Name):"); printf("",comment_author); printf("
    Comment:"); printf("",comment_data); printf("
    Comment ID:"); printf("",comment_id); printf("
    Host Name:"); printf("",host_name); printf("
    Notification Delay (minutes from now):"); printf("",notification_delay); printf("
    Host Name:"); printf("",host_name); printf("
    Service:"); printf("",service_desc); printf("
    Notification Delay (minutes from now):"); printf("",notification_delay); printf("
    Host Name:"); printf("",host_name); printf("
    Service:"); printf("",service_desc); printf("
    Check Time:"); printf("",buffer); printf("
    Force Check:"); printf(""); printf("
    Host Name:"); printf("",host_name); printf("
    Service:"); printf("",service_desc); printf("
    Host Name:"); printf("",host_name); printf("
    %s For Host Too:",(cmd==CMD_ENABLE_HOST_SVC_CHECKS || cmd==CMD_ENABLE_HOST_SVC_NOTIFICATIONS)?"Enable":"Disable"); printf(""); printf("
    %s Notifications For Child Hosts Too:",(cmd==CMD_ENABLE_HOST_NOTIFICATIONS)?"Enable":"Disable"); printf(""); printf("
    There are no options for this command.
    Click the 'Commit' button to submit the command.
    Host Name:"); printf("",host_name); printf("
    Service:"); printf("",service_desc); printf("
    Check Result:"); printf("\n"); printf("
    Check Output:"); printf(""); printf("
    Performance Data:"); printf(""); printf("
    Host Name:"); printf("",host_name); printf("
    Service:"); printf("",service_desc); } printf("
    Author (Your Name):"); printf("",comment_author); printf("
    Comment:"); printf("",comment_data); printf("

    Triggered By:\n"); printf("\n"); printf("

    Start Time:"); printf("",buffer); printf("
    End Time:"); printf("",buffer); printf("
    Type:"); printf("\n"); printf("
    If Flexible, Duration:"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("
    HoursMinutes
    \n"); printf("

    Child Hosts:"); printf("\n"); printf("

    Hostgroup Name:"); printf("",hostgroup_name); printf("
    %s For Hosts Too:",(cmd==CMD_ENABLE_HOSTGROUP_SVC_CHECKS || cmd==CMD_ENABLE_HOSTGROUP_SVC_NOTIFICATIONS)?"Enable":"Disable"); printf(""); printf("
    Servicegroup Name:"); printf("",servicegroup_name); printf("
    %s For Hosts Too:",(cmd==CMD_ENABLE_SERVICEGROUP_SVC_CHECKS || cmd==CMD_ENABLE_SERVICEGROUP_SVC_NOTIFICATIONS)?"Enable":"Disable"); printf(""); printf("
    Scheduled Downtime ID:"); printf("",downtime_id); printf("
    Hostgroup Name:"); printf("",hostgroup_name); printf("
    Servicegroup Name:"); printf("",servicegroup_name); printf("
    Author (Your Name):"); printf("",comment_author); printf("
    Comment:"); printf("",comment_data); printf("
    Start Time:"); printf("",buffer); printf("
    End Time:"); printf("",buffer); printf("
    Type:"); printf("\n"); printf("
    If Flexible, Duration:"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("
    HoursMinutes
    \n"); printf("
    Schedule Downtime For Hosts Too:"); printf(""); printf("
    This should not be happening... :-(
    \n"); printf("
    \n"); printf("
    \n"); printf("
    \n"); /* show information about the command... */ show_command_help(cmd); printf("
    \n"); printf("
    \n"); printf("

    \n"); printf("

    Please enter all required information before committing the command.
    Required fields are marked in red.
    Failure to supply all required values will result in an error.

    "); return; } void commit_command_data(int cmd){ char *error_string=NULL; int result=OK; int authorized=FALSE; service *temp_service; host *temp_host; hostgroup *temp_hostgroup; comment *temp_comment; scheduled_downtime *temp_downtime; servicegroup *temp_servicegroup=NULL; /* get authentication information */ get_authentication_information(¤t_authdata); switch(cmd){ case CMD_ADD_HOST_COMMENT: case CMD_ACKNOWLEDGE_HOST_PROBLEM: /* make sure we have author name, and comment data... */ if(!strcmp(comment_author,"")){ if(!error_string) error_string=strdup("Author was not entered"); } if(!strcmp(comment_data,"")){ if(!error_string) error_string=strdup("Comment was not entered"); } /* clean up the comment data */ clean_comment_data(comment_author); clean_comment_data(comment_data); /* see if the user is authorized to issue a command... */ temp_host=find_host(host_name); if(is_authorized_for_host_commands(temp_host,¤t_authdata)==TRUE) authorized=TRUE; break; case CMD_ADD_SVC_COMMENT: case CMD_ACKNOWLEDGE_SVC_PROBLEM: /* make sure we have author name, and comment data... */ if(!strcmp(comment_author,"")){ if(!error_string) error_string=strdup("Author was not entered"); } if(!strcmp(comment_data,"")){ if(!error_string) error_string=strdup("Comment was not entered"); } /* clean up the comment data */ clean_comment_data(comment_author); clean_comment_data(comment_data); /* see if the user is authorized to issue a command... */ temp_service=find_service(host_name,service_desc); if(is_authorized_for_service_commands(temp_service,¤t_authdata)==TRUE) authorized=TRUE; break; case CMD_DEL_HOST_COMMENT: case CMD_DEL_SVC_COMMENT: /* check the sanity of the comment id */ if(comment_id==0){ if(!error_string) error_string=strdup("Comment id cannot be 0"); } /* read comments */ read_comment_data(get_cgi_config_location()); /* find the comment */ if(cmd==CMD_DEL_HOST_COMMENT) temp_comment=find_host_comment(comment_id); else temp_comment=find_service_comment(comment_id); /* see if the user is authorized to issue a command... */ if(cmd==CMD_DEL_HOST_COMMENT && temp_comment!=NULL){ temp_host=find_host(temp_comment->host_name); if(is_authorized_for_host_commands(temp_host,¤t_authdata)==TRUE) authorized=TRUE; } if(cmd==CMD_DEL_SVC_COMMENT && temp_comment!=NULL){ temp_service=find_service(temp_comment->host_name,temp_comment->service_description); if(is_authorized_for_service_commands(temp_service,¤t_authdata)==TRUE) authorized=TRUE; } /* free comment data */ free_comment_data(); break; case CMD_DEL_HOST_DOWNTIME: case CMD_DEL_SVC_DOWNTIME: /* check the sanity of the downtime id */ if(downtime_id==0){ if(!error_string) error_string=strdup("Downtime id cannot be 0"); } /* read scheduled downtime */ read_downtime_data(get_cgi_config_location()); /* find the downtime entry */ if(cmd==CMD_DEL_HOST_DOWNTIME) temp_downtime=find_host_downtime(downtime_id); else temp_downtime=find_service_downtime(downtime_id); /* see if the user is authorized to issue a command... */ if(cmd==CMD_DEL_HOST_DOWNTIME && temp_downtime!=NULL){ temp_host=find_host(temp_downtime->host_name); if(is_authorized_for_host_commands(temp_host,¤t_authdata)==TRUE) authorized=TRUE; } if(cmd==CMD_DEL_SVC_DOWNTIME && temp_downtime!=NULL){ temp_service=find_service(temp_downtime->host_name,temp_downtime->service_description); if(is_authorized_for_service_commands(temp_service,¤t_authdata)==TRUE) authorized=TRUE; } /* free downtime data */ free_downtime_data(); break; case CMD_SCHEDULE_SVC_CHECK: case CMD_ENABLE_SVC_CHECK: case CMD_DISABLE_SVC_CHECK: case CMD_DEL_ALL_SVC_COMMENTS: case CMD_ENABLE_SVC_NOTIFICATIONS: case CMD_DISABLE_SVC_NOTIFICATIONS: case CMD_ENABLE_PASSIVE_SVC_CHECKS: case CMD_DISABLE_PASSIVE_SVC_CHECKS: case CMD_ENABLE_SVC_EVENT_HANDLER: case CMD_DISABLE_SVC_EVENT_HANDLER: case CMD_REMOVE_SVC_ACKNOWLEDGEMENT: case CMD_PROCESS_SERVICE_CHECK_RESULT: case CMD_SCHEDULE_SVC_DOWNTIME: case CMD_DELAY_SVC_NOTIFICATION: case CMD_ENABLE_SVC_FLAP_DETECTION: case CMD_DISABLE_SVC_FLAP_DETECTION: case CMD_START_OBSESSING_OVER_SVC: case CMD_STOP_OBSESSING_OVER_SVC: /* make sure we have author name and comment data... */ if(cmd==CMD_SCHEDULE_SVC_DOWNTIME){ if(!strcmp(comment_data,"")){ if(!error_string) error_string=strdup("Comment was not entered"); } else if(!strcmp(comment_author,"")){ if(!error_string) error_string=strdup("Author was not entered"); } } /* see if the user is authorized to issue a command... */ temp_service=find_service(host_name,service_desc); if(is_authorized_for_service_commands(temp_service,¤t_authdata)==TRUE) authorized=TRUE; /* make sure we have passive check info (if necessary) */ if(cmd==CMD_PROCESS_SERVICE_CHECK_RESULT && !strcmp(plugin_output,"")){ if(!error_string) error_string=strdup("Plugin output cannot be blank"); } /* make sure we have a notification delay (if necessary) */ if(cmd==CMD_DELAY_SVC_NOTIFICATION && notification_delay<=0){ if(!error_string) error_string=strdup("Notification delay must be greater than 0"); } /* clean up the comment data if scheduling downtime */ if(cmd==CMD_SCHEDULE_SVC_DOWNTIME){ clean_comment_data(comment_author); clean_comment_data(comment_data); } /* make sure we have check time (if necessary) */ if(cmd==CMD_SCHEDULE_SVC_CHECK && start_time==(time_t)0){ if(!error_string) error_string=strdup("Start time must be non-zero"); } /* make sure we have start/end times for downtime (if necessary) */ if(cmd==CMD_SCHEDULE_SVC_DOWNTIME && (start_time==(time_t)0 || end_time==(time_t)0 || end_timeend_time)){ if(!error_string) error_string=strdup("Start or end time not valid"); } /* make sure we have check time (if necessary) */ if((cmd==CMD_SCHEDULE_HOST_CHECK || cmd==CMD_SCHEDULE_HOST_SVC_CHECKS)&& start_time==(time_t)0){ if(!error_string) error_string=strdup("Start time must be non-zero"); } /* make sure we have passive check info (if necessary) */ if(cmd==CMD_PROCESS_HOST_CHECK_RESULT && !strcmp(plugin_output,"")){ if(!error_string) error_string=strdup("Plugin output cannot be blank"); } break; case CMD_ENABLE_HOSTGROUP_SVC_NOTIFICATIONS: case CMD_DISABLE_HOSTGROUP_SVC_NOTIFICATIONS: case CMD_ENABLE_HOSTGROUP_HOST_NOTIFICATIONS: case CMD_DISABLE_HOSTGROUP_HOST_NOTIFICATIONS: case CMD_ENABLE_HOSTGROUP_SVC_CHECKS: case CMD_DISABLE_HOSTGROUP_SVC_CHECKS: case CMD_SCHEDULE_HOSTGROUP_HOST_DOWNTIME: case CMD_SCHEDULE_HOSTGROUP_SVC_DOWNTIME: /* make sure we have author and comment data */ if(cmd==CMD_SCHEDULE_HOSTGROUP_HOST_DOWNTIME || cmd==CMD_SCHEDULE_HOSTGROUP_SVC_DOWNTIME) { if(!strcmp(comment_data,"")){ if(!error_string) error_string=strdup("Comment was not entered"); } else if(!strcmp(comment_author,"")){ if(!error_string) error_string=strdup("Author was not entered"); } } /* make sure we have start/end times for downtime */ if((cmd==CMD_SCHEDULE_HOSTGROUP_HOST_DOWNTIME || cmd==CMD_SCHEDULE_HOSTGROUP_SVC_DOWNTIME) && (start_time==(time_t)0 || end_time==(time_t)0 || start_time>end_time)){ if(!error_string) error_string=strdup("Start or end time not valid"); } /* see if the user is authorized to issue a command... */ temp_hostgroup=find_hostgroup(hostgroup_name); if(is_authorized_for_hostgroup(temp_hostgroup,¤t_authdata)==TRUE) authorized=TRUE; /* clean up the comment data if scheduling downtime */ if(cmd==CMD_SCHEDULE_HOSTGROUP_HOST_DOWNTIME || cmd==CMD_SCHEDULE_HOSTGROUP_SVC_DOWNTIME){ clean_comment_data(comment_author); clean_comment_data(comment_data); } break; case CMD_ENABLE_SERVICEGROUP_SVC_NOTIFICATIONS: case CMD_DISABLE_SERVICEGROUP_SVC_NOTIFICATIONS: case CMD_ENABLE_SERVICEGROUP_HOST_NOTIFICATIONS: case CMD_DISABLE_SERVICEGROUP_HOST_NOTIFICATIONS: case CMD_ENABLE_SERVICEGROUP_SVC_CHECKS: case CMD_DISABLE_SERVICEGROUP_SVC_CHECKS: case CMD_SCHEDULE_SERVICEGROUP_HOST_DOWNTIME: case CMD_SCHEDULE_SERVICEGROUP_SVC_DOWNTIME: /* make sure we have author and comment data */ if(cmd==CMD_SCHEDULE_SERVICEGROUP_HOST_DOWNTIME || cmd==CMD_SCHEDULE_SERVICEGROUP_SVC_DOWNTIME) { if(!strcmp(comment_data,"")){ if(!error_string) error_string=strdup("Comment was not entered"); } else if(!strcmp(comment_author,"")){ if(!error_string) error_string=strdup("Author was not entered"); } } /* make sure we have start/end times for downtime */ if((cmd==CMD_SCHEDULE_SERVICEGROUP_HOST_DOWNTIME || cmd==CMD_SCHEDULE_SERVICEGROUP_SVC_DOWNTIME) && (start_time==(time_t)0 || end_time==(time_t)0 || start_time>end_time)){ if(!error_string) error_string=strdup("Start or end time not valid"); } /* see if the user is authorized to issue a command... */ temp_servicegroup=find_servicegroup(servicegroup_name); if(is_authorized_for_servicegroup(temp_servicegroup,¤t_authdata)==TRUE) authorized=TRUE; break; default: if(!error_string)error_string=strdup("An error occurred while processing your command!"); } /* to be safe, we are going to REQUIRE that the authentication functionality is enabled... */ if(use_authentication==FALSE){ if(content_type==WML_CONTENT) printf("

    Error: Authentication is not enabled!

    \n"); else{ printf("

    \n"); printf("

    Sorry Dave, I can't let you do that...

    "); printf("
    "); printf("It seems that you have chosen to not use the authentication functionality of the CGIs.

    "); printf("I don't want to be personally responsible for what may happen as a result of allowing unauthorized users to issue commands to Nagios,"); printf("so you'll have to disable this safeguard if you are really stubborn and want to invite trouble.

    "); printf("Read the section on CGI authentication in the HTML documentation to learn how you can enable authentication and why you should want to.\n"); printf("
    \n"); printf("

    \n"); } } /* the user is not authorized to issue the given command */ else if(authorized==FALSE){ if(content_type==WML_CONTENT) printf("

    Error: You're not authorized to commit that command!

    \n"); else{ printf("

    Sorry, but you are not authorized to commit the specified command.

    \n"); printf("

    Read the section of the documentation that deals with authentication and authorization in the CGIs for more information.

    \n"); printf("Return from whence you came

    \n"); } } /* some error occurred (data was probably missing) */ else if(error_string){ if(content_type==WML_CONTENT) printf("

    %s

    \n", error_string); else{ printf("

    %s

    \n", error_string); free(error_string); printf("

    Go back and verify that you entered all required information correctly.
    \n"); printf("Return from whence you came

    \n"); } } /* if Nagios isn't checking external commands, don't do anything... */ else if(check_external_commands==FALSE){ if(content_type==WML_CONTENT) printf("

    Error: Nagios is not checking external commands!

    \n"); else{ printf("

    Sorry, but Nagios is currently not checking for external commands, so your command will not be committed!

    \n"); printf("

    Read the documentation for information on how to enable external commands...

    \n"); printf("Return from whence you came

    \n"); } } /* everything looks okay, so let's go ahead and commit the command... */ else{ /* commit the command */ result=commit_command(cmd); if(result==OK){ if(content_type==WML_CONTENT) printf("

    Your command was submitted sucessfully...

    \n"); else{ printf("

    Your command request was successfully submitted to Nagios for processing.

    \n"); printf("Note: It may take a while before the command is actually processed.

    \n"); printf("Done

    "); } } else{ if(content_type==WML_CONTENT) printf("

    An error occurred while committing your command!

    \n"); else{ printf("

    An error occurred while attempting to commit your command for processing.

    \n"); printf("Return from whence you came

    \n"); } } } return; } /* commits a command for processing */ int commit_command(int cmd){ char command_buffer[MAX_INPUT_BUFFER]; time_t current_time; time_t scheduled_time; time_t notification_time; int result; /* get the current time */ time(¤t_time); /* get the scheduled time */ scheduled_time=current_time+(schedule_delay*60); /* get the notification time */ notification_time=current_time+(notification_delay*60); /* decide how to form the command line... */ switch(cmd){ case CMD_ADD_HOST_COMMENT: snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] ADD_HOST_COMMENT;%s;%d;%s;%s\n",current_time,host_name,(persistent_comment==TRUE)?1:0,comment_author,comment_data); break; case CMD_ADD_SVC_COMMENT: snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] ADD_SVC_COMMENT;%s;%s;%d;%s;%s\n",current_time,host_name,service_desc,(persistent_comment==TRUE)?1:0,comment_author,comment_data); break; case CMD_DEL_HOST_COMMENT: snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] DEL_HOST_COMMENT;%lu\n",current_time,comment_id); break; case CMD_DEL_SVC_COMMENT: snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] DEL_SVC_COMMENT;%lu\n",current_time,comment_id); break; case CMD_DELAY_HOST_NOTIFICATION: snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] DELAY_HOST_NOTIFICATION;%s;%lu\n",current_time,host_name,notification_time); break; case CMD_DELAY_SVC_NOTIFICATION: snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] DELAY_SVC_NOTIFICATION;%s;%s;%lu\n",current_time,host_name,service_desc,notification_time); break; case CMD_SCHEDULE_SVC_CHECK: snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] SCHEDULE_%sSVC_CHECK;%s;%s;%lu\n",current_time,(force_check==TRUE)?"FORCED_":"",host_name,service_desc,start_time); break; case CMD_ENABLE_SVC_CHECK: case CMD_DISABLE_SVC_CHECK: snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] %s_SVC_CHECK;%s;%s\n",current_time,(cmd==CMD_ENABLE_SVC_CHECK)?"ENABLE":"DISABLE",host_name,service_desc); break; case CMD_DISABLE_NOTIFICATIONS: snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] DISABLE_NOTIFICATIONS;%lu\n",current_time,scheduled_time); break; case CMD_ENABLE_NOTIFICATIONS: snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] ENABLE_NOTIFICATIONS;%lu\n",current_time,scheduled_time); break; case CMD_SHUTDOWN_PROCESS: case CMD_RESTART_PROCESS: snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] %s_PROGRAM;%lu\n",current_time,(cmd==CMD_SHUTDOWN_PROCESS)?"SHUTDOWN":"RESTART",scheduled_time); break; case CMD_ENABLE_HOST_SVC_CHECKS: case CMD_DISABLE_HOST_SVC_CHECKS: if(affect_host_and_services==FALSE) snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] %s_HOST_SVC_CHECKS;%s\n",current_time,(cmd==CMD_ENABLE_HOST_SVC_CHECKS)?"ENABLE":"DISABLE",host_name); else snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] %s_HOST_SVC_CHECKS;%s\n[%lu] %s_HOST_CHECK;%s\n",current_time,(cmd==CMD_ENABLE_HOST_SVC_CHECKS)?"ENABLE":"DISABLE",host_name,current_time,(cmd==CMD_ENABLE_HOST_SVC_CHECKS)?"ENABLE":"DISABLE",host_name); break; case CMD_SCHEDULE_HOST_SVC_CHECKS: snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] SCHEDULE_%sHOST_SVC_CHECKS;%s;%lu\n",current_time,(force_check==TRUE)?"FORCED_":"",host_name,scheduled_time); break; case CMD_DEL_ALL_HOST_COMMENTS: snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] DEL_ALL_HOST_COMMENTS;%s\n",current_time,host_name); break; case CMD_DEL_ALL_SVC_COMMENTS: snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] DEL_ALL_SVC_COMMENTS;%s;%s\n",current_time,host_name,service_desc); break; case CMD_ENABLE_SVC_NOTIFICATIONS: case CMD_DISABLE_SVC_NOTIFICATIONS: snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] %s_SVC_NOTIFICATIONS;%s;%s\n",current_time,(cmd==CMD_ENABLE_SVC_NOTIFICATIONS)?"ENABLE":"DISABLE",host_name,service_desc); break; case CMD_ENABLE_HOST_NOTIFICATIONS: case CMD_DISABLE_HOST_NOTIFICATIONS: if(propagate_to_children==TRUE) snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] %s_HOST_AND_CHILD_NOTIFICATIONS;%s\n",current_time,(cmd==CMD_ENABLE_HOST_NOTIFICATIONS)?"ENABLE":"DISABLE",host_name); else snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] %s_HOST_NOTIFICATIONS;%s\n",current_time,(cmd==CMD_ENABLE_HOST_NOTIFICATIONS)?"ENABLE":"DISABLE",host_name); break; case CMD_ENABLE_ALL_NOTIFICATIONS_BEYOND_HOST: case CMD_DISABLE_ALL_NOTIFICATIONS_BEYOND_HOST: snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] %s_ALL_NOTIFICATIONS_BEYOND_HOST;%s\n",current_time,(cmd==CMD_ENABLE_ALL_NOTIFICATIONS_BEYOND_HOST)?"ENABLE":"DISABLE",host_name); break; case CMD_ENABLE_HOST_SVC_NOTIFICATIONS: case CMD_DISABLE_HOST_SVC_NOTIFICATIONS: if(affect_host_and_services==FALSE) snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] %s_HOST_SVC_NOTIFICATIONS;%s\n",current_time,(cmd==CMD_ENABLE_HOST_SVC_NOTIFICATIONS)?"ENABLE":"DISABLE",host_name); else snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] %s_HOST_SVC_NOTIFICATIONS;%s\n[%lu] %s_HOST_NOTIFICATIONS;%s\n",current_time,(cmd==CMD_ENABLE_HOST_SVC_NOTIFICATIONS)?"ENABLE":"DISABLE",host_name,current_time,(cmd==CMD_ENABLE_HOST_SVC_NOTIFICATIONS)?"ENABLE":"DISABLE",host_name); break; case CMD_ACKNOWLEDGE_HOST_PROBLEM: snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] ACKNOWLEDGE_HOST_PROBLEM;%s;%d;%d;%d;%s;%s\n",current_time,host_name,(sticky_ack==TRUE)?ACKNOWLEDGEMENT_STICKY:ACKNOWLEDGEMENT_NORMAL,(send_notification==TRUE)?1:0,(persistent_comment==TRUE)?1:0,comment_author,comment_data); break; case CMD_ACKNOWLEDGE_SVC_PROBLEM: snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] ACKNOWLEDGE_SVC_PROBLEM;%s;%s;%d;%d;%d;%s;%s\n",current_time,host_name,service_desc,(sticky_ack==TRUE)?ACKNOWLEDGEMENT_STICKY:ACKNOWLEDGEMENT_NORMAL,(send_notification==TRUE)?1:0,(persistent_comment==TRUE)?1:0,comment_author,comment_data); break; case CMD_START_EXECUTING_SVC_CHECKS: case CMD_STOP_EXECUTING_SVC_CHECKS: snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] %s_EXECUTING_SVC_CHECKS;\n",current_time,(cmd==CMD_START_EXECUTING_SVC_CHECKS)?"START":"STOP"); break; case CMD_START_ACCEPTING_PASSIVE_SVC_CHECKS: case CMD_STOP_ACCEPTING_PASSIVE_SVC_CHECKS: snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] %s_ACCEPTING_PASSIVE_SVC_CHECKS;\n",current_time,(cmd==CMD_START_ACCEPTING_PASSIVE_SVC_CHECKS)?"START":"STOP"); break; case CMD_ENABLE_PASSIVE_SVC_CHECKS: case CMD_DISABLE_PASSIVE_SVC_CHECKS: snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] %s_PASSIVE_SVC_CHECKS;%s;%s\n",current_time,(cmd==CMD_ENABLE_PASSIVE_SVC_CHECKS)?"ENABLE":"DISABLE",host_name,service_desc); break; case CMD_ENABLE_EVENT_HANDLERS: case CMD_DISABLE_EVENT_HANDLERS: snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] %s_EVENT_HANDLERS;\n",current_time,(cmd==CMD_ENABLE_EVENT_HANDLERS)?"ENABLE":"DISABLE"); break; case CMD_ENABLE_SVC_EVENT_HANDLER: case CMD_DISABLE_SVC_EVENT_HANDLER: snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] %s_SVC_EVENT_HANDLER;%s;%s\n",current_time,(cmd==CMD_ENABLE_SVC_EVENT_HANDLER)?"ENABLE":"DISABLE",host_name,service_desc); break; case CMD_ENABLE_HOST_EVENT_HANDLER: case CMD_DISABLE_HOST_EVENT_HANDLER: snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] %s_HOST_EVENT_HANDLER;%s\n",current_time,(cmd==CMD_ENABLE_HOST_EVENT_HANDLER)?"ENABLE":"DISABLE",host_name); break; case CMD_ENABLE_HOST_CHECK: case CMD_DISABLE_HOST_CHECK: snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] %s_HOST_CHECK;%s\n",current_time,(cmd==CMD_ENABLE_HOST_CHECK)?"ENABLE":"DISABLE",host_name); break; case CMD_START_OBSESSING_OVER_SVC_CHECKS: case CMD_STOP_OBSESSING_OVER_SVC_CHECKS: snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] %s_OBSESSING_OVER_SVC_CHECKS;\n",current_time,(cmd==CMD_START_OBSESSING_OVER_SVC_CHECKS)?"START":"STOP"); break; case CMD_REMOVE_HOST_ACKNOWLEDGEMENT: snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] REMOVE_HOST_ACKNOWLEDGEMENT;%s\n",current_time,host_name); break; case CMD_REMOVE_SVC_ACKNOWLEDGEMENT: snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] REMOVE_SVC_ACKNOWLEDGEMENT;%s;%s\n",current_time,host_name,service_desc); break; case CMD_PROCESS_SERVICE_CHECK_RESULT: snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] PROCESS_SERVICE_CHECK_RESULT;%s;%s;%d;%s|%s\n",current_time,host_name,service_desc,plugin_state,plugin_output,performance_data); break; case CMD_PROCESS_HOST_CHECK_RESULT: snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] PROCESS_HOST_CHECK_RESULT;%s;%d;%s|%s\n",current_time,host_name,plugin_state,plugin_output,performance_data); break; case CMD_SCHEDULE_HOST_DOWNTIME: if(child_options==1) snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] SCHEDULE_AND_PROPAGATE_TRIGGERED_HOST_DOWNTIME;%s;%lu;%lu;%d;%lu;%lu;%s;%s\n",current_time,host_name,start_time,end_time,(fixed==TRUE)?1:0,triggered_by,duration,comment_author,comment_data); else if(child_options==2) snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] SCHEDULE_AND_PROPAGATE_HOST_DOWNTIME;%s;%lu;%lu;%d;%lu;%lu;%s;%s\n",current_time,host_name,start_time,end_time,(fixed==TRUE)?1:0,triggered_by,duration,comment_author,comment_data); else snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] SCHEDULE_HOST_DOWNTIME;%s;%lu;%lu;%d;%lu;%lu;%s;%s\n",current_time,host_name,start_time,end_time,(fixed==TRUE)?1:0,triggered_by,duration,comment_author,comment_data); break; case CMD_SCHEDULE_SVC_DOWNTIME: snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] SCHEDULE_SVC_DOWNTIME;%s;%s;%lu;%lu;%d;%lu;%lu;%s;%s\n",current_time,host_name,service_desc,start_time,end_time,(fixed==TRUE)?1:0,triggered_by,duration,comment_author,comment_data); break; case CMD_ENABLE_HOST_FLAP_DETECTION: case CMD_DISABLE_HOST_FLAP_DETECTION: snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] %s_HOST_FLAP_DETECTION;%s\n",current_time,(cmd==CMD_ENABLE_HOST_FLAP_DETECTION)?"ENABLE":"DISABLE",host_name); break; case CMD_ENABLE_SVC_FLAP_DETECTION: case CMD_DISABLE_SVC_FLAP_DETECTION: snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] %s_SVC_FLAP_DETECTION;%s;%s\n",current_time,(cmd==CMD_ENABLE_SVC_FLAP_DETECTION)?"ENABLE":"DISABLE",host_name,service_desc); break; case CMD_ENABLE_FLAP_DETECTION: case CMD_DISABLE_FLAP_DETECTION: snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] %s_FLAP_DETECTION\n",current_time,(cmd==CMD_ENABLE_FLAP_DETECTION)?"ENABLE":"DISABLE"); break; case CMD_DEL_HOST_DOWNTIME: case CMD_DEL_SVC_DOWNTIME: snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] DEL_%s_DOWNTIME;%lu\n",current_time,(cmd==CMD_DEL_HOST_DOWNTIME)?"HOST":"SVC",downtime_id); break; case CMD_ENABLE_FAILURE_PREDICTION: case CMD_DISABLE_FAILURE_PREDICTION: snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] %s_FAILURE_PREDICTION\n",current_time,(cmd==CMD_ENABLE_FAILURE_PREDICTION)?"ENABLE":"DISABLE"); break; case CMD_ENABLE_PERFORMANCE_DATA: case CMD_DISABLE_PERFORMANCE_DATA: snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] %s_PERFORMANCE_DATA\n",current_time,(cmd==CMD_ENABLE_PERFORMANCE_DATA)?"ENABLE":"DISABLE"); break; case CMD_START_EXECUTING_HOST_CHECKS: case CMD_STOP_EXECUTING_HOST_CHECKS: snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] %s_EXECUTING_HOST_CHECKS;\n",current_time,(cmd==CMD_START_EXECUTING_HOST_CHECKS)?"START":"STOP"); break; case CMD_START_ACCEPTING_PASSIVE_HOST_CHECKS: case CMD_STOP_ACCEPTING_PASSIVE_HOST_CHECKS: snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] %s_ACCEPTING_PASSIVE_HOST_CHECKS;\n",current_time,(cmd==CMD_START_ACCEPTING_PASSIVE_HOST_CHECKS)?"START":"STOP"); break; case CMD_ENABLE_PASSIVE_HOST_CHECKS: case CMD_DISABLE_PASSIVE_HOST_CHECKS: snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] %s_PASSIVE_HOST_CHECKS;%s\n",current_time,(cmd==CMD_ENABLE_PASSIVE_HOST_CHECKS)?"ENABLE":"DISABLE",host_name); break; case CMD_START_OBSESSING_OVER_HOST_CHECKS: case CMD_STOP_OBSESSING_OVER_HOST_CHECKS: snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] %s_OBSESSING_OVER_HOST_CHECKS;\n",current_time,(cmd==CMD_START_OBSESSING_OVER_HOST_CHECKS)?"START":"STOP"); break; case CMD_SCHEDULE_HOST_CHECK: snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] SCHEDULE_%sHOST_CHECK;%s;%lu\n",current_time,(force_check==TRUE)?"FORCED_":"",host_name,start_time); break; case CMD_START_OBSESSING_OVER_SVC: case CMD_STOP_OBSESSING_OVER_SVC: snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] %s_OBSESSING_OVER_SVC;%s;%s\n",current_time,(cmd==CMD_START_OBSESSING_OVER_SVC)?"START":"STOP",host_name,service_desc); break; case CMD_START_OBSESSING_OVER_HOST: case CMD_STOP_OBSESSING_OVER_HOST: snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] %s_OBSESSING_OVER_HOST;%s\n",current_time,(cmd==CMD_START_OBSESSING_OVER_HOST)?"START":"STOP",host_name); break; /***** HOSTGROUP COMMANDS *****/ case CMD_ENABLE_HOSTGROUP_SVC_NOTIFICATIONS: case CMD_DISABLE_HOSTGROUP_SVC_NOTIFICATIONS: if(affect_host_and_services==FALSE) snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] %s_HOSTGROUP_SVC_NOTIFICATIONS;%s\n",current_time,(cmd==CMD_ENABLE_HOSTGROUP_SVC_NOTIFICATIONS)?"ENABLE":"DISABLE",hostgroup_name); else snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] %s_HOSTGROUP_SVC_NOTIFICATIONS;%s\n[%lu] %s_HOSTGROUP_HOST_NOTIFICATIONS;%s\n",current_time,(cmd==CMD_ENABLE_HOSTGROUP_SVC_NOTIFICATIONS)?"ENABLE":"DISABLE",hostgroup_name,current_time,(cmd==CMD_ENABLE_HOSTGROUP_SVC_NOTIFICATIONS)?"ENABLE":"DISABLE",hostgroup_name); break; case CMD_ENABLE_HOSTGROUP_HOST_NOTIFICATIONS: case CMD_DISABLE_HOSTGROUP_HOST_NOTIFICATIONS: snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] %s_HOSTGROUP_HOST_NOTIFICATIONS;%s\n",current_time,(cmd==CMD_ENABLE_HOSTGROUP_HOST_NOTIFICATIONS)?"ENABLE":"DISABLE",hostgroup_name); break; case CMD_ENABLE_HOSTGROUP_SVC_CHECKS: case CMD_DISABLE_HOSTGROUP_SVC_CHECKS: if(affect_host_and_services==FALSE) snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] %s_HOSTGROUP_SVC_CHECKS;%s\n",current_time,(cmd==CMD_ENABLE_HOSTGROUP_SVC_CHECKS)?"ENABLE":"DISABLE",hostgroup_name); else snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] %s_HOSTGROUP_SVC_CHECKS;%s\n[%lu] %s_HOSTGROUP_HOST_CHECKS;%s\n",current_time,(cmd==CMD_ENABLE_HOSTGROUP_SVC_CHECKS)?"ENABLE":"DISABLE",hostgroup_name,current_time,(cmd==CMD_ENABLE_HOSTGROUP_SVC_CHECKS)?"ENABLE":"DISABLE",hostgroup_name); break; case CMD_SCHEDULE_HOSTGROUP_HOST_DOWNTIME: snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] SCHEDULE_HOSTGROUP_HOST_DOWNTIME;%s;%lu;%lu;%d;0;%lu;%s;%s\n",current_time,hostgroup_name,start_time,end_time,(fixed==TRUE)?1:0,duration,comment_author,comment_data); break; case CMD_SCHEDULE_HOSTGROUP_SVC_DOWNTIME: if(affect_host_and_services==FALSE) snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] SCHEDULE_HOSTGROUP_SVC_DOWNTIME;%s;%lu;%lu;%d;0;%lu;%s;%s\n",current_time,hostgroup_name,start_time,end_time,(fixed==TRUE)?1:0,duration,comment_author,comment_data); else snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] SCHEDULE_HOSTGROUP_SVC_DOWNTIME;%s;%lu;%lu;%d;0;%lu;%s;%s\n[%lu] SCHEDULE_HOSTGROUP_HOST_DOWNTIME;%s;%lu;%lu;%d;%lu;%s;%s\n",current_time,hostgroup_name,start_time,end_time,(fixed==TRUE)?1:0,duration,comment_author,comment_data,current_time,hostgroup_name,start_time,end_time,(fixed==TRUE)?1:0,duration,comment_author,comment_data); break; /***** SERVICEGROUP COMMANDS *****/ case CMD_ENABLE_SERVICEGROUP_SVC_NOTIFICATIONS: case CMD_DISABLE_SERVICEGROUP_SVC_NOTIFICATIONS: if(affect_host_and_services==FALSE) snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] %s_SERVICEGROUP_SVC_NOTIFICATIONS;%s\n",current_time,(cmd==CMD_ENABLE_SERVICEGROUP_SVC_NOTIFICATIONS)?"ENABLE":"DISABLE",servicegroup_name); else snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] %s_SERVICEGROUP_SVC_NOTIFICATIONS;%s\n[%lu] %s_SERVICEGROUP_HOST_NOTIFICATIONS;%s\n",current_time,(cmd==CMD_ENABLE_SERVICEGROUP_SVC_NOTIFICATIONS)?"ENABLE":"DISABLE",servicegroup_name,current_time,(cmd==CMD_ENABLE_SERVICEGROUP_SVC_NOTIFICATIONS)?"ENABLE":"DISABLE",servicegroup_name); break; case CMD_ENABLE_SERVICEGROUP_HOST_NOTIFICATIONS: case CMD_DISABLE_SERVICEGROUP_HOST_NOTIFICATIONS: snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] %s_SERVICEGROUP_HOST_NOTIFICATIONS;%s\n",current_time,(cmd==CMD_ENABLE_SERVICEGROUP_HOST_NOTIFICATIONS)?"ENABLE":"DISABLE",servicegroup_name); break; case CMD_ENABLE_SERVICEGROUP_SVC_CHECKS: case CMD_DISABLE_SERVICEGROUP_SVC_CHECKS: if(affect_host_and_services==FALSE) snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] %s_SERVICEGROUP_SVC_CHECKS;%s\n",current_time,(cmd==CMD_ENABLE_SERVICEGROUP_SVC_CHECKS)?"ENABLE":"DISABLE",servicegroup_name); else snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] %s_SERVICEGROUP_SVC_CHECKS;%s\n[%lu] %s_SERVICEGROUP_HOST_CHECKS;%s\n",current_time,(cmd==CMD_ENABLE_SERVICEGROUP_SVC_CHECKS)?"ENABLE":"DISABLE",servicegroup_name,current_time,(cmd==CMD_ENABLE_SERVICEGROUP_SVC_CHECKS)?"ENABLE":"DISABLE",servicegroup_name); break; case CMD_SCHEDULE_SERVICEGROUP_HOST_DOWNTIME: snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] SCHEDULE_SERVICEGROUP_HOST_DOWNTIME;%s;%lu;%lu;%d;0;%lu;%s;%s\n",current_time,servicegroup_name,start_time,end_time,(fixed==TRUE)?1:0,duration,comment_author,comment_data); break; case CMD_SCHEDULE_SERVICEGROUP_SVC_DOWNTIME: if(affect_host_and_services==FALSE) snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] SCHEDULE_SERVICEGROUP_SVC_DOWNTIME;%s;%lu;%lu;%d;0;%lu;%s;%s\n",current_time,servicegroup_name,start_time,end_time,(fixed==TRUE)?1:0,duration,comment_author,comment_data); else snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] SCHEDULE_SERVICEGROUP_SVC_DOWNTIME;%s;%lu;%lu;%d;0;%lu;%s;%s\n[%lu] SCHEDULE_SERVICEGROUP_HOST_DOWNTIME;%s;%lu;%lu;%d;%lu;%s;%s\n",current_time,servicegroup_name,start_time,end_time,(fixed==TRUE)?1:0,duration,comment_author,comment_data,current_time,servicegroup_name,start_time,end_time,(fixed==TRUE)?1:0,duration,comment_author,comment_data); break; default: return ERROR; break; } /* make sure command buffer is terminated */ command_buffer[sizeof(command_buffer)-1]='\x0'; /* write the command to the command file */ result=write_command_to_file(command_buffer); return result; } /* write a command entry to the command file */ int write_command_to_file(char *cmd){ FILE *fp; struct stat statbuf; /* bail out if the external command file doesn't exist */ if(stat(command_file,&statbuf)){ if(content_type==WML_CONTENT) printf("

    Error: Could not stat() external command file!

    \n"); else{ printf("

    Error: Could not stat() command file '%s'!

    \n",command_file); printf("

    "); printf("The external command file may be missing, Nagios may not be running, and/or Nagios may not be checking external commands.\n"); printf("

    \n"); } return ERROR; } /* open the command for writing (since this is a pipe, it will really be appended) */ fp=fopen(command_file,"w"); if(fp==NULL){ if(content_type==WML_CONTENT) printf("

    Error: Could not open command file for update!

    \n"); else{ printf("

    Error: Could not open command file '%s' for update!

    \n",command_file); printf("

    "); printf("The permissions on the external command file and/or directory may be incorrect. Read the FAQs on how to setup proper permissions.\n"); printf("

    \n"); } return ERROR; } /* write the command to file */ fputs(cmd,fp); /* flush buffer */ fflush(fp); fclose(fp); return OK; } /* strips out semicolons from comment data */ void clean_comment_data(char *buffer){ int x; int y; y=(int)strlen(buffer); for(x=0;xCommand Description
    \n"); printf("\n"); printf("\n"); printf("
    \n"); /* decide what information to print out... */ switch(cmd){ case CMD_ADD_HOST_COMMENT: printf("This command is used to add a comment for the specified host. If you work with other administrators, you may find it useful to share information about a host\n"); printf("that is having problems if more than one of you may be working on it. If you do not check the 'persistent' option, the comment will be automatically be deleted\n"); printf("the next time Nagios is restarted.\n"); break; case CMD_ADD_SVC_COMMENT: printf("This command is used to add a comment for the specified service. If you work with other administrators, you may find it useful to share information about a host\n"); printf("or service that is having problems if more than one of you may be working on it. If you do not check the 'persistent' option, the comment will automatically be\n"); printf("deleted the next time Nagios is restarted.\n"); break; case CMD_DEL_HOST_COMMENT: printf("This command is used to delete a specific host comment.\n"); break; case CMD_DEL_SVC_COMMENT: printf("This command is used to delete a specific service comment.\n"); break; case CMD_DELAY_HOST_NOTIFICATION: printf("This command is used to delay the next problem notification that is sent out for the specified host. The notification delay will be disregarded if\n"); printf("the host changes state before the next notification is scheduled to be sent out. This command has no effect if the host is currently UP.\n"); break; case CMD_DELAY_SVC_NOTIFICATION: printf("This command is used to delay the next problem notification that is sent out for the specified service. The notification delay will be disregarded if\n"); printf("the service changes state before the next notification is scheduled to be sent out. This command has no effect if the service is currently in an OK state.\n"); break; case CMD_SCHEDULE_SVC_CHECK: printf("This command is used to schedule the next check of a particular service. Nagios will re-queue the service to be checked at the time you specify.\n"); printf("If you select the force check option, Nagios will force a check of the service regardless of both what time the scheduled check occurs and whether or not checks are enabled for the service.\n"); break; case CMD_ENABLE_SVC_CHECK: printf("This command is used to enable active checks of a service.\n"); break; case CMD_DISABLE_SVC_CHECK: printf("This command is used to disable active checks of a service.\n"); break; case CMD_DISABLE_NOTIFICATIONS: printf("This command is used to disable host and service notifications on a program-wide basis.\n"); break; case CMD_ENABLE_NOTIFICATIONS: printf("This command is used to enable host and service notifications on a program-wide basis.\n"); break; case CMD_SHUTDOWN_PROCESS: printf("This command is used to shutdown the Nagios process. Note: Once the Nagios has been shutdown, it cannot be restarted via the web interface!\n"); break; case CMD_RESTART_PROCESS: printf("This command is used to restart the Nagios process. Executing a restart command is equivalent to sending the process a HUP signal.\n"); printf("All information will be flushed from memory, the configuration files will be re-read, and Nagios will start monitoring with the new configuration information.\n"); break; case CMD_ENABLE_HOST_SVC_CHECKS: printf("This command is used to enable active checks of all services associated with the specified host. This does not enable checks of the host unless you check the 'Enable for host too' option.\n"); break; case CMD_DISABLE_HOST_SVC_CHECKS: printf("This command is used to disable active checks of all services associated with the specified host. When a service is disabled Nagios will not monitor the service. Doing this will prevent any notifications being sent out for\n"); printf("the specified service while it is disabled. In order to have Nagios check the service in the future you will have to re-enable the service.\n"); printf("Note that disabling service checks may not necessarily prevent notifications from being sent out about the host which those services are associated with. This does not disable checks of the host unless you check the 'Disable for host too' option.\n"); break; case CMD_SCHEDULE_HOST_SVC_CHECKS: printf("This command is used to scheduled the next check of all services on the specified host. If you select the force check option, Nagios will force a check of all services on the host regardless of both what time the scheduled checks occur and whether or not checks are enabled for those services.\n"); break; case CMD_DEL_ALL_HOST_COMMENTS: printf("This command is used to delete all comments associated with the specified host.\n"); break; case CMD_DEL_ALL_SVC_COMMENTS: printf("This command is used to delete all comments associated with the specified service.\n"); break; case CMD_ENABLE_SVC_NOTIFICATIONS: printf("This command is used to enable notifications for the specified service. Notifications will only be sent out for the\n"); printf("service state types you defined in your service definition.\n"); break; case CMD_DISABLE_SVC_NOTIFICATIONS: printf("This command is used to prevent notifications from being sent out for the specified service. You will have to re-enable notifications\n"); printf("for this service before any alerts can be sent out in the future.\n"); break; case CMD_ENABLE_HOST_NOTIFICATIONS: printf("This command is used to enable notifications for the specified host. Notifications will only be sent out for the\n"); printf("host state types you defined in your host definition. Note that this command does not enable notifications\n"); printf("for services associated with this host.\n"); break; case CMD_DISABLE_HOST_NOTIFICATIONS: printf("This command is used to prevent notifications from being sent out for the specified host. You will have to re-enable notifications for this host\n"); printf("before any alerts can be sent out in the future. Note that this command does not disable notifications for services associated with this host.\n"); break; case CMD_ENABLE_ALL_NOTIFICATIONS_BEYOND_HOST: printf("This command is used to enable notifications for all hosts and services that lie \"beyond\" the specified host\n"); printf("(from the view of Nagios).\n"); break; case CMD_DISABLE_ALL_NOTIFICATIONS_BEYOND_HOST: printf("This command is used to temporarily prevent notifications from being sent out for all hosts and services that lie\n"); printf("\"beyone\" the specified host (from the view of Nagios).\n"); break; case CMD_ENABLE_HOST_SVC_NOTIFICATIONS: printf("This command is used to enable notifications for all services on the specified host. Notifications will only be sent out for the\n"); printf("service state types you defined in your service definition. This does not enable notifications for the host unless you check the 'Enable for host too' option.\n"); break; case CMD_DISABLE_HOST_SVC_NOTIFICATIONS: printf("This command is used to prevent notifications from being sent out for all services on the specified host. You will have to re-enable notifications for\n"); printf("all services associated with this host before any alerts can be sent out in the future. This does not prevent notifications from being sent out about the host unless you check the 'Disable for host too' option.\n"); break; case CMD_ACKNOWLEDGE_HOST_PROBLEM: printf("This command is used to acknowledge a host problem. When a host problem is acknowledged, future notifications about problems are temporarily disabled until the host changes from its current state.\n"); printf("If you want acknowledgement to disable notifications until the host recovers, check the 'Sticky Acknowledgement' checkbox.\n"); printf("Contacts for this host will receive a notification about the acknowledgement, so they are aware that someone is working on the problem. Additionally, a comment will also be added to the host.\n"); printf("Make sure to enter your name and fill in a brief description of what you are doing in the comment field. If you would like the host comment to be retained between restarts of Nagios, check\n"); printf("the 'Persistent Comment' checkbox. If you do not want an acknowledgement notification sent out to the appropriate contacts, uncheck the 'Send Notification' checkbox.\n"); break; case CMD_ACKNOWLEDGE_SVC_PROBLEM: printf("This command is used to acknowledge a service problem. When a service problem is acknowledged, future notifications about problems are temporarily disabled until the service changes from its current state.\n"); printf("If you want acknowledgement to disable notifications until the service recovers, check the 'Sticky Acknowledgement' checkbox.\n"); printf("Contacts for this service will receive a notification about the acknowledgement, so they are aware that someone is working on the problem. Additionally, a comment will also be added to the service.\n"); printf("Make sure to enter your name and fill in a brief description of what you are doing in the comment field. If you would like the service comment to be retained between restarts of Nagios, check\n"); printf("the 'Persistent Comment' checkbox. If you do not want an acknowledgement notification sent out to the appropriate contacts, uncheck the 'Send Notification' checkbox.\n"); break; case CMD_START_EXECUTING_SVC_CHECKS: printf("This command is used to resume execution of active service checks on a program-wide basis. Individual services which are disabled will still not be checked.\n"); break; case CMD_STOP_EXECUTING_SVC_CHECKS: printf("This command is used to temporarily stop Nagios from actively executing any service checks. This will have the side effect of preventing any notifications from being sent out (for any and all services and hosts).\n"); printf("Service checks will not be executed again until you issue a command to resume service check execution.\n"); break; case CMD_START_ACCEPTING_PASSIVE_SVC_CHECKS: printf("This command is used to make Nagios start accepting passive service check results that it finds in the external command file\n"); break; case CMD_STOP_ACCEPTING_PASSIVE_SVC_CHECKS: printf("This command is use to make Nagios stop accepting passive service check results that it finds in the external command file. All passive check results that are found will be ignored.\n"); break; case CMD_ENABLE_PASSIVE_SVC_CHECKS: printf("This command is used to allow Nagios to accept passive service check results that it finds in the external command file for this particular service.\n"); break; case CMD_DISABLE_PASSIVE_SVC_CHECKS: printf("This command is used to stop Nagios accepting passive service check results that it finds in the external command file for this particular service. All passive check results that are found for this service will be ignored.\n"); break; case CMD_ENABLE_EVENT_HANDLERS: printf("This command is used to allow Nagios to run host and service event handlers.\n"); break; case CMD_DISABLE_EVENT_HANDLERS: printf("This command is used to temporarily prevent Nagios from running any host or service event handlers.\n"); break; case CMD_ENABLE_SVC_EVENT_HANDLER: printf("This command is used to allow Nagios to run the service event handler for a particular service when necessary (if one is defined).\n"); break; case CMD_DISABLE_SVC_EVENT_HANDLER: printf("This command is used to temporarily prevent Nagios from running the service event handler for a particular service.\n"); break; case CMD_ENABLE_HOST_EVENT_HANDLER: printf("This command is used to allow Nagios to run the host event handler for a particular service when necessary (if one is defined).\n"); break; case CMD_DISABLE_HOST_EVENT_HANDLER: printf("This command is used to temporarily prevent Nagios from running the host event handler for a particular host.\n"); break; case CMD_ENABLE_HOST_CHECK: printf("This command is used to enable active checks of this host.\n"); break; case CMD_DISABLE_HOST_CHECK: printf("This command is used to temporarily prevent Nagios from actively checking the status of a particular host. If Nagios needs to check the status of this host, it will assume that it is in the same state that it was in before checks were disabled.\n"); break; case CMD_START_OBSESSING_OVER_SVC_CHECKS: printf("This command is used to have Nagios start obsessing over service checks. Read the documentation on distributed monitoring for more information on this.\n"); break; case CMD_STOP_OBSESSING_OVER_SVC_CHECKS: printf("This command is used stop Nagios from obsessing over service checks.\n"); break; case CMD_REMOVE_HOST_ACKNOWLEDGEMENT: printf("This command is used to remove an acknowledgement for a particular host problem. Once the acknowledgement is removed, notifications may start being\n"); printf("sent out about the host problem. Note: Removing the acknowledgement does not remove the host comment that was originally associated\n"); printf("with the acknowledgement. You'll have to remove that as well if that's what you want.\n"); break; case CMD_REMOVE_SVC_ACKNOWLEDGEMENT: printf("This command is used to remove an acknowledgement for a particular service problem. Once the acknowledgement is removed, notifications may start being\n"); printf("sent out about the service problem. Note: Removing the acknowledgement does not remove the service comment that was originally associated\n"); printf("with the acknowledgement. You'll have to remove that as well if that's what you want.\n"); break; case CMD_PROCESS_SERVICE_CHECK_RESULT: printf("This command is used to submit a passive check result for a particular service. It is particularly useful for resetting security-related services to OK states once they have been dealt with.\n"); break; case CMD_PROCESS_HOST_CHECK_RESULT: printf("This command is used to submit a passive check result for a particular host.\n"); break; case CMD_SCHEDULE_HOST_DOWNTIME: printf("This command is used to schedule downtime for a particular host. During the specified downtime, Nagios will not send notifications out about the host.\n"); printf("When the scheduled downtime expires, Nagios will send out notifications for this host as it normally would. Scheduled downtimes are preserved\n"); printf("across program shutdowns and restarts. Both the start and end times should be specified in the following format: mm/dd/yyyy hh:mm:ss.\n"); printf("If you select the fixed option, the downtime will be in effect between the start and end times you specify. If you do not select the fixed\n"); printf("option, Nagios will treat this as \"flexible\" downtime. Flexible downtime starts when the host goes down or becomes unreachable (sometime between the\n"); printf("start and end times you specified) and lasts as long as the duration of time you enter. The duration fields do not apply for fixed downtime.\n"); break; case CMD_SCHEDULE_SVC_DOWNTIME: printf("This command is used to schedule downtime for a particular service. During the specified downtime, Nagios will not send notifications out about the service.\n"); printf("When the scheduled downtime expires, Nagios will send out notifications for this service as it normally would. Scheduled downtimes are preserved\n"); printf("across program shutdowns and restarts. Both the start and end times should be specified in the following format: mm/dd/yyyy hh:mm:ss.\n"); printf("option, Nagios will treat this as \"flexible\" downtime. Flexible downtime starts when the service enters a non-OK state (sometime between the\n"); printf("start and end times you specified) and lasts as long as the duration of time you enter. The duration fields do not apply for fixed downtime.\n"); break; case CMD_ENABLE_HOST_FLAP_DETECTION: printf("This command is used to enable flap detection for a specific host. If flap detection is disabled on a program-wide basis, this will have no effect,\n"); break; case CMD_DISABLE_HOST_FLAP_DETECTION: printf("This command is used to disable flap detection for a specific host.\n"); break; case CMD_ENABLE_SVC_FLAP_DETECTION: printf("This command is used to enable flap detection for a specific service. If flap detection is disabled on a program-wide basis, this will have no effect,\n"); break; case CMD_DISABLE_SVC_FLAP_DETECTION: printf("This command is used to disable flap detection for a specific service.\n"); break; case CMD_ENABLE_FLAP_DETECTION: printf("This command is used to enable flap detection for hosts and services on a program-wide basis. Individual hosts and services may have flap detection disabled.\n"); break; case CMD_DISABLE_FLAP_DETECTION: printf("This command is used to disable flap detection for hosts and services on a program-wide basis.\n"); break; case CMD_ENABLE_HOSTGROUP_SVC_NOTIFICATIONS: printf("This command is used to enable notifications for all services in the specified hostgroup. Notifications will only be sent out for the\n"); printf("service state types you defined in your service definitions. This does not enable notifications for the hosts in this hostgroup unless you check the 'Enable for hosts too' option.\n"); break; case CMD_DISABLE_HOSTGROUP_SVC_NOTIFICATIONS: printf("This command is used to prevent notifications from being sent out for all services in the specified hostgroup. You will have to re-enable notifications for\n"); printf("all services in this hostgroup before any alerts can be sent out in the future. This does not prevent notifications from being sent out about the hosts in this hostgroup unless you check the 'Disable for hosts too' option.\n"); break; case CMD_ENABLE_HOSTGROUP_HOST_NOTIFICATIONS: printf("This command is used to enable notifications for all hosts in the specified hostgroup. Notifications will only be sent out for the\n"); printf("host state types you defined in your host definitions.\n"); break; case CMD_DISABLE_HOSTGROUP_HOST_NOTIFICATIONS: printf("This command is used to prevent notifications from being sent out for all hosts in the specified hostgroup. You will have to re-enable notifications for\n"); printf("all hosts in this hostgroup before any alerts can be sent out in the future.\n"); break; case CMD_ENABLE_HOSTGROUP_SVC_CHECKS: printf("This command is used to enable active checks of all services in the specified hostgroup. This does not enable active checks of the hosts in the hostgroup unless you check the 'Enable for hosts too' option.\n"); break; case CMD_DISABLE_HOSTGROUP_SVC_CHECKS: printf("This command is used to disable active checks of all services in the specified hostgroup. This does not disable checks of the hosts in the hostgroup unless you check the 'Disable for hosts too' option.\n"); break; case CMD_DEL_HOST_DOWNTIME: printf("This command is used to cancel active or pending scheduled downtime for the specified host.\n"); break; case CMD_DEL_SVC_DOWNTIME: printf("This command is used to cancel active or pending scheduled downtime for the specified service.\n"); break; case CMD_ENABLE_FAILURE_PREDICTION: printf("This command is used to enable failure prediction for hosts and services on a program-wide basis. Individual hosts and services may have failure prediction disabled.\n"); break; case CMD_DISABLE_FAILURE_PREDICTION: printf("This command is used to disable failure prediction for hosts and services on a program-wide basis.\n"); break; case CMD_ENABLE_PERFORMANCE_DATA: printf("This command is used to enable the processing of performance data for hosts and services on a program-wide basis. Individual hosts and services may have performance data processing disabled.\n"); break; case CMD_DISABLE_PERFORMANCE_DATA: printf("This command is used to disable the processing of performance data for hosts and services on a program-wide basis.\n"); break; case CMD_SCHEDULE_HOSTGROUP_HOST_DOWNTIME: printf("This command is used to schedule downtime for all hosts in a particular hostgroup. During the specified downtime, Nagios will not send notifications out about the hosts.\n"); printf("When the scheduled downtime expires, Nagios will send out notifications for the hosts as it normally would. Scheduled downtimes are preserved\n"); printf("across program shutdowns and restarts. Both the start and end times should be specified in the following format: mm/dd/yyyy hh:mm:ss.\n"); printf("If you select the fixed option, the downtime will be in effect between the start and end times you specify. If you do not select the fixed\n"); printf("option, Nagios will treat this as \"flexible\" downtime. Flexible downtime starts when a host goes down or becomes unreachable (sometime between the\n"); printf("start and end times you specified) and lasts as long as the duration of time you enter. The duration fields do not apply for fixed dowtime.\n"); break; case CMD_SCHEDULE_HOSTGROUP_SVC_DOWNTIME: printf("This command is used to schedule downtime for all services in a particular hostgroup. During the specified downtime, Nagios will not send notifications out about the services.\n"); printf("When the scheduled downtime expires, Nagios will send out notifications for the services as it normally would. Scheduled downtimes are preserved\n"); printf("across program shutdowns and restarts. Both the start and end times should be specified in the following format: mm/dd/yyyy hh:mm:ss.\n"); printf("If you select the fixed option, the downtime will be in effect between the start and end times you specify. If you do not select the fixed\n"); printf("option, Nagios will treat this as \"flexible\" downtime. Flexible downtime starts when a service enters a non-OK state (sometime between the\n"); printf("start and end times you specified) and lasts as long as the duration of time you enter. The duration fields do not apply for fixed dowtime.\n"); printf("Note that scheduling downtime for services does not automatically schedule downtime for the hosts those services are associated with. If you want to also schedule downtime for all hosts in the hostgroup, check the 'Schedule downtime for hosts too' option.\n"); break; case CMD_START_EXECUTING_HOST_CHECKS: printf("This command is used to enable active host checks on a program-wide basis.\n"); break; case CMD_STOP_EXECUTING_HOST_CHECKS: printf("This command is used to disable active host checks on a program-wide basis.\n"); break; case CMD_START_ACCEPTING_PASSIVE_HOST_CHECKS: printf("This command is used to have Nagios start obsessing over host checks. Read the documentation on distributed monitoring for more information on this.\n"); break; case CMD_STOP_ACCEPTING_PASSIVE_HOST_CHECKS: printf("This command is used to stop Nagios from obsessing over host checks.\n"); break; case CMD_ENABLE_PASSIVE_HOST_CHECKS: printf("This command is used to allow Nagios to accept passive host check results that it finds in the external command file for a particular host.\n"); break; case CMD_DISABLE_PASSIVE_HOST_CHECKS: printf("This command is used to stop Nagios from accepting passive host check results that it finds in the external command file for a particular host. All passive check results that are found for this host will be ignored.\n"); break; case CMD_START_OBSESSING_OVER_HOST_CHECKS: printf("This command is used to have Nagios start obsessing over host checks. Read the documentation on distributed monitoring for more information on this.\n"); break; case CMD_STOP_OBSESSING_OVER_HOST_CHECKS: printf("This command is used to stop Nagios from obsessing over host checks.\n"); break; case CMD_SCHEDULE_HOST_CHECK: printf("This command is used to schedule the next check of a particular host. Nagios will re-queue the host to be checked at the time you specify.\n"); printf("If you select the force check option, Nagios will force a check of the host regardless of both what time the scheduled check occurs and whether or not checks are enabled for the host.\n"); break; case CMD_START_OBSESSING_OVER_SVC: printf("This command is used to have Nagios start obsessing over a particular service.\n"); break; case CMD_STOP_OBSESSING_OVER_SVC: printf("This command is used to stop Nagios from obsessing over a particular service.\n"); break; case CMD_START_OBSESSING_OVER_HOST: printf("This command is used to have Nagios start obsessing over a particular host.\n"); break; case CMD_STOP_OBSESSING_OVER_HOST: printf("This command is used to stop Nagios from obsessing over a particular host.\n"); break; case CMD_ENABLE_SERVICEGROUP_SVC_NOTIFICATIONS: printf("This command is used to enable notifications for all services in the specified servicegroup. Notifications will only be sent out for the\n"); printf("service state types you defined in your service definitions. This does not enable notifications for the hosts in this servicegroup unless you check the 'Enable for hosts too' option.\n"); break; case CMD_DISABLE_SERVICEGROUP_SVC_NOTIFICATIONS: printf("This command is used to prevent notifications from being sent out for all services in the specified servicegroup. You will have to re-enable notifications for\n"); printf("all services in this servicegroup before any alerts can be sent out in the future. This does not prevent notifications from being sent out about the hosts in this servicegroup unless you check the 'Disable for hosts too' option.\n"); break; case CMD_ENABLE_SERVICEGROUP_HOST_NOTIFICATIONS: printf("This command is used to enable notifications for all hosts in the specified servicegroup. Notifications will only be sent out for the\n"); printf("host state types you defined in your host definitions.\n"); break; case CMD_DISABLE_SERVICEGROUP_HOST_NOTIFICATIONS: printf("This command is used to prevent notifications from being sent out for all hosts in the specified servicegroup. You will have to re-enable notifications for\n"); printf("all hosts in this servicegroup before any alerts can be sent out in the future.\n"); break; case CMD_ENABLE_SERVICEGROUP_SVC_CHECKS: printf("This command is used to enable active checks of all services in the specified servicegroup. This does not enable active checks of the hosts in the servicegroup unless you check the 'Enable for hosts too' option.\n"); break; case CMD_DISABLE_SERVICEGROUP_SVC_CHECKS: printf("This command is used to disable active checks of all services in the specified servicegroup. This does not disable checks of the hosts in the servicegroup unless you check the 'Disable for hosts too' option.\n"); break; case CMD_SCHEDULE_SERVICEGROUP_HOST_DOWNTIME: printf("This command is used to schedule downtime for all hosts in a particular servicegroup. During the specified downtime, Nagios will not send notifications out about the hosts.\n"); printf("When the scheduled downtime expires, Nagios will send out notifications for the hosts as it normally would. Scheduled downtimes are preserved\n"); printf("across program shutdowns and restarts. Both the start and end times should be specified in the following format: mm/dd/yyyy hh:mm:ss.\n"); printf("If you select the fixed option, the downtime will be in effect between the start and end times you specify. If you do not select the fixed\n"); printf("option, Nagios will treat this as \"flexible\" downtime. Flexible downtime starts when a host goes down or becomes unreachable (sometime between the\n"); printf("start and end times you specified) and lasts as long as the duration of time you enter. The duration fields do not apply for fixed dowtime.\n"); break; case CMD_SCHEDULE_SERVICEGROUP_SVC_DOWNTIME: printf("This command is used to schedule downtime for all services in a particular servicegroup. During the specified downtime, Nagios will not send notifications out about the services.\n"); printf("When the scheduled downtime expires, Nagios will send out notifications for the services as it normally would. Scheduled downtimes are preserved\n"); printf("across program shutdowns and restarts. Both the start and end times should be specified in the following format: mm/dd/yyyy hh:mm:ss.\n"); printf("If you select the fixed option, the downtime will be in effect between the start and end times you specify. If you do not select the fixed\n"); printf("option, Nagios will treat this as \"flexible\" downtime. Flexible downtime starts when a service enters a non-OK state (sometime between the\n"); printf("start and end times you specified) and lasts as long as the duration of time you enter. The duration fields do not apply for fixed dowtime.\n"); printf("Note that scheduling downtime for services does not automatically schedule downtime for the hosts those services are associated with. If you want to also schedule downtime for all hosts in the servicegroup, check the 'Schedule downtime for hosts too' option.\n"); break; default: printf("Sorry, but no information is available for this command."); } printf("
    \n"); return; } /* converts a time string to a UNIX timestamp, respecting the date_format option */ int string_to_time(char *buffer, time_t *t){ struct tm lt; /* Initialize some variables just in case they don't get parsed by the sscanf() call. A better solution is to also check the CGI input for validity, but this should suffice to prevent strange problems if the input is not valid. Jan 15 2003 Steve Bonds */ lt.tm_mon=0; lt.tm_mday=1; lt.tm_year=1900; lt.tm_hour=0; lt.tm_min=0; lt.tm_sec=0; lt.tm_wday=0; lt.tm_yday=0; if(date_format==DATE_FORMAT_EURO) sscanf(buffer,"%02d-%02d-%04d %02d:%02d:%02d",<.tm_mday,<.tm_mon,<.tm_year,<.tm_hour,<.tm_min,<.tm_sec); else if(date_format==DATE_FORMAT_ISO8601 || date_format==DATE_FORMAT_STRICT_ISO8601) sscanf(buffer,"%04d-%02d-%02d%*[ T]%02d:%02d:%02d",<.tm_year,<.tm_mon,<.tm_mday,<.tm_hour,<.tm_min,<.tm_sec); else sscanf(buffer,"%02d-%02d-%04d %02d:%02d:%02d",<.tm_mon,<.tm_mday,<.tm_year,<.tm_hour,<.tm_min,<.tm_sec); lt.tm_mon--; lt.tm_year-=1900; /* tell mktime() to try and compute DST automatically */ lt.tm_isdst=-1; *t=mktime(<); return OK; } nagios-2.6/cgi/config.c0000664000076500007650000017520010410070302014342 0ustar nagiosnagios/*********************************************************************** * * CONFIG.C - Nagios Configuration CGI (View Only) * * Copyright (c) 1999-2006 Ethan Galstad (nagios@nagios.org) * Last Modified: 03-21-2006 * * This CGI program will display various configuration information. * * * 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. ***********************************************************************/ #include "../include/config.h" #include "../include/common.h" #include "../include/objects.h" #include "../include/cgiutils.h" #include "../include/cgiauth.h" #include "../include/getcgi.h" extern char main_config_file[MAX_FILENAME_LENGTH]; extern char url_html_path[MAX_FILENAME_LENGTH]; extern char url_docs_path[MAX_FILENAME_LENGTH]; extern char url_images_path[MAX_FILENAME_LENGTH]; extern char url_logo_images_path[MAX_FILENAME_LENGTH]; extern char url_stylesheets_path[MAX_FILENAME_LENGTH]; extern host *host_list; extern service *service_list; extern hostgroup *hostgroup_list; extern servicegroup *servicegroup_list; extern contactgroup *contactgroup_list; extern command *command_list; extern timeperiod *timeperiod_list; extern contact *contact_list; extern servicedependency *servicedependency_list; extern serviceescalation *serviceescalation_list; extern hostdependency *hostdependency_list; extern hostescalation *hostescalation_list; extern hostextinfo *hostextinfo_list; extern serviceextinfo *serviceextinfo_list; #define DISPLAY_NONE 0 #define DISPLAY_HOSTS 1 #define DISPLAY_HOSTGROUPS 2 #define DISPLAY_CONTACTS 3 #define DISPLAY_CONTACTGROUPS 4 #define DISPLAY_SERVICES 5 #define DISPLAY_TIMEPERIODS 6 #define DISPLAY_COMMANDS 7 #define DISPLAY_HOSTGROUPESCALATIONS 8 /* no longer implemented */ #define DISPLAY_SERVICEDEPENDENCIES 9 #define DISPLAY_SERVICEESCALATIONS 10 #define DISPLAY_HOSTDEPENDENCIES 11 #define DISPLAY_HOSTESCALATIONS 12 #define DISPLAY_HOSTEXTINFO 13 #define DISPLAY_SERVICEEXTINFO 14 #define DISPLAY_SERVICEGROUPS 15 void document_header(int); void document_footer(void); int process_cgivars(void); void display_options(void); void display_hosts(void); void display_hostgroups(void); void display_servicegroups(void); void display_contacts(void); void display_contactgroups(void); void display_services(void); void display_timeperiods(void); void display_commands(void); void display_servicedependencies(void); void display_serviceescalations(void); void display_hostdependencies(void); void display_hostescalations(void); void display_hostextinfo(void); void display_serviceextinfo(void); void unauthorized_message(void); authdata current_authdata; int display_type=DISPLAY_NONE; int embedded=FALSE; int main(void){ int result=OK; /* get the arguments passed in the URL */ process_cgivars(); /* reset internal variables */ reset_cgi_vars(); /* read the CGI configuration file */ result=read_cgi_config_file(get_cgi_config_location()); if(result==ERROR){ document_header(FALSE); cgi_config_file_error(get_cgi_config_location()); document_footer(); return ERROR; } /* read the main configuration file */ result=read_main_config_file(main_config_file); if(result==ERROR){ document_header(FALSE); main_config_file_error(main_config_file); document_footer(); return ERROR; } /* read all object configuration data */ result=read_all_object_configuration_data(main_config_file,READ_ALL_OBJECT_DATA); if(result==ERROR){ document_header(FALSE); object_data_error(); document_footer(); return ERROR; } document_header(TRUE); /* get authentication information */ get_authentication_information(¤t_authdata); /* begin top table */ printf("\n"); printf("\n"); /* left column of the first row */ printf("\n"); /* right hand column of top row */ printf("\n"); /* end of top table */ printf("\n"); printf("
    \n"); display_info_table("Configuration",FALSE,¤t_authdata); printf("\n"); if(display_type!=DISPLAY_NONE){ printf("
    \n",CONFIG_CGI); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("
    Object Type:
    "); printf("\n"); printf("
    \n"); printf("
    \n"); } /* display context-sensitive help */ switch(display_type){ case DISPLAY_HOSTS: display_context_help(CONTEXTHELP_CONFIG_HOSTS); break; case DISPLAY_HOSTGROUPS: display_context_help(CONTEXTHELP_CONFIG_HOSTGROUPS); break; case DISPLAY_SERVICEGROUPS: display_context_help(CONTEXTHELP_CONFIG_SERVICEGROUPS); break; case DISPLAY_CONTACTS: display_context_help(CONTEXTHELP_CONFIG_CONTACTS); break; case DISPLAY_CONTACTGROUPS: display_context_help(CONTEXTHELP_CONFIG_CONTACTGROUPS); break; case DISPLAY_SERVICES: display_context_help(CONTEXTHELP_CONFIG_SERVICES); break; case DISPLAY_TIMEPERIODS: display_context_help(CONTEXTHELP_CONFIG_TIMEPERIODS); break; case DISPLAY_COMMANDS: display_context_help(CONTEXTHELP_CONFIG_COMMANDS); break; case DISPLAY_SERVICEDEPENDENCIES: display_context_help(CONTEXTHELP_CONFIG_SERVICEDEPENDENCIES); break; case DISPLAY_SERVICEESCALATIONS: display_context_help(CONTEXTHELP_CONFIG_HOSTESCALATIONS); break; case DISPLAY_HOSTDEPENDENCIES: display_context_help(CONTEXTHELP_CONFIG_HOSTDEPENDENCIES); break; case DISPLAY_HOSTESCALATIONS: display_context_help(CONTEXTHELP_CONFIG_HOSTESCALATIONS); break; case DISPLAY_HOSTEXTINFO: display_context_help(CONTEXTHELP_CONFIG_HOSTEXTINFO); break; case DISPLAY_SERVICEEXTINFO: display_context_help(CONTEXTHELP_CONFIG_SERVICEEXTINFO); break; default: display_context_help(CONTEXTHELP_CONFIG_MENU); break; } printf("
    \n"); switch(display_type){ case DISPLAY_HOSTS: display_hosts(); break; case DISPLAY_HOSTGROUPS: display_hostgroups(); break; case DISPLAY_SERVICEGROUPS: display_servicegroups(); break; case DISPLAY_CONTACTS: display_contacts(); break; case DISPLAY_CONTACTGROUPS: display_contactgroups(); break; case DISPLAY_SERVICES: display_services(); break; case DISPLAY_TIMEPERIODS: display_timeperiods(); break; case DISPLAY_COMMANDS: display_commands(); break; case DISPLAY_SERVICEDEPENDENCIES: display_servicedependencies(); break; case DISPLAY_SERVICEESCALATIONS: display_serviceescalations(); break; case DISPLAY_HOSTDEPENDENCIES: display_hostdependencies(); break; case DISPLAY_HOSTESCALATIONS: display_hostescalations(); break; case DISPLAY_HOSTEXTINFO: display_hostextinfo(); break; case DISPLAY_SERVICEEXTINFO: display_serviceextinfo(); break; default: display_options(); break; } document_footer(); return OK; } void document_header(int use_stylesheet){ char date_time[MAX_DATETIME_LENGTH]; time_t t; if(embedded==TRUE) return; time(&t); get_time_string(&t,date_time,sizeof(date_time),HTTP_DATE_TIME); printf("Cache-Control: no-store\r\n"); printf("Pragma: no-cache\r\n"); printf("Last-Modified: %s\r\n",date_time); printf("Expires: %s\r\n",date_time); printf("Content-type: text/html\r\n\r\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("Configuration\n"); printf("\n"); if(use_stylesheet==TRUE){ printf("\n",url_stylesheets_path,COMMON_CSS); printf("\n",url_stylesheets_path,CONFIG_CSS); } printf("\n"); printf("\n"); /* include user SSI header */ include_ssi_files(CONFIG_CGI,SSI_HEADER); return; } void document_footer(void){ if(embedded==TRUE) return; /* include user SSI footer */ include_ssi_files(CONFIG_CGI,SSI_FOOTER); printf("\n"); printf("\n"); return; } int process_cgivars(void){ char **variables; int error=FALSE; int x; variables=getcgivars(); for(x=0;variables[x]!=NULL;x++){ /* do some basic length checking on the variable identifier to prevent buffer overflows */ if(strlen(variables[x])>=MAX_INPUT_BUFFER-1){ x++; continue; } /* we found the configuration type argument */ else if(!strcmp(variables[x],"type")){ x++; if(variables[x]==NULL){ error=TRUE; break; } /* what information should we display? */ if(!strcmp(variables[x],"hosts")) display_type=DISPLAY_HOSTS; else if(!strcmp(variables[x],"hostgroups")) display_type=DISPLAY_HOSTGROUPS; else if(!strcmp(variables[x],"servicegroups")) display_type=DISPLAY_SERVICEGROUPS; else if(!strcmp(variables[x],"contacts")) display_type=DISPLAY_CONTACTS; else if(!strcmp(variables[x],"contactgroups")) display_type=DISPLAY_CONTACTGROUPS; else if(!strcmp(variables[x],"services")) display_type=DISPLAY_SERVICES; else if(!strcmp(variables[x],"timeperiods")) display_type=DISPLAY_TIMEPERIODS; else if(!strcmp(variables[x],"commands")) display_type=DISPLAY_COMMANDS; else if(!strcmp(variables[x],"servicedependencies")) display_type=DISPLAY_SERVICEDEPENDENCIES; else if(!strcmp(variables[x],"serviceescalations")) display_type=DISPLAY_SERVICEESCALATIONS; else if(!strcmp(variables[x],"hostdependencies")) display_type=DISPLAY_HOSTDEPENDENCIES; else if(!strcmp(variables[x],"hostescalations")) display_type=DISPLAY_HOSTESCALATIONS; else if(!strcmp(variables[x],"hostextinfo")) display_type=DISPLAY_HOSTEXTINFO; else if(!strcmp(variables[x],"serviceextinfo")) display_type=DISPLAY_SERVICEEXTINFO; /* we found the embed option */ else if(!strcmp(variables[x],"embedded")) embedded=TRUE; } /* we received an invalid argument */ else error=TRUE; } /* free memory allocated to the CGI variables */ free_cgivars(variables); return error; } void display_hosts(void){ host *temp_host; hostsmember *temp_hostsmember; contactgroupsmember *temp_contactgroupsmember; int options=0; int odd=0; char time_string[16]; char *bg_class=""; /* see if user is authorized to view host information... */ if(is_authorized_for_configuration_information(¤t_authdata)==FALSE){ unauthorized_message(); return; } printf("

    Hosts

    \n"); printf("

    \n"); printf("\n"); printf("\n"); printf(""); printf(""); printf(""); printf(""); printf(""); printf("\n"); printf(""); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf(""); printf(""); printf(""); printf(""); printf(""); printf("\n"); printf(""); printf(""); printf(""); printf(""); printf(""); printf(""); printf(""); printf("\n"); /* check all the hosts... */ for(temp_host=host_list;temp_host!=NULL;temp_host=temp_host->next){ if(odd){ odd=0; bg_class="dataOdd"; } else{ odd=1; bg_class="dataEven"; } printf("\n",bg_class); printf("\n",bg_class,url_encode(temp_host->name),temp_host->name); printf("\n",bg_class,temp_host->alias); printf("\n",bg_class,temp_host->address); printf("\n"); printf("\n",bg_class,temp_host->max_attempts); get_interval_time_string(temp_host->check_interval,time_string,sizeof(time_string)); printf("\n",bg_class,time_string); printf("\n",CONFIG_CGI,url_encode(temp_host->host_check_command),temp_host->host_check_command); printf("\n"); printf("\n",bg_class,(temp_host->obsess_over_host==TRUE)?"Yes":"No"); printf("\n",bg_class,(temp_host->checks_enabled==TRUE)?"Yes":"No"); printf("\n",bg_class,(temp_host->accept_passive_host_checks==TRUE)?"Yes":"No"); printf("\n",bg_class,(temp_host->check_freshness==TRUE)?"Yes":"No"); printf("\n"); printf("\n"); get_interval_time_string(temp_host->notification_interval,time_string,sizeof(time_string)); printf("\n",bg_class,(temp_host->notification_interval==0)?"No Re-notification":time_string); printf("\n"); printf("\n"); printf("\n",CONFIG_CGI,url_encode(temp_host->event_handler),temp_host->event_handler); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n",bg_class,(temp_host->failure_prediction_options==NULL)?" ":temp_host->failure_prediction_options); printf("\n"); printf("\n"); } printf("
    Host NameAlias/DescriptionAddressParent HostsMax. Check AttemptsCheck IntervalHost Check CommandObsess OverEnable Active ChecksEnable Passive ChecksCheck FreshnessFreshness ThresholdDefault Contact GroupsNotification IntervalNotification OptionsNotification PeriodEvent HandlerEnable Event HandlerStalking OptionsEnable Flap DetectionLow Flap ThresholdHigh Flap ThresholdProcess Performance DataEnable Failure PredictionFailure Prediction OptionsRetention Options
    %s%s%s",bg_class); for(temp_hostsmember=temp_host->parent_hosts;temp_hostsmember!=NULL;temp_hostsmember=temp_hostsmember->next){ if(temp_hostsmember!=temp_host->parent_hosts) printf(", "); printf("%s\n",CONFIG_CGI,url_encode(temp_hostsmember->host_name),temp_hostsmember->host_name); } if(temp_host->parent_hosts==NULL) printf(" "); printf("%d%s",bg_class); if(temp_host->host_check_command==NULL) printf(" "); else printf("%s%s%s%s%s",bg_class); if(temp_host->freshness_threshold==0) printf("Auto-determined value\n"); else printf("%d seconds\n",temp_host->freshness_threshold); printf("",bg_class); /* find all the contact groups for this host... */ for(temp_contactgroupsmember=temp_host->contact_groups;temp_contactgroupsmember!=NULL;temp_contactgroupsmember=temp_contactgroupsmember->next){ if(temp_contactgroupsmember!=temp_host->contact_groups) printf(", "); printf("%s\n",CONFIG_CGI,url_encode(temp_contactgroupsmember->group_name),temp_contactgroupsmember->group_name); } printf("%s",bg_class); options=0; if(temp_host->notify_on_down==TRUE){ options=1; printf("Down"); } if(temp_host->notify_on_unreachable==TRUE){ printf("%sUnreachable",(options)?", ":""); options=1; } if(temp_host->notify_on_recovery==TRUE){ printf("%sRecovery",(options)?", ":""); options=1; } if(temp_host->notify_on_flapping==TRUE){ printf("%sFlapping",(options)?", ":""); options=1; } if(options==0) printf("None"); printf("",bg_class); if(temp_host->notification_period==NULL) printf(" "); else printf("%s",CONFIG_CGI,url_encode(temp_host->notification_period),temp_host->notification_period); printf("",bg_class); if(temp_host->event_handler==NULL) printf(" "); else printf("%s",bg_class); printf("%s\n",(temp_host->event_handler_enabled==TRUE)?"Yes":"No"); printf("",bg_class); options=0; if(temp_host->stalk_on_up==TRUE){ options=1; printf("Up"); } if(temp_host->stalk_on_down==TRUE){ printf("%sDown",(options)?", ":""); options=1; } if(temp_host->stalk_on_unreachable==TRUE){ printf("%sUnreachable",(options)?", ":""); options=1; } if(options==0) printf("None"); printf("",bg_class); printf("%s\n",(temp_host->flap_detection_enabled==TRUE)?"Yes":"No"); printf("",bg_class); if(temp_host->low_flap_threshold==0.0) printf("Program-wide value\n"); else printf("%3.1f%%\n",temp_host->low_flap_threshold); printf("",bg_class); if(temp_host->high_flap_threshold==0.0) printf("Program-wide value\n"); else printf("%3.1f%%\n",temp_host->high_flap_threshold); printf("",bg_class); printf("%s\n",(temp_host->process_performance_data==TRUE)?"Yes":"No"); printf("",bg_class); printf("%s\n",(temp_host->failure_prediction_enabled==TRUE)?"Yes":"No"); printf("%s",bg_class); options=0; if(temp_host->retain_status_information==TRUE){ options=1; printf("Status Information"); } if(temp_host->retain_nonstatus_information==TRUE){ printf("%sNon-Status Information",(options==1)?", ":""); options=1; } if(options==0) printf("None"); printf("
    \n"); printf("
    \n"); printf("

    \n"); return; } void display_hostgroups(void){ hostgroup *temp_hostgroup; hostgroupmember *temp_hostgroupmember; int odd=0; char *bg_class=""; /* see if user is authorized to view hostgroup information... */ if(is_authorized_for_configuration_information(¤t_authdata)==FALSE){ unauthorized_message(); return; } printf("

    Host Groups

    \n"); printf("

    \n"); printf("

    \n"); printf("\n"); printf("\n"); printf(""); printf(""); printf(""); printf("\n"); /* check all the hostgroups... */ for(temp_hostgroup=hostgroup_list;temp_hostgroup!=NULL;temp_hostgroup=temp_hostgroup->next){ if(odd){ odd=0; bg_class="dataOdd"; } else{ odd=1; bg_class="dataEven"; } printf("\n",bg_class); printf("",bg_class,temp_hostgroup->group_name); printf("\n",bg_class,temp_hostgroup->alias); printf("\n"); printf("\n"); } printf("
    Group NameDescriptionHost Members
    %s%s",bg_class); /* find all the hosts that are members of this hostgroup... */ for(temp_hostgroupmember=temp_hostgroup->members;temp_hostgroupmember!=NULL;temp_hostgroupmember=temp_hostgroupmember->next){ if(temp_hostgroupmember!=temp_hostgroup->members) printf(", "); printf("%s\n",CONFIG_CGI,url_encode(temp_hostgroupmember->host_name),temp_hostgroupmember->host_name); } printf("
    \n"); printf("
    \n"); printf("

    \n"); return; } void display_servicegroups(void){ servicegroup *temp_servicegroup; servicegroupmember *temp_servicegroupmember; int odd=0; char *bg_class=""; /* see if user is authorized to view servicegroup information... */ if(is_authorized_for_configuration_information(¤t_authdata)==FALSE){ unauthorized_message(); return; } printf("

    Service Groups

    \n"); printf("

    \n"); printf("

    \n"); printf("\n"); printf("\n"); printf(""); printf(""); printf(""); printf("\n"); /* check all the servicegroups... */ for(temp_servicegroup=servicegroup_list;temp_servicegroup!=NULL;temp_servicegroup=temp_servicegroup->next){ if(odd){ odd=0; bg_class="dataOdd"; } else{ odd=1; bg_class="dataEven"; } printf("\n",bg_class); printf("",bg_class,temp_servicegroup->group_name); printf("\n",bg_class,temp_servicegroup->alias); printf("\n"); printf("\n"); } printf("
    Group NameDescriptionService Members
    %s%s",bg_class); /* find all the services that are members of this servicegroup... */ for(temp_servicegroupmember=temp_servicegroup->members;temp_servicegroupmember!=NULL;temp_servicegroupmember=temp_servicegroupmember->next){ printf("%s%s / ",(temp_servicegroupmember==temp_servicegroup->members)?"":", ",CONFIG_CGI,url_encode(temp_servicegroupmember->host_name),temp_servicegroupmember->host_name); printf("%s\n",url_encode(temp_servicegroupmember->service_description),temp_servicegroupmember->service_description); } printf("
    \n"); printf("
    \n"); printf("

    \n"); return; } void display_contacts(void){ contact *temp_contact; commandsmember *temp_commandsmember; int odd=0; int options; int found; char *bg_class=""; /* see if user is authorized to view contact information... */ if(is_authorized_for_configuration_information(¤t_authdata)==FALSE){ unauthorized_message(); return; } /* read in contact definitions... */ read_all_object_configuration_data(main_config_file,READ_CONTACTS); printf("

    Contacts

    \n"); printf("

    \n"); printf("

    \n"); printf("\n"); printf("\n"); printf(""); printf(""); printf(""); printf(""); printf(""); printf(""); printf(""); printf(""); printf(""); printf(""); printf("\n"); /* check all contacts... */ for(temp_contact=contact_list;temp_contact!=NULL;temp_contact=temp_contact->next){ if(odd){ odd=0; bg_class="dataOdd"; } else{ odd=1; bg_class="dataEven"; } printf("\n",bg_class); printf("\n",bg_class,url_encode(temp_contact->name),temp_contact->name); printf("\n",bg_class,temp_contact->alias); printf("\n",bg_class,(temp_contact->email==NULL)?" ":temp_contact->email,(temp_contact->email==NULL)?" ":temp_contact->email); printf("\n",bg_class,(temp_contact->pager==NULL)?" ":temp_contact->pager); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); } printf("
    Contact NameAliasEmail AddressPager Address/NumberService Notification OptionsHost Notification OptionsService Notification PeriodHost Notification PeriodService Notification CommandsHost Notification Commands
    %s%s%s%s",bg_class); options=0; if(temp_contact->notify_on_service_unknown==TRUE){ options=1; printf("Unknown"); } if(temp_contact->notify_on_service_warning==TRUE){ printf("%sWarning",(options)?", ":""); options=1; } if(temp_contact->notify_on_service_critical==TRUE){ printf("%sCritical",(options)?", ":""); options=1; } if(temp_contact->notify_on_service_recovery==TRUE){ printf("%sRecovery",(options)?", ":""); options=1; } if(temp_contact->notify_on_service_flapping==TRUE){ printf("%sFlapping",(options)?", ":""); options=1; } if(!options) printf("None"); printf("",bg_class); options=0; if(temp_contact->notify_on_host_down==TRUE){ options=1; printf("Down"); } if(temp_contact->notify_on_host_unreachable==TRUE){ printf("%sUnreachable",(options)?", ":""); options=1; } if(temp_contact->notify_on_host_recovery==TRUE){ printf("%sRecovery",(options)?", ":""); options=1; } if(temp_contact->notify_on_host_flapping==TRUE){ printf("%sFlapping",(options)?", ":""); options=1; } if(!options) printf("None"); printf("\n",bg_class); if(temp_contact->service_notification_period==NULL) printf(" "); else printf("%s",CONFIG_CGI,url_encode(temp_contact->service_notification_period),temp_contact->service_notification_period); printf("\n",bg_class); if(temp_contact->host_notification_period==NULL) printf(" "); else printf("%s",CONFIG_CGI,url_encode(temp_contact->host_notification_period),temp_contact->host_notification_period); printf("",bg_class); found=FALSE; for(temp_commandsmember=temp_contact->service_notification_commands;temp_commandsmember!=NULL;temp_commandsmember=temp_commandsmember->next){ if(temp_commandsmember!=temp_contact->service_notification_commands) printf(", "); printf("%s",CONFIG_CGI,url_encode(temp_commandsmember->command),temp_commandsmember->command); found=TRUE; } if(found==FALSE) printf("None"); printf("",bg_class); found=FALSE; for(temp_commandsmember=temp_contact->host_notification_commands;temp_commandsmember!=NULL;temp_commandsmember=temp_commandsmember->next){ if(temp_commandsmember!=temp_contact->host_notification_commands) printf(", "); printf("%s",CONFIG_CGI,url_encode(temp_commandsmember->command),temp_commandsmember->command); found=TRUE; } if(found==FALSE) printf("None"); printf("
    \n"); printf("
    \n"); printf("

    \n"); return; } void display_contactgroups(void){ contactgroup *temp_contactgroup; contactgroupmember *temp_contactgroupmember; int odd=0; char *bg_class=""; /* see if user is authorized to view contactgroup information... */ if(is_authorized_for_configuration_information(¤t_authdata)==FALSE){ unauthorized_message(); return; } printf("

    Contact Groups

    \n"); printf("

    \n"); printf("

    \n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); /* check all the contact groups... */ for(temp_contactgroup=contactgroup_list;temp_contactgroup!=NULL;temp_contactgroup=temp_contactgroup->next){ if(odd){ odd=0; bg_class="dataOdd"; } else{ odd=1; bg_class="dataEven"; } printf("\n",bg_class); printf("\n",bg_class,url_encode(temp_contactgroup->group_name),temp_contactgroup->group_name); printf("\n",bg_class,temp_contactgroup->alias); /* find all the contact who are members of this contact group... */ printf("\n"); printf("\n"); } printf("
    Group NameDescriptionContact Members
    %s%s",bg_class); for(temp_contactgroupmember=temp_contactgroup->members;temp_contactgroupmember!=NULL;temp_contactgroupmember=temp_contactgroupmember->next){ if(temp_contactgroupmember!=temp_contactgroup->members) printf(", "); printf("%s\n",CONFIG_CGI,url_encode(temp_contactgroupmember->contact_name),temp_contactgroupmember->contact_name); } printf("
    \n"); printf("
    \n"); printf("

    \n"); return; } void display_services(void){ service *temp_service; contactgroupsmember *temp_contactgroupsmember; char command_line[MAX_INPUT_BUFFER]; char *command_name=""; int options; int odd=0; char time_string[16]; char *bg_class; /* see if user is authorized to view service information... */ if(is_authorized_for_configuration_information(¤t_authdata)==FALSE){ unauthorized_message(); return; } /* read in service definitions... */ read_all_object_configuration_data(main_config_file,READ_SERVICES); printf("

    Services

    \n"); printf("

    \n"); printf("

    \n"); printf("\n"); printf("\n"); printf(""); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf(""); printf(""); printf("\n"); printf(""); printf(""); printf(""); printf(""); printf(""); printf(""); printf(""); printf("\n"); /* check all the services... */ for(temp_service=service_list;temp_service!=NULL;temp_service=temp_service->next){ if(odd){ odd=0; bg_class="dataOdd"; } else{ odd=1; bg_class="dataEven"; } printf("\n",bg_class); printf("\n",CONFIG_CGI,url_encode(temp_service->host_name),temp_service->host_name); printf("\n",bg_class,temp_service->description); printf("\n",bg_class,temp_service->max_attempts); get_interval_time_string(temp_service->check_interval,time_string,sizeof(time_string)); printf("\n",bg_class,time_string); get_interval_time_string(temp_service->retry_interval,time_string,sizeof(time_string)); printf("\n",bg_class,time_string); strncpy(command_line,temp_service->service_check_command,sizeof(command_line)); command_line[sizeof(command_line)-1]='\x0'; command_name=strtok(command_line,"!"); printf("\n",bg_class,CONFIG_CGI,url_encode(command_name),temp_service->service_check_command); printf("\n"); printf("\n",bg_class,(temp_service->parallelize==TRUE)?"Yes":"No"); printf("\n",bg_class,(temp_service->is_volatile==TRUE)?"Yes":"No"); printf("\n",bg_class,(temp_service->obsess_over_service==TRUE)?"Yes":"No"); printf("\n",bg_class,(temp_service->checks_enabled==TRUE)?"Yes":"No"); printf("\n",bg_class,(temp_service->accept_passive_service_checks==TRUE)?"Yes":"No"); printf("\n",bg_class,(temp_service->check_freshness==TRUE)?"Yes":"No"); printf("\n"); printf("\n"); printf("\n"); get_interval_time_string(temp_service->notification_interval,time_string,sizeof(time_string)); printf("\n",bg_class,(temp_service->notification_interval==0)?"No Re-notification":time_string); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n",bg_class,(temp_service->failure_prediction_options==NULL)?" ":temp_service->failure_prediction_options); printf("\n"); printf("\n"); } printf("
    Service
    HostDescriptionMax. Check AttemptsNormal Check IntervalRetry Check InteralCheck CommandCheck PeriodParallelizeVolatileObsess OverEnable Active ChecksEnable Passive ChecksCheck FreshnessFreshness ThresholdDefault Contact GroupsEnable NotificationsNotification IntervalNotification OptionsNotification PeriodEvent HandlerEnable Event HandlerStalking OptionsEnable Flap DetectionLow Flap ThresholdHigh Flap ThresholdProcess Performance DataEnable Failure PredictionFailure Prediction OptionsRetention Options
    ",url_encode(temp_service->description)); printf("%s%s%d%s%s%s",bg_class); if(temp_service->check_period==NULL) printf(" "); else printf("%s",CONFIG_CGI,url_encode(temp_service->check_period),temp_service->check_period); printf("%s%s%s%s%s%s",bg_class); if(temp_service->freshness_threshold==0) printf("Auto-determined value\n"); else printf("%d seconds\n",temp_service->freshness_threshold); printf("",bg_class); for(temp_contactgroupsmember=temp_service->contact_groups;temp_contactgroupsmember!=NULL;temp_contactgroupsmember=temp_contactgroupsmember->next){ if(temp_contactgroupsmember!=temp_service->contact_groups) printf(", "); printf("%s",CONFIG_CGI,url_encode(temp_contactgroupsmember->group_name),temp_contactgroupsmember->group_name); } if(temp_service->contact_groups==NULL) printf(" "); printf("",bg_class); printf("%s\n",(temp_service->notifications_enabled==TRUE)?"Yes":"No"); printf("%s",bg_class); options=0; if(temp_service->notify_on_unknown==TRUE){ options=1; printf("Unknown"); } if(temp_service->notify_on_warning==TRUE){ printf("%sWarning",(options)?", ":""); options=1; } if(temp_service->notify_on_critical==TRUE){ printf("%sCritical",(options)?", ":""); options=1; } if(temp_service->notify_on_recovery==TRUE){ printf("%sRecovery",(options)?", ":""); options=1; } if(temp_service->notify_on_flapping==TRUE){ printf("%sFlapping",(options)?", ":""); options=1; } if(!options) printf("None"); printf("",bg_class); if(temp_service->notification_period==NULL) printf(" "); else printf("%s",CONFIG_CGI,url_encode(temp_service->notification_period),temp_service->notification_period); printf("",bg_class); if(temp_service->event_handler==NULL) printf(" "); else printf("%s",CONFIG_CGI,url_encode(temp_service->event_handler),temp_service->event_handler); printf("",bg_class); printf("%s\n",(temp_service->event_handler_enabled==TRUE)?"Yes":"No"); printf("",bg_class); options=0; if(temp_service->stalk_on_ok==TRUE){ options=1; printf("Ok"); } if(temp_service->stalk_on_warning==TRUE){ printf("%sWarning",(options)?", ":""); options=1; } if(temp_service->stalk_on_unknown==TRUE){ printf("%sUnknown",(options)?", ":""); options=1; } if(temp_service->stalk_on_critical==TRUE){ printf("%sCritical",(options)?", ":""); options=1; } if(options==0) printf("None"); printf("",bg_class); printf("%s\n",(temp_service->flap_detection_enabled==TRUE)?"Yes":"No"); printf("",bg_class); if(temp_service->low_flap_threshold==0.0) printf("Program-wide value\n"); else printf("%3.1f%%\n",temp_service->low_flap_threshold); printf("",bg_class); if(temp_service->high_flap_threshold==0.0) printf("Program-wide value\n"); else printf("%3.1f%%\n",temp_service->high_flap_threshold); printf("",bg_class); printf("%s\n",(temp_service->process_performance_data==TRUE)?"Yes":"No"); printf("",bg_class); printf("%s\n",(temp_service->failure_prediction_enabled==TRUE)?"Yes":"No"); printf("%s",bg_class); options=0; if(temp_service->retain_status_information==TRUE){ options=1; printf("Status Information"); } if(temp_service->retain_nonstatus_information==TRUE){ printf("%sNon-Status Information",(options==1)?", ":""); options=1; } if(options==0) printf("None"); printf("
    \n"); printf("
    \n"); printf("

    \n"); return; } void display_timeperiods(void){ timerange *temp_timerange; timeperiod *temp_timeperiod; int odd=0; int day=0; char *bg_class=""; char timestring[10]; int hours=0; int minutes=0; int seconds=0; /* see if user is authorized to view time period information... */ if(is_authorized_for_configuration_information(¤t_authdata)==FALSE){ unauthorized_message(); return; } /* read in time period definitions... */ read_all_object_configuration_data(main_config_file,READ_TIMEPERIODS); printf("

    Time Periods

    \n"); printf("

    \n"); printf("

    \n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); /* check all the time periods... */ for(temp_timeperiod=timeperiod_list;temp_timeperiod!=NULL;temp_timeperiod=temp_timeperiod->next){ if(odd){ odd=0; bg_class="dataOdd"; } else{ odd=1; bg_class="dataEven"; } printf("\n",bg_class); printf("\n",bg_class,url_encode(temp_timeperiod->name),temp_timeperiod->name); printf("\n",bg_class,temp_timeperiod->alias); for(day=0;day<7;day++){ printf("\n"); } printf("\n"); } printf("
    NameAlias/DescriptionSunday Time RangesMonday Time RangesTuesday Time RangesWednesday Time RangesThursday Time RangesFriday Time RangesSaturday Time Ranges
    %s%s",bg_class); for(temp_timerange=temp_timeperiod->days[day];temp_timerange!=NULL;temp_timerange=temp_timerange->next){ if(temp_timerange!=temp_timeperiod->days[day]) printf(", "); hours=temp_timerange->range_start/3600; minutes=(temp_timerange->range_start-(hours*3600))/60; seconds=temp_timerange->range_start-(hours*3600)-(minutes*60); snprintf(timestring,sizeof(timestring)-1,"%02d:%02d:%02d",hours,minutes,seconds); timestring[sizeof(timestring)-1]='\x0'; printf("%s - ",timestring); hours=temp_timerange->range_end/3600; minutes=(temp_timerange->range_end-(hours*3600))/60; seconds=temp_timerange->range_end-(hours*3600)-(minutes*60); snprintf(timestring,sizeof(timestring)-1,"%02d:%02d:%02d",hours,minutes,seconds); timestring[sizeof(timestring)-1]='\x0'; printf("%s",timestring); } if(temp_timeperiod->days[day]==NULL) printf(" "); printf("
    \n"); printf("
    \n"); printf("

    \n"); return; } void display_commands(void){ command *temp_command; int odd=0; char *bg_class=""; /* see if user is authorized to view command information... */ if(is_authorized_for_configuration_information(¤t_authdata)==FALSE){ unauthorized_message(); return; } /* read in command definitions... */ read_all_object_configuration_data(main_config_file,READ_COMMANDS); printf("

    Commands

    \n"); printf("

    \n"); printf("\n"); printf("\n"); /* check all commands */ for(temp_command=command_list;temp_command!=NULL;temp_command=temp_command->next){ if(odd){ odd=0; bg_class="dataEven"; } else{ odd=1; bg_class="dataOdd"; } printf("\n",bg_class); printf("\n",bg_class,url_encode(temp_command->name),temp_command->name); printf("\n",bg_class,temp_command->command_line); printf("\n"); } printf("
    Command NameCommand Line
    %s%s
    \n"); printf("

    \n"); return; } void display_servicedependencies(void){ servicedependency *temp_sd; int odd=0; int options; char *bg_class=""; /* see if user is authorized to view hostgroup information... */ if(is_authorized_for_configuration_information(¤t_authdata)==FALSE){ unauthorized_message(); return; } /* read in command definitions... */ read_all_object_configuration_data(main_config_file,READ_SERVICEDEPENDENCIES); printf("

    Service Dependencies

    \n"); printf("

    \n"); printf("

    \n"); printf("\n"); printf("\n"); printf(""); printf(""); printf("\n"); printf("\n"); printf(""); printf(""); printf(""); printf(""); printf(""); printf(""); printf("\n"); /* check all the service dependencies... */ for(temp_sd=servicedependency_list;temp_sd!=NULL;temp_sd=temp_sd->next){ if(odd){ odd=0; bg_class="dataOdd"; } else{ odd=1; bg_class="dataEven"; } printf("\n",bg_class); printf("",bg_class,CONFIG_CGI,url_encode(temp_sd->dependent_host_name),temp_sd->dependent_host_name); printf("\n",url_encode(temp_sd->dependent_service_description),temp_sd->dependent_service_description); printf("",bg_class,CONFIG_CGI,url_encode(temp_sd->host_name),temp_sd->host_name); printf("\n",url_encode(temp_sd->service_description),temp_sd->service_description); printf("",bg_class,(temp_sd->dependency_type==NOTIFICATION_DEPENDENCY)?"Notification":"Check Execution"); printf("\n"); printf("\n"); } printf("
    Dependent ServiceMaster Service
    HostServiceHostServiceDependency TypeDependency Failure Options
    %s%s%s%s%s",bg_class); options=FALSE; if(temp_sd->fail_on_ok==TRUE){ printf("Ok"); options=TRUE; } if(temp_sd->fail_on_warning==TRUE){ printf("%sWarning",(options==TRUE)?", ":""); options=TRUE; } if(temp_sd->fail_on_unknown==TRUE){ printf("%sUnknown",(options==TRUE)?", ":""); options=TRUE; } if(temp_sd->fail_on_critical==TRUE){ printf("%sCritical",(options==TRUE)?", ":""); options=TRUE; } if(temp_sd->fail_on_pending==TRUE){ printf("%sPending",(options==TRUE)?", ":""); options=TRUE; } printf("
    \n"); printf("
    \n"); printf("

    \n"); return; } void display_serviceescalations(void){ serviceescalation *temp_se; contactgroupsmember *temp_contactgroupsmember; int options=FALSE; int odd=0; char *bg_class=""; /* see if user is authorized to view hostgroup information... */ if(is_authorized_for_configuration_information(¤t_authdata)==FALSE){ unauthorized_message(); return; } /* read in command definitions... */ read_all_object_configuration_data(main_config_file,READ_SERVICEESCALATIONS); printf("

    Service Escalations

    \n"); printf("

    \n"); printf("

    \n"); printf("\n"); printf("\n"); printf(""); printf("\n"); printf("\n"); printf(""); printf(""); printf(""); printf(""); printf(""); printf(""); printf(""); printf(""); printf("\n"); /* check all the service escalations... */ for(temp_se=serviceescalation_list;temp_se!=NULL;temp_se=temp_se->next){ if(odd){ odd=0; bg_class="dataOdd"; } else{ odd=1; bg_class="dataEven"; } printf("\n",bg_class); printf("",bg_class,CONFIG_CGI,url_encode(temp_se->host_name),temp_se->host_name); printf("\n",url_encode(temp_se->description),temp_se->description); printf("\n"); printf("",bg_class,temp_se->first_notification); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); } printf("
    Service
    HostDescriptionContact GroupsFirst NotificationLast NotificationNotification IntervalEscalation PeriodEscalation Options
    %s%s",bg_class); for(temp_contactgroupsmember=temp_se->contact_groups;temp_contactgroupsmember!=NULL;temp_contactgroupsmember=temp_contactgroupsmember->next){ if(temp_contactgroupsmember!=temp_se->contact_groups) printf(", "); printf("%s\n",CONFIG_CGI,url_encode(temp_contactgroupsmember->group_name),temp_contactgroupsmember->group_name); } printf("%d",bg_class); if(temp_se->last_notification==0) printf("Infinity"); else printf("%d",temp_se->last_notification); printf("",bg_class); if(temp_se->notification_interval==0) printf("Notify Only Once (No Re-notification)"); else printf("%d",temp_se->notification_interval); printf("",bg_class); if(temp_se->escalation_period==NULL) printf(" "); else printf("%s",CONFIG_CGI,url_encode(temp_se->escalation_period),temp_se->escalation_period); printf("",bg_class); options=FALSE; if(temp_se->escalate_on_warning==TRUE){ printf("%sWarning",(options==TRUE)?", ":""); options=TRUE; } if(temp_se->escalate_on_unknown==TRUE){ printf("%sUnknown",(options==TRUE)?", ":""); options=TRUE; } if(temp_se->escalate_on_critical==TRUE){ printf("%sCritical",(options==TRUE)?", ":""); options=TRUE; } if(temp_se->escalate_on_recovery==TRUE){ printf("%sRecovery",(options==TRUE)?", ":""); options=TRUE; } if(options==FALSE) printf("None"); printf("
    \n"); printf("
    \n"); printf("

    \n"); return; } void display_hostdependencies(void){ hostdependency *temp_hd; int odd=0; int options; char *bg_class=""; /* see if user is authorized to view hostdependency information... */ if(is_authorized_for_configuration_information(¤t_authdata)==FALSE){ unauthorized_message(); return; } /* read in command definitions... */ read_all_object_configuration_data(main_config_file,READ_HOSTDEPENDENCIES); printf("

    Host Dependencies

    \n"); printf("

    \n"); printf("

    \n"); printf("\n"); printf("\n"); printf(""); printf(""); printf(""); printf(""); printf("\n"); /* check all the host dependencies... */ for(temp_hd=hostdependency_list;temp_hd!=NULL;temp_hd=temp_hd->next){ if(odd){ odd=0; bg_class="dataOdd"; } else{ odd=1; bg_class="dataEven"; } printf("\n",bg_class); printf("",bg_class,CONFIG_CGI,url_encode(temp_hd->dependent_host_name),temp_hd->dependent_host_name); printf("",bg_class,CONFIG_CGI,url_encode(temp_hd->host_name),temp_hd->host_name); printf("",bg_class,(temp_hd->dependency_type==NOTIFICATION_DEPENDENCY)?"Notification":"Check Execution"); printf("\n"); printf("\n"); } printf("
    Dependent HostMaster HostDependency TypeDependency Failure Options
    %s%s%s",bg_class); options=FALSE; if(temp_hd->fail_on_up==TRUE){ printf("Up"); options=TRUE; } if(temp_hd->fail_on_down==TRUE){ printf("%sDown",(options==TRUE)?", ":""); options=TRUE; } if(temp_hd->fail_on_unreachable==TRUE){ printf("%sUnreachable",(options==TRUE)?", ":""); options=TRUE; } if(temp_hd->fail_on_pending==TRUE){ printf("%sPending",(options==TRUE)?", ":""); options=TRUE; } printf("
    \n"); printf("
    \n"); printf("

    \n"); return; } void display_hostescalations(void){ hostescalation *temp_he; contactgroupsmember *temp_contactgroupsmember; int options=FALSE; int odd=0; char *bg_class=""; /* see if user is authorized to view hostgroup information... */ if(is_authorized_for_configuration_information(¤t_authdata)==FALSE){ unauthorized_message(); return; } /* read in command definitions... */ read_all_object_configuration_data(main_config_file,READ_HOSTESCALATIONS); printf("

    Host Escalations

    \n"); printf("

    \n"); printf("

    \n"); printf("\n"); printf("\n"); printf(""); printf(""); printf(""); printf(""); printf(""); printf(""); printf(""); printf("\n"); /* check all the host escalations... */ for(temp_he=hostescalation_list;temp_he!=NULL;temp_he=temp_he->next){ if(odd){ odd=0; bg_class="dataOdd"; } else{ odd=1; bg_class="dataEven"; } printf("\n",bg_class); printf("",bg_class,CONFIG_CGI,url_encode(temp_he->host_name),temp_he->host_name); printf("\n"); printf("",bg_class,temp_he->first_notification); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); } printf("
    HostContact GroupsFirst NotificationLast NotificationNotification IntervalEscalation PeriodEscalation Options
    %s",bg_class); for(temp_contactgroupsmember=temp_he->contact_groups;temp_contactgroupsmember!=NULL;temp_contactgroupsmember=temp_contactgroupsmember->next){ if(temp_contactgroupsmember!=temp_he->contact_groups) printf(", "); printf("%s\n",CONFIG_CGI,url_encode(temp_contactgroupsmember->group_name),temp_contactgroupsmember->group_name); } printf("%d",bg_class); if(temp_he->last_notification==0) printf("Infinity"); else printf("%d",temp_he->last_notification); printf("",bg_class); if(temp_he->notification_interval==0) printf("Notify Only Once (No Re-notification)"); else printf("%d",temp_he->notification_interval); printf("",bg_class); if(temp_he->escalation_period==NULL) printf(" "); else printf("%s",CONFIG_CGI,url_encode(temp_he->escalation_period),temp_he->escalation_period); printf("",bg_class); options=FALSE; if(temp_he->escalate_on_down==TRUE){ printf("%sDown",(options==TRUE)?", ":""); options=TRUE; } if(temp_he->escalate_on_unreachable==TRUE){ printf("%sUnreachable",(options==TRUE)?", ":""); options=TRUE; } if(temp_he->escalate_on_recovery==TRUE){ printf("%sRecovery",(options==TRUE)?", ":""); options=TRUE; } if(options==FALSE) printf("None"); printf("
    \n"); printf("
    \n"); printf("

    \n"); return; } void display_hostextinfo(void){ hostextinfo *temp_hostextinfo; int odd=0; char *bg_class=""; /* see if user is authorized to view hostdependency information... */ if(is_authorized_for_configuration_information(¤t_authdata)==FALSE){ unauthorized_message(); return; } /* read in command definitions... */ read_all_object_configuration_data(main_config_file,READ_HOSTEXTINFO); printf("

    Extended Host Information

    \n"); printf("

    \n"); printf("

    \n"); printf("\n"); printf("\n"); printf(""); printf(""); printf(""); printf(""); printf(""); printf(""); printf(""); printf(""); printf("\n"); /* check all the definitions... */ for(temp_hostextinfo=hostextinfo_list;temp_hostextinfo!=NULL;temp_hostextinfo=temp_hostextinfo->next){ if(odd){ odd=0; bg_class="dataOdd"; } else{ odd=1; bg_class="dataEven"; } printf("\n",bg_class); printf("",bg_class,CONFIG_CGI,url_encode(temp_hostextinfo->host_name),temp_hostextinfo->host_name); printf("",bg_class,(temp_hostextinfo->notes_url==NULL)?" ":temp_hostextinfo->notes_url); if(temp_hostextinfo->have_2d_coords==FALSE) printf("",bg_class); else printf("",bg_class,temp_hostextinfo->x_2d,temp_hostextinfo->y_2d); if(temp_hostextinfo->have_3d_coords==FALSE) printf("",bg_class); else printf("",bg_class,temp_hostextinfo->x_3d,temp_hostextinfo->y_3d,temp_hostextinfo->z_3d); if(temp_hostextinfo->statusmap_image==NULL) printf("",bg_class); else printf("",bg_class,url_logo_images_path,temp_hostextinfo->statusmap_image,temp_hostextinfo->statusmap_image); if(temp_hostextinfo->vrml_image==NULL) printf("",bg_class); else printf("",bg_class,url_logo_images_path,temp_hostextinfo->vrml_image,temp_hostextinfo->vrml_image); if(temp_hostextinfo->icon_image==NULL) printf("",bg_class); else printf("",bg_class,url_logo_images_path,temp_hostextinfo->icon_image,temp_hostextinfo->icon_image); printf("",bg_class,(temp_hostextinfo->icon_image_alt==NULL)?" ":temp_hostextinfo->icon_image_alt); printf("\n"); } printf("
    HostNotes URL2-D Coords3-D CoordsStatusmap ImageVRML ImageLogo ImageImage Alt
    %s%s %d,%d %.2f,%.2f,%.2f  %s  %s  %s%s
    \n"); printf("
    \n"); printf("

    \n"); return; } void display_serviceextinfo(void){ serviceextinfo *temp_serviceextinfo; int odd=0; char *bg_class=""; /* see if user is authorized to view hostdependency information... */ if(is_authorized_for_configuration_information(¤t_authdata)==FALSE){ unauthorized_message(); return; } /* read in command definitions... */ read_all_object_configuration_data(main_config_file,READ_HOSTEXTINFO); printf("

    Extended Service Information

    \n"); printf("

    \n"); printf("

    \n"); printf("\n"); printf("\n"); printf(""); printf("\n"); printf("\n"); printf(""); printf(""); printf(""); printf(""); printf(""); printf("\n"); /* check all the definitions... */ for(temp_serviceextinfo=serviceextinfo_list;temp_serviceextinfo!=NULL;temp_serviceextinfo=temp_serviceextinfo->next){ if(odd){ odd=0; bg_class="dataOdd"; } else{ odd=1; bg_class="dataEven"; } printf("\n",bg_class); printf("",bg_class,CONFIG_CGI,url_encode(temp_serviceextinfo->host_name),temp_serviceextinfo->host_name); printf("\n",url_encode(temp_serviceextinfo->description),temp_serviceextinfo->description); printf("",bg_class,(temp_serviceextinfo->notes_url==NULL)?" ":temp_serviceextinfo->notes_url); if(temp_serviceextinfo->icon_image==NULL) printf("",bg_class); else printf("",bg_class,url_logo_images_path,temp_serviceextinfo->icon_image,temp_serviceextinfo->icon_image); printf("",bg_class,(temp_serviceextinfo->icon_image_alt==NULL)?" ":temp_serviceextinfo->icon_image_alt); printf("\n"); } printf("
    Service
    HostDescriptionNotes URLLogo ImageImage Alt
    %s%s%s  %s%s
    \n"); printf("
    \n"); printf("

    \n"); return; } void unauthorized_message(void){ printf("

    It appears as though you do not have permission to view the configuration information you requested...

    \n"); printf("

    If you believe this is an error, check the HTTP server authentication requirements for accessing this CGI
    "); printf("and check the authorization options in your CGI configuration file.

    \n"); return; } void display_options(void){ printf("

    \n"); printf("
    Select Type of Config Data You Wish To View
    \n"); printf("

    \n"); printf("
    \n",CONFIG_CGI); printf("
    \n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("
    Object Type:
    "); printf("\n"); printf("
    \n"); printf("
    \n"); printf("
    \n"); return; } nagios-2.6/cgi/extinfo.c0000664000076500007650000043553210512470706014577 0ustar nagiosnagios/************************************************************************** * * EXTINFO.C - Nagios Extended Information CGI * * Copyright (c) 1999-2006 Ethan Galstad (nagios@nagios.org) * Last Modified: 10-09-2006 * * 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. *************************************************************************/ #include "../include/config.h" #include "../include/common.h" #include "../include/objects.h" #include "../include/comments.h" #include "../include/downtime.h" #include "../include/statusdata.h" #include "../include/cgiutils.h" #include "../include/getcgi.h" #include "../include/cgiauth.h" extern char nagios_check_command[MAX_INPUT_BUFFER]; extern char nagios_process_info[MAX_INPUT_BUFFER]; extern int nagios_process_state; extern int refresh_rate; extern time_t program_start; extern int nagios_pid; extern int daemon_mode; extern time_t last_command_check; extern time_t last_log_rotation; extern int enable_notifications; extern int execute_service_checks; extern int accept_passive_service_checks; extern int execute_host_checks; extern int accept_passive_host_checks; extern int enable_event_handlers; extern int obsess_over_services; extern int obsess_over_hosts; extern int enable_flap_detection; extern int enable_failure_prediction; extern int process_performance_data; extern char main_config_file[MAX_FILENAME_LENGTH]; extern char url_html_path[MAX_FILENAME_LENGTH]; extern char url_stylesheets_path[MAX_FILENAME_LENGTH]; extern char url_docs_path[MAX_FILENAME_LENGTH]; extern char url_images_path[MAX_FILENAME_LENGTH]; extern char url_logo_images_path[MAX_FILENAME_LENGTH]; extern char log_file[MAX_FILENAME_LENGTH]; extern comment *comment_list; extern scheduled_downtime *scheduled_downtime_list; extern hoststatus *hoststatus_list; extern servicestatus *servicestatus_list; extern hostgroup *hostgroup_list; extern servicegroup *servicegroup_list; #define MAX_MESSAGE_BUFFER 4096 #define HEALTH_WARNING_PERCENTAGE 85 #define HEALTH_CRITICAL_PERCENTAGE 75 /* SORTDATA structure */ typedef struct sortdata_struct{ int is_service; servicestatus *svcstatus; hoststatus *hststatus; struct sortdata_struct *next; }sortdata; void document_header(int); void document_footer(void); int process_cgivars(void); void show_process_info(void); void show_host_info(void); void show_service_info(void); void show_all_comments(void); void show_performance_data(void); void show_hostgroup_info(void); void show_servicegroup_info(void); void show_all_downtime(void); void show_scheduling_queue(void); void display_comments(int); int sort_data(int,int); int compare_sortdata_entries(int,int,sortdata *,sortdata *); void free_sortdata_list(void); authdata current_authdata; sortdata *sortdata_list=NULL; char *host_name=""; char *hostgroup_name=""; char *servicegroup_name=""; char *service_desc=""; int display_type=DISPLAY_PROCESS_INFO; int sort_type=SORT_ASCENDING; int sort_option=SORT_NEXTCHECKTIME; int embedded=FALSE; int display_header=TRUE; int main(void){ int result=OK; int found=FALSE; char temp_buffer[MAX_INPUT_BUFFER]; hostextinfo *temp_hostextinfo=NULL; serviceextinfo *temp_serviceextinfo=NULL; host *temp_host=NULL; hostgroup *temp_hostgroup=NULL; service *temp_service=NULL; servicegroup *temp_servicegroup=NULL; /* get the arguments passed in the URL */ process_cgivars(); /* reset internal variables */ reset_cgi_vars(); /* read the CGI configuration file */ result=read_cgi_config_file(get_cgi_config_location()); if(result==ERROR){ document_header(FALSE); cgi_config_file_error(main_config_file); document_footer(); return ERROR; } /* read the main configuration file */ result=read_main_config_file(main_config_file); if(result==ERROR){ document_header(FALSE); main_config_file_error(main_config_file); document_footer(); return ERROR; } /* read all object configuration data */ result=read_all_object_configuration_data(main_config_file,READ_ALL_OBJECT_DATA); if(result==ERROR){ document_header(FALSE); object_data_error(); document_footer(); return ERROR; } /* read all status data */ result=read_all_status_data(get_cgi_config_location(),READ_ALL_STATUS_DATA); if(result==ERROR){ document_header(FALSE); status_data_error(); document_footer(); free_memory(); return ERROR; } document_header(TRUE); /* get authentication information */ get_authentication_information(¤t_authdata); if(display_header==TRUE){ /* begin top table */ printf("\n"); printf("\n"); /* left column of the first row */ printf("\n"); /* middle column of top row */ printf("\n"); /* right column of top row */ printf("\n"); /* end of top table */ printf("\n"); printf("
    \n"); if(display_type==DISPLAY_HOST_INFO) snprintf(temp_buffer,sizeof(temp_buffer)-1,"Host Information"); else if(display_type==DISPLAY_SERVICE_INFO) snprintf(temp_buffer,sizeof(temp_buffer)-1,"Service Information"); else if(display_type==DISPLAY_COMMENTS) snprintf(temp_buffer,sizeof(temp_buffer)-1,"All Host and Service Comments"); else if(display_type==DISPLAY_PERFORMANCE) snprintf(temp_buffer,sizeof(temp_buffer)-1,"Performance Information"); else if(display_type==DISPLAY_HOSTGROUP_INFO) snprintf(temp_buffer,sizeof(temp_buffer)-1,"Hostgroup Information"); else if(display_type==DISPLAY_SERVICEGROUP_INFO) snprintf(temp_buffer,sizeof(temp_buffer)-1,"Servicegroup Information"); else if(display_type==DISPLAY_DOWNTIME) snprintf(temp_buffer,sizeof(temp_buffer)-1,"All Host and Service Scheduled Downtime"); else if(display_type==DISPLAY_SCHEDULING_QUEUE) snprintf(temp_buffer,sizeof(temp_buffer)-1,"Check Scheduling Queue"); else snprintf(temp_buffer,sizeof(temp_buffer)-1,"Nagios Process Information"); temp_buffer[sizeof(temp_buffer)-1]='\x0'; display_info_table(temp_buffer,TRUE,¤t_authdata); /* find the host */ if(display_type==DISPLAY_HOST_INFO || display_type==DISPLAY_SERVICE_INFO){ temp_host=find_host(host_name); if(display_type==DISPLAY_SERVICE_INFO) temp_service=find_service(host_name,service_desc); /* write some Javascript helper functions */ if(temp_host!=NULL){ printf("\n"); } } /* find the hostgroup */ else if(display_type==DISPLAY_HOSTGROUP_INFO) temp_hostgroup=find_hostgroup(hostgroup_name); /* find the servicegroup */ else if(display_type==DISPLAY_SERVICEGROUP_INFO) temp_servicegroup=find_servicegroup(servicegroup_name); if(((display_type==DISPLAY_HOST_INFO || display_type==DISPLAY_SERVICE_INFO) && temp_host!=NULL) || (display_type==DISPLAY_HOSTGROUP_INFO && temp_hostgroup!=NULL) || (display_type==DISPLAY_SERVICEGROUP_INFO && temp_servicegroup!=NULL)){ printf("\n"); printf("\n"); printf("\n"); } printf("\n"); if(((display_type==DISPLAY_HOST_INFO || display_type==DISPLAY_SERVICE_INFO) && temp_host!=NULL) || (display_type==DISPLAY_HOSTGROUP_INFO && temp_hostgroup!=NULL) || (display_type==DISPLAY_SERVICEGROUP_INFO && temp_servicegroup!=NULL)){ if(display_type==DISPLAY_HOST_INFO){ printf("
    Host
    \n"); printf("
    %s
    \n",temp_host->alias); printf("
    (%s)

    \n",temp_host->name); printf("
    Member of
    "); for(temp_hostgroup=hostgroup_list;temp_hostgroup!=NULL;temp_hostgroup=temp_hostgroup->next){ if(is_host_member_of_hostgroup(temp_hostgroup,temp_host)==TRUE){ if(found==TRUE) printf(", "); printf("%s",STATUS_CGI,url_encode(temp_hostgroup->group_name),temp_hostgroup->group_name); found=TRUE; } } if(found==FALSE) printf("No hostgroups"); printf("

    \n"); printf("
    %s
    \n",temp_host->address); } if(display_type==DISPLAY_SERVICE_INFO){ printf("
    Service
    %s
    On Host
    \n",service_desc); printf("
    %s
    \n",temp_host->alias); printf("
    (%s)

    \n",EXTINFO_CGI,DISPLAY_HOST_INFO,url_encode(temp_host->name),temp_host->name); printf("
    Member of
    "); for(temp_servicegroup=servicegroup_list;temp_servicegroup!=NULL;temp_servicegroup=temp_servicegroup->next){ if(is_service_member_of_servicegroup(temp_servicegroup,temp_service)==TRUE){ if(found==TRUE) printf(", "); printf("%s",STATUS_CGI,url_encode(temp_servicegroup->group_name),temp_servicegroup->group_name); found=TRUE; } } if(found==FALSE) printf("No servicegroups."); printf("

    \n"); printf("
    %s
    \n",temp_host->address); } if(display_type==DISPLAY_HOSTGROUP_INFO){ printf("
    Hostgroup
    \n"); printf("
    %s
    \n",temp_hostgroup->alias); printf("
    (%s)
    \n",temp_hostgroup->group_name); } if(display_type==DISPLAY_SERVICEGROUP_INFO){ printf("
    Servicegroup
    \n"); printf("
    %s
    \n",temp_servicegroup->alias); printf("
    (%s)
    \n",temp_servicegroup->group_name); } if(display_type==DISPLAY_SERVICE_INFO){ temp_serviceextinfo=find_serviceextinfo(host_name,service_desc); if(temp_serviceextinfo!=NULL){ if(temp_serviceextinfo->icon_image!=NULL){ printf("%s
    ",(temp_serviceextinfo->icon_image_alt==NULL)?"":temp_serviceextinfo->icon_image_alt,(temp_serviceextinfo->icon_image_alt==NULL)?"":temp_serviceextinfo->icon_image_alt); } if(temp_serviceextinfo->icon_image_alt!=NULL) printf("( %s )\n",temp_serviceextinfo->icon_image_alt); if(temp_serviceextinfo->notes!=NULL) printf("

    %s

    \n",temp_serviceextinfo->notes); } } if(display_type==DISPLAY_HOST_INFO){ temp_hostextinfo=find_hostextinfo(host_name); if(temp_hostextinfo!=NULL){ if(temp_hostextinfo->icon_image!=NULL){ printf("%s
    ",(temp_hostextinfo->icon_image_alt==NULL)?"":temp_hostextinfo->icon_image_alt,(temp_hostextinfo->icon_image_alt==NULL)?"":temp_hostextinfo->icon_image_alt); } if(temp_hostextinfo->icon_image_alt!=NULL) printf("( %s )\n",temp_hostextinfo->icon_image_alt); if(temp_hostextinfo->notes!=NULL) printf("

    %s

    \n",temp_hostextinfo->notes); } } } printf("
    \n"); if(display_type==DISPLAY_HOST_INFO){ if(temp_hostextinfo!=NULL){ printf("\n"); if(temp_hostextinfo->action_url!=NULL && strcmp(temp_hostextinfo->action_url,"")){ printf("\n"); } if(temp_hostextinfo->notes_url!=NULL && strcmp(temp_hostextinfo->notes_url,"")){ printf("\n"); } printf("
    \n"); printf("Perform Additional Actions On This Host\n",url_images_path,ACTION_ICON); printf("
    Extra Host Actions

    \n"); printf("
    \n"); printf("View Additional Notes For This Host\n",url_images_path,NOTES_ICON); printf("
    Extra Host Notes

    \n"); printf("
    \n"); } } else if(display_type==DISPLAY_SERVICE_INFO){ if(temp_serviceextinfo!=NULL){ printf("\n"); if(temp_serviceextinfo->action_url!=NULL && strcmp(temp_serviceextinfo->action_url,"")){ printf("Perform Additional Actions On This Service\n",url_images_path,ACTION_ICON); printf("
    Extra Service Actions

    \n"); } if(temp_serviceextinfo->notes_url!=NULL && strcmp(temp_serviceextinfo->notes_url,"")){ printf("View Additional Notes For This Service\n",url_images_path,NOTES_ICON); printf("
    Extra Service Notes

    \n"); } printf("
    \n"); } } /* display context-sensitive help */ if(display_type==DISPLAY_HOST_INFO) display_context_help(CONTEXTHELP_EXT_HOST); else if(display_type==DISPLAY_SERVICE_INFO) display_context_help(CONTEXTHELP_EXT_SERVICE); else if(display_type==DISPLAY_HOSTGROUP_INFO) display_context_help(CONTEXTHELP_EXT_HOSTGROUP); else if(display_type==DISPLAY_SERVICEGROUP_INFO) display_context_help(CONTEXTHELP_EXT_SERVICEGROUP); else if(display_type==DISPLAY_PROCESS_INFO) display_context_help(CONTEXTHELP_EXT_PROCESS); else if(display_type==DISPLAY_PERFORMANCE) display_context_help(CONTEXTHELP_EXT_PERFORMANCE); else if(display_type==DISPLAY_COMMENTS) display_context_help(CONTEXTHELP_EXT_COMMENTS); else if(display_type==DISPLAY_DOWNTIME) display_context_help(CONTEXTHELP_EXT_DOWNTIME); else if(display_type==DISPLAY_SCHEDULING_QUEUE) display_context_help(CONTEXTHELP_EXT_QUEUE); printf("
    \n"); } printf("
    \n"); if(display_type==DISPLAY_HOST_INFO) show_host_info(); else if(display_type==DISPLAY_SERVICE_INFO) show_service_info(); else if(display_type==DISPLAY_COMMENTS) show_all_comments(); else if(display_type==DISPLAY_PERFORMANCE) show_performance_data(); else if(display_type==DISPLAY_HOSTGROUP_INFO) show_hostgroup_info(); else if(display_type==DISPLAY_SERVICEGROUP_INFO) show_servicegroup_info(); else if(display_type==DISPLAY_DOWNTIME) show_all_downtime(); else if(display_type==DISPLAY_SCHEDULING_QUEUE) show_scheduling_queue(); else show_process_info(); document_footer(); /* free all allocated memory */ free_memory(); free_comment_data(); free_downtime_data(); return OK; } void document_header(int use_stylesheet){ char date_time[MAX_DATETIME_LENGTH]; time_t current_time; time_t expire_time; printf("Cache-Control: no-store\r\n"); printf("Pragma: no-cache\r\n"); printf("Refresh: %d\r\n",refresh_rate); time(¤t_time); get_time_string(¤t_time,date_time,(int)sizeof(date_time),HTTP_DATE_TIME); printf("Last-Modified: %s\r\n",date_time); expire_time=(time_t)0L; get_time_string(&expire_time,date_time,(int)sizeof(date_time),HTTP_DATE_TIME); printf("Expires: %s\r\n",date_time); printf("Content-type: text/html\r\n\r\n"); if(embedded==TRUE) return; printf("\n"); printf("\n"); printf("\n"); printf("Extended Information\n"); printf("\n"); if(use_stylesheet==TRUE){ printf("",url_stylesheets_path,COMMON_CSS); printf("",url_stylesheets_path,EXTINFO_CSS); } printf("\n"); printf("\n"); /* include user SSI header */ include_ssi_files(EXTINFO_CGI,SSI_HEADER); return; } void document_footer(void){ if(embedded==TRUE) return; /* include user SSI footer */ include_ssi_files(EXTINFO_CGI,SSI_FOOTER); printf("\n"); printf("\n"); return; } int process_cgivars(void){ char **variables; int error=FALSE; int temp_type; int x; variables=getcgivars(); for(x=0;variables[x]!=NULL;x++){ /* do some basic length checking on the variable identifier to prevent buffer overflows */ if(strlen(variables[x])>=MAX_INPUT_BUFFER-1){ x++; continue; } /* we found the display type */ else if(!strcmp(variables[x],"type")){ x++; if(variables[x]==NULL){ error=TRUE; break; } temp_type=atoi(variables[x]); if(temp_type==DISPLAY_HOST_INFO) display_type=DISPLAY_HOST_INFO; else if(temp_type==DISPLAY_SERVICE_INFO) display_type=DISPLAY_SERVICE_INFO; else if(temp_type==DISPLAY_COMMENTS) display_type=DISPLAY_COMMENTS; else if(temp_type==DISPLAY_PERFORMANCE) display_type=DISPLAY_PERFORMANCE; else if(temp_type==DISPLAY_HOSTGROUP_INFO) display_type=DISPLAY_HOSTGROUP_INFO; else if(temp_type==DISPLAY_SERVICEGROUP_INFO) display_type=DISPLAY_SERVICEGROUP_INFO; else if(temp_type==DISPLAY_DOWNTIME) display_type=DISPLAY_DOWNTIME; else if(temp_type==DISPLAY_SCHEDULING_QUEUE) display_type=DISPLAY_SCHEDULING_QUEUE; else display_type=DISPLAY_PROCESS_INFO; } /* we found the host name */ else if(!strcmp(variables[x],"host")){ x++; if(variables[x]==NULL){ error=TRUE; break; } host_name=strdup(variables[x]); if(host_name==NULL) host_name=""; } /* we found the hostgroup name */ else if(!strcmp(variables[x],"hostgroup")){ x++; if(variables[x]==NULL){ error=TRUE; break; } hostgroup_name=strdup(variables[x]); if(hostgroup_name==NULL) hostgroup_name=""; } /* we found the service name */ else if(!strcmp(variables[x],"service")){ x++; if(variables[x]==NULL){ error=TRUE; break; } service_desc=strdup(variables[x]); if(service_desc==NULL) service_desc=""; } /* we found the servicegroup name */ else if(!strcmp(variables[x],"servicegroup")){ x++; if(variables[x]==NULL){ error=TRUE; break; } servicegroup_name=strdup(variables[x]); if(servicegroup_name==NULL) servicegroup_name=""; } /* we found the sort type argument */ else if(!strcmp(variables[x],"sorttype")){ x++; if(variables[x]==NULL){ error=TRUE; break; } sort_type=atoi(variables[x]); } /* we found the sort option argument */ else if(!strcmp(variables[x],"sortoption")){ x++; if(variables[x]==NULL){ error=TRUE; break; } sort_option=atoi(variables[x]); } /* we found the embed option */ else if(!strcmp(variables[x],"embedded")) embedded=TRUE; /* we found the noheader option */ else if(!strcmp(variables[x],"noheader")) display_header=FALSE; } /* free memory allocated to the CGI variables */ free_cgivars(variables); return error; } void show_process_info(void){ char date_time[MAX_DATETIME_LENGTH]; time_t current_time; unsigned long run_time; char run_time_string[24]; int days=0; int hours=0; int minutes=0; int seconds=0; /* make sure the user has rights to view system information */ if(is_authorized_for_system_information(¤t_authdata)==FALSE){ printf("

    It appears as though you do not have permission to view process information...

    \n"); printf("

    If you believe this is an error, check the HTTP server authentication requirements for accessing this CGI
    "); printf("and check the authorization options in your CGI configuration file.

    \n"); return; } printf("

    \n"); printf("

    \n"); printf("\n"); printf("
    \n"); printf("
    Process Information
    \n"); printf("\n"); printf("\n"); printf("
    \n"); printf("\n"); /* program start time */ get_time_string(&program_start,date_time,(int)sizeof(date_time),SHORT_DATE_TIME); printf("\n",date_time); /* total running time */ time(¤t_time); run_time=(unsigned long)(current_time-program_start); get_time_breakdown(run_time,&days,&hours,&minutes,&seconds); sprintf(run_time_string,"%dd %dh %dm %ds",days,hours,minutes,seconds); printf("\n",run_time_string); /* last external check */ get_time_string(&last_command_check,date_time,(int)sizeof(date_time),SHORT_DATE_TIME); printf("\n",(last_command_check==(time_t)0)?"N/A":date_time); /* last log file rotation */ get_time_string(&last_log_rotation,date_time,(int)sizeof(date_time),SHORT_DATE_TIME); printf("\n",(last_log_rotation==(time_t)0)?"N/A":date_time); /* PID */ printf("\n",nagios_pid); /* notifications enabled */ printf("\n",(enable_notifications==TRUE)?"ENABLED":"DISABLED",(enable_notifications==TRUE)?"YES":"NO"); /* service check execution enabled */ printf("\n",(execute_service_checks==TRUE)?"ENABLED":"DISABLED",(execute_service_checks==TRUE)?"YES":"NO"); /* passive service check acceptance */ printf("\n",(accept_passive_service_checks==TRUE)?"ENABLED":"DISABLED",(accept_passive_service_checks==TRUE)?"YES":"NO"); /* host check execution enabled */ printf("\n",(execute_host_checks==TRUE)?"ENABLED":"DISABLED",(execute_host_checks==TRUE)?"YES":"NO"); /* passive host check acceptance */ printf("\n",(accept_passive_host_checks==TRUE)?"ENABLED":"DISABLED",(accept_passive_host_checks==TRUE)?"YES":"NO"); /* event handlers enabled */ printf("\n",(enable_event_handlers==TRUE)?"Yes":"No"); /* obsessing over services */ printf("\n",(obsess_over_services==TRUE)?"Yes":"No"); /* obsessing over hosts */ printf("\n",(obsess_over_hosts==TRUE)?"Yes":"No"); /* flap detection enabled */ printf("\n",(enable_flap_detection==TRUE)?"Yes":"No"); #ifdef PREDICT_FAILURES /* failure prediction enabled */ printf("\n",(enable_failure_prediction==TRUE)?"Yes":"No"); #endif /* process performance data */ printf("\n",(process_performance_data==TRUE)?"Yes":"No"); #ifdef USE_OLDCRUD /* daemon mode */ printf("\n",(daemon_mode==TRUE)?"Yes":"No"); #endif printf("
    Program Start Time:%s
    Total Running Time:%s
    Last External Command Check:%s
    Last Log File Rotation:%s
    Nagios PID%d
    Notifications Enabled?
      %s  
    Service Checks Being Executed?
      %s  
    Passive Service Checks Being Accepted?
      %s  
    Host Checks Being Executed?
      %s  
    Passive Host Checks Being Accepted?
      %s  
    Event Handlers Enabled?%s
    Obsessing Over Services?%s
    Obsessing Over Hosts?%s
    Flap Detection Enabled?%s
    Failure Prediction Enabled?%s
    Performance Data Being Processed?%s
    Running As A Daemon?%s
    \n"); printf("
    \n"); printf("
    \n"); printf("
    Process Commands
    \n"); printf("\n"); printf("\n"); printf("
    \n"); if(nagios_process_state==STATE_OK){ printf("\n"); #ifndef DUMMY_INSTALL printf("\n",url_images_path,STOP_ICON,COMMAND_CGI,CMD_SHUTDOWN_PROCESS); printf("\n",url_images_path,RESTART_ICON,COMMAND_CGI,CMD_RESTART_PROCESS); #endif if(enable_notifications==TRUE) printf("\n",url_images_path,DISABLED_ICON,COMMAND_CGI,CMD_DISABLE_NOTIFICATIONS); else printf("\n",url_images_path,ENABLED_ICON,COMMAND_CGI,CMD_ENABLE_NOTIFICATIONS); if(execute_service_checks==TRUE) printf("\n",url_images_path,DISABLED_ICON,COMMAND_CGI,CMD_STOP_EXECUTING_SVC_CHECKS); else printf("\n",url_images_path,ENABLED_ICON,COMMAND_CGI,CMD_START_EXECUTING_SVC_CHECKS); if(accept_passive_service_checks==TRUE) printf("\n",url_images_path,DISABLED_ICON,COMMAND_CGI,CMD_STOP_ACCEPTING_PASSIVE_SVC_CHECKS); else printf("\n",url_images_path,ENABLED_ICON,COMMAND_CGI,CMD_START_ACCEPTING_PASSIVE_SVC_CHECKS); if(execute_host_checks==TRUE) printf("\n",url_images_path,DISABLED_ICON,COMMAND_CGI,CMD_STOP_EXECUTING_HOST_CHECKS); else printf("\n",url_images_path,ENABLED_ICON,COMMAND_CGI,CMD_START_EXECUTING_HOST_CHECKS); if(accept_passive_host_checks==TRUE) printf("\n",url_images_path,DISABLED_ICON,COMMAND_CGI,CMD_STOP_ACCEPTING_PASSIVE_HOST_CHECKS); else printf("\n",url_images_path,ENABLED_ICON,COMMAND_CGI,CMD_START_ACCEPTING_PASSIVE_HOST_CHECKS); if(enable_event_handlers==TRUE) printf("\n",url_images_path,DISABLED_ICON,COMMAND_CGI,CMD_DISABLE_EVENT_HANDLERS); else printf("\n",url_images_path,ENABLED_ICON,COMMAND_CGI,CMD_ENABLE_EVENT_HANDLERS); if(obsess_over_services==TRUE) printf("\n",url_images_path,DISABLED_ICON,COMMAND_CGI,CMD_STOP_OBSESSING_OVER_SVC_CHECKS); else printf("\n",url_images_path,ENABLED_ICON,COMMAND_CGI,CMD_START_OBSESSING_OVER_SVC_CHECKS); if(obsess_over_hosts==TRUE) printf("\n",url_images_path,DISABLED_ICON,COMMAND_CGI,CMD_STOP_OBSESSING_OVER_HOST_CHECKS); else printf("\n",url_images_path,ENABLED_ICON,COMMAND_CGI,CMD_START_OBSESSING_OVER_HOST_CHECKS); if(enable_flap_detection==TRUE) printf("\n",url_images_path,DISABLED_ICON,COMMAND_CGI,CMD_DISABLE_FLAP_DETECTION); else printf("\n",url_images_path,ENABLED_ICON,COMMAND_CGI,CMD_ENABLE_FLAP_DETECTION); #ifdef PREDICT_FAILURES if(enable_failure_prediction==TRUE) printf("\n",url_images_path,DISABLED_ICON,COMMAND_CGI,CMD_DISABLE_FAILURE_PREDICTION); else printf("\n",url_images_path,ENABLED_ICON,COMMAND_CGI,CMD_ENABLE_FAILURE_PREDICTION); #endif if(process_performance_data==TRUE) printf("\n",url_images_path,DISABLED_ICON,COMMAND_CGI,CMD_DISABLE_PERFORMANCE_DATA); else printf("\n",url_images_path,ENABLED_ICON,COMMAND_CGI,CMD_ENABLE_PERFORMANCE_DATA); printf("
    Shutdown the Nagios ProcessShutdown the Nagios process
    Restart the Nagios ProcessRestart the Nagios process
    Disable NotificationsDisable notifications
    Enable NotificationsEnable notifications
    Stop Executing Service ChecksStop executing service checks
    Start Executing Service ChecksStart executing service checks
    Stop Accepting Passive Service ChecksStop accepting passive service checks
    Start Accepting Passive Service ChecksStart accepting passive service checks
    Stop Executing Host ChecksStop executing host checks
    Start Executing Host ChecksStart executing host checks
    Stop Accepting Passive Host ChecksStop accepting passive host checks
    Start Accepting Passive Host ChecksStart accepting passive host checks
    Disable Event HandlersDisable event handlers
    Enable Event HandlersEnable event handlers
    Stop Obsessing Over ServicesStop obsessing over services
    Start Obsessing Over ServicesStart obsessing over services
    Stop Obsessing Over HostsStop obsessing over hosts
    Start Obsessing Over HostsStart obsessing over hosts
    Disable Flap DetectionDisable flap detection
    Enable Flap DetectionEnable flap detection
    Disable Failure PredictionDisable failure prediction
    Enable Failure PredictionEnable failure prediction
    Disable Performance DataDisable performance data
    Enable Performance DataEnable performance data
    \n"); } else{ printf("
    It appears as though Nagios is not running, so commands are temporarily unavailable...\n"); if(!strcmp(nagios_check_command,"")){ printf("

    \n"); printf("Hint: It looks as though you have not defined a command for checking the process state by supplying a value for the nagios_check_command option in the CGI configuration file.
    \n"); printf("Read the documentation for more information on checking the status of the Nagios process in the CGIs.\n"); } printf("
    \n"); } printf("
    \n"); printf("
    \n"); #ifdef REMOVED_081203 printf("

    "); printf("

    \n"); printf("
    Process Status Information
    \n"); printf("\n"); printf("\n"); printf("
    \n"); printf("\n"); if(nagios_process_state==STATE_OK){ strcpy(state_string,"OK"); state_class="processOK"; } else if(nagios_process_state==STATE_WARNING){ strcpy(state_string,"WARNING"); state_class="processWARNING"; } else if(nagios_process_state==STATE_CRITICAL){ strcpy(state_string,"CRITICAL"); state_class="processCRITICAL"; } else{ strcpy(state_string,"UNKNOWN"); state_class="processUNKNOWN"; } /* process state */ printf("\n",state_class,state_string); /* process check command result */ printf("\n",nagios_process_info); printf("
    Process Status:
      %s  
    Check Command Output: %s 
    \n"); printf("
    \n"); printf("
    \n"); printf("

    \n"); #endif return; } void show_host_info(void){ hoststatus *temp_hoststatus; host *temp_host; char date_time[MAX_DATETIME_LENGTH]; char state_duration[48]; char status_age[48]; char state_string[MAX_INPUT_BUFFER]; char *bg_class=""; int days; int hours; int minutes; int seconds; time_t current_time; time_t t; int duration_error=FALSE; /* get host info */ temp_host=find_host(host_name); /* make sure the user has rights to view host information */ if(is_authorized_for_host(temp_host,¤t_authdata)==FALSE){ printf("

    It appears as though you do not have permission to view information for this host...

    \n"); printf("

    If you believe this is an error, check the HTTP server authentication requirements for accessing this CGI
    "); printf("and check the authorization options in your CGI configuration file.

    \n"); return; } /* get host status info */ temp_hoststatus=find_hoststatus(host_name); /* make sure host information exists */ if(temp_host==NULL){ printf("

    Error: Host Not Found!

    >"); return; } if(temp_hoststatus==NULL){ printf("

    Error: Host Status Information Not Found!
    \n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("
    \n"); printf("
    Host State Information
    \n"); if(temp_hoststatus->has_been_checked==FALSE) printf("

    This host has not yet been checked, so status information is not available.

    \n"); else{ printf("\n"); printf("\n"); printf("\n"); printf("
    \n"); printf("\n"); printf("\n"); printf("
    \n"); printf("\n"); if(temp_hoststatus->status==HOST_UP){ strcpy(state_string,"UP"); bg_class="hostUP"; } else if(temp_hoststatus->status==HOST_DOWN){ strcpy(state_string,"DOWN"); bg_class="hostDOWN"; } else if(temp_hoststatus->status==HOST_UNREACHABLE){ strcpy(state_string,"UNREACHABLE"); bg_class="hostUNREACHABLE"; } printf("\n",bg_class,state_string,(temp_hoststatus->problem_has_been_acknowledged==TRUE)?"(Has been acknowledged)":""); printf("\n",(temp_hoststatus->plugin_output==NULL)?"":temp_hoststatus->plugin_output); printf("\n",(temp_hoststatus->perf_data==NULL)?"":temp_hoststatus->perf_data); printf("\n",temp_hoststatus->current_attempt,temp_hoststatus->max_attempts); printf("\n",(temp_hoststatus->state_type==HARD_STATE)?"HARD":"SOFT"); printf("\n",(temp_hoststatus->check_type==HOST_CHECK_ACTIVE)?"ACTIVE":"PASSIVE"); get_time_string(&temp_hoststatus->last_check,date_time,(int)sizeof(date_time),SHORT_DATE_TIME); printf("\n",date_time); current_time=time(NULL); t=0; duration_error=FALSE; if(temp_hoststatus->last_check>current_time) duration_error=TRUE; else t=current_time-temp_hoststatus->last_check; get_time_breakdown((unsigned long)t,&days,&hours,&minutes,&seconds); if(duration_error==TRUE) snprintf(status_age,sizeof(status_age)-1,"???"); else if(temp_hoststatus->last_check==(time_t)0) snprintf(status_age,sizeof(status_age)-1,"N/A"); else snprintf(status_age,sizeof(status_age)-1,"%2dd %2dh %2dm %2ds",days,hours,minutes,seconds); status_age[sizeof(status_age)-1]='\x0'; printf("\n",status_age); get_time_string(&temp_hoststatus->next_check,date_time,(int)sizeof(date_time),SHORT_DATE_TIME); printf("\n",(temp_hoststatus->checks_enabled && temp_hoststatus->next_check!=(time_t)0 && temp_hoststatus->should_be_scheduled==TRUE)?date_time:"N/A"); printf("\n"); printf("\n",temp_hoststatus->execution_time); get_time_string(&temp_hoststatus->last_state_change,date_time,(int)sizeof(date_time),SHORT_DATE_TIME); printf("\n",(temp_hoststatus->last_state_change==(time_t)0)?"N/A":date_time); t=0; duration_error=FALSE; if(temp_hoststatus->last_state_change==(time_t)0){ if(program_start>current_time) duration_error=TRUE; else t=current_time-program_start; } else{ if(temp_hoststatus->last_state_change>current_time) duration_error=TRUE; else t=current_time-temp_hoststatus->last_state_change; } get_time_breakdown((unsigned long)t,&days,&hours,&minutes,&seconds); if(duration_error==TRUE) snprintf(state_duration,sizeof(state_duration)-1,"???"); else snprintf(state_duration,sizeof(state_duration)-1,"%2dd %2dh %2dm %2ds%s",days,hours,minutes,seconds,(temp_hoststatus->last_state_change==(time_t)0)?"+":""); state_duration[sizeof(state_duration)-1]='\x0'; printf("\n",state_duration); get_time_string(&temp_hoststatus->last_notification,date_time,(int)sizeof(date_time),SHORT_DATE_TIME); printf("\n",(temp_hoststatus->last_notification==(time_t)0)?"N/A":date_time); printf("\n",temp_hoststatus->current_notification_number); printf("\n"); printf("\n"); printf("\n",(temp_hoststatus->scheduled_downtime_depth>0)?"ACTIVE":"INACTIVE",(temp_hoststatus->scheduled_downtime_depth>0)?"YES":"NO"); get_time_string(&temp_hoststatus->last_update,date_time,(int)sizeof(date_time),SHORT_DATE_TIME); printf("\n",(temp_hoststatus->last_update==(time_t)0)?"N/A":date_time); printf("
    Host Status:
      %s  %s  
    Status Information:%s
    Performance Data:%s
    Current Attempt:%d/%d
    State Type:%s
    Last Check Type:%s
    Last Check Time:%s
    Status Data Age:%s
    Next Scheduled Active Check:  %s
    Latency:"); if(temp_hoststatus->check_type==HOST_CHECK_ACTIVE) printf("%.3f seconds",temp_hoststatus->latency); else printf("N/A"); printf("
    Check Duration:%.3f seconds
    Last State Change:%s
    Current State Duration:%s
    Last Host Notification:%s
    Current Notification Number:  %d  
    Is This Host Flapping?"); if(temp_hoststatus->flap_detection_enabled==FALSE || enable_flap_detection==FALSE) printf("N/A"); else printf("
      %s  
    ",(temp_hoststatus->is_flapping==TRUE)?"":"not",(temp_hoststatus->is_flapping==TRUE)?"YES":"NO"); printf("
    Percent State Change:"); if(temp_hoststatus->flap_detection_enabled==FALSE || enable_flap_detection==FALSE) printf("N/A"); else printf("%3.2f%%",temp_hoststatus->percent_state_change); printf("
    In Scheduled Downtime?
      %s  
    Last Update:%s
    \n"); printf("
    \n"); printf("
    \n"); printf("\n"); printf("\n"); printf("
    \n"); printf("\n"); printf("\n",(temp_hoststatus->checks_enabled==TRUE)?"ENABLED":"DISABLED",(temp_hoststatus->checks_enabled==TRUE)?"ENABLED":"DISABLED"); printf("\n",(temp_hoststatus->accept_passive_host_checks==TRUE)?"ENABLED":"DISABLED",(temp_hoststatus->accept_passive_host_checks)?"ENABLED":"DISABLED"); printf("\n",(temp_hoststatus->obsess_over_host==TRUE)?"ENABLED":"DISABLED",(temp_hoststatus->obsess_over_host)?"ENABLED":"DISABLED"); printf("\n",(temp_hoststatus->notifications_enabled)?"ENABLED":"DISABLED",(temp_hoststatus->notifications_enabled)?"ENABLED":"DISABLED"); printf("\n",(temp_hoststatus->event_handler_enabled)?"ENABLED":"DISABLED",(temp_hoststatus->event_handler_enabled)?"ENABLED":"DISABLED"); printf("\n",(temp_hoststatus->flap_detection_enabled==TRUE)?"ENABLED":"DISABLED",(temp_hoststatus->flap_detection_enabled==TRUE)?"ENABLED":"DISABLED"); printf("
    Active Checks:
      %s  
    Passive Checks:
      %s  
    Obsessing:
      %s  
    Notifications:
      %s  
    Event Handler:
      %s  
    Flap Detection:
      %s  
    \n"); printf("
    \n"); printf("
    \n"); } printf("
    \n"); printf("\n"); printf("\n"); printf("\n"); printf("
    \n"); printf("
    Host Commands
    \n"); printf("
    \n"); if(nagios_process_state==STATE_OK){ printf("\n"); #ifdef USE_STATUSMAP printf("\n",url_images_path,STATUSMAP_ICON,STATUSMAP_CGI,url_encode(host_name)); #endif if(temp_hoststatus->checks_enabled==TRUE){ printf("\n",url_images_path,DISABLED_ICON,COMMAND_CGI,CMD_DISABLE_HOST_CHECK,url_encode(host_name)); printf("\n",url_images_path,DELAY_ICON,COMMAND_CGI,CMD_SCHEDULE_HOST_CHECK,url_encode(host_name)); } else printf("\n",url_images_path,ENABLED_ICON,COMMAND_CGI,CMD_ENABLE_HOST_CHECK,url_encode(host_name)); if(temp_hoststatus->accept_passive_host_checks==TRUE){ printf("\n",url_images_path,PASSIVE_ICON,COMMAND_CGI,CMD_PROCESS_HOST_CHECK_RESULT,url_encode(host_name)); printf("\n",url_images_path,DISABLED_ICON,COMMAND_CGI,CMD_DISABLE_PASSIVE_HOST_CHECKS,url_encode(host_name)); } else printf("\n",url_images_path,ENABLED_ICON,COMMAND_CGI,CMD_ENABLE_PASSIVE_HOST_CHECKS,url_encode(host_name)); if(temp_hoststatus->obsess_over_host==TRUE) printf("\n",url_images_path,DISABLED_ICON,COMMAND_CGI,CMD_STOP_OBSESSING_OVER_HOST,url_encode(host_name)); else printf("\n",url_images_path,ENABLED_ICON,COMMAND_CGI,CMD_START_OBSESSING_OVER_HOST,url_encode(host_name)); if(temp_hoststatus->status==HOST_DOWN || temp_hoststatus->status==HOST_UNREACHABLE){ if(temp_hoststatus->problem_has_been_acknowledged==FALSE) printf("\n",url_images_path,ACKNOWLEDGEMENT_ICON,COMMAND_CGI,CMD_ACKNOWLEDGE_HOST_PROBLEM,url_encode(host_name)); else printf("\n",url_images_path,REMOVE_ACKNOWLEDGEMENT_ICON,COMMAND_CGI,CMD_REMOVE_HOST_ACKNOWLEDGEMENT,url_encode(host_name)); } if(temp_hoststatus->notifications_enabled==TRUE) printf("\n",url_images_path,DISABLED_ICON,COMMAND_CGI,CMD_DISABLE_HOST_NOTIFICATIONS,url_encode(host_name)); else printf("\n",url_images_path,ENABLED_ICON,COMMAND_CGI,CMD_ENABLE_HOST_NOTIFICATIONS,url_encode(host_name)); if(temp_hoststatus->status!=HOST_UP) printf("\n",url_images_path,DELAY_ICON,COMMAND_CGI,CMD_DELAY_HOST_NOTIFICATION,url_encode(host_name)); printf("\n",url_images_path,DOWNTIME_ICON,COMMAND_CGI,CMD_SCHEDULE_HOST_DOWNTIME,url_encode(host_name)); /* printf("\n",url_images_path,SCHEDULED_DOWNTIME_ICON,COMMAND_CGI,CMD_CANCEL_HOST_DOWNTIME,url_encode(host_name)); */ printf("\n",url_images_path,DISABLED_ICON,COMMAND_CGI,CMD_DISABLE_HOST_SVC_NOTIFICATIONS,url_encode(host_name)); printf("\n",url_images_path,ENABLED_ICON,COMMAND_CGI,CMD_ENABLE_HOST_SVC_NOTIFICATIONS,url_encode(host_name)); printf("\n",url_images_path,DELAY_ICON,COMMAND_CGI,CMD_SCHEDULE_HOST_SVC_CHECKS,url_encode(host_name)); printf("\n",url_images_path,DISABLED_ICON,COMMAND_CGI,CMD_DISABLE_HOST_SVC_CHECKS,url_encode(host_name)); printf("\n",url_images_path,ENABLED_ICON,COMMAND_CGI,CMD_ENABLE_HOST_SVC_CHECKS,url_encode(host_name)); if(temp_hoststatus->event_handler_enabled==TRUE) printf("\n",url_images_path,DISABLED_ICON,COMMAND_CGI,CMD_DISABLE_HOST_EVENT_HANDLER,url_encode(host_name)); else printf("\n",url_images_path,ENABLED_ICON,COMMAND_CGI,CMD_ENABLE_HOST_EVENT_HANDLER,url_encode(host_name)); if(temp_hoststatus->flap_detection_enabled==TRUE) printf("\n",url_images_path,DISABLED_ICON,COMMAND_CGI,CMD_DISABLE_HOST_FLAP_DETECTION,url_encode(host_name)); else printf("\n",url_images_path,ENABLED_ICON,COMMAND_CGI,CMD_ENABLE_HOST_FLAP_DETECTION,url_encode(host_name)); printf("
    Locate Host On MapLocate host on map
    Disable Active Checks Of This HostDisable active checks of this host
    Re-schedule Next Host CheckRe-schedule the next check of this host
    Enable Active Checks Of This HostEnable active checks of this host
    Submit Passive Check Result For This HostSubmit passive check result for this host
    Stop Accepting Passive Checks For This HostStop accepting passive checks for this host
    Start Accepting Passive Checks For This HostStart accepting passive checks for this host
    Stop Obsessing Over This HostStop obsessing over this host
    Start Obsessing Over This HostStart obsessing over this host
    Acknowledge This Host ProblemAcknowledge this host problem
    Remove Problem AcknowledgementRemove problem acknowledgement
    Disable Notifications For This HostDisable notifications for this host
    Enable Notifications For This HostEnable notifications for this host
    Delay Next Host NotificationDelay next host notification
    Schedule Downtime For This HostSchedule downtime for this host
    Cancel Scheduled Downtime For This HostCancel scheduled downtime for this host
    Disable Notifications For All Services On This HostDisable notifications for all services on this host
    Enable Notifications For All Services On This HostEnable notifications for all services on this host
    Schedule A Check Of All Services On This HostSchedule a check of all services on this host
    Disable Checks Of All Services On This HostDisable checks of all services on this host
    Enable Checks Of All Services On This HostEnable checks of all services on this host
    Disable Event Handler For This HostDisable event handler for this host
    Enable Event Handler For This HostEnable event handler for this host
    Disable Flap Detection For This HostDisable flap detection for this host
    Enable Flap Detection For This HostEnable flap detection for this host
    \n"); } else{ printf("
    It appears as though Nagios is not running, so commands are temporarily unavailable...
    \n"); printf("Click here to view Nagios process information
    \n",EXTINFO_CGI,DISPLAY_PROCESS_INFO); } printf("
    \n"); printf("
    \n"); /* display comments */ display_comments(HOST_COMMENT); printf("
    \n"); printf("
    \n"); return; } void show_service_info(void){ service *temp_service; char date_time[MAX_DATETIME_LENGTH]; char status_age[48]; char state_duration[48]; servicestatus *temp_svcstatus; char state_string[MAX_INPUT_BUFFER]; char *bg_class=""; int days; int hours; int minutes; int seconds; time_t t; time_t current_time; int duration_error=FALSE; /* find the service */ temp_service=find_service(host_name,service_desc); /* make sure the user has rights to view service information */ if(is_authorized_for_service(temp_service,¤t_authdata)==FALSE){ printf("

    It appears as though you do not have permission to view information for this service...

    \n"); printf("

    If you believe this is an error, check the HTTP server authentication requirements for accessing this CGI
    "); printf("and check the authorization options in your CGI configuration file.

    \n"); return; } /* get service status info */ temp_svcstatus=find_servicestatus(host_name,service_desc); /* make sure service information exists */ if(temp_service==NULL){ printf("

    Error: Service Not Found!

    "); return; } if(temp_svcstatus==NULL){ printf("

    Error: Service Status Not Found!

    "); return; } printf("
    \n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("
    \n"); printf("
    Service State Information
    \n"); if(temp_svcstatus->has_been_checked==FALSE) printf("

    This service has not yet been checked, so status information is not available.

    \n"); else{ printf("\n"); printf("\n"); printf("\n"); printf("
    \n"); printf("\n"); printf("\n"); printf("
    \n"); printf("\n"); if(temp_svcstatus->status==SERVICE_OK){ strcpy(state_string,"OK"); bg_class="serviceOK"; } else if(temp_svcstatus->status==SERVICE_WARNING){ strcpy(state_string,"WARNING"); bg_class="serviceWARNING"; } else if(temp_svcstatus->status==SERVICE_CRITICAL){ strcpy(state_string,"CRITICAL"); bg_class="serviceCRITICAL"; } else{ strcpy(state_string,"UNKNOWN"); bg_class="serviceUNKNOWN"; } printf("\n",bg_class,state_string,(temp_svcstatus->problem_has_been_acknowledged==TRUE)?"(Has been acknowledged)":""); printf("\n",(temp_svcstatus->plugin_output==NULL)?"":temp_svcstatus->plugin_output); printf("\n",(temp_svcstatus->perf_data==NULL)?"":temp_svcstatus->perf_data); printf("\n",temp_svcstatus->current_attempt,temp_svcstatus->max_attempts); printf("\n",(temp_svcstatus->state_type==HARD_STATE)?"HARD":"SOFT"); printf("\n",(temp_svcstatus->check_type==SERVICE_CHECK_ACTIVE)?"ACTIVE":"PASSIVE"); get_time_string(&temp_svcstatus->last_check,date_time,(int)sizeof(date_time),SHORT_DATE_TIME); printf("\n",date_time); current_time=time(NULL); t=0; duration_error=FALSE; if(temp_svcstatus->last_check>current_time) duration_error=TRUE; else t=current_time-temp_svcstatus->last_check; get_time_breakdown((unsigned long)t,&days,&hours,&minutes,&seconds); if(duration_error==TRUE) snprintf(status_age,sizeof(status_age)-1,"???"); else if(temp_svcstatus->last_check==(time_t)0) snprintf(status_age,sizeof(status_age)-1,"N/A"); else snprintf(status_age,sizeof(status_age)-1,"%2dd %2dh %2dm %2ds",days,hours,minutes,seconds); status_age[sizeof(status_age)-1]='\x0'; printf("\n",status_age); get_time_string(&temp_svcstatus->next_check,date_time,(int)sizeof(date_time),SHORT_DATE_TIME); printf("\n",(temp_svcstatus->checks_enabled && temp_svcstatus->next_check!=(time_t)0 && temp_svcstatus->should_be_scheduled==TRUE)?date_time:"N/A"); printf("\n"); printf("\n",temp_svcstatus->execution_time); get_time_string(&temp_svcstatus->last_state_change,date_time,(int)sizeof(date_time),SHORT_DATE_TIME); printf("\n",(temp_svcstatus->last_state_change==(time_t)0)?"N/A":date_time); t=0; duration_error=FALSE; if(temp_svcstatus->last_state_change==(time_t)0){ if(program_start>current_time) duration_error=TRUE; else t=current_time-program_start; } else{ if(temp_svcstatus->last_state_change>current_time) duration_error=TRUE; else t=current_time-temp_svcstatus->last_state_change; } get_time_breakdown((unsigned long)t,&days,&hours,&minutes,&seconds); if(duration_error==TRUE) snprintf(state_duration,sizeof(state_duration)-1,"???"); else snprintf(state_duration,sizeof(state_duration)-1,"%2dd %2dh %2dm %2ds%s",days,hours,minutes,seconds,(temp_svcstatus->last_state_change==(time_t)0)?"+":""); state_duration[sizeof(state_duration)-1]='\x0'; printf("\n",state_duration); get_time_string(&temp_svcstatus->last_notification,date_time,(int)sizeof(date_time),SHORT_DATE_TIME); printf("\n",(temp_svcstatus->last_notification==(time_t)0)?"N/A":date_time); get_time_string(&temp_svcstatus->last_notification,date_time,(int)sizeof(date_time),SHORT_DATE_TIME); printf("\n",temp_svcstatus->current_notification_number); printf("\n"); printf("\n"); printf("\n",(temp_svcstatus->scheduled_downtime_depth>0)?"ACTIVE":"INACTIVE",(temp_svcstatus->scheduled_downtime_depth>0)?"YES":"NO"); get_time_string(&temp_svcstatus->last_update,date_time,(int)sizeof(date_time),SHORT_DATE_TIME); printf("\n",(temp_svcstatus->last_update==(time_t)0)?"N/A":date_time); printf("
    Current Status:
      %s  %s  
    Status Information:%s
    Performance Data:%s
    Current Attempt:%d/%d
    State Type:%s
    Last Check Type:%s
    Last Check Time:%s
    Status Data Age:%s
    Next Scheduled Active Check:  %s
    Latency:"); if(temp_svcstatus->check_type==SERVICE_CHECK_ACTIVE) printf("%.3f seconds",temp_svcstatus->latency); else printf("N/A"); printf("
    Check Duration:%.3f seconds
    Last State Change:%s
    Current State Duration:%s
    Last Service Notification:%s
    Current Notification Number:%d
    Is This Service Flapping?"); if(temp_svcstatus->flap_detection_enabled==FALSE || enable_flap_detection==FALSE) printf("N/A"); else printf("
      %s  
    ",(temp_svcstatus->is_flapping==TRUE)?"":"not",(temp_svcstatus->is_flapping==TRUE)?"YES":"NO"); printf("
    Percent State Change:"); if(temp_svcstatus->flap_detection_enabled==FALSE || enable_flap_detection==FALSE) printf("N/A"); else printf("%3.2f%%",temp_svcstatus->percent_state_change); printf("
    In Scheduled Downtime?
      %s  
    Last Update:%s
    \n"); printf("
    \n"); printf("
    \n"); printf("\n"); printf("\n"); printf("
    \n"); printf("\n"); printf("\n",(temp_svcstatus->checks_enabled)?"ENABLED":"DISABLED",(temp_svcstatus->checks_enabled)?"ENABLED":"DISABLED"); printf("\n",(temp_svcstatus->accept_passive_service_checks==TRUE)?"ENABLED":"DISABLED",(temp_svcstatus->accept_passive_service_checks)?"ENABLED":"DISABLED"); printf("\n",(temp_svcstatus->obsess_over_service==TRUE)?"ENABLED":"DISABLED",(temp_svcstatus->obsess_over_service)?"ENABLED":"DISABLED"); printf("\n",(temp_svcstatus->notifications_enabled)?"ENABLED":"DISABLED",(temp_svcstatus->notifications_enabled)?"ENABLED":"DISABLED"); printf("\n",(temp_svcstatus->event_handler_enabled)?"ENABLED":"DISABLED",(temp_svcstatus->event_handler_enabled)?"ENABLED":"DISABLED"); printf("\n",(temp_svcstatus->flap_detection_enabled==TRUE)?"ENABLED":"DISABLED",(temp_svcstatus->flap_detection_enabled==TRUE)?"ENABLED":"DISABLED"); printf("
    Active Checks:
      %s  
    Passive Checks:
      %s  
    Obsessing:
      %s  
    Notifications:
      %s  
    Event Handler:
      %s  
    Flap Detection:
      %s  
    \n"); printf("
    \n"); printf("
    \n"); } printf("
    \n"); printf("\n"); printf("\n"); printf("
    \n"); printf("
    Service Commands
    \n"); printf("\n"); printf("\n"); printf("
    \n"); if(nagios_process_state==STATE_OK){ printf("\n"); if(temp_svcstatus->checks_enabled){ printf("\n",url_encode(service_desc)); printf("\n",url_encode(service_desc)); } else{ printf("\n",url_encode(service_desc)); } if(temp_svcstatus->accept_passive_service_checks==TRUE){ printf("\n",url_encode(service_desc)); printf("\n",url_encode(service_desc)); } else{ printf("\n",url_encode(service_desc)); } if(temp_svcstatus->obsess_over_service==TRUE){ printf("\n",url_encode(service_desc)); } else{ printf("\n",url_encode(service_desc)); } if((temp_svcstatus->status==SERVICE_WARNING || temp_svcstatus->status==SERVICE_UNKNOWN || temp_svcstatus->status==SERVICE_CRITICAL) && temp_svcstatus->state_type==HARD_STATE){ if(temp_svcstatus->problem_has_been_acknowledged==FALSE){ printf("\n",url_encode(service_desc)); } else{ printf("\n",url_encode(service_desc)); } } if(temp_svcstatus->notifications_enabled==TRUE){ printf("\n",url_encode(service_desc)); if(temp_svcstatus->status!=SERVICE_OK){ printf("\n",url_encode(service_desc)); } } else{ printf("\n",url_encode(service_desc)); } printf("\n",url_encode(service_desc)); /* printf("\n",url_encode(service_desc)); */ if(temp_svcstatus->event_handler_enabled==TRUE){ printf("\n",url_encode(service_desc)); } else{ printf("\n",url_encode(service_desc)); } if(temp_svcstatus->flap_detection_enabled==TRUE){ printf("\n",url_encode(service_desc)); } else{ printf("\n",url_encode(service_desc)); } printf("
    Disable Active Checks Of This ServiceDisable active checks of this service
    Re-schedule Next Service CheckRe-schedule the next check of this service
    Enable Active Checks Of This ServiceEnable active checks of this service
    Submit Passive Check Result For This ServiceSubmit passive check result for this service
    Stop Accepting Passive Checks For This ServiceStop accepting passive checks for this service
    Start Accepting Passive Checks For This ServiceStart accepting passive checks for this service
    Stop Obsessing Over This ServiceStop obsessing over this service
    Start Obsessing Over This ServiceStart obsessing over this service
    Acknowledge This Service ProblemAcknowledge this service problem
    Remove Problem AcknowledgementRemove problem acknowledgement
    Disable Notifications For This ServiceDisable notifications for this service
    Delay Next Service NotificationDelay next service notification
    Enable Notifications For This ServiceEnable notifications for this service
    Schedule Downtime For This ServiceSchedule downtime for this service
    Cancel Scheduled Downtime For This ServiceCancel scheduled downtime for this service
    Disable Event Handler For This ServiceDisable event handler for this service
    Enable Event Handler For This ServiceEnable event handler for this service
    Disable Flap Detection For This ServiceDisable flap detection for this service
    Enable Flap Detection For This ServiceEnable flap detection for this service
    \n"); } else{ printf("
    It appears as though Nagios is not running, so commands are temporarily unavailable...
    \n"); printf("Click here to view Nagios process information
    \n",EXTINFO_CGI,DISPLAY_PROCESS_INFO); } printf("
    \n"); printf("

    \n"); /* display comments */ display_comments(SERVICE_COMMENT); printf("
    \n"); printf("
    \n"); return; } void show_hostgroup_info(void){ hostgroup *temp_hostgroup; /* get hostgroup info */ temp_hostgroup=find_hostgroup(hostgroup_name); /* make sure the user has rights to view hostgroup information */ if(is_authorized_for_hostgroup(temp_hostgroup,¤t_authdata)==FALSE){ printf("

    It appears as though you do not have permission to view information for this hostgroup...

    \n"); printf("

    If you believe this is an error, check the HTTP server authentication requirements for accessing this CGI
    "); printf("and check the authorization options in your CGI configuration file.

    \n"); return; } /* make sure hostgroup information exists */ if(temp_hostgroup==NULL){ printf("

    Error: Hostgroup Not Found!

    "); return; } printf("
    \n"); printf("\n"); printf("\n"); /* top left panel */ printf("\n"); printf("\n"); /* left bottom panel */ printf("\n"); printf("
    \n"); /* right top panel */ printf("\n"); printf("
    Hostgroup Commands
    \n"); if(nagios_process_state==STATE_OK){ printf("\n"); printf("\n"); printf("
    \n"); printf("\n"); printf("\n",url_images_path,DOWNTIME_ICON,COMMAND_CGI,CMD_SCHEDULE_HOSTGROUP_HOST_DOWNTIME,url_encode(hostgroup_name)); printf("\n",url_images_path,DOWNTIME_ICON,COMMAND_CGI,CMD_SCHEDULE_HOSTGROUP_SVC_DOWNTIME,url_encode(hostgroup_name)); printf("\n",url_images_path,NOTIFICATION_ICON,COMMAND_CGI,CMD_ENABLE_HOSTGROUP_HOST_NOTIFICATIONS,url_encode(hostgroup_name)); printf("\n",url_images_path,NOTIFICATIONS_DISABLED_ICON,COMMAND_CGI,CMD_DISABLE_HOSTGROUP_HOST_NOTIFICATIONS,url_encode(hostgroup_name)); printf("\n",url_images_path,NOTIFICATION_ICON,COMMAND_CGI,CMD_ENABLE_HOSTGROUP_SVC_NOTIFICATIONS,url_encode(hostgroup_name)); printf("\n",url_images_path,NOTIFICATIONS_DISABLED_ICON,COMMAND_CGI,CMD_DISABLE_HOSTGROUP_SVC_NOTIFICATIONS,url_encode(hostgroup_name)); printf("\n",url_images_path,ENABLED_ICON,COMMAND_CGI,CMD_ENABLE_HOSTGROUP_SVC_CHECKS,url_encode(hostgroup_name)); printf("\n",url_images_path,DISABLED_ICON,COMMAND_CGI,CMD_DISABLE_HOSTGROUP_SVC_CHECKS,url_encode(hostgroup_name)); printf("
    Schedule Downtime For All Hosts In This HostgroupSchedule downtime for all hosts in this hostgroup
    Schedule Downtime For All Services In This HostgroupSchedule downtime for all services in this hostgroup
    Enable Notifications For All Hosts In This HostgroupEnable notifications for all hosts in this hostgroup
    Disable Notifications For All Hosts In This HostgroupDisable notifications for all hosts in this hostgroup
    Enable Notifications For All Services In This HostgroupEnable notifications for all services in this hostgroup
    Disable Notifications For All Services In This HostgroupDisable notifications for all services in this hostgroup
    Enable Active Checks Of All Services In This HostgroupEnable active checks of all services in this hostgroup
    Disable Active Checks Of All Services In This HostgroupDisable active checks of all services in this hostgroup
    \n"); printf("
    \n"); } else{ printf("
    It appears as though Nagios is not running, so commands are temporarily unavailable...
    \n"); printf("Click here to view Nagios process information
    \n",EXTINFO_CGI,DISPLAY_PROCESS_INFO); } printf("
    \n"); printf("
    \n"); printf("
    \n"); printf("\n"); printf("\n"); return; } void show_servicegroup_info(){ servicegroup *temp_servicegroup; /* get servicegroup info */ temp_servicegroup=find_servicegroup(servicegroup_name); /* make sure the user has rights to view servicegroup information */ if(is_authorized_for_servicegroup(temp_servicegroup,¤t_authdata)==FALSE){ printf("

    It appears as though you do not have permission to view information for this servicegroup...

    \n"); printf("

    If you believe this is an error, check the HTTP server authentication requirements for accessing this CGI
    "); printf("and check the authorization options in your CGI configuration file.

    \n"); return; } /* make sure servicegroup information exists */ if(temp_servicegroup==NULL){ printf("

    Error: Servicegroup Not Found!

    "); return; } printf("
    \n"); printf("\n"); printf("\n"); /* top left panel */ printf("\n"); printf("\n"); /* left bottom panel */ printf("\n"); printf("
    \n"); /* right top panel */ printf("\n"); printf("
    Servicegroup Commands
    \n"); if(nagios_process_state==STATE_OK){ printf("\n"); printf("\n"); printf("
    \n"); printf("\n"); printf("\n",url_images_path,DOWNTIME_ICON,COMMAND_CGI,CMD_SCHEDULE_SERVICEGROUP_HOST_DOWNTIME,url_encode(servicegroup_name)); printf("\n",url_images_path,DOWNTIME_ICON,COMMAND_CGI,CMD_SCHEDULE_SERVICEGROUP_SVC_DOWNTIME,url_encode(servicegroup_name)); printf("\n",url_images_path,NOTIFICATION_ICON,COMMAND_CGI,CMD_ENABLE_SERVICEGROUP_HOST_NOTIFICATIONS,url_encode(servicegroup_name)); printf("\n",url_images_path,NOTIFICATIONS_DISABLED_ICON,COMMAND_CGI,CMD_DISABLE_SERVICEGROUP_HOST_NOTIFICATIONS,url_encode(servicegroup_name)); printf("\n",url_images_path,NOTIFICATION_ICON,COMMAND_CGI,CMD_ENABLE_SERVICEGROUP_SVC_NOTIFICATIONS,url_encode(servicegroup_name)); printf("\n",url_images_path,NOTIFICATIONS_DISABLED_ICON,COMMAND_CGI,CMD_DISABLE_SERVICEGROUP_SVC_NOTIFICATIONS,url_encode(servicegroup_name)); printf("\n",url_images_path,ENABLED_ICON,COMMAND_CGI,CMD_ENABLE_SERVICEGROUP_SVC_CHECKS,url_encode(servicegroup_name)); printf("\n",url_images_path,DISABLED_ICON,COMMAND_CGI,CMD_DISABLE_SERVICEGROUP_SVC_CHECKS,url_encode(servicegroup_name)); printf("
    Schedule Downtime For All Hosts In This ServicegroupSchedule downtime for all hosts in this servicegroup
    Schedule Downtime For All Services In This ServicegroupSchedule downtime for all services in this servicegroup
    Enable Notifications For All Hosts In This ServicegroupEnable notifications for all hosts in this servicegroup
    Disable Notifications For All Hosts In This ServicegroupDisable notifications for all hosts in this servicegroup
    Enable Notifications For All Services In This ServicegroupEnable notifications for all services in this servicegroup
    Disable Notifications For All Services In This ServicegroupDisable notifications for all services in this servicegroup
    Enable Active Checks Of All Services In This ServicegroupEnable active checks of all services in this servicegroup
    Disable Active Checks Of All Services In This ServicegroupDisable active checks of all services in this servicegroup
    \n"); printf("
    \n"); } else{ printf("
    It appears as though Nagios is not running, so commands are temporarily unavailable...
    \n"); printf("Click here to view Nagios process information
    \n",EXTINFO_CGI,DISPLAY_PROCESS_INFO); } printf("
    \n"); printf("
    \n"); printf("
    \n"); printf("\n"); printf("\n"); return; } /* shows all service and host comments */ void show_all_comments(void){ int total_comments=0; char *bg_class=""; int odd=0; char date_time[MAX_DATETIME_LENGTH]; comment *temp_comment; host *temp_host; service *temp_service; char *comment_type; char expire_time[MAX_DATETIME_LENGTH]; /* read in all comments */ read_comment_data(get_cgi_config_location()); printf("

    \n"); printf("

    \n"); printf("

    \n"); printf("\n"); printf("
    Host Comments
    \n"); printf("\n"); printf("

    \n"); printf("

    \n"); printf("\n"); printf("\n"); /* display all the host comments */ for(temp_comment=comment_list,total_comments=0;temp_comment!=NULL;temp_comment=temp_comment->next){ if(temp_comment->comment_type!=HOST_COMMENT) continue; temp_host=find_host(temp_comment->host_name); /* make sure the user has rights to view host information */ if(is_authorized_for_host(temp_host,¤t_authdata)==FALSE) continue; total_comments++; if(odd){ odd=0; bg_class="commentOdd"; } else{ odd=1; bg_class="commentEven"; } switch(temp_comment->entry_type){ case USER_COMMENT: comment_type="User"; break; case DOWNTIME_COMMENT: comment_type="Scheduled Downtime"; break; case FLAPPING_COMMENT: comment_type="Flap Detection"; break; case ACKNOWLEDGEMENT_COMMENT: comment_type="Acknowledgement"; break; default: comment_type="?"; } get_time_string(&temp_comment->entry_time,date_time,(int)sizeof(date_time),SHORT_DATE_TIME); get_time_string(&temp_comment->expire_time,expire_time,(int)sizeof(date_time),SHORT_DATE_TIME); printf("",bg_class); printf("",bg_class,EXTINFO_CGI,DISPLAY_HOST_INFO,url_encode(temp_comment->host_name),temp_comment->host_name); printf("",bg_class,date_time,bg_class,temp_comment->author,bg_class,temp_comment->comment_data,bg_class,temp_comment->comment_id,bg_class,(temp_comment->persistent)?"Yes":"No",bg_class,comment_type,bg_class,(temp_comment->expires==TRUE)?expire_time:"N/A"); printf("",COMMAND_CGI,CMD_DEL_HOST_COMMENT,temp_comment->comment_id,url_images_path,DELETE_ICON); printf("\n"); } if(total_comments==0) printf(""); printf("\n"); printf("
    Host NameEntry TimeAuthorCommentComment IDPersistentTypeExpiresActions
    %s%s%s%s%ld%s%s%sDelete This Comment
    There are no host comments
    \n"); printf("


    \n"); printf("\n"); printf("
    Service Comments
    \n"); printf("\n"); printf("

    \n"); printf("

    \n"); printf("\n"); printf("\n"); /* display all the service comments */ for(temp_comment=comment_list,total_comments=0;temp_comment!=NULL;temp_comment=temp_comment->next){ if(temp_comment->comment_type!=SERVICE_COMMENT) continue; temp_service=find_service(temp_comment->host_name,temp_comment->service_description); /* make sure the user has rights to view service information */ if(is_authorized_for_service(temp_service,¤t_authdata)==FALSE) continue; total_comments++; if(odd){ odd=0; bg_class="commentOdd"; } else{ odd=1; bg_class="commentEven"; } switch(temp_comment->entry_type){ case USER_COMMENT: comment_type="User"; break; case DOWNTIME_COMMENT: comment_type="Scheduled Downtime"; break; case FLAPPING_COMMENT: comment_type="Flap Detection"; break; case ACKNOWLEDGEMENT_COMMENT: comment_type="Acknowledgement"; break; default: comment_type="?"; } get_time_string(&temp_comment->entry_time,date_time,(int)sizeof(date_time),SHORT_DATE_TIME); get_time_string(&temp_comment->expire_time,expire_time,(int)sizeof(date_time),SHORT_DATE_TIME); printf("",bg_class); printf("",bg_class,EXTINFO_CGI,DISPLAY_HOST_INFO,url_encode(temp_comment->host_name),temp_comment->host_name); printf("",url_encode(temp_comment->service_description),temp_comment->service_description); printf("",bg_class,date_time,bg_class,temp_comment->author,bg_class,temp_comment->comment_data,bg_class,temp_comment->comment_id,bg_class,(temp_comment->persistent)?"Yes":"No",bg_class,comment_type,bg_class,(temp_comment->expires==TRUE)?expire_time:"N/A"); printf("",COMMAND_CGI,CMD_DEL_SVC_COMMENT,temp_comment->comment_id,url_images_path,DELETE_ICON); printf("\n"); } if(total_comments==0) printf(""); printf("\n"); printf("
    Host NameServiceEntry TimeAuthorCommentComment IDPersistentTypeExpiresActions
    %s%s%s%s%s%ld%s%s%sDelete This Comment
    There are no service comments
    \n"); return; } void show_performance_data(void){ service *temp_service=NULL; servicestatus *temp_servicestatus=NULL; host *temp_host=NULL; hoststatus *temp_hoststatus=NULL; int total_active_service_checks=0; int total_passive_service_checks=0; double min_service_execution_time=0.0; double max_service_execution_time=0.0; double total_service_execution_time=0.0; int have_min_service_execution_time=FALSE; int have_max_service_execution_time=FALSE; double min_service_latency=0.0; double max_service_latency=0.0; double long total_service_latency=0.0; int have_min_service_latency=FALSE; int have_max_service_latency=FALSE; double min_host_latency=0.0; double max_host_latency=0.0; double total_host_latency=0.0; int have_min_host_latency=FALSE; int have_max_host_latency=FALSE; double min_service_percent_change_a=0.0; double max_service_percent_change_a=0.0; double total_service_percent_change_a=0.0; int have_min_service_percent_change_a=FALSE; int have_max_service_percent_change_a=FALSE; double min_service_percent_change_b=0.0; double max_service_percent_change_b=0.0; double total_service_percent_change_b=0.0; int have_min_service_percent_change_b=FALSE; int have_max_service_percent_change_b=FALSE; int active_service_checks_1min=0; int active_service_checks_5min=0; int active_service_checks_15min=0; int active_service_checks_1hour=0; int active_service_checks_start=0; int active_service_checks_ever=0; int passive_service_checks_1min=0; int passive_service_checks_5min=0; int passive_service_checks_15min=0; int passive_service_checks_1hour=0; int passive_service_checks_start=0; int passive_service_checks_ever=0; int total_active_host_checks=0; int total_passive_host_checks=0; double min_host_execution_time=0.0; double max_host_execution_time=0.0; double total_host_execution_time=0.0; int have_min_host_execution_time=FALSE; int have_max_host_execution_time=FALSE; double min_host_percent_change_a=0.0; double max_host_percent_change_a=0.0; double total_host_percent_change_a=0.0; int have_min_host_percent_change_a=FALSE; int have_max_host_percent_change_a=FALSE; double min_host_percent_change_b=0.0; double max_host_percent_change_b=0.0; double total_host_percent_change_b=0.0; int have_min_host_percent_change_b=FALSE; int have_max_host_percent_change_b=FALSE; int active_host_checks_1min=0; int active_host_checks_5min=0; int active_host_checks_15min=0; int active_host_checks_1hour=0; int active_host_checks_start=0; int active_host_checks_ever=0; int passive_host_checks_1min=0; int passive_host_checks_5min=0; int passive_host_checks_15min=0; int passive_host_checks_1hour=0; int passive_host_checks_start=0; int passive_host_checks_ever=0; time_t current_time; time(¤t_time); /* check all services */ for(temp_servicestatus=servicestatus_list;temp_servicestatus!=NULL;temp_servicestatus=temp_servicestatus->next){ /* find the service */ temp_service=find_service(temp_servicestatus->host_name,temp_servicestatus->description); /* make sure the user has rights to view service information */ if(is_authorized_for_service(temp_service,¤t_authdata)==FALSE) continue; /* is this an active or passive check? */ if(temp_servicestatus->check_type==SERVICE_CHECK_ACTIVE){ total_active_service_checks++; total_service_execution_time+=temp_servicestatus->execution_time; if(have_min_service_execution_time==FALSE || temp_servicestatus->execution_timeexecution_time; } if(have_max_service_execution_time==FALSE || temp_servicestatus->execution_time>max_service_execution_time){ have_max_service_execution_time=TRUE; max_service_execution_time=temp_servicestatus->execution_time; } total_service_percent_change_a+=temp_servicestatus->percent_state_change; if(have_min_service_percent_change_a==FALSE || temp_servicestatus->percent_state_changepercent_state_change; } if(have_max_service_percent_change_a==FALSE || temp_servicestatus->percent_state_change>max_service_percent_change_a){ have_max_service_percent_change_a=TRUE; max_service_percent_change_a=temp_servicestatus->percent_state_change; } total_service_latency+=temp_servicestatus->latency; if(have_min_service_latency==FALSE || temp_servicestatus->latencylatency; } if(have_max_service_latency==FALSE || temp_servicestatus->latency>max_service_latency){ have_max_service_latency=TRUE; max_service_latency=temp_servicestatus->latency; } if(temp_servicestatus->last_check>=(current_time-60)) active_service_checks_1min++; if(temp_servicestatus->last_check>=(current_time-300)) active_service_checks_5min++; if(temp_servicestatus->last_check>=(current_time-900)) active_service_checks_15min++; if(temp_servicestatus->last_check>=(current_time-3600)) active_service_checks_1hour++; if(temp_servicestatus->last_check>=program_start) active_service_checks_start++; if(temp_servicestatus->last_check!=(time_t)0) active_service_checks_ever++; } else{ total_passive_service_checks++; total_service_percent_change_b+=temp_servicestatus->percent_state_change; if(have_min_service_percent_change_b==FALSE || temp_servicestatus->percent_state_changepercent_state_change; } if(have_max_service_percent_change_b==FALSE || temp_servicestatus->percent_state_change>max_service_percent_change_b){ have_max_service_percent_change_b=TRUE; max_service_percent_change_b=temp_servicestatus->percent_state_change; } if(temp_servicestatus->last_check>=(current_time-60)) passive_service_checks_1min++; if(temp_servicestatus->last_check>=(current_time-300)) passive_service_checks_5min++; if(temp_servicestatus->last_check>=(current_time-900)) passive_service_checks_15min++; if(temp_servicestatus->last_check>=(current_time-3600)) passive_service_checks_1hour++; if(temp_servicestatus->last_check>=program_start) passive_service_checks_start++; if(temp_servicestatus->last_check!=(time_t)0) passive_service_checks_ever++; } } /* check all hosts */ for(temp_hoststatus=hoststatus_list;temp_hoststatus!=NULL;temp_hoststatus=temp_hoststatus->next){ /* find the host */ temp_host=find_host(temp_hoststatus->host_name); /* make sure the user has rights to view host information */ if(is_authorized_for_host(temp_host,¤t_authdata)==FALSE) continue; /* is this an active or passive check? */ if(temp_hoststatus->check_type==HOST_CHECK_ACTIVE){ total_active_host_checks++; total_host_execution_time+=temp_hoststatus->execution_time; if(have_min_host_execution_time==FALSE || temp_hoststatus->execution_timeexecution_time; } if(have_max_host_execution_time==FALSE || temp_hoststatus->execution_time>max_host_execution_time){ have_max_host_execution_time=TRUE; max_host_execution_time=temp_hoststatus->execution_time; } total_host_percent_change_a+=temp_hoststatus->percent_state_change; if(have_min_host_percent_change_a==FALSE || temp_hoststatus->percent_state_changepercent_state_change; } if(have_max_host_percent_change_a==FALSE || temp_hoststatus->percent_state_change>max_host_percent_change_a){ have_max_host_percent_change_a=TRUE; max_host_percent_change_a=temp_hoststatus->percent_state_change; } total_host_latency+=temp_hoststatus->latency; if(have_min_host_latency==FALSE || temp_hoststatus->latencylatency; } if(have_max_host_latency==FALSE || temp_hoststatus->latency>max_host_latency){ have_max_host_latency=TRUE; max_host_latency=temp_hoststatus->latency; } if(temp_hoststatus->last_check>=(current_time-60)) active_host_checks_1min++; if(temp_hoststatus->last_check>=(current_time-300)) active_host_checks_5min++; if(temp_hoststatus->last_check>=(current_time-900)) active_host_checks_15min++; if(temp_hoststatus->last_check>=(current_time-3600)) active_host_checks_1hour++; if(temp_hoststatus->last_check>=program_start) active_host_checks_start++; if(temp_hoststatus->last_check!=(time_t)0) active_host_checks_ever++; } else{ total_passive_host_checks++; total_host_percent_change_b+=temp_hoststatus->percent_state_change; if(have_min_host_percent_change_b==FALSE || temp_hoststatus->percent_state_changepercent_state_change; } if(have_max_host_percent_change_b==FALSE || temp_hoststatus->percent_state_change>max_host_percent_change_b){ have_max_host_percent_change_b=TRUE; max_host_percent_change_b=temp_hoststatus->percent_state_change; } if(temp_hoststatus->last_check>=(current_time-60)) passive_host_checks_1min++; if(temp_hoststatus->last_check>=(current_time-300)) passive_host_checks_5min++; if(temp_hoststatus->last_check>=(current_time-900)) passive_host_checks_15min++; if(temp_hoststatus->last_check>=(current_time-3600)) passive_host_checks_1hour++; if(temp_hoststatus->last_check>=program_start) passive_host_checks_start++; if(temp_hoststatus->last_check!=(time_t)0) passive_host_checks_ever++; } } printf("
    \n"); printf("
    Program-Wide Performance Information
    \n"); printf("\n"); /***** ACTIVE SERVICE CHECKS *****/ printf("\n"); printf("\n"); printf("\n"); printf("\n"); /***** PASSIVE SERVICE CHECKS *****/ printf("\n"); printf("\n"); printf("\n"); printf("\n"); /***** ACTIVE HOST CHECKS *****/ printf("\n"); printf("\n"); printf("\n"); printf("\n"); /***** PASSIVE HOST CHECKS *****/ printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("
    Active Service Checks:
    \n"); /* fake this so we don't divide by zero for just showing the table */ if(total_active_service_checks==0) total_active_service_checks=1; printf("\n"); printf("\n"); printf("
    \n"); printf("\n"); printf("\n"); printf("",active_service_checks_1min,(double)(((double)active_service_checks_1min*100.0)/(double)total_active_service_checks)); printf("",active_service_checks_5min,(double)(((double)active_service_checks_5min*100.0)/(double)total_active_service_checks)); printf("",active_service_checks_15min,(double)(((double)active_service_checks_15min*100.0)/(double)total_active_service_checks)); printf("",active_service_checks_1hour,(double)(((double)active_service_checks_1hour*100.0)/(double)total_active_service_checks)); printf("",active_service_checks_start,(double)(((double)active_service_checks_start*100.0)/(double)total_active_service_checks)); printf("
    Time FrameChecks Completed
    <= 1 minute:%d (%.1f%%)
    <= 5 minutes:%d (%.1f%%)
    <= 15 minutes:%d (%.1f%%)
    <= 1 hour:%d (%.1f%%)
    Since program start:  %d (%.1f%%)
    \n"); printf("
    \n"); printf("
    \n"); printf("\n"); printf("\n"); printf("
    \n"); printf("\n"); printf("\n"); printf("\n",min_service_execution_time,max_service_execution_time,(double)((double)total_service_execution_time/(double)total_active_service_checks)); printf("\n",min_service_latency,max_service_latency,(double)((double)total_service_latency/(double)total_active_service_checks)); printf("\n",min_service_percent_change_a,max_service_percent_change_a,(double)((double)total_service_percent_change_a/(double)total_active_service_checks)); printf("
    MetricMin.Max.Average
    Check Execution Time:  %.2f sec%.2f sec%.3f sec
    Check Latency:%.2f sec%.2f sec%.3f sec
    Percent State Change:%.2f%%%.2f%%%.2f%%
    \n"); printf("
    \n"); printf("
    Passive Service Checks:
    \n"); /* fake this so we don't divide by zero for just showing the table */ if(total_passive_service_checks==0) total_passive_service_checks=1; printf("\n"); printf("\n"); printf("
    \n"); printf("\n"); printf("\n"); printf("",passive_service_checks_1min,(double)(((double)passive_service_checks_1min*100.0)/(double)total_passive_service_checks)); printf("",passive_service_checks_5min,(double)(((double)passive_service_checks_5min*100.0)/(double)total_passive_service_checks)); printf("",passive_service_checks_15min,(double)(((double)passive_service_checks_15min*100.0)/(double)total_passive_service_checks)); printf("",passive_service_checks_1hour,(double)(((double)passive_service_checks_1hour*100.0)/(double)total_passive_service_checks)); printf("",passive_service_checks_start,(double)(((double)passive_service_checks_start*100.0)/(double)total_passive_service_checks)); printf("
    Time FrameChecks Completed
    <= 1 minute:%d (%.1f%%)
    <= 5 minutes:%d (%.1f%%)
    <= 15 minutes:%d (%.1f%%)
    <= 1 hour:%d (%.1f%%)
    Since program start:  %d (%.1f%%)
    \n"); printf("
    \n"); printf("
    \n"); printf("\n"); printf("\n"); printf("
    \n"); printf("\n"); printf("\n"); printf("\n",min_service_percent_change_b,max_service_percent_change_b,(double)((double)total_service_percent_change_b/(double)total_passive_service_checks)); printf("
    MetricMin.Max.Average
    Percent State Change:  %.2f%%%.2f%%%.2f%%
    \n"); printf("
    \n"); printf("
    Active Host Checks:
    \n"); /* fake this so we don't divide by zero for just showing the table */ if(total_active_host_checks==0) total_active_host_checks=1; printf("\n"); printf("\n"); printf("
    \n"); printf("\n"); printf("\n"); printf("",active_host_checks_1min,(double)(((double)active_host_checks_1min*100.0)/(double)total_active_host_checks)); printf("",active_host_checks_5min,(double)(((double)active_host_checks_5min*100.0)/(double)total_active_host_checks)); printf("",active_host_checks_15min,(double)(((double)active_host_checks_15min*100.0)/(double)total_active_host_checks)); printf("",active_host_checks_1hour,(double)(((double)active_host_checks_1hour*100.0)/(double)total_active_host_checks)); printf("",active_host_checks_start,(double)(((double)active_host_checks_start*100.0)/(double)total_active_host_checks)); printf("
    Time FrameChecks Completed
    <= 1 minute:%d (%.1f%%)
    <= 5 minutes:%d (%.1f%%)
    <= 15 minutes:%d (%.1f%%)
    <= 1 hour:%d (%.1f%%)
    Since program start:  %d (%.1f%%)
    \n"); printf("
    \n"); printf("
    \n"); printf("\n"); printf("\n"); printf("
    \n"); printf("\n"); printf("\n"); printf("\n",min_host_execution_time,max_host_execution_time,(double)((double)total_host_execution_time/(double)total_active_host_checks)); printf("\n",min_host_latency,max_host_latency,(double)((double)total_host_latency/(double)total_active_host_checks)); printf("\n",min_host_percent_change_a,max_host_percent_change_a,(double)((double)total_host_percent_change_a/(double)total_active_host_checks)); printf("
    MetricMin.Max.Average
    Check Execution Time:  %.2f sec%.2f sec%.3f sec
    Check Latency:%.2f sec%.2f sec%.3f sec
    Percent State Change:%.2f%%%.2f%%%.2f%%
    \n"); printf("
    \n"); printf("
    Passive Host Checks:
    \n"); /* fake this so we don't divide by zero for just showing the table */ if(total_passive_host_checks==0) total_passive_host_checks=1; printf("\n"); printf("\n"); printf("
    \n"); printf("\n"); printf("\n"); printf("",passive_host_checks_1min,(double)(((double)passive_host_checks_1min*100.0)/(double)total_passive_host_checks)); printf("",passive_host_checks_5min,(double)(((double)passive_host_checks_5min*100.0)/(double)total_passive_host_checks)); printf("",passive_host_checks_15min,(double)(((double)passive_host_checks_15min*100.0)/(double)total_passive_host_checks)); printf("",passive_host_checks_1hour,(double)(((double)passive_host_checks_1hour*100.0)/(double)total_passive_host_checks)); printf("",passive_host_checks_start,(double)(((double)passive_host_checks_start*100.0)/(double)total_passive_host_checks)); printf("
    Time FrameChecks Completed
    <= 1 minute:%d (%.1f%%)
    <= 5 minutes:%d (%.1f%%)
    <= 15 minutes:%d (%.1f%%)
    <= 1 hour:%d (%.1f%%)
    Since program start:  %d (%.1f%%)
    \n"); printf("
    \n"); printf("
    \n"); printf("\n"); printf("\n"); printf("
    \n"); printf("\n"); printf("\n"); printf("\n",min_host_percent_change_b,max_host_percent_change_b,(double)((double)total_host_percent_change_b/(double)total_passive_host_checks)); printf("
    MetricMin.Max.Average
    Percent State Change:  %.2f%%%.2f%%%.2f%%
    \n"); printf("
    \n"); printf("
    \n"); printf("
    \n"); return; } void display_comments(int type){ host *temp_host=NULL; service *temp_service=NULL; int total_comments=0; int display_comment=FALSE; char *bg_class=""; int odd=1; char date_time[MAX_DATETIME_LENGTH]; comment *temp_comment; char *comment_type; char expire_time[MAX_DATETIME_LENGTH]; /* find the host or service */ if(type==HOST_COMMENT){ temp_host=find_host(host_name); if(temp_host==NULL) return; } else{ temp_service=find_service(host_name,service_desc); if(temp_service==NULL) return; } printf("\n"); printf("
    %s Comments
    \n",(type==HOST_COMMENT)?"Host":"Service"); printf("\n"); printf("\n"); printf("\n"); printf("
    ",url_images_path,COMMENT_ICON); if(type==HOST_COMMENT) printf("",COMMAND_CGI,CMD_ADD_HOST_COMMENT,url_encode(host_name)); else{ printf("",url_encode(service_desc)); } printf("Add a new comment
    ",url_images_path,DELETE_ICON); if(type==HOST_COMMENT) printf("",COMMAND_CGI,CMD_DEL_ALL_HOST_COMMENTS,url_encode(host_name)); else{ printf("",url_encode(service_desc)); } printf("Delete all comments
    \n"); printf("
    \n"); printf("

    \n"); printf("

    \n"); printf("

    \n"); printf("\n"); printf("\n"); /* read in all comments */ read_comment_data(get_cgi_config_location()); /* check all the comments to see if they apply to this host or service */ for(temp_comment=get_first_comment_by_host(host_name);temp_comment!=NULL;temp_comment=get_next_comment_by_host(host_name,temp_comment)){ display_comment=FALSE; if(type==HOST_COMMENT && temp_comment->comment_type==HOST_COMMENT) display_comment=TRUE; else if(type==SERVICE_COMMENT && temp_comment->comment_type==SERVICE_COMMENT && !strcmp(temp_comment->service_description,service_desc)) display_comment=TRUE; if(display_comment==TRUE){ if(odd){ odd=0; bg_class="commentOdd"; } else{ odd=1; bg_class="commentEven"; } switch(temp_comment->entry_type){ case USER_COMMENT: comment_type="User"; break; case DOWNTIME_COMMENT: comment_type="Scheduled Downtime"; break; case FLAPPING_COMMENT: comment_type="Flap Detection"; break; case ACKNOWLEDGEMENT_COMMENT: comment_type="Acknowledgement"; break; default: comment_type="?"; } get_time_string(&temp_comment->entry_time,date_time,(int)sizeof(date_time),SHORT_DATE_TIME); get_time_string(&temp_comment->expire_time,expire_time,(int)sizeof(date_time),SHORT_DATE_TIME); printf("",bg_class); printf("",bg_class,date_time,bg_class,temp_comment->author,bg_class,temp_comment->comment_data,bg_class,temp_comment->comment_id,bg_class,(temp_comment->persistent)?"Yes":"No",bg_class,comment_type,bg_class,(temp_comment->expires==TRUE)?expire_time:"N/A"); printf("",COMMAND_CGI,(type==HOST_COMMENT)?CMD_DEL_HOST_COMMENT:CMD_DEL_SVC_COMMENT,temp_comment->comment_id,url_images_path,DELETE_ICON); printf("\n"); total_comments++; } } /* see if this host or service has any comments associated with it */ if(total_comments==0) printf("",(type==HOST_COMMENT)?9:10,(type==HOST_COMMENT)?"host":"service"); printf("
    Entry TimeAuthorCommentComment IDPersistentTypeExpiresActions
    %s%s%s%lu%s%s%sDelete This Comment
    This %s has no comments associated with it
    \n"); return; } /* shows all service and host scheduled downtime */ void show_all_downtime(void){ int total_downtime=0; char *bg_class=""; int odd=0; char date_time[MAX_DATETIME_LENGTH]; scheduled_downtime *temp_downtime; host *temp_host; service *temp_service; int days; int hours; int minutes; int seconds; /* read in all downtime */ read_downtime_data(get_cgi_config_location()); printf("

    \n"); printf("

    \n"); printf("

    \n"); printf("\n"); printf("
    Scheduled Host Downtime
    \n"); printf("\n"); printf("

    \n"); printf("

    \n"); printf("\n"); printf("\n"); /* display all the host downtime */ for(temp_downtime=scheduled_downtime_list,total_downtime=0;temp_downtime!=NULL;temp_downtime=temp_downtime->next){ if(temp_downtime->type!=HOST_DOWNTIME) continue; temp_host=find_host(temp_downtime->host_name); /* make sure the user has rights to view host information */ if(is_authorized_for_host(temp_host,¤t_authdata)==FALSE) continue; total_downtime++; if(odd){ odd=0; bg_class="downtimeOdd"; } else{ odd=1; bg_class="downtimeEven"; } printf("",bg_class); printf("",bg_class,EXTINFO_CGI,DISPLAY_HOST_INFO,url_encode(temp_downtime->host_name),temp_downtime->host_name); get_time_string(&temp_downtime->entry_time,date_time,(int)sizeof(date_time),SHORT_DATE_TIME); printf("",bg_class,date_time); printf("",bg_class,(temp_downtime->author==NULL)?"N/A":temp_downtime->author); printf("",bg_class,(temp_downtime->comment==NULL)?"N/A":temp_downtime->comment); get_time_string(&temp_downtime->start_time,date_time,(int)sizeof(date_time),SHORT_DATE_TIME); printf("",bg_class,date_time); get_time_string(&temp_downtime->end_time,date_time,(int)sizeof(date_time),SHORT_DATE_TIME); printf("",bg_class,date_time); printf("",bg_class,(temp_downtime->fixed==TRUE)?"Fixed":"Flexible"); get_time_breakdown(temp_downtime->duration,&days,&hours,&minutes,&seconds); printf("",bg_class,days,hours,minutes,seconds); printf("",bg_class,temp_downtime->downtime_id); printf("\n"); printf("",COMMAND_CGI,CMD_DEL_HOST_DOWNTIME,temp_downtime->downtime_id,url_images_path,DELETE_ICON); printf("\n"); } if(total_downtime==0) printf(""); printf("\n"); printf("
    Host NameEntry TimeAuthorCommentStart TimeEnd TimeTypeDurationDowntime IDTrigger IDActions
    %s%s%s%s%s%s%s%dd %dh %dm %ds%lu",bg_class); if(temp_downtime->triggered_by==0) printf("N/A"); else printf("%lu",temp_downtime->triggered_by); printf("Delete/Cancel This Scheduled Downtime Entry
    There are no hosts with scheduled downtime
    \n"); printf("


    \n"); printf("\n"); printf("
    Scheduled Service Downtime
    \n"); printf("\n"); printf("

    \n"); printf("

    \n"); printf("\n"); printf("\n"); /* display all the service downtime */ for(temp_downtime=scheduled_downtime_list,total_downtime=0;temp_downtime!=NULL;temp_downtime=temp_downtime->next){ if(temp_downtime->type!=SERVICE_DOWNTIME) continue; temp_service=find_service(temp_downtime->host_name,temp_downtime->service_description); /* make sure the user has rights to view service information */ if(is_authorized_for_service(temp_service,¤t_authdata)==FALSE) continue; total_downtime++; if(odd){ odd=0; bg_class="downtimeOdd"; } else{ odd=1; bg_class="downtimeEven"; } printf("",bg_class); printf("",bg_class,EXTINFO_CGI,DISPLAY_HOST_INFO,url_encode(temp_downtime->host_name),temp_downtime->host_name); printf("",url_encode(temp_downtime->service_description),temp_downtime->service_description); get_time_string(&temp_downtime->entry_time,date_time,(int)sizeof(date_time),SHORT_DATE_TIME); printf("",bg_class,date_time); printf("",bg_class,(temp_downtime->author==NULL)?"N/A":temp_downtime->author); printf("",bg_class,(temp_downtime->comment==NULL)?"N/A":temp_downtime->comment); get_time_string(&temp_downtime->start_time,date_time,(int)sizeof(date_time),SHORT_DATE_TIME); printf("",bg_class,date_time); get_time_string(&temp_downtime->end_time,date_time,(int)sizeof(date_time),SHORT_DATE_TIME); printf("",bg_class,date_time); printf("",bg_class,(temp_downtime->fixed==TRUE)?"Fixed":"Flexible"); get_time_breakdown(temp_downtime->duration,&days,&hours,&minutes,&seconds); printf("",bg_class,days,hours,minutes,seconds); printf("",bg_class,temp_downtime->downtime_id); printf("\n"); printf("",COMMAND_CGI,CMD_DEL_SVC_DOWNTIME,temp_downtime->downtime_id,url_images_path,DELETE_ICON); printf("\n"); } if(total_downtime==0) printf(""); printf("\n"); printf("
    Host NameServiceEntry TimeAuthorCommentStart TimeEnd TimeTypeDurationDowntime IDTrigger IDActions
    %s%s%s%s%s%s%s%s%dd %dh %dm %ds%lu",bg_class); if(temp_downtime->triggered_by==0) printf("N/A"); else printf("%lu",temp_downtime->triggered_by); printf("Delete/Cancel This Scheduled Downtime Entry
    There are no services with scheduled downtime
    \n"); return; } /* shows check scheduling queue */ void show_scheduling_queue(void){ sortdata *temp_sortdata; servicestatus *temp_svcstatus=NULL; hoststatus *temp_hststatus=NULL; char date_time[MAX_DATETIME_LENGTH]; char temp_url[MAX_INPUT_BUFFER]; int odd=0; char *bgclass=""; /* make sure the user has rights to view system information */ if(is_authorized_for_system_information(¤t_authdata)==FALSE){ printf("

    It appears as though you do not have permission to view process information...

    \n"); printf("

    If you believe this is an error, check the HTTP server authentication requirements for accessing this CGI
    "); printf("and check the authorization options in your CGI configuration file.

    \n"); return; } /* sort hosts and services */ sort_data(sort_type,sort_option); printf("
    Entries sorted by "); if(sort_option==SORT_HOSTNAME) printf("host name"); else if(sort_option==SORT_SERVICENAME) printf("service name"); else if(sort_option==SORT_SERVICESTATUS) printf("service status"); else if(sort_option==SORT_LASTCHECKTIME) printf("last check time"); else if(sort_option==SORT_NEXTCHECKTIME) printf("next check time"); printf(" (%s)\n",(sort_type==SORT_ASCENDING)?"ascending":"descending"); printf("
    \n"); printf("

    \n"); printf("

    \n"); printf("\n"); printf(""); snprintf(temp_url,sizeof(temp_url)-1,"%s?type=%d",EXTINFO_CGI,DISPLAY_SCHEDULING_QUEUE); temp_url[sizeof(temp_url)-1]='\x0'; printf("",temp_url,SORT_ASCENDING,SORT_HOSTNAME,url_images_path,UP_ARROW_ICON,temp_url,SORT_DESCENDING,SORT_HOSTNAME,url_images_path,DOWN_ARROW_ICON); printf("",temp_url,SORT_ASCENDING,SORT_SERVICENAME,url_images_path,UP_ARROW_ICON,temp_url,SORT_DESCENDING,SORT_SERVICENAME,url_images_path,DOWN_ARROW_ICON); printf("",temp_url,SORT_ASCENDING,SORT_LASTCHECKTIME,url_images_path,UP_ARROW_ICON,temp_url,SORT_DESCENDING,SORT_LASTCHECKTIME,url_images_path,DOWN_ARROW_ICON); printf("",temp_url,SORT_ASCENDING,SORT_NEXTCHECKTIME,url_images_path,UP_ARROW_ICON,temp_url,SORT_DESCENDING,SORT_NEXTCHECKTIME,url_images_path,DOWN_ARROW_ICON); printf("\n"); /* display all services and hosts */ for(temp_sortdata=sortdata_list;temp_sortdata!=NULL;temp_sortdata=temp_sortdata->next){ /* skip hosts and services that shouldn't be scheduled */ if(temp_sortdata->is_service==TRUE){ temp_svcstatus=temp_sortdata->svcstatus; if(temp_svcstatus->should_be_scheduled==FALSE) continue; } else{ temp_hststatus=temp_sortdata->hststatus; if(temp_hststatus->should_be_scheduled==FALSE) continue; } if(odd){ odd=0; bgclass="Even"; } else{ odd=1; bgclass="Odd"; } printf("",bgclass); /* get the service status */ if(temp_sortdata->is_service==TRUE){ printf("",bgclass,EXTINFO_CGI,DISPLAY_HOST_INFO,url_encode(temp_svcstatus->host_name),temp_svcstatus->host_name); printf("",url_encode(temp_svcstatus->description),temp_svcstatus->description); get_time_string(&temp_svcstatus->last_check,date_time,(int)sizeof(date_time),SHORT_DATE_TIME); printf("",bgclass,(temp_svcstatus->last_check==(time_t)0)?"N/A":date_time); get_time_string(&temp_svcstatus->next_check,date_time,(int)sizeof(date_time),SHORT_DATE_TIME); printf("",bgclass,(temp_svcstatus->next_check==(time_t)0)?"N/A":date_time); printf("",(temp_svcstatus->checks_enabled==TRUE)?"ENABLED":"DISABLED",(temp_svcstatus->checks_enabled==TRUE)?"ENABLED":"DISABLED"); printf("\n"); } /* get the host status */ else{ printf("",bgclass,EXTINFO_CGI,DISPLAY_HOST_INFO,url_encode(temp_hststatus->host_name),temp_hststatus->host_name); printf("",bgclass); get_time_string(&temp_hststatus->last_check,date_time,(int)sizeof(date_time),SHORT_DATE_TIME); printf("",bgclass,(temp_hststatus->last_check==(time_t)0)?"N/A":date_time); get_time_string(&temp_hststatus->next_check,date_time,(int)sizeof(date_time),SHORT_DATE_TIME); printf("",bgclass,(temp_hststatus->next_check==(time_t)0)?"N/A":date_time); printf("",(temp_hststatus->checks_enabled==TRUE)?"ENABLED":"DISABLED",(temp_hststatus->checks_enabled==TRUE)?"ENABLED":"DISABLED"); printf("\n"); } printf("\n"); } printf("
    Host Sort by host name (ascending)Sort by host name (descending)Service Sort by service name (ascending)Sort by service name (descending)Last Check Sort by last check time (ascending)Sort by last check time (descending)Next Check Sort by next check time (ascending)Sort by next check time (descending)Active ChecksActions
    %s%s%s%s%s",bgclass); if(temp_svcstatus->checks_enabled==TRUE){ printf("Disable Active Checks Of This Service\n",url_encode(temp_svcstatus->description),url_images_path,DISABLED_ICON); } else{ printf("Enable Active Checks Of This Service\n",url_encode(temp_svcstatus->description),url_images_path,ENABLED_ICON); } printf("Re-schedule This Service Check\n",url_encode(temp_svcstatus->description),url_images_path,DELAY_ICON); printf("%s %s%s%s",bgclass); if(temp_hststatus->checks_enabled==TRUE){ printf("Disable Active Checks Of This Host\n",url_images_path,DISABLED_ICON); } else{ printf("Enable Active Checks Of This Host\n",url_images_path,ENABLED_ICON); } printf("Re-schedule This Host Check\n",url_images_path,DELAY_ICON); printf("
    \n"); printf("
    \n"); printf("

    \n"); /* free memory allocated to sorted data list */ free_sortdata_list(); return; } /* sorts host and service data */ int sort_data(int s_type, int s_option){ sortdata *new_sortdata; sortdata *last_sortdata; sortdata *temp_sortdata; servicestatus *temp_svcstatus; hoststatus *temp_hststatus; if(s_type==SORT_NONE) return ERROR; /* sort all service status entries */ for(temp_svcstatus=servicestatus_list;temp_svcstatus!=NULL;temp_svcstatus=temp_svcstatus->next){ /* allocate memory for a new sort structure */ new_sortdata=(sortdata *)malloc(sizeof(sortdata)); if(new_sortdata==NULL) return ERROR; new_sortdata->is_service=TRUE; new_sortdata->svcstatus=temp_svcstatus; new_sortdata->hststatus=NULL; last_sortdata=sortdata_list; for(temp_sortdata=sortdata_list;temp_sortdata!=NULL;temp_sortdata=temp_sortdata->next){ if(compare_sortdata_entries(s_type,s_option,new_sortdata,temp_sortdata)==TRUE){ new_sortdata->next=temp_sortdata; if(temp_sortdata==sortdata_list) sortdata_list=new_sortdata; else last_sortdata->next=new_sortdata; break; } else last_sortdata=temp_sortdata; } if(sortdata_list==NULL){ new_sortdata->next=NULL; sortdata_list=new_sortdata; } else if(temp_sortdata==NULL){ new_sortdata->next=NULL; last_sortdata->next=new_sortdata; } } /* sort all host status entries */ for(temp_hststatus=hoststatus_list;temp_hststatus!=NULL;temp_hststatus=temp_hststatus->next){ /* allocate memory for a new sort structure */ new_sortdata=(sortdata *)malloc(sizeof(sortdata)); if(new_sortdata==NULL) return ERROR; new_sortdata->is_service=FALSE; new_sortdata->svcstatus=NULL; new_sortdata->hststatus=temp_hststatus; last_sortdata=sortdata_list; for(temp_sortdata=sortdata_list;temp_sortdata!=NULL;temp_sortdata=temp_sortdata->next){ if(compare_sortdata_entries(s_type,s_option,new_sortdata,temp_sortdata)==TRUE){ new_sortdata->next=temp_sortdata; if(temp_sortdata==sortdata_list) sortdata_list=new_sortdata; else last_sortdata->next=new_sortdata; break; } else last_sortdata=temp_sortdata; } if(sortdata_list==NULL){ new_sortdata->next=NULL; sortdata_list=new_sortdata; } else if(temp_sortdata==NULL){ new_sortdata->next=NULL; last_sortdata->next=new_sortdata; } } return OK; } int compare_sortdata_entries(int s_type, int s_option, sortdata *new_sortdata, sortdata *temp_sortdata){ hoststatus *temp_hststatus=NULL; servicestatus *temp_svcstatus=NULL; time_t last_check[2]; time_t next_check[2]; int current_attempt[2]; int status[2]; char *host_name[2]; char *service_description[2]; if(new_sortdata->is_service==TRUE){ temp_svcstatus=new_sortdata->svcstatus; last_check[0]=temp_svcstatus->last_check; next_check[0]=temp_svcstatus->next_check; status[0]=temp_svcstatus->status; host_name[0]=temp_svcstatus->host_name; service_description[0]=temp_svcstatus->description; current_attempt[0]=temp_svcstatus->current_attempt; } else{ temp_hststatus=new_sortdata->hststatus; last_check[0]=temp_hststatus->last_check; next_check[0]=temp_hststatus->next_check; status[0]=temp_hststatus->status; host_name[0]=temp_hststatus->host_name; service_description[0]=""; current_attempt[0]=temp_hststatus->current_attempt; } if(temp_sortdata->is_service==TRUE){ temp_svcstatus=temp_sortdata->svcstatus; last_check[1]=temp_svcstatus->last_check; next_check[1]=temp_svcstatus->next_check; status[1]=temp_svcstatus->status; host_name[1]=temp_svcstatus->host_name; service_description[1]=temp_svcstatus->description; current_attempt[1]=temp_svcstatus->current_attempt; } else{ temp_hststatus=temp_sortdata->hststatus; last_check[1]=temp_hststatus->last_check; next_check[1]=temp_hststatus->next_check; status[1]=temp_hststatus->status; host_name[1]=temp_hststatus->host_name; service_description[1]=""; current_attempt[1]=temp_hststatus->current_attempt; } if(s_type==SORT_ASCENDING){ if(s_option==SORT_LASTCHECKTIME){ if(last_check[0] <= last_check[1]) return TRUE; else return FALSE; } if(s_option==SORT_NEXTCHECKTIME){ if(next_check[0] <= next_check[1]) return TRUE; else return FALSE; } else if(s_option==SORT_CURRENTATTEMPT){ if(current_attempt[0] <= current_attempt[1]) return TRUE; else return FALSE; } else if(s_option==SORT_SERVICESTATUS){ if(status[0] <= status[1]) return TRUE; else return FALSE; } else if(s_option==SORT_HOSTNAME){ if(strcasecmp(host_name[0],host_name[1])<0) return TRUE; else return FALSE; } else if(s_option==SORT_SERVICENAME){ if(strcasecmp(service_description[0],service_description[1])<0) return TRUE; else return FALSE; } } else{ if(s_option==SORT_LASTCHECKTIME){ if(last_check[0] > last_check[1]) return TRUE; else return FALSE; } if(s_option==SORT_NEXTCHECKTIME){ if(next_check[0] > next_check[1]) return TRUE; else return FALSE; } else if(s_option==SORT_CURRENTATTEMPT){ if(current_attempt[0] > current_attempt[1]) return TRUE; else return FALSE; } else if(s_option==SORT_SERVICESTATUS){ if(status[0] > status[1]) return TRUE; else return FALSE; } else if(s_option==SORT_HOSTNAME){ if(strcasecmp(host_name[0],host_name[1])>0) return TRUE; else return FALSE; } else if(s_option==SORT_SERVICENAME){ if(strcasecmp(service_description[0],service_description[1])>0) return TRUE; else return FALSE; } } return TRUE; } /* free all memory allocated to the sortdata structures */ void free_sortdata_list(void){ sortdata *this_sortdata; sortdata *next_sortdata; /* free memory for the sortdata list */ for(this_sortdata=sortdata_list;this_sortdata!=NULL;this_sortdata=next_sortdata){ next_sortdata=this_sortdata->next; free(this_sortdata); } return; } nagios-2.6/cgi/getcgi.c0000664000076500007650000001663210432133072014352 0ustar nagiosnagios/****************************************** * * GETCGI.C - Nagios CGI Input Routines * * Last Modified: 05-15-2006 * *****************************************/ #include "../include/config.h" #include "../include/getcgi.h" #include #include #undef PARANOID_CGI_INPUT /* Remove potentially harmful characters from CGI input that we don't need or want */ void sanitize_cgi_input(char **cgivars){ char *strptr; int x,y,i; int keep; /* don't strip for now... */ return; for(strptr=cgivars[i=0];strptr!=NULL;strptr=cgivars[++i]){ for(x=0,y=0;strptr[x]!='\x0';x++){ keep=1; /* remove potentially nasty characters */ if(strptr[x]==';' || strptr[x]=='|' || strptr[x]=='&' || strptr[x]=='<' || strptr[x]=='>') keep=0; #ifdef PARANOID_CGI_INPUT else if(strptr[x]=='/' || strptr[x]=='\\') keep=0; #endif if(keep==1) strptr[y++]=strptr[x]; } strptr[y]='\x0'; } return; } /* convert encoded hex string (2 characters representing an 8-bit number) to its ASCII char equivalent */ unsigned char hex_to_char(char *input){ unsigned char outchar='\x0'; unsigned int outint; char tempbuf[3]; /* NULL or empty string */ if(input==NULL) return '\x0'; if(input[0]=='\x0') return '\x0'; tempbuf[0]=input[0]; tempbuf[1]=input[1]; tempbuf[2]='\x0'; sscanf(tempbuf,"%X",&outint); /* only convert "normal" ASCII characters - we don't want the rest. Normally you would convert all characters (i.e. for allowing users to post binary files), but since we aren't doing this, stay on the cautious side of things and reject outsiders... */ #ifdef PARANOID_CGI_INPUT if(outint<32 || outint>126) outint=0; #endif outchar=(unsigned char)outint; return outchar; } /* unescape hex characters in CGI input */ void unescape_cgi_input(char *input){ int x,y; int len; if(input==NULL) return; len=strlen(input); for(x=0,y=0;x=INT_MAX-1)){ printf("getcgivars(): Suspicious Content-Length was sent with the POST request.\n"); exit(1); } if(!(cgiinput=(char *)malloc(content_length+1))){ printf("getcgivars(): Could not allocate memory for CGI input.\n"); exit(1); } if(!fread(cgiinput,content_length,1,stdin)){ printf("getcgivars(): Could not read input from STDIN.\n"); exit(1); } cgiinput[content_length]='\0'; } else{ printf("getcgivars(): Unsupported REQUEST_METHOD -> '%s'\n",request_method); printf("\n"); printf("I'm guessing you're trying to execute the CGI from a command line.\n"); printf("In order to do that, you need to set the REQUEST_METHOD environment\n"); printf("variable to either \"GET\", \"HEAD\", or \"POST\". When using the\n"); printf("GET and HEAD methods, arguments can be passed to the CGI\n"); printf("by setting the \"QUERY_STRING\" environment variable. If you're\n"); printf("using the POST method, data is read from standard input. Also of\n"); printf("note: if you've enabled authentication in the CGIs, you must set the\n"); printf("\"REMOTE_USER\" environment variable to be the name of the user you're\n"); printf("\"authenticated\" as.\n"); printf("\n"); exit(1); } /* change all plus signs back to spaces */ for(i=0;cgiinput[i];i++){ if(cgiinput[i]=='+') cgiinput[i]=' '; } /* first, split on ampersands (&) to extract the name-value pairs into pairlist */ /* allocate memory for 256 name-value pairs at a time, increasing by same amount as necessary... */ pairlist=(char **)malloc(256*sizeof(char **)); if(pairlist==NULL){ printf("getcgivars(): Could not allocate memory for name-value pairlist.\n"); exit(1); } paircount=0; nvpair=strtok(cgiinput,"&"); while(nvpair){ pairlist[paircount++]=strdup(nvpair); if(!(paircount%256)){ pairlist=(char **)realloc(pairlist,(paircount+256)*sizeof(char **)); if(pairlist==NULL){ printf("getcgivars(): Could not re-allocate memory for name-value pairlist.\n"); exit(1); } } nvpair=strtok(NULL,"&"); } /* terminate the list */ pairlist[paircount]='\x0'; /* extract the names and values from the pairlist */ cgivars=(char **)malloc((paircount*2+1)*sizeof(char **)); if(cgivars==NULL){ printf("getcgivars(): Could not allocate memory for name-value list.\n"); exit(1); } for(i=0;i /* Boutell's GD library function */ #include /* GD library small font definition */ /*#define DEBUG 1*/ #define HISTOGRAM_IMAGE "histogram.png" /* archived state types */ #define AS_NO_DATA 0 #define AS_PROGRAM_START 1 #define AS_PROGRAM_END 2 #define AS_HOST_UP 3 #define AS_HOST_DOWN 4 #define AS_HOST_UNREACHABLE 5 #define AS_SVC_OK 6 #define AS_SVC_UNKNOWN 7 #define AS_SVC_WARNING 8 #define AS_SVC_CRITICAL 9 /* display types */ #define DISPLAY_HOST_HISTOGRAM 0 #define DISPLAY_SERVICE_HISTOGRAM 1 #define DISPLAY_NO_HISTOGRAM 2 /* input types */ #define GET_INPUT_NONE 0 #define GET_INPUT_TARGET_TYPE 1 #define GET_INPUT_HOST_TARGET 2 #define GET_INPUT_SERVICE_TARGET 3 #define GET_INPUT_OPTIONS 4 /* breakdown types */ #define BREAKDOWN_MONTHLY 0 #define BREAKDOWN_DAY_OF_MONTH 1 #define BREAKDOWN_DAY_OF_WEEK 2 #define BREAKDOWN_HOURLY 3 /* modes */ #define CREATE_HTML 0 #define CREATE_IMAGE 1 /* standard report times */ #define TIMEPERIOD_CUSTOM 0 #define TIMEPERIOD_TODAY 1 #define TIMEPERIOD_YESTERDAY 2 #define TIMEPERIOD_THISWEEK 3 #define TIMEPERIOD_LASTWEEK 4 #define TIMEPERIOD_THISMONTH 5 #define TIMEPERIOD_LASTMONTH 6 #define TIMEPERIOD_THISQUARTER 7 #define TIMEPERIOD_LASTQUARTER 8 #define TIMEPERIOD_THISYEAR 9 #define TIMEPERIOD_LASTYEAR 10 #define TIMEPERIOD_LAST24HOURS 11 #define TIMEPERIOD_LAST7DAYS 12 #define TIMEPERIOD_LAST31DAYS 13 #define MAX_ARCHIVE_SPREAD 65 #define MAX_ARCHIVE 65 #define MAX_ARCHIVE_BACKTRACKS 60 #define DRAWING_WIDTH 550 #define DRAWING_HEIGHT 195 #define DRAWING_X_OFFSET 60 #define DRAWING_Y_OFFSET 235 #define GRAPH_HOST_UP 1 #define GRAPH_HOST_DOWN 2 #define GRAPH_HOST_UNREACHABLE 4 #define GRAPH_SERVICE_OK 8 #define GRAPH_SERVICE_WARNING 16 #define GRAPH_SERVICE_UNKNOWN 32 #define GRAPH_SERVICE_CRITICAL 64 #define GRAPH_HOST_PROBLEMS 6 #define GRAPH_HOST_ALL 7 #define GRAPH_SERVICE_PROBLEMS 112 #define GRAPH_SERVICE_ALL 120 #define GRAPH_EVERYTHING 255 #define GRAPH_SOFT_STATETYPES 1 #define GRAPH_HARD_STATETYPES 2 #define GRAPH_ALL_STATETYPES 3 extern char main_config_file[MAX_FILENAME_LENGTH]; extern char url_images_path[MAX_FILENAME_LENGTH]; extern char url_stylesheets_path[MAX_FILENAME_LENGTH]; extern char physical_images_path[MAX_FILENAME_LENGTH]; extern int log_rotation_method; extern host *host_list; extern service *service_list; authdata current_authdata; typedef struct timeslice_data_struct{ unsigned long service_ok; unsigned long host_up; unsigned long service_critical; unsigned long host_down; unsigned long service_unknown; unsigned long host_unreachable; unsigned long service_warning; }timeslice_data; timeslice_data *tsdata; void convert_timeperiod_to_times(int); void compute_report_times(void); void graph_all_histogram_data(void); void add_archived_state(int,time_t); void read_archived_state_data(void); void scan_log_file_for_archived_state_data(char *); void draw_line(int,int,int,int,int); void draw_dashed_line(int,int,int,int,int); void document_header(int); void document_footer(void); int process_cgivars(void); time_t t1; time_t t2; int start_second=0; int start_minute=0; int start_hour=0; int start_day=1; int start_month=1; int start_year=2000; int end_second=0; int end_minute=0; int end_hour=24; int end_day=1; int end_month=1; int end_year=2000; int display_type=DISPLAY_NO_HISTOGRAM; int mode=CREATE_HTML; int input_type=GET_INPUT_NONE; int timeperiod_type=TIMEPERIOD_LAST24HOURS; int breakdown_type=BREAKDOWN_HOURLY; int compute_time_from_parts=FALSE; int initial_states_logged=FALSE; int assume_state_retention=TRUE; int new_states_only=FALSE; int last_state=AS_NO_DATA; int program_restart_has_occurred=FALSE; int graph_events=GRAPH_EVERYTHING; int graph_statetypes=GRAPH_HARD_STATETYPES; int embedded=FALSE; int display_header=TRUE; char *host_name=""; char *svc_description=""; gdImagePtr histogram_image=0; int color_white=0; int color_black=0; int color_red=0; int color_darkred=0; int color_green=0; int color_yellow=0; int color_orange=0; int color_lightgray=0; FILE *image_file=NULL; int backtrack_archives=0; int earliest_archive=0; time_t earliest_time; time_t latest_time; int image_width=900; int image_height=320; int total_buckets=96; int main(int argc, char **argv){ int result=OK; char temp_buffer[MAX_INPUT_BUFFER]; char image_template[MAX_INPUT_BUFFER]; char start_timestring[MAX_INPUT_BUFFER]; char end_timestring[MAX_INPUT_BUFFER]; host *temp_host; service *temp_service; int is_authorized=TRUE; int found=FALSE; int days,hours,minutes,seconds; char *first_service=NULL; int x; time_t t3; time_t current_time; struct tm *t; /* initialize time period to last 24 hours */ time(&t2); t1=(time_t)(t2-(60*60*24)); /* get the arguments passed in the URL */ process_cgivars(); /* reset internal CGI variables */ reset_cgi_vars(); /* read the CGI configuration file */ result=read_cgi_config_file(get_cgi_config_location()); if(result==ERROR){ if(mode==CREATE_HTML){ document_header(FALSE); cgi_config_file_error(get_cgi_config_location()); document_footer(); } return ERROR; } /* read the main configuration file */ result=read_main_config_file(main_config_file); if(result==ERROR){ if(mode==CREATE_HTML){ document_header(FALSE); main_config_file_error(main_config_file); document_footer(); } return ERROR; } /* read all object configuration data */ result=read_all_object_configuration_data(main_config_file,READ_ALL_OBJECT_DATA); if(result==ERROR){ if(mode==CREATE_HTML){ document_header(FALSE); object_data_error(); document_footer(); } return ERROR; } /* read all status data */ result=read_all_status_data(get_cgi_config_location(),READ_ALL_STATUS_DATA); if(result==ERROR){ if(mode==CREATE_HTML){ document_header(FALSE); status_data_error(); document_footer(); } free_memory(); return ERROR; } document_header(TRUE); /* get authentication information */ get_authentication_information(¤t_authdata); if(compute_time_from_parts==TRUE) compute_report_times(); /* make sure times are sane, otherwise swap them */ if(t2\n"); printf("\n"); /* left column of the first row */ printf("\n"); if(display_type==DISPLAY_HOST_HISTOGRAM) snprintf(temp_buffer,sizeof(temp_buffer)-1,"Host Alert Histogram"); else if(display_type==DISPLAY_SERVICE_HISTOGRAM) snprintf(temp_buffer,sizeof(temp_buffer)-1,"Service Alert Histogram"); else snprintf(temp_buffer,sizeof(temp_buffer)-1,"Host and Service Alert Histogram"); temp_buffer[sizeof(temp_buffer)-1]='\x0'; display_info_table(temp_buffer,FALSE,¤t_authdata); if(display_type!=DISPLAY_NO_HISTOGRAM && input_type==GET_INPUT_NONE){ printf("\n"); printf("\n"); printf("\n"); } printf("\n"); /* center column of top row */ printf("\n"); if(display_type!=DISPLAY_NO_HISTOGRAM && input_type==GET_INPUT_NONE){ printf("
    \n"); if(display_type==DISPLAY_HOST_HISTOGRAM) printf("Host '%s'",host_name); else if(display_type==DISPLAY_SERVICE_HISTOGRAM) printf("Service '%s' On Host '%s'",svc_description,host_name); printf("
    \n"); printf("
    \n"); printf("%s Event Histogram\n",url_images_path,TRENDS_ICON,(display_type==DISPLAY_HOST_HISTOGRAM)?"Host":"Service",(display_type==DISPLAY_HOST_HISTOGRAM)?"Host":"Service"); printf("
    \n"); get_time_string(&t1,start_timestring,sizeof(start_timestring)-1,SHORT_DATE_TIME); get_time_string(&t2,end_timestring,sizeof(end_timestring)-1,SHORT_DATE_TIME); printf("
    %s to %s
    \n",start_timestring,end_timestring); get_time_breakdown((time_t)(t2-t1),&days,&hours,&minutes,&seconds); printf("
    Duration: %dd %dh %dm %ds
    \n",days,hours,minutes,seconds); } printf("\n"); /* right hand column of top row */ printf("\n"); printf("\n"); if(display_type!=DISPLAY_NO_HISTOGRAM && input_type==GET_INPUT_NONE){ printf("\n",HISTOGRAM_CGI); printf("\n",(unsigned long)t1); printf("\n",(unsigned long)t2); printf("\n",host_name); if(display_type==DISPLAY_SERVICE_HISTOGRAM) printf("\n",svc_description); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); } /* display context-sensitive help */ printf("\n"); printf("
    Report period:Assume state retention:
    \n"); printf("\n"); printf("\n"); printf("\n"); printf("
    Breakdown type:Initial states logged:
    \n"); printf("\n"); printf("\n"); printf("\n"); printf("
    Events to graph:Ignore repeated states:
    \n"); printf("\n"); printf("\n"); printf("\n"); printf("
    State types to graph:
    \n"); printf("\n"); printf("\n"); printf("\n"); printf("
    \n"); if(display_type!=DISPLAY_NO_HISTOGRAM && input_type==GET_INPUT_NONE){ if(display_type==DISPLAY_HOST_HISTOGRAM) display_context_help(CONTEXTHELP_HISTOGRAM_HOST); else display_context_help(CONTEXTHELP_HISTOGRAM_SERVICE); } else if(display_type==DISPLAY_NO_HISTOGRAM || input_type!=GET_INPUT_NONE){ if(input_type==GET_INPUT_NONE) display_context_help(CONTEXTHELP_HISTOGRAM_MENU1); else if(input_type==GET_INPUT_TARGET_TYPE) display_context_help(CONTEXTHELP_HISTOGRAM_MENU1); else if(input_type==GET_INPUT_HOST_TARGET) display_context_help(CONTEXTHELP_HISTOGRAM_MENU2); else if(input_type==GET_INPUT_SERVICE_TARGET) display_context_help(CONTEXTHELP_HISTOGRAM_MENU3); else if(input_type==GET_INPUT_OPTIONS) display_context_help(CONTEXTHELP_HISTOGRAM_MENU4); } printf("
    \n"); printf("\n"); /* end of top table */ printf("\n"); printf("\n"); } /* check authorization... */ if(display_type==DISPLAY_HOST_HISTOGRAM){ temp_host=find_host(host_name); if(temp_host==NULL || is_authorized_for_host(temp_host,¤t_authdata)==FALSE) is_authorized=FALSE; } else if(display_type==DISPLAY_SERVICE_HISTOGRAM){ temp_service=find_service(host_name,svc_description); if(temp_service==NULL || is_authorized_for_service(temp_service,¤t_authdata)==FALSE) is_authorized=FALSE; } if(is_authorized==FALSE){ if(mode==CREATE_HTML) printf("

    It appears as though you are not authorized to view information for the specified %s...

    \n",(display_type==DISPLAY_HOST_HISTOGRAM)?"host":"service"); document_footer(); free_memory(); return ERROR; } if(display_type!=DISPLAY_NO_HISTOGRAM && input_type==GET_INPUT_NONE){ /* print URL to image */ if(mode==CREATE_HTML){ printf("

    \n"); printf("
    \n"); printf("\n"); printf("
    \n"); } /* read and process state data */ else{ /* allocate memory */ tsdata=NULL; if(breakdown_type==BREAKDOWN_MONTHLY) total_buckets=12; else if(breakdown_type==BREAKDOWN_DAY_OF_MONTH) total_buckets=31; else if(breakdown_type==BREAKDOWN_DAY_OF_WEEK) total_buckets=7; else total_buckets=96; tsdata=(timeslice_data *)malloc(sizeof(timeslice_data)*total_buckets); if(tsdata==NULL) return ERROR; for(x=0;x
    \n"); printf("
    Step 2: Select Host
    \n"); printf("

    \n"); printf("

    \n"); printf("\n"); printf("\n",HISTOGRAM_CGI); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("
    Host:\n"); printf("\n"); printf("
    \n"); printf("\n"); printf("
    \n"); printf("

    \n"); } /* ask the user for what service they want a report for */ else if(input_type==GET_INPUT_SERVICE_TARGET){ printf("\n"); printf("

    \n"); printf("
    Step 2: Select Service
    \n"); printf("

    \n"); printf("

    \n"); printf("\n"); printf("\n",HISTOGRAM_CGI); printf("\n"); printf("\n",(first_service==NULL)?"unknown":first_service); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("
    Service:\n"); printf("\n"); printf("
    \n"); printf("\n"); printf("
    \n"); printf("

    \n"); } /* ask the user for report range and options */ else if(input_type==GET_INPUT_OPTIONS){ time(¤t_time); t=localtime(¤t_time); start_day=1; start_year=t->tm_year+1900; end_day=t->tm_mday; end_year=t->tm_year+1900; printf("

    \n"); printf("
    Step 3: Select Report Options
    \n"); printf("

    \n"); printf("

    \n"); printf("\n"); printf("\n",HISTOGRAM_CGI); printf("\n",host_name); if(display_type==DISPLAY_SERVICE_HISTOGRAM) printf("\n",svc_description); printf("\n"); printf("\n"); printf("\n"); printf(""); printf("\n"); printf("\n"); printf("\n"); printf(""); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("
    Report Period:\n"); printf("\n"); printf("
    If Custom Report Period...
    Start Date (Inclusive):"); printf("\n "); printf(" ",start_day); printf("",start_year); printf("\n"); printf("\n"); printf("\n"); printf("
    End Date (Inclusive):"); printf("\n "); printf(" ",end_day); printf("",end_year); printf("\n"); printf("\n"); printf("\n"); printf("

    Statistics Breakdown:\n"); printf("\n"); printf("
    Events To Graph:\n"); printf("\n"); printf("
    State Types To Graph:\n"); printf("\n"); printf("
    Assume State Retention:\n"); printf("\n"); printf("
    Initial States Logged:\n"); printf("\n"); printf("
    Ignore Repeated States:\n"); printf("\n"); printf("
    \n"); printf("

    \n"); } /* as the user whether they want a graph for a host or service */ else{ printf("

    \n"); printf("
    Step 1: Select Report Type
    \n"); printf("

    \n"); printf("

    \n"); printf("\n"); printf("\n",HISTOGRAM_CGI); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("
    Type:\n"); printf("\n"); printf("
    \n"); printf("\n"); printf("
    \n"); printf("

    \n"); } } document_footer(); /* free all other allocated memory */ free_memory(); return OK; } void document_header(int use_stylesheet){ char date_time[MAX_DATETIME_LENGTH]; time_t current_time; time_t expire_time; if(mode==CREATE_HTML){ printf("Cache-Control: no-store\r\n"); printf("Pragma: no-cache\r\n"); time(¤t_time); get_time_string(¤t_time,date_time,sizeof(date_time),HTTP_DATE_TIME); printf("Last-Modified: %s\r\n",date_time); expire_time=(time_t)0; get_time_string(&expire_time,date_time,sizeof(date_time),HTTP_DATE_TIME); printf("Expires: %s\r\n",date_time); printf("Content-type: text/html\r\n\r\n"); if(embedded==TRUE) return; printf("\n"); printf("\n"); printf("\n"); printf("Nagios Histogram\n"); printf("\n"); if(use_stylesheet==TRUE){ printf("\n",url_stylesheets_path,COMMON_CSS); printf("\n",url_stylesheets_path,HISTOGRAM_CSS); } printf("\n"); printf("\n"); /* include user SSI header */ include_ssi_files(HISTOGRAM_CGI,SSI_HEADER); printf("
    \n"); } else{ printf("Cache-Control: no-store\r\n"); printf("Pragma: no-cache\r\n"); time(¤t_time); get_time_string(¤t_time,date_time,sizeof(date_time),HTTP_DATE_TIME); printf("Last-Modified: %s\r\n",date_time); expire_time=(time_t)0L; get_time_string(&expire_time,date_time,sizeof(date_time),HTTP_DATE_TIME); printf("Expires: %s\r\n",date_time); printf("Content-Type: image/png\r\n\r\n"); } return; } void document_footer(void){ if(embedded==TRUE) return; if(mode==CREATE_HTML){ /* include user SSI footer */ include_ssi_files(HISTOGRAM_CGI,SSI_FOOTER); printf("\n"); printf("\n"); } return; } int process_cgivars(void){ char **variables; int error=FALSE; int x; variables=getcgivars(); for(x=0;variables[x]!=NULL;x++){ /* do some basic length checking on the variable identifier to prevent buffer overflows */ if(strlen(variables[x])>=MAX_INPUT_BUFFER-1){ x++; continue; } /* we found the host argument */ else if(!strcmp(variables[x],"host")){ x++; if(variables[x]==NULL){ error=TRUE; break; } host_name=(char *)malloc(strlen(variables[x])+1); if(host_name==NULL) host_name=""; else strcpy(host_name,variables[x]); display_type=DISPLAY_HOST_HISTOGRAM; } /* we found the node width argument */ else if(!strcmp(variables[x],"service")){ x++; if(variables[x]==NULL){ error=TRUE; break; } svc_description=(char *)malloc(strlen(variables[x])+1); if(svc_description==NULL) svc_description=""; else strcpy(svc_description,variables[x]); display_type=DISPLAY_SERVICE_HISTOGRAM; } /* we found first time argument */ else if(!strcmp(variables[x],"t1")){ x++; if(variables[x]==NULL){ error=TRUE; break; } t1=(time_t)strtoul(variables[x],NULL,10); timeperiod_type=TIMEPERIOD_CUSTOM; } /* we found first time argument */ else if(!strcmp(variables[x],"t2")){ x++; if(variables[x]==NULL){ error=TRUE; break; } t2=(time_t)strtoul(variables[x],NULL,10); timeperiod_type=TIMEPERIOD_CUSTOM; } /* we found the image creation option */ else if(!strcmp(variables[x],"createimage")){ mode=CREATE_IMAGE; } /* we found the backtrack archives argument */ else if(!strcmp(variables[x],"backtrack")){ x++; if(variables[x]==NULL){ error=TRUE; break; } backtrack_archives=atoi(variables[x]); if(backtrack_archives<0) backtrack_archives=0; if(backtrack_archives>MAX_ARCHIVE_BACKTRACKS) backtrack_archives=MAX_ARCHIVE_BACKTRACKS; } /* we found the standard timeperiod argument */ else if(!strcmp(variables[x],"timeperiod")){ x++; if(variables[x]==NULL){ error=TRUE; break; } if(!strcmp(variables[x],"today")) timeperiod_type=TIMEPERIOD_TODAY; else if(!strcmp(variables[x],"yesterday")) timeperiod_type=TIMEPERIOD_YESTERDAY; else if(!strcmp(variables[x],"thisweek")) timeperiod_type=TIMEPERIOD_THISWEEK; else if(!strcmp(variables[x],"lastweek")) timeperiod_type=TIMEPERIOD_LASTWEEK; else if(!strcmp(variables[x],"thismonth")) timeperiod_type=TIMEPERIOD_THISMONTH; else if(!strcmp(variables[x],"lastmonth")) timeperiod_type=TIMEPERIOD_LASTMONTH; else if(!strcmp(variables[x],"thisquarter")) timeperiod_type=TIMEPERIOD_THISQUARTER; else if(!strcmp(variables[x],"lastquarter")) timeperiod_type=TIMEPERIOD_LASTQUARTER; else if(!strcmp(variables[x],"thisyear")) timeperiod_type=TIMEPERIOD_THISYEAR; else if(!strcmp(variables[x],"lastyear")) timeperiod_type=TIMEPERIOD_LASTYEAR; else if(!strcmp(variables[x],"last24hours")) timeperiod_type=TIMEPERIOD_LAST24HOURS; else if(!strcmp(variables[x],"last7days")) timeperiod_type=TIMEPERIOD_LAST7DAYS; else if(!strcmp(variables[x],"last31days")) timeperiod_type=TIMEPERIOD_LAST31DAYS; else if(!strcmp(variables[x],"custom")) timeperiod_type=TIMEPERIOD_CUSTOM; else timeperiod_type=TIMEPERIOD_TODAY; if(timeperiod_type!=TIMEPERIOD_CUSTOM) convert_timeperiod_to_times(timeperiod_type); } /* we found time argument */ else if(!strcmp(variables[x],"smon")){ x++; if(variables[x]==NULL){ error=TRUE; break; } if(timeperiod_type!=TIMEPERIOD_CUSTOM) continue; start_month=atoi(variables[x]); timeperiod_type=TIMEPERIOD_CUSTOM; compute_time_from_parts=TRUE; } /* we found time argument */ else if(!strcmp(variables[x],"sday")){ x++; if(variables[x]==NULL){ error=TRUE; break; } if(timeperiod_type!=TIMEPERIOD_CUSTOM) continue; start_day=atoi(variables[x]); timeperiod_type=TIMEPERIOD_CUSTOM; compute_time_from_parts=TRUE; } /* we found time argument */ else if(!strcmp(variables[x],"syear")){ x++; if(variables[x]==NULL){ error=TRUE; break; } if(timeperiod_type!=TIMEPERIOD_CUSTOM) continue; start_year=atoi(variables[x]); timeperiod_type=TIMEPERIOD_CUSTOM; compute_time_from_parts=TRUE; } /* we found time argument */ else if(!strcmp(variables[x],"smin")){ x++; if(variables[x]==NULL){ error=TRUE; break; } if(timeperiod_type!=TIMEPERIOD_CUSTOM) continue; start_minute=atoi(variables[x]); timeperiod_type=TIMEPERIOD_CUSTOM; compute_time_from_parts=TRUE; } /* we found time argument */ else if(!strcmp(variables[x],"ssec")){ x++; if(variables[x]==NULL){ error=TRUE; break; } if(timeperiod_type!=TIMEPERIOD_CUSTOM) continue; start_second=atoi(variables[x]); timeperiod_type=TIMEPERIOD_CUSTOM; compute_time_from_parts=TRUE; } /* we found time argument */ else if(!strcmp(variables[x],"shour")){ x++; if(variables[x]==NULL){ error=TRUE; break; } if(timeperiod_type!=TIMEPERIOD_CUSTOM) continue; start_hour=atoi(variables[x]); timeperiod_type=TIMEPERIOD_CUSTOM; compute_time_from_parts=TRUE; } /* we found time argument */ else if(!strcmp(variables[x],"emon")){ x++; if(variables[x]==NULL){ error=TRUE; break; } if(timeperiod_type!=TIMEPERIOD_CUSTOM) continue; end_month=atoi(variables[x]); timeperiod_type=TIMEPERIOD_CUSTOM; compute_time_from_parts=TRUE; } /* we found time argument */ else if(!strcmp(variables[x],"eday")){ x++; if(variables[x]==NULL){ error=TRUE; break; } if(timeperiod_type!=TIMEPERIOD_CUSTOM) continue; end_day=atoi(variables[x]); timeperiod_type=TIMEPERIOD_CUSTOM; compute_time_from_parts=TRUE; } /* we found time argument */ else if(!strcmp(variables[x],"eyear")){ x++; if(variables[x]==NULL){ error=TRUE; break; } if(timeperiod_type!=TIMEPERIOD_CUSTOM) continue; end_year=atoi(variables[x]); timeperiod_type=TIMEPERIOD_CUSTOM; compute_time_from_parts=TRUE; } /* we found time argument */ else if(!strcmp(variables[x],"emin")){ x++; if(variables[x]==NULL){ error=TRUE; break; } if(timeperiod_type!=TIMEPERIOD_CUSTOM) continue; end_minute=atoi(variables[x]); timeperiod_type=TIMEPERIOD_CUSTOM; compute_time_from_parts=TRUE; } /* we found time argument */ else if(!strcmp(variables[x],"esec")){ x++; if(variables[x]==NULL){ error=TRUE; break; } if(timeperiod_type!=TIMEPERIOD_CUSTOM) continue; end_second=atoi(variables[x]); timeperiod_type=TIMEPERIOD_CUSTOM; compute_time_from_parts=TRUE; } /* we found time argument */ else if(!strcmp(variables[x],"ehour")){ x++; if(variables[x]==NULL){ error=TRUE; break; } if(timeperiod_type!=TIMEPERIOD_CUSTOM) continue; end_hour=atoi(variables[x]); timeperiod_type=TIMEPERIOD_CUSTOM; compute_time_from_parts=TRUE; } /* we found the embed option */ else if(!strcmp(variables[x],"embedded")) embedded=TRUE; /* we found the noheader option */ else if(!strcmp(variables[x],"noheader")) display_header=FALSE; /* we found the input option */ else if(!strcmp(variables[x],"input")){ x++; if(variables[x]==NULL){ error=TRUE; break; } if(!strcmp(variables[x],"gethost")) input_type=GET_INPUT_HOST_TARGET; else if(!strcmp(variables[x],"getservice")) input_type=GET_INPUT_SERVICE_TARGET; else if(!strcmp(variables[x],"getoptions")) input_type=GET_INPUT_OPTIONS; else input_type=GET_INPUT_TARGET_TYPE; } /* we found the graph states option */ else if(!strcmp(variables[x],"graphevents")){ x++; if(variables[x]==NULL){ error=TRUE; break; } graph_events=atoi(variables[x]); } /* we found the graph state types option */ else if(!strcmp(variables[x],"graphstatetypes")){ x++; if(variables[x]==NULL){ error=TRUE; break; } graph_statetypes=atoi(variables[x]); } /* we found the breakdown option */ else if(!strcmp(variables[x],"breakdown")){ x++; if(variables[x]==NULL){ error=TRUE; break; } if(!strcmp(variables[x],"monthly")) breakdown_type=BREAKDOWN_MONTHLY; else if(!strcmp(variables[x],"dayofmonth")) breakdown_type=BREAKDOWN_DAY_OF_MONTH; else if(!strcmp(variables[x],"dayofweek")) breakdown_type=BREAKDOWN_DAY_OF_WEEK; else breakdown_type=BREAKDOWN_HOURLY; } /* we found the assume state retention option */ else if(!strcmp(variables[x],"assumestateretention")){ x++; if(variables[x]==NULL){ error=TRUE; break; } if(!strcmp(variables[x],"yes")) assume_state_retention=TRUE; else assume_state_retention=FALSE; } /* we found the initial states logged option */ else if(!strcmp(variables[x],"initialstateslogged")){ x++; if(variables[x]==NULL){ error=TRUE; break; } if(!strcmp(variables[x],"yes")) initial_states_logged=TRUE; else initial_states_logged=FALSE; } /* we found the new states only option */ else if(!strcmp(variables[x],"newstatesonly")){ x++; if(variables[x]==NULL){ error=TRUE; break; } if(!strcmp(variables[x],"yes")) new_states_only=TRUE; else new_states_only=FALSE; } } /* free memory allocated to the CGI variables */ free_cgivars(variables); return error; } /* graphs histogram data */ void graph_all_histogram_data(void){ int pixel_x; int pixel_y; int last_pixel_y; int current_bucket; int actual_bucket; unsigned long max_value; double x_scaling_factor; double y_scaling_factor; double x_units; double y_units; int current_unit; int actual_unit; char temp_buffer[MAX_INPUT_BUFFER]; int string_width; int string_height; char *days[7]={"Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"}; char *months[12]={"January","February","March","April","May","June","July","August","September","October","November","December"}; char start_time[MAX_INPUT_BUFFER]; char end_time[MAX_INPUT_BUFFER]; unsigned long state1_max=0L; unsigned long state1_min=0L; int have_state1_min=FALSE; unsigned long state1_sum=0L; double state1_avg=0.0; unsigned long state2_max=0L; unsigned long state2_min=0L; int have_state2_min=FALSE; unsigned long state2_sum=0L; double state2_avg=0.0; unsigned long state3_max=0L; unsigned long state3_min=0L; int have_state3_min=FALSE; unsigned long state3_sum=0L; double state3_avg=0.0; unsigned long state4_max=0L; unsigned long state4_min=0L; int have_state4_min=FALSE; unsigned long state4_sum=0L; double state4_avg=0.0; #ifdef DEBUG printf("Total Buckets: %d\n",total_buckets); #endif /* determine max value in the buckets (for scaling) */ max_value=0L; for(current_bucket=0;current_bucketmax_value) max_value=tsdata[current_bucket].service_ok; if(tsdata[current_bucket].service_warning>max_value) max_value=tsdata[current_bucket].service_warning; if(tsdata[current_bucket].service_unknown>max_value) max_value=tsdata[current_bucket].service_unknown; if(tsdata[current_bucket].service_critical>max_value) max_value=tsdata[current_bucket].service_critical; if(tsdata[current_bucket].host_up>max_value) max_value=tsdata[current_bucket].host_up; if(tsdata[current_bucket].host_down>max_value) max_value=tsdata[current_bucket].host_down; if(tsdata[current_bucket].host_unreachable>max_value) max_value=tsdata[current_bucket].host_unreachable; } #ifdef DEBUG printf("Done determining max bucket values\n"); printf("MAX_VALUE=%lu\n",max_value); printf("DRAWING_HEIGHT=%lu\n",DRAWING_HEIGHT); #endif /* min number of values to graph */ if(max_value<10) max_value=10; #ifdef DEBUG printf("ADJUSTED MAX_VALUE=%lu\n",max_value); #endif /* determine y scaling factor */ /*y_scaling_factor=floor((double)DRAWING_HEIGHT/(double)max_value);*/ y_scaling_factor=(double)((double)DRAWING_HEIGHT/(double)max_value); /* determine x scaling factor */ x_scaling_factor=(double)((double)DRAWING_WIDTH/(double)total_buckets); /* determine y units resolution - we want a max of about 10 y grid lines */ /* y_units=(double)((double)DRAWING_HEIGHT/19.0); y_units=ceil(y_units/y_scaling_factor)*y_scaling_factor; */ y_units=ceil(19.0/y_scaling_factor); /* determine x units resolution */ if(breakdown_type==BREAKDOWN_HOURLY) x_units=(double)((double)DRAWING_WIDTH/(double)(total_buckets/4.0)); else x_units=x_scaling_factor; #ifdef DEBUG printf("DRAWING_WIDTH: %d\n",DRAWING_WIDTH); printf("DRAWING_HEIGHT: %d\n",DRAWING_HEIGHT); printf("max_value: %lu\n",max_value); printf("x_scaling_factor: %.3f\n",x_scaling_factor); printf("y_scaling_factor: %.3f\n",y_scaling_factor); printf("x_units: %.3f\n",x_units); printf("y_units: %.3f\n",y_units); printf("y units to draw: %.3f\n",((double)max_value/y_units)); #endif string_height=gdFontSmall->h; #ifdef DEBUG printf("Starting to draw Y grid lines...\n"); #endif /* draw y grid lines */ if(max_value>0){ for(current_unit=1;(current_unit*y_units*y_scaling_factor)<=DRAWING_HEIGHT;current_unit++){ draw_dashed_line(DRAWING_X_OFFSET,DRAWING_Y_OFFSET-(current_unit*y_units*y_scaling_factor),DRAWING_X_OFFSET+DRAWING_WIDTH,DRAWING_Y_OFFSET-(current_unit*y_units*y_scaling_factor),color_lightgray); #ifdef DEBUG printf(" Drawing Y unit #%d @ %d\n",current_unit,(int)(current_unit*y_units*y_scaling_factor)); #endif } } #ifdef DEBUG printf("Starting to draw X grid lines...\n"); #endif /* draw x grid lines */ for(current_unit=1;(int)(current_unit*x_units)<=DRAWING_WIDTH;current_unit++) draw_dashed_line(DRAWING_X_OFFSET+(int)(current_unit*x_units),DRAWING_Y_OFFSET,DRAWING_X_OFFSET+(int)(current_unit*x_units),DRAWING_Y_OFFSET-DRAWING_HEIGHT,color_lightgray); #ifdef DEBUG printf("Starting to draw grid units...\n"); #endif /* draw y units */ if(max_value>0){ for(current_unit=0;(current_unit*y_units*y_scaling_factor)<=DRAWING_HEIGHT;current_unit++){ snprintf(temp_buffer,sizeof(temp_buffer)-1,"%d",(int)(current_unit*y_units)); temp_buffer[sizeof(temp_buffer)-1]='\x0'; string_width=gdFontSmall->w*strlen(temp_buffer); gdImageString(histogram_image,gdFontSmall,DRAWING_X_OFFSET-string_width-5,DRAWING_Y_OFFSET-(current_unit*y_units*y_scaling_factor)-(string_height/2),(unsigned char *)temp_buffer,color_black); } } /* draw x units */ for(current_unit=0,actual_unit=0;(int)(current_unit*x_units)<=DRAWING_WIDTH;current_unit++,actual_unit++){ if(actual_unit>=total_buckets) actual_unit=0; if(breakdown_type==BREAKDOWN_MONTHLY) snprintf(temp_buffer,sizeof(temp_buffer)-1,"%s",months[actual_unit]); else if(breakdown_type==BREAKDOWN_DAY_OF_MONTH) snprintf(temp_buffer,sizeof(temp_buffer)-1,"%d",actual_unit+1); else if(breakdown_type==BREAKDOWN_DAY_OF_WEEK) snprintf(temp_buffer,sizeof(temp_buffer)-1,"%s",days[actual_unit]); else snprintf(temp_buffer,sizeof(temp_buffer)-1,"%02d:00",(actual_unit==24)?0:actual_unit); temp_buffer[sizeof(temp_buffer)-1]='\x0'; string_width=gdFontSmall->w*strlen(temp_buffer); gdImageStringUp(histogram_image,gdFontSmall,DRAWING_X_OFFSET+(current_unit*x_units)-(string_height/2),DRAWING_Y_OFFSET+5+string_width,(unsigned char *)temp_buffer,color_black); } /* draw y unit measure */ snprintf(temp_buffer,sizeof(temp_buffer)-1,"Number of Events"); temp_buffer[sizeof(temp_buffer)-1]='\x0'; string_width=gdFontSmall->w*strlen(temp_buffer); gdImageStringUp(histogram_image,gdFontSmall,0,DRAWING_Y_OFFSET-(DRAWING_HEIGHT/2)+(string_width/2),(unsigned char *)temp_buffer,color_black); /* draw x unit measure */ if(breakdown_type==BREAKDOWN_MONTHLY) snprintf(temp_buffer,sizeof(temp_buffer)-1,"Month"); else if(breakdown_type==BREAKDOWN_DAY_OF_MONTH) snprintf(temp_buffer,sizeof(temp_buffer)-1,"Day of the Month"); else if(breakdown_type==BREAKDOWN_DAY_OF_WEEK) snprintf(temp_buffer,sizeof(temp_buffer)-1,"Day of the Week"); else snprintf(temp_buffer,sizeof(temp_buffer)-1,"Hour of the Day (15 minute increments)"); temp_buffer[sizeof(temp_buffer)-1]='\x0'; string_width=gdFontSmall->w*strlen(temp_buffer); gdImageString(histogram_image,gdFontSmall,DRAWING_X_OFFSET+(DRAWING_WIDTH/2)-(string_width/2),DRAWING_Y_OFFSET+70,(unsigned char *)temp_buffer,color_black); /* draw title */ snprintf(start_time,sizeof(start_time)-1,"%s",ctime(&t1)); start_time[sizeof(start_time)-1]='\x0'; start_time[strlen(start_time)-1]='\x0'; snprintf(end_time,sizeof(end_time)-1,"%s",ctime(&t2)); end_time[sizeof(end_time)-1]='\x0'; end_time[strlen(end_time)-1]='\x0'; if(display_type==DISPLAY_HOST_HISTOGRAM) snprintf(temp_buffer,sizeof(temp_buffer)-1,"Event History For Host '%s'",host_name); else snprintf(temp_buffer,sizeof(temp_buffer)-1,"Event History For Service '%s' On Host '%s'",svc_description,host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; string_width=gdFontSmall->w*strlen(temp_buffer); gdImageString(histogram_image,gdFontSmall,DRAWING_X_OFFSET+(DRAWING_WIDTH/2)-(string_width/2),0,(unsigned char *)temp_buffer,color_black); snprintf(temp_buffer,sizeof(temp_buffer)-1,"%s to %s",start_time,end_time); temp_buffer[sizeof(temp_buffer)-1]='\x0'; string_width=gdFontSmall->w*strlen(temp_buffer); gdImageString(histogram_image,gdFontSmall,DRAWING_X_OFFSET+(DRAWING_WIDTH/2)-(string_width/2),string_height+5,(unsigned char *)temp_buffer,color_black); #ifdef DEBUG printf("About to starting graphing (total_buckets=%d)...\n",total_buckets); #endif /* graph service states */ if(display_type==DISPLAY_HOST_HISTOGRAM){ /* graph host recoveries */ if(graph_events & GRAPH_HOST_UP){ last_pixel_y=0; for(current_bucket=0,actual_bucket=0;current_bucket<=total_buckets;current_bucket++,actual_bucket++){ if(actual_bucket>=total_buckets) actual_bucket=0; pixel_x=(int)(current_bucket*x_scaling_factor); pixel_y=(int)(tsdata[actual_bucket].host_up*y_scaling_factor); if(current_bucket>0 && !(last_pixel_y==0 && pixel_y==0)) draw_line(DRAWING_X_OFFSET+pixel_x-(int)x_scaling_factor,DRAWING_Y_OFFSET-last_pixel_y,DRAWING_X_OFFSET+pixel_x,DRAWING_Y_OFFSET-pixel_y,color_green); last_pixel_y=pixel_y; if(current_bucketstate1_max) state1_max=tsdata[actual_bucket].host_up; state1_sum+=tsdata[actual_bucket].host_up; } } } #ifdef DEBUG printf("Done graphing HOST UP states...\n"); #endif /* graph host down states */ if(graph_events & GRAPH_HOST_DOWN){ last_pixel_y=0; for(current_bucket=0,actual_bucket=0;current_bucket<=total_buckets;current_bucket++,actual_bucket++){ if(actual_bucket>=total_buckets) actual_bucket=0; pixel_x=(int)(current_bucket*x_scaling_factor); pixel_y=(int)(tsdata[actual_bucket].host_down*y_scaling_factor); if(current_bucket>0 && !(last_pixel_y==0 && pixel_y==0)) draw_line(DRAWING_X_OFFSET+pixel_x-(int)x_scaling_factor,DRAWING_Y_OFFSET-last_pixel_y,DRAWING_X_OFFSET+pixel_x,DRAWING_Y_OFFSET-pixel_y,color_red); last_pixel_y=pixel_y; if(current_bucketstate2_max) state2_max=tsdata[actual_bucket].host_down; state2_sum+=tsdata[actual_bucket].host_down; } } } #ifdef DEBUG printf("Done graphing HOST DOWN states...\n"); #endif /* graph host unreachable states */ if(graph_events & GRAPH_HOST_UNREACHABLE){ last_pixel_y=0; for(current_bucket=0,actual_bucket=0;current_bucket<=total_buckets;current_bucket++,actual_bucket++){ if(actual_bucket>=total_buckets) actual_bucket=0; pixel_x=(int)(current_bucket*x_scaling_factor); pixel_y=(int)(tsdata[actual_bucket].host_unreachable*y_scaling_factor); if(current_bucket>0 && !(last_pixel_y==0 && pixel_y==0)) draw_line(DRAWING_X_OFFSET+pixel_x-(int)x_scaling_factor,DRAWING_Y_OFFSET-last_pixel_y,DRAWING_X_OFFSET+pixel_x,DRAWING_Y_OFFSET-pixel_y,color_darkred); last_pixel_y=pixel_y; if(current_bucketstate3_max) state3_max=tsdata[actual_bucket].host_unreachable; state3_sum+=tsdata[actual_bucket].host_unreachable; } } } #ifdef DEBUG printf("Done graphing HOST UNREACHABLE states...\n"); #endif } /* graph service states */ else{ /* graph service recoveries */ if(graph_events & GRAPH_SERVICE_OK){ last_pixel_y=0; for(current_bucket=0,actual_bucket=0;current_bucket<=total_buckets;current_bucket++,actual_bucket++){ if(actual_bucket>=total_buckets) actual_bucket=0; pixel_x=(int)(current_bucket*x_scaling_factor); pixel_y=(int)(tsdata[actual_bucket].service_ok*y_scaling_factor); if(current_bucket>0 && !(last_pixel_y==0 && pixel_y==0)) draw_line(DRAWING_X_OFFSET+pixel_x-(int)x_scaling_factor,DRAWING_Y_OFFSET-last_pixel_y,DRAWING_X_OFFSET+pixel_x,DRAWING_Y_OFFSET-pixel_y,color_green); last_pixel_y=pixel_y; if(current_bucketstate1_max) state1_max=tsdata[actual_bucket].service_ok; state1_sum+=tsdata[actual_bucket].service_ok; } } } /* graph service warning states */ if(graph_events & GRAPH_SERVICE_WARNING){ last_pixel_y=0; for(current_bucket=0,actual_bucket=0;current_bucket<=total_buckets;current_bucket++,actual_bucket++){ if(actual_bucket>=total_buckets) actual_bucket=0; pixel_x=(int)(current_bucket*x_scaling_factor); pixel_y=(int)(tsdata[actual_bucket].service_warning*y_scaling_factor); if(current_bucket>0 && !(last_pixel_y==0 && pixel_y==0)) draw_line(DRAWING_X_OFFSET+pixel_x-(int)x_scaling_factor,DRAWING_Y_OFFSET-last_pixel_y,DRAWING_X_OFFSET+pixel_x,DRAWING_Y_OFFSET-pixel_y,color_yellow); last_pixel_y=pixel_y; if(current_bucketstate2_max) state2_max=tsdata[actual_bucket].service_warning; state2_sum+=tsdata[actual_bucket].service_warning; } } } /* graph service unknown states */ if(graph_events & GRAPH_SERVICE_UNKNOWN){ last_pixel_y=0; for(current_bucket=0,actual_bucket=0;current_bucket<=total_buckets;current_bucket++,actual_bucket++){ if(actual_bucket>=total_buckets) actual_bucket=0; pixel_x=(int)(current_bucket*x_scaling_factor); pixel_y=(int)(tsdata[actual_bucket].service_unknown*y_scaling_factor); if(current_bucket>0 && !(last_pixel_y==0 && pixel_y==0)) draw_line(DRAWING_X_OFFSET+pixel_x-(int)x_scaling_factor,DRAWING_Y_OFFSET-last_pixel_y,DRAWING_X_OFFSET+pixel_x,DRAWING_Y_OFFSET-pixel_y,color_orange); last_pixel_y=pixel_y; if(current_bucketstate3_max) state3_max=tsdata[actual_bucket].service_unknown; state3_sum+=tsdata[actual_bucket].service_unknown; } } } /* graph service critical states */ if(graph_events & GRAPH_SERVICE_CRITICAL){ last_pixel_y=0; for(current_bucket=0,actual_bucket=0;current_bucket<=total_buckets;current_bucket++,actual_bucket++){ if(actual_bucket>=total_buckets) actual_bucket=0; pixel_x=(int)(current_bucket*x_scaling_factor); pixel_y=(int)(tsdata[actual_bucket].service_critical*y_scaling_factor); if(current_bucket>0 && !(last_pixel_y==0 && pixel_y==0)) draw_line(DRAWING_X_OFFSET+pixel_x-(int)x_scaling_factor,DRAWING_Y_OFFSET-last_pixel_y,DRAWING_X_OFFSET+pixel_x,DRAWING_Y_OFFSET-pixel_y,color_red); last_pixel_y=pixel_y; if(current_bucketstate4_max) state4_max=tsdata[actual_bucket].service_critical; state4_sum+=tsdata[actual_bucket].service_critical; } } } } #ifdef DEBUG printf("Done graphing states...\n"); #endif /* draw graph boundaries */ draw_line(DRAWING_X_OFFSET,DRAWING_Y_OFFSET,DRAWING_X_OFFSET,DRAWING_Y_OFFSET-DRAWING_HEIGHT,color_black); draw_line(DRAWING_X_OFFSET+DRAWING_WIDTH,DRAWING_Y_OFFSET,DRAWING_X_OFFSET+DRAWING_WIDTH,DRAWING_Y_OFFSET-DRAWING_HEIGHT,color_black); draw_line(DRAWING_X_OFFSET,DRAWING_Y_OFFSET,DRAWING_X_OFFSET+DRAWING_WIDTH,DRAWING_Y_OFFSET,color_black); /* graph stats */ snprintf(temp_buffer,sizeof(temp_buffer)-1,"EVENT TYPE"); temp_buffer[sizeof(temp_buffer)-1]='\x0'; string_width=gdFontSmall->w*strlen(temp_buffer); gdImageString(histogram_image,gdFontSmall,DRAWING_X_OFFSET+DRAWING_WIDTH+15,DRAWING_Y_OFFSET-DRAWING_HEIGHT,(unsigned char *)temp_buffer,color_black); snprintf(temp_buffer,sizeof(temp_buffer)-1," MIN MAX SUM AVG"); temp_buffer[sizeof(temp_buffer)-1]='\x0'; string_width=gdFontSmall->w*strlen(temp_buffer); gdImageString(histogram_image,gdFontSmall,DRAWING_X_OFFSET+DRAWING_WIDTH+115,DRAWING_Y_OFFSET-DRAWING_HEIGHT,(unsigned char *)temp_buffer,color_black); draw_line(DRAWING_X_OFFSET+DRAWING_WIDTH+15,DRAWING_Y_OFFSET-DRAWING_HEIGHT+string_height+2,DRAWING_X_OFFSET+DRAWING_WIDTH+275,DRAWING_Y_OFFSET-DRAWING_HEIGHT+string_height+2,color_black); snprintf(temp_buffer,sizeof(temp_buffer)-1,"Recovery (%s):",(display_type==DISPLAY_SERVICE_HISTOGRAM)?"Ok":"Up"); temp_buffer[sizeof(temp_buffer)-1]='\x0'; string_width=gdFontSmall->w*strlen(temp_buffer); gdImageString(histogram_image,gdFontSmall,DRAWING_X_OFFSET+DRAWING_WIDTH+15,DRAWING_Y_OFFSET-DRAWING_HEIGHT+((string_height+5)*1),(unsigned char *)temp_buffer,color_green); state1_avg=(double)((double)state1_sum/(double)total_buckets); snprintf(temp_buffer,sizeof(temp_buffer)-1,"%5lu %5lu %5lu %.2f",state1_min,state1_max,state1_sum,state1_avg); temp_buffer[sizeof(temp_buffer)-1]='\x0'; string_width=gdFontSmall->w*strlen(temp_buffer); gdImageString(histogram_image,gdFontSmall,DRAWING_X_OFFSET+DRAWING_WIDTH+115,DRAWING_Y_OFFSET-DRAWING_HEIGHT+((string_height+5)*1),(unsigned char *)temp_buffer,color_black); snprintf(temp_buffer,sizeof(temp_buffer)-1,"%s:",(display_type==DISPLAY_SERVICE_HISTOGRAM)?"Warning":"Down"); temp_buffer[sizeof(temp_buffer)-1]='\x0'; string_width=gdFontSmall->w*strlen(temp_buffer); gdImageString(histogram_image,gdFontSmall,DRAWING_X_OFFSET+DRAWING_WIDTH+15,DRAWING_Y_OFFSET-DRAWING_HEIGHT+((string_height+5)*2),(unsigned char *)temp_buffer,(display_type==DISPLAY_SERVICE_HISTOGRAM)?color_yellow:color_red); state2_avg=(double)((double)state2_sum/(double)total_buckets); snprintf(temp_buffer,sizeof(temp_buffer)-1,"%5lu %5lu %5lu %.2f",state2_min,state2_max,state2_sum,state2_avg); temp_buffer[sizeof(temp_buffer)-1]='\x0'; string_width=gdFontSmall->w*strlen(temp_buffer); gdImageString(histogram_image,gdFontSmall,DRAWING_X_OFFSET+DRAWING_WIDTH+115,DRAWING_Y_OFFSET-DRAWING_HEIGHT+((string_height+5)*2),(unsigned char *)temp_buffer,color_black); snprintf(temp_buffer,sizeof(temp_buffer)-1,"%s:",(display_type==DISPLAY_SERVICE_HISTOGRAM)?"Unknown":"Unreachable"); temp_buffer[sizeof(temp_buffer)-1]='\x0'; string_width=gdFontSmall->w*strlen(temp_buffer); gdImageString(histogram_image,gdFontSmall,DRAWING_X_OFFSET+DRAWING_WIDTH+15,DRAWING_Y_OFFSET-DRAWING_HEIGHT+((string_height+5)*3),(unsigned char *)temp_buffer,(display_type==DISPLAY_SERVICE_HISTOGRAM)?color_orange:color_darkred); state3_avg=(double)((double)state3_sum/(double)total_buckets); snprintf(temp_buffer,sizeof(temp_buffer)-1,"%5lu %5lu %5lu %.2f",state3_min,state3_max,state3_sum,state3_avg); temp_buffer[sizeof(temp_buffer)-1]='\x0'; string_width=gdFontSmall->w*strlen(temp_buffer); gdImageString(histogram_image,gdFontSmall,DRAWING_X_OFFSET+DRAWING_WIDTH+115,DRAWING_Y_OFFSET-DRAWING_HEIGHT+((string_height+5)*3),(unsigned char *)temp_buffer,color_black); if(display_type==DISPLAY_SERVICE_HISTOGRAM){ snprintf(temp_buffer,sizeof(temp_buffer)-1,"Critical:"); temp_buffer[sizeof(temp_buffer)-1]='\x0'; string_width=gdFontSmall->w*strlen(temp_buffer); gdImageString(histogram_image,gdFontSmall,DRAWING_X_OFFSET+DRAWING_WIDTH+15,DRAWING_Y_OFFSET-DRAWING_HEIGHT+((string_height+5)*4),(unsigned char *)temp_buffer,color_red); state4_avg=(double)((double)state4_sum/(double)total_buckets); snprintf(temp_buffer,sizeof(temp_buffer)-1,"%5lu %5lu %5lu %.2f",state4_min,state4_max,state4_sum,state4_avg); temp_buffer[sizeof(temp_buffer)-1]='\x0'; string_width=gdFontSmall->w*strlen(temp_buffer); gdImageString(histogram_image,gdFontSmall,DRAWING_X_OFFSET+DRAWING_WIDTH+115,DRAWING_Y_OFFSET-DRAWING_HEIGHT+((string_height+5)*4),(unsigned char *)temp_buffer,color_black); } return; } /* adds an archived state entry */ void add_archived_state(int state_type, time_t time_stamp){ struct tm *our_time; int bucket; int skip_state=FALSE; #ifdef DEBUG2 printf("NEW ENTRY: last=%d this=%d\n",last_state,state_type); #endif /* don't record program starts/stops, just make a note that one occurred */ if(state_type==AS_PROGRAM_START || state_type==AS_PROGRAM_END){ #ifdef DEBUG2 printf("Recording a program start: %d\n",state_type); #endif program_restart_has_occurred=TRUE; return; } /* see if we should even take into account this event */ if(program_restart_has_occurred==TRUE){ #ifdef DEBUG2 printf("program_restart_has_occurred: last=%d this=%d\n",last_state,state_type); #endif if(initial_states_logged==TRUE){ if(state_type==AS_SVC_OK && last_state==AS_SVC_OK) skip_state=TRUE; if(state_type==AS_HOST_UP && last_state==AS_HOST_UP) skip_state=TRUE; } if(assume_state_retention==TRUE && initial_states_logged==TRUE){ if(state_type==AS_SVC_WARNING && last_state==AS_SVC_WARNING) skip_state=TRUE; if(state_type==AS_SVC_UNKNOWN && last_state==AS_SVC_UNKNOWN) skip_state=TRUE; if(state_type==AS_SVC_CRITICAL && last_state==AS_SVC_CRITICAL) skip_state=TRUE; if(state_type==AS_HOST_DOWN && last_state==AS_HOST_DOWN) skip_state=TRUE; if(state_type==AS_HOST_UNREACHABLE && last_state==AS_HOST_UNREACHABLE) skip_state=TRUE; } if(skip_state==TRUE){ program_restart_has_occurred=FALSE; #ifdef DEBUG2 printf("Skipping state...\n"); #endif return; } } /* reset program restart variable */ program_restart_has_occurred=FALSE; /* are we only processing new states */ if(new_states_only==TRUE && state_type==last_state){ #ifdef DEBUG2 printf("Skipping state (not a new state)...\n"); #endif return; } #ifdef DEBUG2 printf("GOODSTATE: %d @ %lu\n",state_type,(unsigned long)time_stamp); #endif our_time=localtime(&time_stamp); /* calculate the correct bucket to dump the data into */ if(breakdown_type==BREAKDOWN_MONTHLY) bucket=our_time->tm_mon; else if(breakdown_type==BREAKDOWN_DAY_OF_MONTH) bucket=our_time->tm_mday-1; else if(breakdown_type==BREAKDOWN_DAY_OF_WEEK) bucket=our_time->tm_wday; else bucket=(our_time->tm_hour*4)+(our_time->tm_min/15); #ifdef DEBUG2 printf("\tBucket=%d\n",bucket); #endif /* save the data in the correct bucket */ if(state_type==AS_SVC_OK) tsdata[bucket].service_ok++; else if(state_type==AS_SVC_UNKNOWN) tsdata[bucket].service_unknown++; else if(state_type==AS_SVC_WARNING) tsdata[bucket].service_warning++; else if(state_type==AS_SVC_CRITICAL) tsdata[bucket].service_critical++; else if(state_type==AS_HOST_UP) tsdata[bucket].host_up++; else if(state_type==AS_HOST_DOWN) tsdata[bucket].host_down++; else if(state_type==AS_HOST_UNREACHABLE) tsdata[bucket].host_unreachable++; /* record last state type */ last_state=state_type; return; } /* reads log files for archived state data */ void read_archived_state_data(void){ char filename[MAX_FILENAME_LENGTH]; int newest_archive=0; int oldest_archive=0; int current_archive; #ifdef DEBUG2 printf("Determining archives to use...\n"); #endif /* determine earliest archive to use */ oldest_archive=determine_archive_to_use_from_time(t1); if(log_rotation_method!=LOG_ROTATION_NONE) oldest_archive+=backtrack_archives; /* determine most recent archive to use */ newest_archive=determine_archive_to_use_from_time(t2); if(oldest_archivetm_sec=0; t->tm_min=0; t->tm_hour=0; switch(type){ case TIMEPERIOD_LAST24HOURS: t1=current_time-(60*60*24); t2=current_time; break; case TIMEPERIOD_TODAY: t1=mktime(t); t2=current_time; break; case TIMEPERIOD_YESTERDAY: t1=(time_t)(mktime(t)-(60*60*24)); t2=(time_t)mktime(t); break; case TIMEPERIOD_THISWEEK: t1=(time_t)(mktime(t)-(60*60*24*t->tm_wday)); t2=current_time; break; case TIMEPERIOD_LASTWEEK: t1=(time_t)(mktime(t)-(60*60*24*t->tm_wday)-(60*60*24*7)); t2=(time_t)(mktime(t)-(60*60*24*t->tm_wday)); break; case TIMEPERIOD_THISMONTH: t->tm_mday=1; t1=mktime(t); t2=current_time; break; case TIMEPERIOD_LASTMONTH: t->tm_mday=1; t2=mktime(t); if(t->tm_mon==0){ t->tm_mon=11; t->tm_year--; } else t->tm_mon--; t1=mktime(t); break; case TIMEPERIOD_THISQUARTER: break; case TIMEPERIOD_LASTQUARTER: break; case TIMEPERIOD_THISYEAR: t->tm_mon=0; t->tm_mday=1; t1=mktime(t); t2=current_time; break; case TIMEPERIOD_LASTYEAR: t->tm_mon=0; t->tm_mday=1; t2=mktime(t); t->tm_year--; t1=mktime(t); break; case TIMEPERIOD_LAST7DAYS: t2=current_time; t1=current_time-(7*24*60*60); break; case TIMEPERIOD_LAST31DAYS: t2=current_time; t1=current_time-(31*24*60*60); break; default: break; } return; } void compute_report_times(void){ time_t current_time; struct tm *st; struct tm *et; /* get the current time */ time(¤t_time); st=localtime(¤t_time); st->tm_sec=start_second; st->tm_min=start_minute; st->tm_hour=start_hour; st->tm_mday=start_day; st->tm_mon=start_month-1; st->tm_year=start_year-1900; t1=mktime(st); et=localtime(¤t_time); et->tm_sec=end_second; et->tm_min=end_minute; et->tm_hour=end_hour; et->tm_mday=end_day; et->tm_mon=end_month-1; et->tm_year=end_year-1900; t2=mktime(et); } /* draws a solid line */ void draw_line(int x1,int y1,int x2,int y2,int color){ int styleSolid[1]; styleSolid[0]=color; /* sets current style to a solid line */ gdImageSetStyle(histogram_image,styleSolid,1); /* draws a line (dashed) */ gdImageLine(histogram_image,x1,y1,x2,y2,gdStyled); return; } /* draws a dashed line */ void draw_dashed_line(int x1,int y1,int x2,int y2,int color){ int styleDashed[6]; styleDashed[0]=color; styleDashed[1]=color; styleDashed[2]=gdTransparent; styleDashed[3]=gdTransparent; styleDashed[4]=gdTransparent; styleDashed[5]=gdTransparent; /* sets current style to a solid line */ gdImageSetStyle(histogram_image,styleDashed,6); /* draws a line (dashed) */ gdImageLine(histogram_image,x1,y1,x2,y2,gdStyled); return; } nagios-2.6/cgi/history.c0000664000076500007650000007275610410070302014612 0ustar nagiosnagios/*********************************************************************** * * HISTORY.C - Nagios History CGI * * Copyright (c) 1999-2006 Ethan Galstad (nagios@nagios.org) * Last Modified: 03-21-2006 * * This CGI program will display the history for the specified host. * If no host is specified, the history for all hosts will be displayed. * * 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. ***********************************************************************/ #include "../include/config.h" #include "../include/common.h" #include "../include/objects.h" #include "../include/getcgi.h" #include "../include/cgiutils.h" #include "../include/cgiauth.h" #define DISPLAY_HOSTS 0 #define DISPLAY_SERVICES 1 #define SERVICE_HISTORY 0 #define HOST_HISTORY 1 #define SERVICE_FLAPPING_HISTORY 2 #define HOST_FLAPPING_HISTORY 3 #define SERVICE_DOWNTIME_HISTORY 4 #define HOST_DOWNTIME_HISTORY 5 #define STATE_ALL 0 #define STATE_SOFT 1 #define STATE_HARD 2 void get_history(void); void document_header(int); void document_footer(void); int process_cgivars(void); extern char main_config_file[MAX_FILENAME_LENGTH]; extern char url_images_path[MAX_FILENAME_LENGTH]; extern char url_stylesheets_path[MAX_FILENAME_LENGTH]; extern int log_rotation_method; authdata current_authdata; char log_file_to_use[MAX_FILENAME_LENGTH]; int log_archive=0; int show_all_hosts=TRUE; char *host_name="all"; char *svc_description=""; int display_type=DISPLAY_HOSTS; int use_lifo=TRUE; int history_options=HISTORY_ALL; int state_options=STATE_ALL; int embedded=FALSE; int display_header=TRUE; int display_frills=TRUE; int display_timebreaks=TRUE; int display_system_messages=TRUE; int display_flapping_alerts=TRUE; int display_downtime_alerts=TRUE; int main(void){ int result=OK; char temp_buffer[MAX_INPUT_BUFFER]; char temp_buffer2[MAX_INPUT_BUFFER]; /* get the variables passed to us */ process_cgivars(); /* reset internal CGI variables */ reset_cgi_vars(); /* read the CGI configuration file */ result=read_cgi_config_file(get_cgi_config_location()); if(result==ERROR){ document_header(FALSE); cgi_config_file_error(get_cgi_config_location()); document_footer(); return ERROR; } /* read the main configuration file */ result=read_main_config_file(main_config_file); if(result==ERROR){ document_header(FALSE); main_config_file_error(main_config_file); document_footer(); return ERROR; } /* read all object configuration data */ result=read_all_object_configuration_data(main_config_file,READ_ALL_OBJECT_DATA); if(result==ERROR){ document_header(FALSE); object_data_error(); document_footer(); return ERROR; } document_header(TRUE); /* get authentication information */ get_authentication_information(¤t_authdata); /* determine what log file we should be using */ get_log_archive_to_use(log_archive,log_file_to_use,(int)sizeof(log_file_to_use)); if(display_header==TRUE){ /* begin top table */ printf("\n"); printf("\n"); /* left column of the first row */ printf("\n"); /* middle column of top row */ printf("\n"); /* right hand column of top row */ printf("\n"); /* end of top table */ printf("\n"); printf("
    \n"); if(display_type==DISPLAY_SERVICES) snprintf(temp_buffer,sizeof(temp_buffer)-1,"Service Alert History"); else if(show_all_hosts==TRUE) snprintf(temp_buffer,sizeof(temp_buffer)-1,"Alert History"); else snprintf(temp_buffer,sizeof(temp_buffer)-1,"Host Alert History"); temp_buffer[sizeof(temp_buffer)-1]='\x0'; display_info_table(temp_buffer,FALSE,¤t_authdata); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("
    \n"); if(display_type==DISPLAY_SERVICES) printf("Service '%s' On Host '%s'",svc_description,host_name); else if(show_all_hosts==TRUE) printf("All Hosts and Services"); else printf("Host '%s'",host_name); printf("
    \n"); printf("
    \n"); snprintf(temp_buffer,sizeof(temp_buffer)-1,"%s?%shost=%s&type=%d&statetype=%d&",HISTORY_CGI,(use_lifo==FALSE)?"oldestfirst&":"",url_encode(host_name),history_options,state_options); temp_buffer[sizeof(temp_buffer)-1]='\x0'; if(display_type==DISPLAY_SERVICES){ snprintf(temp_buffer2,sizeof(temp_buffer2)-1,"service=%s&",url_encode(svc_description)); temp_buffer2[sizeof(temp_buffer2)-1]='\x0'; strncat(temp_buffer,temp_buffer2,sizeof(temp_buffer)-strlen(temp_buffer)-1); temp_buffer[sizeof(temp_buffer)-1]='\x0'; } display_nav_table(temp_buffer,log_archive); printf("
    \n"); printf("\n"); printf("\n",HISTORY_CGI); printf("\n",(show_all_hosts==TRUE)?"all":host_name); if(display_type==DISPLAY_SERVICES) printf("\n",svc_description); printf("\n",log_archive); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n") ; printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("",(display_flapping_alerts==FALSE)?"checked":""); printf("\n"); printf("\n"); printf("",(display_downtime_alerts==FALSE)?"checked":""); printf("\n"); printf("\n"); printf("",(display_system_messages==FALSE)?"checked":""); printf("\n"); printf("\n"); printf("",(use_lifo==FALSE)?"checked":""); printf("\n"); printf("\n"); printf("\n"); printf("\n"); /* display context-sensitive help */ printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("
    State type options:
    History detail level for "); if(display_type==DISPLAY_HOSTS) printf("%s host%s",(show_all_hosts==TRUE)?"all":"this",(show_all_hosts==TRUE)?"s":""); else printf("service"); printf(":
    Hide Flapping Alerts
    Hide Downtime Alerts
    Hide Process Messages
    Older Entries First
    \n"); display_context_help(CONTEXTHELP_HISTORY); printf("
    \n"); printf("
    \n"); } /* display history */ get_history(); document_footer(); /* free allocated memory */ free_memory(); return OK; } void document_header(int use_stylesheet){ char date_time[MAX_DATETIME_LENGTH]; time_t current_time; time_t expire_time; printf("Cache-Control: no-store\r\n"); printf("Pragma: no-cache\r\n"); time(¤t_time); get_time_string(¤t_time,date_time,sizeof(date_time),HTTP_DATE_TIME); printf("Last-Modified: %s\r\n",date_time); expire_time=(time_t)0L; get_time_string(&expire_time,date_time,sizeof(date_time),HTTP_DATE_TIME); printf("Expires: %s\r\n",date_time); printf("Content-type: text/html\r\n\r\n"); if(embedded==TRUE) return; printf("\n"); printf("\n"); printf("\n"); printf("Nagios History\n"); printf("\n"); if(use_stylesheet==TRUE){ printf("\n",url_stylesheets_path,COMMON_CSS); printf("\n",url_stylesheets_path,HISTORY_CSS); } printf("\n"); printf("\n"); /* include user SSI header */ include_ssi_files(HISTORY_CGI,SSI_HEADER); return; } void document_footer(void){ if(embedded==TRUE) return; /* include user SSI footer */ include_ssi_files(HISTORY_CGI,SSI_FOOTER); printf("\n"); printf("\n"); return; } int process_cgivars(void){ char **variables; int error=FALSE; int x; variables=getcgivars(); for(x=0;variables[x]!=NULL;x++){ /* do some basic length checking on the variable identifier to prevent buffer overflows */ if(strlen(variables[x])>=MAX_INPUT_BUFFER-1) continue; /* we found the host argument */ else if(!strcmp(variables[x],"host")){ x++; if(variables[x]==NULL){ error=TRUE; break; } host_name=(char *)malloc(strlen(variables[x])+1); if(host_name==NULL) host_name=""; else strcpy(host_name,variables[x]); display_type=DISPLAY_HOSTS; if(!strcmp(host_name,"all")) show_all_hosts=TRUE; else show_all_hosts=FALSE; } /* we found the service argument */ else if(!strcmp(variables[x],"service")){ x++; if(variables[x]==NULL){ error=TRUE; break; } svc_description=(char *)malloc(strlen(variables[x])+1); if(svc_description==NULL) svc_description=""; else strcpy(svc_description,variables[x]); display_type=DISPLAY_SERVICES; } /* we found the history type argument */ else if(!strcmp(variables[x],"type")){ x++; if(variables[x]==NULL){ error=TRUE; break; } history_options=atoi(variables[x]); } /* we found the history state type argument */ else if(!strcmp(variables[x],"statetype")){ x++; if(variables[x]==NULL){ error=TRUE; break; } state_options=atoi(variables[x]); } /* we found the log archive argument */ else if(!strcmp(variables[x],"archive")){ x++; if(variables[x]==NULL){ error=TRUE; break; } log_archive=atoi(variables[x]); if(log_archive<0) log_archive=0; } /* we found the order argument */ else if(!strcmp(variables[x],"oldestfirst")){ use_lifo=FALSE; } /* we found the embed option */ else if(!strcmp(variables[x],"embedded")) embedded=TRUE; /* we found the noheader option */ else if(!strcmp(variables[x],"noheader")) display_header=FALSE; /* we found the nofrills option */ else if(!strcmp(variables[x],"nofrills")) display_frills=FALSE; /* we found the notimebreaks option */ else if(!strcmp(variables[x],"notimebreaks")) display_timebreaks=FALSE; /* we found the no system messages option */ else if(!strcmp(variables[x],"nosystem")) display_system_messages=FALSE; /* we found the no flapping alerts option */ else if(!strcmp(variables[x],"noflapping")) display_flapping_alerts=FALSE; /* we found the no downtime alerts option */ else if(!strcmp(variables[x],"nodowntime")) display_downtime_alerts=FALSE; } /* free memory allocated to the CGI variables */ free_cgivars(variables); return error; } void get_history(void){ mmapfile *thefile; char image[MAX_INPUT_BUFFER]; char image_alt[MAX_INPUT_BUFFER]; char *input=NULL; char input_buffer2[MAX_INPUT_BUFFER]; char match1[MAX_INPUT_BUFFER]; char match2[MAX_INPUT_BUFFER]; int found_line=FALSE; int system_message=FALSE; int display_line=FALSE; time_t t; char date_time[MAX_DATETIME_LENGTH]; char *temp_buffer; int history_type=SERVICE_HISTORY; int history_detail_type=HISTORY_SERVICE_CRITICAL; char entry_host_name[MAX_HOSTNAME_LENGTH]; char entry_service_desc[MAX_SERVICEDESC_LENGTH]; host *temp_host; service *temp_service; int result; char last_message_date[MAX_INPUT_BUFFER]=""; char current_message_date[MAX_INPUT_BUFFER]=""; struct tm *time_ptr; if(use_lifo==TRUE){ result=read_file_into_lifo(log_file_to_use); if(result!=LIFO_OK){ if(result==LIFO_ERROR_MEMORY){ printf("

    Not enough memory to reverse log file - displaying history in natural order...

    \n"); } else if(result==LIFO_ERROR_FILE){ printf("

    Error: Cannot open log file '%s' for reading!


    ",log_file_to_use); return; } use_lifo=FALSE; } } if(use_lifo==FALSE){ if((thefile=mmap_fopen(log_file_to_use))==NULL){ printf("

    Error: Cannot open log file '%s' for reading!


    ",log_file_to_use); return; } } printf("

    \n"); while(1){ free(input); if(use_lifo==TRUE){ if((input=pop_lifo())==NULL) break; } else{ if((input=mmap_fgets(thefile))==NULL) break; } strip(input); strcpy(image,""); strcpy(image_alt,""); system_message=FALSE; strcpy(input_buffer2,input); /* service state alerts */ if(strstr(input,"SERVICE ALERT:")){ history_type=SERVICE_HISTORY; /* get host and service names */ temp_buffer=my_strtok(input_buffer2,"]"); temp_buffer=my_strtok(NULL,":"); temp_buffer=my_strtok(NULL,";"); strncpy(entry_host_name,(temp_buffer==NULL)?"":temp_buffer+1,sizeof(entry_host_name)); entry_host_name[sizeof(entry_host_name)-1]='\x0'; temp_buffer=my_strtok(NULL,";"); strncpy(entry_service_desc,(temp_buffer==NULL)?"":temp_buffer,sizeof(entry_service_desc)); entry_service_desc[sizeof(entry_service_desc)-1]='\x0'; if(strstr(input,";CRITICAL;")){ strncpy(image,CRITICAL_ICON,sizeof(image)); strncpy(image_alt,CRITICAL_ICON_ALT,sizeof(image_alt)); history_detail_type=HISTORY_SERVICE_CRITICAL; } else if(strstr(input,";WARNING;")){ strncpy(image,WARNING_ICON,sizeof(image)); strncpy(image_alt,WARNING_ICON_ALT,sizeof(image_alt)); history_detail_type=HISTORY_SERVICE_WARNING; } else if(strstr(input,";UNKNOWN;")){ strncpy(image,UNKNOWN_ICON,sizeof(image)); strncpy(image_alt,UNKNOWN_ICON_ALT,sizeof(image_alt)); history_detail_type=HISTORY_SERVICE_UNKNOWN; } else if(strstr(input,";RECOVERY;") || strstr(input,";OK;")){ strncpy(image,OK_ICON,sizeof(image)); strncpy(image_alt,OK_ICON_ALT,sizeof(image_alt)); history_detail_type=HISTORY_SERVICE_RECOVERY; } } /* service flapping alerts */ else if(strstr(input,"SERVICE FLAPPING ALERT:")){ if(display_flapping_alerts==FALSE) continue; history_type=SERVICE_FLAPPING_HISTORY; /* get host and service names */ temp_buffer=my_strtok(input_buffer2,"]"); temp_buffer=my_strtok(NULL,":"); temp_buffer=my_strtok(NULL,";"); strncpy(entry_host_name,(temp_buffer==NULL)?"":temp_buffer+1,sizeof(entry_host_name)); entry_host_name[sizeof(entry_host_name)-1]='\x0'; temp_buffer=my_strtok(NULL,";"); strncpy(entry_service_desc,(temp_buffer==NULL)?"":temp_buffer,sizeof(entry_service_desc)); entry_service_desc[sizeof(entry_service_desc)-1]='\x0'; strncpy(image,FLAPPING_ICON,sizeof(image)); if(strstr(input,";STARTED;")) strncpy(image_alt,"Service started flapping",sizeof(image_alt)); else if(strstr(input,";STOPPED;")) strncpy(image_alt,"Service stopped flapping",sizeof(image_alt)); else if(strstr(input,";DISABLED;")) strncpy(image_alt,"Service flap detection disabled",sizeof(image_alt)); } /* service downtime alerts */ else if(strstr(input,"SERVICE DOWNTIME ALERT:")){ if(display_downtime_alerts==FALSE) continue; history_type=SERVICE_DOWNTIME_HISTORY; /* get host and service names */ temp_buffer=my_strtok(input_buffer2,"]"); temp_buffer=my_strtok(NULL,":"); temp_buffer=my_strtok(NULL,";"); strncpy(entry_host_name,(temp_buffer==NULL)?"":temp_buffer+1,sizeof(entry_host_name)); entry_host_name[sizeof(entry_host_name)-1]='\x0'; temp_buffer=my_strtok(NULL,";"); strncpy(entry_service_desc,(temp_buffer==NULL)?"":temp_buffer,sizeof(entry_service_desc)); entry_service_desc[sizeof(entry_service_desc)-1]='\x0'; strncpy(image,SCHEDULED_DOWNTIME_ICON,sizeof(image)); if(strstr(input,";STARTED;")) strncpy(image_alt,"Service entered a period of scheduled downtime",sizeof(image_alt)); else if(strstr(input,";STOPPED;")) strncpy(image_alt,"Service exited from a period of scheduled downtime",sizeof(image_alt)); else if(strstr(input,";CANCELLED;")) strncpy(image_alt,"Service scheduled downtime has been cancelled",sizeof(image_alt)); } /* host state alerts */ else if(strstr(input,"HOST ALERT:")){ history_type=HOST_HISTORY; /* get host name */ temp_buffer=my_strtok(input_buffer2,"]"); temp_buffer=my_strtok(NULL,":"); temp_buffer=my_strtok(NULL,";"); strncpy(entry_host_name,(temp_buffer==NULL)?"":temp_buffer+1,sizeof(entry_host_name)); entry_host_name[sizeof(entry_host_name)-1]='\x0'; if(strstr(input,";DOWN;")){ strncpy(image,HOST_DOWN_ICON,sizeof(image)); strncpy(image_alt,HOST_DOWN_ICON_ALT,sizeof(image_alt)); history_detail_type=HISTORY_HOST_DOWN; } else if(strstr(input,";UNREACHABLE;")){ strncpy(image,HOST_UNREACHABLE_ICON,sizeof(image)); strncpy(image_alt,HOST_UNREACHABLE_ICON_ALT,sizeof(image_alt)); history_detail_type=HISTORY_HOST_UNREACHABLE; } else if(strstr(input,";RECOVERY") || strstr(input,";UP;")){ strncpy(image,HOST_UP_ICON,sizeof(image)); strncpy(image_alt,HOST_UP_ICON_ALT,sizeof(image_alt)); history_detail_type=HISTORY_HOST_RECOVERY; } } /* host flapping alerts */ else if(strstr(input,"HOST FLAPPING ALERT:")){ if(display_flapping_alerts==FALSE) continue; history_type=HOST_FLAPPING_HISTORY; /* get host name */ temp_buffer=my_strtok(input_buffer2,"]"); temp_buffer=my_strtok(NULL,":"); temp_buffer=my_strtok(NULL,";"); strncpy(entry_host_name,(temp_buffer==NULL)?"":temp_buffer+1,sizeof(entry_host_name)); entry_host_name[sizeof(entry_host_name)-1]='\x0'; strncpy(image,FLAPPING_ICON,sizeof(image)); if(strstr(input,";STARTED;")) strncpy(image_alt,"Host started flapping",sizeof(image_alt)); else if(strstr(input,";STOPPED;")) strncpy(image_alt,"Host stopped flapping",sizeof(image_alt)); else if(strstr(input,";DISABLED;")) strncpy(image_alt,"Host flap detection disabled",sizeof(image_alt)); } /* host downtime alerts */ else if(strstr(input,"HOST DOWNTIME ALERT:")){ if(display_downtime_alerts==FALSE) continue; history_type=HOST_DOWNTIME_HISTORY; /* get host name */ temp_buffer=my_strtok(input_buffer2,"]"); temp_buffer=my_strtok(NULL,":"); temp_buffer=my_strtok(NULL,";"); strncpy(entry_host_name,(temp_buffer==NULL)?"":temp_buffer+1,sizeof(entry_host_name)); entry_host_name[sizeof(entry_host_name)-1]='\x0'; strncpy(image,SCHEDULED_DOWNTIME_ICON,sizeof(image)); if(strstr(input,";STARTED;")) strncpy(image_alt,"Host entered a period of scheduled downtime",sizeof(image_alt)); else if(strstr(input,";STOPPED;")) strncpy(image_alt,"Host exited from a period of scheduled downtime",sizeof(image_alt)); else if(strstr(input,";CANCELLED;")) strncpy(image_alt,"Host scheduled downtime has been cancelled",sizeof(image_alt)); } else if(display_system_messages==FALSE) continue; /* program start */ else if(strstr(input," starting...")){ strncpy(image,START_ICON,sizeof(image)); strncpy(image_alt,START_ICON_ALT,sizeof(image_alt)); system_message=TRUE; } /* normal program termination */ else if(strstr(input," shutting down...")){ strncpy(image,STOP_ICON,sizeof(image)); strncpy(image_alt,STOP_ICON_ALT,sizeof(image_alt)); system_message=TRUE; } /* abnormal program termination */ else if(strstr(input,"Bailing out")){ strncpy(image,STOP_ICON,sizeof(image)); strncpy(image_alt,STOP_ICON_ALT,sizeof(image_alt)); system_message=TRUE; } /* program restart */ else if(strstr(input," restarting...")){ strncpy(image,RESTART_ICON,sizeof(image)); strncpy(image_alt,RESTART_ICON_ALT,sizeof(image_alt)); system_message=TRUE; } image[sizeof(image)-1]='\x0'; image_alt[sizeof(image_alt)-1]='\x0'; /* get the timestamp */ temp_buffer=strtok(input,"]"); t=(temp_buffer==NULL)?0L:strtoul(temp_buffer+1,NULL,10); time_ptr=localtime(&t); strftime(current_message_date,sizeof(current_message_date),"%B %d, %Y %H:00\n",time_ptr); current_message_date[sizeof(current_message_date)-1]='\x0'; get_time_string(&t,date_time,sizeof(date_time),SHORT_DATE_TIME); strip(date_time); temp_buffer=strtok(NULL,"\n"); if(strcmp(image,"")){ display_line=FALSE; if(system_message==TRUE) display_line=TRUE; else if(display_type==DISPLAY_HOSTS){ if(history_type==HOST_HISTORY || history_type==SERVICE_HISTORY){ sprintf(match1," HOST ALERT: %s;",host_name); sprintf(match2," SERVICE ALERT: %s;",host_name); } else if(history_type==HOST_FLAPPING_HISTORY || history_type==SERVICE_FLAPPING_HISTORY){ sprintf(match1," HOST FLAPPING ALERT: %s;",host_name); sprintf(match2," SERVICE FLAPPING ALERT: %s;",host_name); } else if(history_type==HOST_DOWNTIME_HISTORY || history_type==SERVICE_DOWNTIME_HISTORY){ sprintf(match1," HOST DOWNTIME ALERT: %s;",host_name); sprintf(match2," SERVICE DOWNTIME ALERT: %s;",host_name); } if(show_all_hosts==TRUE) display_line=TRUE; else if(strstr(temp_buffer,match1)) display_line=TRUE; else if(strstr(temp_buffer,match2)) display_line=TRUE; if(display_line==TRUE){ if(history_options==HISTORY_ALL) display_line=TRUE; else if(history_options==HISTORY_HOST_ALL && (history_type==HOST_HISTORY || history_type==HOST_FLAPPING_HISTORY || history_type==HOST_DOWNTIME_HISTORY)) display_line=TRUE; else if(history_options==HISTORY_SERVICE_ALL && (history_type==SERVICE_HISTORY || history_type==SERVICE_FLAPPING_HISTORY || history_type==SERVICE_DOWNTIME_HISTORY)) display_line=TRUE; else if((history_type==HOST_HISTORY || history_type==SERVICE_HISTORY) && (history_detail_type & history_options)) display_line=TRUE; else display_line=FALSE; } /* check alert state types */ if(display_line==TRUE && (history_type==HOST_HISTORY || history_type==SERVICE_HISTORY)){ if(state_options==STATE_ALL) display_line=TRUE; else if((state_options & STATE_SOFT) && strstr(temp_buffer,";SOFT;")) display_line=TRUE; else if((state_options & STATE_HARD) && strstr(temp_buffer,";HARD;")) display_line=TRUE; else display_line=FALSE; } } else if(display_type==DISPLAY_SERVICES){ if(history_type==SERVICE_HISTORY) sprintf(match1," SERVICE ALERT: %s;%s;",host_name,svc_description); else if(history_type==SERVICE_FLAPPING_HISTORY) sprintf(match1," SERVICE FLAPPING ALERT: %s;%s;",host_name,svc_description); else if(history_type==SERVICE_DOWNTIME_HISTORY) sprintf(match1," SERVICE DOWNTIME ALERT: %s;%s;",host_name,svc_description); if(strstr(temp_buffer,match1) && (history_type==SERVICE_HISTORY || history_type==SERVICE_FLAPPING_HISTORY || history_type==SERVICE_DOWNTIME_HISTORY)) display_line=TRUE; if(display_line==TRUE){ if(history_options==HISTORY_ALL || history_options==HISTORY_SERVICE_ALL) display_line=TRUE; else if(history_options & history_detail_type) display_line=TRUE; else display_line=FALSE; } /* check alert state type */ if(display_line==TRUE && history_type==SERVICE_HISTORY){ if(state_options==STATE_ALL) display_line=TRUE; else if((state_options & STATE_SOFT) && strstr(temp_buffer,";SOFT;")) display_line=TRUE; else if((state_options & STATE_HARD) && strstr(temp_buffer,";HARD;")) display_line=TRUE; else display_line=FALSE; } } /* make sure user is authorized to view this host or service information */ if(system_message==FALSE){ if(history_type==HOST_HISTORY || history_type==HOST_FLAPPING_HISTORY || history_type==HOST_DOWNTIME_HISTORY){ temp_host=find_host(entry_host_name); if(is_authorized_for_host(temp_host,¤t_authdata)==FALSE) display_line=FALSE; } else{ temp_service=find_service(entry_host_name,entry_service_desc); if(is_authorized_for_service(temp_service,¤t_authdata)==FALSE) display_line=FALSE; } } /* display the entry if we should... */ if(display_line==TRUE){ if(strcmp(last_message_date,current_message_date)!=0 && display_timebreaks==TRUE){ printf("
    \n"); printf("
    \n"); printf(""); printf(""); printf("",current_message_date); printf(""); printf("

    %s
    \n"); printf("
    \n"); printf("
    \n"); strncpy(last_message_date,current_message_date,sizeof(last_message_date)); last_message_date[sizeof(last_message_date)-1]='\x0'; } if(display_frills==TRUE) printf("%s",url_images_path,image,image_alt,image_alt); printf("[%s] %s
    \n",date_time,temp_buffer); found_line=TRUE; } } } printf("

    \n"); if(found_line==FALSE){ printf("
    \n"); printf("

    No history information was found "); if(display_type==DISPLAY_HOSTS) printf("%s",(show_all_hosts==TRUE)?"":"for this host "); else printf("for this this service "); printf("in %s log file

    ",(log_archive==0)?"the current":"this archived"); } printf("
    \n"); free(input); if(use_lifo==TRUE) free_lifo_memory(); else mmap_fclose(thefile); return; } nagios-2.6/cgi/notifications.c0000664000076500007650000005764010512470706015774 0ustar nagiosnagios/************************************************************************ * * NOTIFICATIONS.C - Nagios Notifications CGI * * Copyright (c) 1999-2006 Ethan Galstad (nagios@nagios.org) * Last Modified: 10-09-2006 * * This CGI program will display the notification events for * a given host or contact or for all contacts/hosts. * * 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. ***********************************************************************/ #include "../include/config.h" #include "../include/common.h" #include "../include/getcgi.h" #include "../include/cgiutils.h" #include "../include/cgiauth.h" extern char main_config_file[MAX_FILENAME_LENGTH]; extern char url_html_path[MAX_FILENAME_LENGTH]; extern char url_images_path[MAX_FILENAME_LENGTH]; extern char url_docs_path[MAX_FILENAME_LENGTH]; extern char url_stylesheets_path[MAX_FILENAME_LENGTH]; extern int log_rotation_method; #define FIND_HOST 1 #define FIND_CONTACT 2 #define FIND_SERVICE 3 #define MAX_QUERYNAME_LENGTH 256 #define SERVICE_NOTIFICATION 0 #define HOST_NOTIFICATION 1 #define SERVICE_NOTIFICATION_STRING "] SERVICE NOTIFICATION:" #define HOST_NOTIFICATION_STRING "] HOST NOTIFICATION:" void display_notifications(void); void document_header(int); void document_footer(void); int process_cgivars(void); authdata current_authdata; char log_file_to_use[MAX_FILENAME_LENGTH]; int log_archive=0; int query_type=FIND_HOST; int find_all=TRUE; char *query_contact_name=""; char *query_host_name=""; char *query_svc_description=""; int notification_options=NOTIFICATION_ALL; int use_lifo=TRUE; int embedded=FALSE; int display_header=TRUE; int main(void){ int result=OK; char temp_buffer[MAX_INPUT_BUFFER]; char temp_buffer2[MAX_INPUT_BUFFER]; /* get the arguments passed in the URL */ process_cgivars(); /* reset internal variables */ reset_cgi_vars(); /* read the CGI configuration file */ result=read_cgi_config_file(get_cgi_config_location()); if(result==ERROR){ document_header(FALSE); cgi_config_file_error(get_cgi_config_location()); document_footer(); return ERROR; } /* read the main configuration file */ result=read_main_config_file(main_config_file); if(result==ERROR){ document_header(FALSE); main_config_file_error(main_config_file); document_footer(); return ERROR; } /* read all object configuration data */ result=read_all_object_configuration_data(main_config_file,READ_ALL_OBJECT_DATA); if(result==ERROR){ document_header(FALSE); object_data_error(); document_footer(); return ERROR; } document_header(TRUE); /* get authentication information */ get_authentication_information(¤t_authdata); /* determine what log file we should use */ get_log_archive_to_use(log_archive,log_file_to_use,(int)sizeof(log_file_to_use)); if(display_header==TRUE){ /* begin top table */ printf("\n"); printf("\n"); /* left column of top row */ printf("\n"); /* middle column of top row */ printf("\n"); /* right hand column of top row */ printf("\n"); /* end of top table */ printf("\n"); printf("
    \n"); if(query_type==FIND_SERVICE) snprintf(temp_buffer,sizeof(temp_buffer)-1,"Service Notifications"); else if(query_type==FIND_HOST){ if(find_all==TRUE) snprintf(temp_buffer,sizeof(temp_buffer)-1,"Notifications"); else snprintf(temp_buffer,sizeof(temp_buffer)-1,"Host Notifications"); } else snprintf(temp_buffer,sizeof(temp_buffer)-1,"Contact Notifications"); display_info_table(temp_buffer,FALSE,¤t_authdata); if(query_type==FIND_HOST || query_type==FIND_SERVICE){ printf("\n"); printf("\n"); printf("\n"); } printf("\n"); printf("
    \n"); if(query_type==FIND_SERVICE) printf("Service '%s' On Host '%s'",query_svc_description,query_host_name); else if(query_type==FIND_HOST){ if(find_all==TRUE) printf("All Hosts and Services"); else printf("Host '%s'",query_host_name); } else{ if(find_all==TRUE) printf("All Contacts"); else printf("Contact '%s'",query_contact_name); } printf("
    \n"); printf("
    \n"); if(query_type==FIND_SERVICE){ snprintf(temp_buffer,sizeof(temp_buffer)-1,"%s?%shost=%s&",NOTIFICATIONS_CGI,(use_lifo==FALSE)?"oldestfirst&":"",url_encode(query_host_name)); snprintf(temp_buffer2,sizeof(temp_buffer2)-1,"service=%s&type=%d&",url_encode(query_svc_description),notification_options); strncat(temp_buffer,temp_buffer2,sizeof(temp_buffer)-strlen(temp_buffer)-1); } else snprintf(temp_buffer,sizeof(temp_buffer)-1,"%s?%s%s=%s&type=%d&",NOTIFICATIONS_CGI,(use_lifo==FALSE)?"oldestfirst&":"",(query_type==FIND_HOST)?"host":"contact",(query_type==FIND_HOST)?url_encode(query_host_name):url_encode(query_contact_name),notification_options); temp_buffer[sizeof(temp_buffer)-1]='\x0'; display_nav_table(temp_buffer,log_archive); printf("
    \n"); printf("\n"); printf("\n",NOTIFICATIONS_CGI); if(query_type==FIND_SERVICE){ printf("\n",query_host_name); printf("\n",query_svc_description); } else printf("\n",(query_type==FIND_HOST)?"host":"contact",(query_type==FIND_HOST)?query_host_name:query_contact_name); printf("\n",log_archive); printf("\n"); if(query_type==FIND_SERVICE) printf(""); else printf("",(find_all==TRUE)?"all":"this",(query_type==FIND_HOST)?"host":"contact",(find_all==TRUE)?"s":""); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("",(use_lifo==FALSE)?"checked":""); printf("\n"); printf("\n"); /* display context-sensitive help */ printf("\n"); printf("\n"); printf("
    Notification detail level for this service:Notification detail level for %s %s%s:
    Older Entries First:
    \n"); display_context_help(CONTEXTHELP_NOTIFICATIONS); printf("
    \n"); printf("
    \n"); } /* display notifications */ display_notifications(); document_footer(); /* free allocated memory */ free_memory(); return OK; } void document_header(int use_stylesheet){ char date_time[MAX_DATETIME_LENGTH]; time_t current_time; time_t expire_time; printf("Cache-Control: no-store\r\n"); printf("Pragma: no-cache\r\n"); time(¤t_time); get_time_string(¤t_time,date_time,(int)sizeof(date_time),HTTP_DATE_TIME); printf("Last-Modified: %s\r\n",date_time); expire_time=(time_t)0L; get_time_string(&expire_time,date_time,(int)sizeof(date_time),HTTP_DATE_TIME); printf("Expires: %s\r\n",date_time); printf("Content-type: text/html\r\n\r\n"); if(embedded==TRUE) return; printf("\n"); printf("\n"); printf("\n"); printf("Alert Notifications\n"); printf("\n"); if(use_stylesheet==TRUE){ printf("\n",url_stylesheets_path,COMMON_CSS); printf("\n",url_stylesheets_path,NOTIFICATIONS_CSS); } printf("\n"); printf("\n"); /* include user SSI header */ include_ssi_files(NOTIFICATIONS_CGI,SSI_HEADER); return; } void document_footer(void){ if(embedded==TRUE) return; /* include user SSI footer */ include_ssi_files(NOTIFICATIONS_CGI,SSI_FOOTER); printf("\n"); printf("\n"); return; } int process_cgivars(void){ char **variables; int error=FALSE; int x; variables=getcgivars(); for(x=0;variables[x]!=NULL;x++){ /* do some basic length checking on the variable identifier to prevent buffer overflows */ if(strlen(variables[x])>=MAX_INPUT_BUFFER-1){ x++; continue; } /* we found the host argument */ else if(!strcmp(variables[x],"host")){ query_type=FIND_HOST; x++; if(variables[x]==NULL){ error=TRUE; break; } query_host_name=strdup(variables[x]); if(query_host_name==NULL) query_host_name=""; if(!strcmp(query_host_name,"all")) find_all=TRUE; else find_all=FALSE; } /* we found the contact argument */ else if(!strcmp(variables[x],"contact")){ query_type=FIND_CONTACT; x++; if(variables[x]==NULL){ error=TRUE; break; } query_contact_name=strdup(variables[x]); if(query_contact_name==NULL) query_contact_name=""; if(!strcmp(query_contact_name,"all")) find_all=TRUE; else find_all=FALSE; } /* we found the service argument */ else if(!strcmp(variables[x],"service")){ query_type=FIND_SERVICE; x++; if(variables[x]==NULL){ error=TRUE; break; } query_svc_description=strdup(variables[x]); if(query_svc_description==NULL) query_svc_description=""; } /* we found the notification type argument */ else if(!strcmp(variables[x],"type")){ x++; if(variables[x]==NULL){ error=TRUE; break; } notification_options=atoi(variables[x]); } /* we found the log archive argument */ else if(!strcmp(variables[x],"archive")){ x++; if(variables[x]==NULL){ error=TRUE; break; } log_archive=atoi(variables[x]); if(log_archive<0) log_archive=0; } /* we found the order argument */ else if(!strcmp(variables[x],"oldestfirst")){ use_lifo=FALSE; } /* we found the embed option */ else if(!strcmp(variables[x],"embedded")) embedded=TRUE; /* we found the noheader option */ else if(!strcmp(variables[x],"noheader")) display_header=FALSE; } /* free memory allocated to the CGI variables */ free_cgivars(variables); return error; } void display_notifications(void){ mmapfile *thefile; char *input=NULL; char *temp_buffer; char date_time[MAX_DATETIME_LENGTH]; char alert_level[MAX_INPUT_BUFFER]; char alert_level_class[MAX_INPUT_BUFFER]; char contact_name[MAX_INPUT_BUFFER]; char service_name[MAX_INPUT_BUFFER]; char host_name[MAX_INPUT_BUFFER]; char method_name[MAX_INPUT_BUFFER]; int show_entry; int total_notifications; int notification_type=SERVICE_NOTIFICATION; int notification_detail_type=NOTIFICATION_SERVICE_CRITICAL; int odd=0; time_t t; host *temp_host; service *temp_service; int result; if(use_lifo==TRUE){ result=read_file_into_lifo(log_file_to_use); if(result!=LIFO_OK){ if(result==LIFO_ERROR_MEMORY){ printf("

    Not enough memory to reverse log file - displaying notifications in natural order...

    "); } else if(result==LIFO_ERROR_FILE){ printf("

    Error: Cannot open log file '%s' for reading!

    ",log_file_to_use); return; } use_lifo=FALSE; } } if(use_lifo==FALSE){ if((thefile=mmap_fopen(log_file_to_use))==NULL){ printf("

    Error: Cannot open log file '%s' for reading!

    ",log_file_to_use); return; } } printf("

    \n"); printf("

    \n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); total_notifications=0; while(1){ free(input); if(use_lifo==TRUE){ if((input=pop_lifo())==NULL) break; } else{ if((input=mmap_fgets(thefile))==NULL) break; } strip(input); /* see if this line contains the notification event string */ if(strstr(input,HOST_NOTIFICATION_STRING)||strstr(input,SERVICE_NOTIFICATION_STRING)){ if(strstr(input,HOST_NOTIFICATION_STRING)) notification_type=HOST_NOTIFICATION; else notification_type=SERVICE_NOTIFICATION; /* get the date/time */ temp_buffer=(char *)strtok(input,"]"); t=(time_t)(temp_buffer==NULL)?0L:strtoul(temp_buffer+1,NULL,10); get_time_string(&t,date_time,(int)sizeof(date_time),SHORT_DATE_TIME); strip(date_time); /* get the contact name */ temp_buffer=(char *)strtok(NULL,":"); temp_buffer=(char *)strtok(NULL,";"); snprintf(contact_name,sizeof(contact_name),"%s",(temp_buffer==NULL)?"":temp_buffer+1); contact_name[sizeof(contact_name)-1]='\x0'; /* get the host name */ temp_buffer=(char *)strtok(NULL,";"); snprintf(host_name,sizeof(host_name),"%s",(temp_buffer==NULL)?"":temp_buffer); host_name[sizeof(host_name)-1]='\x0'; /* get the service name */ if(notification_type==SERVICE_NOTIFICATION){ temp_buffer=(char *)strtok(NULL,";"); snprintf(service_name,sizeof(service_name),"%s",(temp_buffer==NULL)?"":temp_buffer); service_name[sizeof(service_name)-1]='\x0'; } /* get the alert level */ temp_buffer=(char *)strtok(NULL,";"); snprintf(alert_level,sizeof(alert_level),"%s",(temp_buffer==NULL)?"":temp_buffer); alert_level[sizeof(alert_level)-1]='\x0'; if(notification_type==SERVICE_NOTIFICATION){ if(!strcmp(alert_level,"CRITICAL")){ notification_detail_type=NOTIFICATION_SERVICE_CRITICAL; strcpy(alert_level_class,"CRITICAL"); } else if(!strcmp(alert_level,"WARNING")){ notification_detail_type=NOTIFICATION_SERVICE_WARNING; strcpy(alert_level_class,"WARNING"); } else if(!strcmp(alert_level,"RECOVERY") || !strcmp(alert_level,"OK")){ strcpy(alert_level,"OK"); notification_detail_type=NOTIFICATION_SERVICE_RECOVERY; strcpy(alert_level_class,"OK"); } else if(strstr(alert_level,"ACKNOWLEDGEMENT (")){ notification_detail_type=NOTIFICATION_SERVICE_ACK; strcpy(alert_level_class,"ACKNOWLEDGEMENT"); } else if(strstr(alert_level,"FLAPPINGSTART (")){ strcpy(alert_level,"FLAPPING START"); notification_detail_type=NOTIFICATION_SERVICE_FLAP; strcpy(alert_level_class,"UNKNOWN"); } else if(strstr(alert_level,"FLAPPINGSTOP (")){ strcpy(alert_level,"FLAPPING STOP"); notification_detail_type=NOTIFICATION_SERVICE_FLAP; strcpy(alert_level_class,"UNKNOWN"); } else{ strcpy(alert_level,"UNKNOWN"); notification_detail_type=NOTIFICATION_SERVICE_UNKNOWN; strcpy(alert_level_class,"UNKNOWN"); } } else{ if(!strcmp(alert_level,"DOWN")){ strncpy(alert_level,"HOST DOWN",sizeof(alert_level)); strcpy(alert_level_class,"HOSTDOWN"); notification_detail_type=NOTIFICATION_HOST_DOWN; } else if(!strcmp(alert_level,"UNREACHABLE")){ strncpy(alert_level,"HOST UNREACHABLE",sizeof(alert_level)); strcpy(alert_level_class,"HOSTUNREACHABLE"); notification_detail_type=NOTIFICATION_HOST_UNREACHABLE; } else if(!strcmp(alert_level,"RECOVERY") || !strcmp(alert_level,"UP")){ strncpy(alert_level,"HOST UP",sizeof(alert_level)); strcpy(alert_level_class,"HOSTUP"); notification_detail_type=NOTIFICATION_HOST_RECOVERY; } else if(strstr(alert_level,"ACKNOWLEDGEMENT (")){ strcpy(alert_level_class,"HOSTACKNOWLEDGEMENT"); notification_detail_type=NOTIFICATION_HOST_ACK; } else if(strstr(alert_level,"FLAPPINGSTART (")){ strcpy(alert_level,"FLAPPING START"); strcpy(alert_level_class,"UNKNOWN"); notification_detail_type=NOTIFICATION_HOST_FLAP; } else if(strstr(alert_level,"FLAPPINGSTOP (")){ strcpy(alert_level,"FLAPPING STOP"); strcpy(alert_level_class,"UNKNOWN"); notification_detail_type=NOTIFICATION_HOST_FLAP; } } /* get the method name */ temp_buffer=(char *)strtok(NULL,";"); snprintf(method_name,sizeof(method_name),"%s",(temp_buffer==NULL)?"":temp_buffer); method_name[sizeof(method_name)-1]='\x0'; /* move to the informational message */ temp_buffer=strtok(NULL,";"); show_entry=FALSE; /* if we're searching by contact, filter out unwanted contact */ if(query_type==FIND_CONTACT){ if(find_all==TRUE) show_entry=TRUE; else if(!strcmp(query_contact_name,contact_name)) show_entry=TRUE; } else if(query_type==FIND_HOST){ if(find_all==TRUE) show_entry=TRUE; else if(!strcmp(query_host_name,host_name)) show_entry=TRUE; } else if(query_type==FIND_SERVICE){ if(!strcmp(query_host_name,host_name) && !strcmp(query_svc_description,service_name)) show_entry=TRUE; } if(show_entry==TRUE){ if(notification_options==NOTIFICATION_ALL) show_entry=TRUE; else if(notification_options==NOTIFICATION_HOST_ALL && notification_type==HOST_NOTIFICATION) show_entry=TRUE; else if(notification_options==NOTIFICATION_SERVICE_ALL && notification_type==SERVICE_NOTIFICATION) show_entry=TRUE; else if(notification_detail_type & notification_options) show_entry=TRUE; else show_entry=FALSE; } /* make sure user has authorization to view this notification */ if(notification_type==HOST_NOTIFICATION){ temp_host=find_host(host_name); if(is_authorized_for_host(temp_host,¤t_authdata)==FALSE) show_entry=FALSE; } else{ temp_service=find_service(host_name,service_name); if(is_authorized_for_service(temp_service,¤t_authdata)==FALSE) show_entry=FALSE; } if(show_entry==TRUE){ total_notifications++; if(odd){ odd=0; printf("\n"); } else{ odd=1; printf("\n"); } printf("\n",(odd)?"Even":"Odd",EXTINFO_CGI,DISPLAY_HOST_INFO,url_encode(host_name),host_name); if(notification_type==SERVICE_NOTIFICATION){ printf("\n",url_encode(service_name),service_name); } else printf("\n",(odd)?"Even":"Odd"); printf("\n",alert_level_class,alert_level); printf("\n",(odd)?"Even":"Odd",date_time); printf("\n",(odd)?"Even":"Odd",CONFIG_CGI,url_encode(contact_name),contact_name); printf("\n",(odd)?"Even":"Odd",CONFIG_CGI,url_encode(method_name),method_name); printf("\n",(odd)?"Even":"Odd",temp_buffer); printf("\n"); } } } printf("
    HostServiceTypeTimeContactNotification CommandInformation
    %s%sN/A%s%s%s%s%s
    \n"); printf("
    \n"); printf("

    \n"); if(total_notifications==0){ printf("

    No notifications have been recorded"); if(find_all==FALSE){ if(query_type==FIND_SERVICE) printf(" for this service"); else if(query_type==FIND_CONTACT) printf(" for this contact"); else printf(" for this host"); } printf(" in %s log file

    ",(log_archive==0)?"the current":"this archived"); } free(input); if(use_lifo==TRUE) free_lifo_memory(); else mmap_fclose(thefile); return; } nagios-2.6/cgi/outages.c0000664000076500007650000004776310410070302014560 0ustar nagiosnagios/************************************************************************** * * OUTAGES.C - Nagios Network Outages CGI * * Copyright (c) 1999-2006 Ethan Galstad (nagios@nagios.org) * Last Modified: 03-21-2006 * * 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. *************************************************************************/ #include "../include/config.h" #include "../include/common.h" #include "../include/objects.h" #include "../include/comments.h" #include "../include/statusdata.h" #include "../include/cgiutils.h" #include "../include/getcgi.h" #include "../include/cgiauth.h" extern int refresh_rate; extern time_t program_start; extern host *host_list; extern service *service_list; extern hoststatus *hoststatus_list; extern servicestatus *servicestatus_list; extern char main_config_file[MAX_FILENAME_LENGTH]; extern char url_html_path[MAX_FILENAME_LENGTH]; extern char url_stylesheets_path[MAX_FILENAME_LENGTH]; extern char url_images_path[MAX_FILENAME_LENGTH]; extern char url_logo_images_path[MAX_FILENAME_LENGTH]; extern char log_file[MAX_FILENAME_LENGTH]; /* HOSTOUTAGE structure */ typedef struct hostoutage_struct{ host *hst; int severity; int affected_child_hosts; int affected_child_services; unsigned long monitored_time; unsigned long time_up; float percent_time_up; unsigned long time_down; float percent_time_down; unsigned long time_unreachable; float percent_time_unreachable; struct hostoutage_struct *next; }hostoutage; /* HOSTOUTAGESORT structure */ typedef struct hostoutagesort_struct{ hostoutage *outage; struct hostoutagesort_struct *next; }hostoutagesort; void document_header(int); void document_footer(void); int process_cgivars(void); void display_network_outages(void); void find_hosts_causing_outages(void); void calculate_outage_effects(void); void calculate_outage_effect_of_host(host *,int *,int *); int is_route_to_host_blocked(host *); int number_of_host_services(host *); void add_hostoutage(host *); void sort_hostoutages(void); void free_hostoutage_list(void); void free_hostoutagesort_list(void); authdata current_authdata; hostoutage *hostoutage_list=NULL; hostoutagesort *hostoutagesort_list=NULL; int service_severity_divisor=4; /* default = services are 1/4 as important as hosts */ int embedded=FALSE; int display_header=TRUE; int main(void){ int result=OK; /* get the arguments passed in the URL */ process_cgivars(); /* reset internal variables */ reset_cgi_vars(); /* read the CGI configuration file */ result=read_cgi_config_file(get_cgi_config_location()); if(result==ERROR){ document_header(FALSE); cgi_config_file_error(get_cgi_config_location()); document_footer(); return ERROR; } /* read the main configuration file */ result=read_main_config_file(main_config_file); if(result==ERROR){ document_header(FALSE); main_config_file_error(main_config_file); document_footer(); return ERROR; } /* read all object configuration data */ result=read_all_object_configuration_data(main_config_file,READ_ALL_OBJECT_DATA); if(result==ERROR){ document_header(FALSE); object_data_error(); document_footer(); return ERROR; } /* read all status data */ result=read_all_status_data(get_cgi_config_location(),READ_ALL_STATUS_DATA); if(result==ERROR){ document_header(FALSE); status_data_error(); document_footer(); free_memory(); return ERROR; } document_header(TRUE); /* read in all host and service comments */ read_comment_data(get_cgi_config_location()); /* get authentication information */ get_authentication_information(¤t_authdata); if(display_header==TRUE){ /* begin top table */ printf("\n"); printf("\n"); /* left column of the first row */ printf("\n"); /* middle column of top row */ printf("\n"); /* right column of top row */ printf("\n"); /* end of top table */ printf("\n"); printf("
    \n"); display_info_table("Network Outages",TRUE,¤t_authdata); printf("\n"); printf("\n"); /* display context-sensitive help */ display_context_help(CONTEXTHELP_OUTAGES); printf("
    \n"); } /* display network outage info */ display_network_outages(); document_footer(); /* free memory allocated to comment data */ free_comment_data(); /* free all allocated memory */ free_memory(); return OK; } void document_header(int use_stylesheet){ char date_time[MAX_DATETIME_LENGTH]; time_t current_time; time_t expire_time; printf("Cache-Control: no-store\r\n"); printf("Pragma: no-cache\r\n"); printf("Refresh: %d\r\n",refresh_rate); time(¤t_time); get_time_string(¤t_time,date_time,(int)sizeof(date_time),HTTP_DATE_TIME); printf("Last-Modified: %s\r\n",date_time); expire_time=(time_t)0L; get_time_string(&expire_time,date_time,(int)sizeof(date_time),HTTP_DATE_TIME); printf("Expires: %s\r\n",date_time); printf("Content-type: text/html\r\n\r\n"); if(embedded==TRUE) return; printf("\n"); printf("\n"); printf("\n"); printf("Network Outages\n"); printf("\n"); if(use_stylesheet==TRUE){ printf("",url_stylesheets_path,COMMON_CSS); printf("",url_stylesheets_path,OUTAGES_CSS); } printf("\n"); printf("\n"); /* include user SSI header */ include_ssi_files(OUTAGES_CGI,SSI_HEADER); return; } void document_footer(void){ if(embedded==TRUE) return; /* include user SSI footer */ include_ssi_files(OUTAGES_CGI,SSI_FOOTER); printf("\n"); printf("\n"); return; } int process_cgivars(void){ char **variables; int error=FALSE; int x; variables=getcgivars(); for(x=0;variables[x]!=NULL;x++){ /* do some basic length checking on the variable identifier to prevent buffer overflows */ if(strlen(variables[x])>=MAX_INPUT_BUFFER-1){ x++; continue; } /* we found the service severity divisor option */ if(!strcmp(variables[x],"service_divisor")){ x++; if(variables[x]==NULL){ error=TRUE; break; } service_severity_divisor=atoi(variables[x]); if(service_severity_divisor<1) service_severity_divisor=1; } /* we found the embed option */ else if(!strcmp(variables[x],"embedded")) embedded=TRUE; /* we found the noheader option */ else if(!strcmp(variables[x],"noheader")) display_header=FALSE; } /* free memory allocated to the CGI variables */ free_cgivars(variables); return error; } /* shows all hosts that are causing network outages */ void display_network_outages(void){ char temp_buffer[MAX_INPUT_BUFFER]; int number_of_problem_hosts=0; int number_of_blocking_problem_hosts=0; hostoutagesort *temp_hostoutagesort; hostoutage *temp_hostoutage; hoststatus *temp_hoststatus; int odd=0; char *bg_class=""; char *status=""; int days; int hours; int minutes; int seconds; int total_comments; time_t t; time_t current_time; char state_duration[48]; int total_entries=0; /* user must be authorized for all hosts.. */ if(is_authorized_for_all_hosts(¤t_authdata)==FALSE){ printf("

    It appears as though you do not have permission to view information you requested...

    \n"); printf("

    If you believe this is an error, check the HTTP server authentication requirements for accessing this CGI
    "); printf("and check the authorization options in your CGI configuration file.

    \n"); return; } /* find all hosts that are causing network outages */ find_hosts_causing_outages(); /* calculate outage effects */ calculate_outage_effects(); /* sort the outage list by severity */ sort_hostoutages(); /* count the number of top-level hosts that are down and the ones that are actually blocking children hosts */ for(temp_hostoutage=hostoutage_list;temp_hostoutage!=NULL;temp_hostoutage=temp_hostoutage->next){ number_of_problem_hosts++; if(temp_hostoutage->affected_child_hosts>1) number_of_blocking_problem_hosts++; } /* display the problem hosts... */ printf("

    \n"); printf("
    Blocking Outages
    \n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); for(temp_hostoutagesort=hostoutagesort_list;temp_hostoutagesort!=NULL;temp_hostoutagesort=temp_hostoutagesort->next){ temp_hostoutage=temp_hostoutagesort->outage; if(temp_hostoutage==NULL) continue; /* skip hosts that are not blocking anyone */ if(temp_hostoutage->affected_child_hosts<=1) continue; temp_hoststatus=find_hoststatus(temp_hostoutage->hst->name); if(temp_hoststatus==NULL) continue; /* make sure we only caught valid state types */ if(temp_hoststatus->status!=HOST_DOWN && temp_hoststatus->status!=HOST_UNREACHABLE) continue; total_entries++; if(odd==0){ odd=1; bg_class="dataOdd"; } else{ odd=0; bg_class="dataEven"; } if(temp_hoststatus->status==HOST_UNREACHABLE) status="UNREACHABLE"; else if(temp_hoststatus->status==HOST_DOWN) status="DOWN"; printf("\n",bg_class); printf("\n",bg_class,temp_hostoutage->severity); printf("\n",bg_class,EXTINFO_CGI,DISPLAY_HOST_INFO,url_encode(temp_hostoutage->hst->name),temp_hostoutage->hst->name); printf("\n",status,status); total_comments=number_of_host_comments(temp_hostoutage->hst->name); if(total_comments>0){ snprintf(temp_buffer,sizeof(temp_buffer)-1,"This host has %d comment%s associated with it",total_comments,(total_comments==1)?"":"s"); temp_buffer[sizeof(temp_buffer)-1]='\x0'; printf("\n",bg_class,EXTINFO_CGI,DISPLAY_HOST_INFO,url_encode(temp_hostoutage->hst->name),url_images_path,COMMENT_ICON,temp_buffer,temp_buffer); } else printf("\n",bg_class); current_time=time(NULL); if(temp_hoststatus->last_state_change==(time_t)0) t=current_time-program_start; else t=current_time-temp_hoststatus->last_state_change; get_time_breakdown((unsigned long)t,&days,&hours,&minutes,&seconds); snprintf(state_duration,sizeof(state_duration)-1,"%2dd %2dh %2dm %2ds%s",days,hours,minutes,seconds,(temp_hoststatus->last_state_change==(time_t)0)?"+":""); state_duration[sizeof(state_duration)-1]='\x0'; printf("\n",bg_class,state_duration); printf("\n",bg_class,temp_hostoutage->affected_child_hosts); printf("\n",bg_class,temp_hostoutage->affected_child_services); printf("\n"); printf("\n"); } printf("
    SeverityHostStateNotesState Duration# Hosts Affected# Services AffectedActions
    %d%s%s%sN/A%s%d%d",bg_class); printf("View status detail for this host\n",STATUS_CGI,url_encode(temp_hostoutage->hst->name),url_images_path,STATUS_DETAIL_ICON); #ifdef USE_STATUSMAP printf("View status map for this host and its children\n",STATUSMAP_CGI,url_encode(temp_hostoutage->hst->name),url_images_path,STATUSMAP_ICON); #endif #ifdef USE_STATUSWRL printf("View 3-D status map for this host and its children\n",STATUSWORLD_CGI,url_encode(temp_hostoutage->hst->name),url_images_path,STATUSWORLD_ICON); #endif #ifdef USE_TRENDS printf("View trends for this host\n",TRENDS_CGI,url_encode(temp_hostoutage->hst->name),url_images_path,TRENDS_ICON); #endif printf("View alert history for this host\n",HISTORY_CGI,url_encode(temp_hostoutage->hst->name),url_images_path,HISTORY_ICON); printf("View notifications for this host\n",NOTIFICATIONS_CGI,url_encode(temp_hostoutage->hst->name),url_images_path,NOTIFICATION_ICON); printf("
    \n"); printf("

    \n"); if(total_entries==0) printf("
    %d Blocking Outages Displayed
    \n",total_entries); /* free memory allocated to the host outage list */ free_hostoutage_list(); free_hostoutagesort_list(); return; } /* determine what hosts are causing network outages */ void find_hosts_causing_outages(void){ hoststatus *temp_hoststatus; host *temp_host; /* check all hosts */ for(temp_hoststatus=hoststatus_list;temp_hoststatus!=NULL;temp_hoststatus=temp_hoststatus->next){ /* check only hosts that are not up and not pending */ if(temp_hoststatus->status!=HOST_UP && temp_hoststatus->status!=HOST_PENDING){ /* find the host entry */ temp_host=find_host(temp_hoststatus->host_name); if(temp_host==NULL) continue; /* if the route to this host is not blocked, it is a causing an outage */ if(is_route_to_host_blocked(temp_host)==FALSE) add_hostoutage(temp_host); } } return; } /* adds a host outage entry */ void add_hostoutage(host *hst){ hostoutage *new_hostoutage; /* allocate memory for a new structure */ new_hostoutage=(hostoutage *)malloc(sizeof(hostoutage)); if(new_hostoutage==NULL) return; new_hostoutage->hst=hst; new_hostoutage->severity=0; new_hostoutage->affected_child_hosts=0; new_hostoutage->affected_child_services=0; /* add the structure to the head of the list in memory */ new_hostoutage->next=hostoutage_list; hostoutage_list=new_hostoutage; return; } /* frees all memory allocated to the host outage list */ void free_hostoutage_list(void){ hostoutage *this_hostoutage; hostoutage *next_hostoutage; /* free all list members */ for(this_hostoutage=hostoutage_list;this_hostoutage!=NULL;this_hostoutage=next_hostoutage){ next_hostoutage=this_hostoutage->next; free(this_hostoutage); } /* reset list pointer */ hostoutage_list=NULL; return; } /* frees all memory allocated to the host outage sort list */ void free_hostoutagesort_list(void){ hostoutagesort *this_hostoutagesort; hostoutagesort *next_hostoutagesort; /* free all list members */ for(this_hostoutagesort=hostoutagesort_list;this_hostoutagesort!=NULL;this_hostoutagesort=next_hostoutagesort){ next_hostoutagesort=this_hostoutagesort->next; free(this_hostoutagesort); } /* reset list pointer */ hostoutagesort_list=NULL; return; } /* calculates network outage effect of all hosts that are causing blockages */ void calculate_outage_effects(void){ hostoutage *temp_hostoutage; /* check all hosts causing problems */ for(temp_hostoutage=hostoutage_list;temp_hostoutage!=NULL;temp_hostoutage=temp_hostoutage->next){ /* calculate the outage effect of this particular hosts */ calculate_outage_effect_of_host(temp_hostoutage->hst,&temp_hostoutage->affected_child_hosts,&temp_hostoutage->affected_child_services); temp_hostoutage->severity=(temp_hostoutage->affected_child_hosts+(temp_hostoutage->affected_child_services/service_severity_divisor)); } return; } /* calculates network outage effect of a particular host being down or unreachable */ void calculate_outage_effect_of_host(host *hst, int *affected_hosts, int *affected_services){ int total_child_hosts_affected=0; int total_child_services_affected=0; int temp_child_hosts_affected=0; int temp_child_services_affected=0; host *temp_host; /* find all child hosts of this host */ for(temp_host=host_list;temp_host!=NULL;temp_host=temp_host->next){ /* skip this host if it is not a child */ if(is_host_immediate_child_of_host(hst,temp_host)==FALSE) continue; /* calculate the outage effect of the child */ calculate_outage_effect_of_host(temp_host,&temp_child_hosts_affected,&temp_child_services_affected); /* keep a running total of outage effects */ total_child_hosts_affected+=temp_child_hosts_affected; total_child_services_affected+=temp_child_services_affected; } *affected_hosts=total_child_hosts_affected+1; *affected_services=total_child_services_affected+number_of_host_services(hst); return; } /* tests whether or not a host is "blocked" by upstream parents (host is already assumed to be down or unreachable) */ int is_route_to_host_blocked(host *hst){ hostsmember *temp_hostsmember; hoststatus *temp_hoststatus; /* if the host has no parents, it is not being blocked by anyone */ if(hst->parent_hosts==NULL) return FALSE; /* check all parent hosts */ for(temp_hostsmember=hst->parent_hosts;temp_hostsmember!=NULL;temp_hostsmember=temp_hostsmember->next){ /* find the parent host's status */ temp_hoststatus=find_hoststatus(temp_hostsmember->host_name); if(temp_hoststatus==NULL) continue; /* at least one parent it up (or pending), so this host is not blocked */ if(temp_hoststatus->status==HOST_UP || temp_hoststatus->status==HOST_PENDING) return FALSE; } return TRUE; } /* calculates the number of services associated a particular host */ int number_of_host_services(host *hst){ int total_services=0; service *temp_service; /* check all services */ for(temp_service=service_list;temp_service!=NULL;temp_service=temp_service->next){ if(!strcmp(temp_service->host_name,hst->name)) total_services++; } return total_services; } /* sort the host outages by severity */ void sort_hostoutages(void){ hostoutagesort *last_hostoutagesort; hostoutagesort *new_hostoutagesort; hostoutagesort *temp_hostoutagesort; hostoutage *temp_hostoutage; if(hostoutage_list==NULL) return; /* sort all host outage entries */ for(temp_hostoutage=hostoutage_list;temp_hostoutage!=NULL;temp_hostoutage=temp_hostoutage->next){ /* allocate memory for a new sort structure */ new_hostoutagesort=(hostoutagesort *)malloc(sizeof(hostoutagesort)); if(new_hostoutagesort==NULL) return; new_hostoutagesort->outage=temp_hostoutage; last_hostoutagesort=hostoutagesort_list; for(temp_hostoutagesort=hostoutagesort_list;temp_hostoutagesort!=NULL;temp_hostoutagesort=temp_hostoutagesort->next){ if(new_hostoutagesort->outage->severity >= temp_hostoutagesort->outage->severity){ new_hostoutagesort->next=temp_hostoutagesort; if(temp_hostoutagesort==hostoutagesort_list) hostoutagesort_list=new_hostoutagesort; else last_hostoutagesort->next=new_hostoutagesort; break; } else last_hostoutagesort=temp_hostoutagesort; } if(hostoutagesort_list==NULL){ new_hostoutagesort->next=NULL; hostoutagesort_list=new_hostoutagesort; } else if(temp_hostoutagesort==NULL){ new_hostoutagesort->next=NULL; last_hostoutagesort->next=new_hostoutagesort; } } return; } nagios-2.6/cgi/showlog.c0000664000076500007650000003704310410070302014561 0ustar nagiosnagios/*********************************************************************** * * SHOWLOG.C - Nagios Log File CGI * * Copyright (c) 1999-2006 Ethan Galstad (nagios@nagios.org) * Last Modified: 03-21-2006 * * This CGI program will display the contents of the Nagios * log file. * * 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. ***********************************************************************/ #include "../include/config.h" #include "../include/common.h" #include "../include/objects.h" #include "../include/getcgi.h" #include "../include/cgiutils.h" #include "../include/cgiauth.h" extern char main_config_file[MAX_FILENAME_LENGTH]; extern char url_images_path[MAX_FILENAME_LENGTH]; extern char url_stylesheets_path[MAX_FILENAME_LENGTH]; extern int log_rotation_method; void document_header(int); void document_footer(void); int process_cgivars(void); authdata current_authdata; int display_log(void); char log_file_to_use[MAX_FILENAME_LENGTH]=""; int log_archive=0; int use_lifo=TRUE; int embedded=FALSE; int display_header=TRUE; int display_frills=TRUE; int display_timebreaks=TRUE; int main(void){ int result=OK; char temp_buffer[MAX_INPUT_BUFFER]; /* get the CGI variables passed in the URL */ process_cgivars(); /* reset internal variables */ reset_cgi_vars(); /* read the CGI configuration file */ result=read_cgi_config_file(get_cgi_config_location()); if(result==ERROR){ document_header(FALSE); cgi_config_file_error(get_cgi_config_location()); document_footer(); return ERROR; } /* read the main configuration file */ result=read_main_config_file(main_config_file); if(result==ERROR){ document_header(FALSE); main_config_file_error(main_config_file); document_footer(); return ERROR; } /* read all object configuration data */ result=read_all_object_configuration_data(main_config_file,READ_ALL_OBJECT_DATA); if(result==ERROR){ document_header(FALSE); object_data_error(); document_footer(); return ERROR; } document_header(TRUE); /* get authentication information */ get_authentication_information(¤t_authdata); /* determine what log file we should be using */ get_log_archive_to_use(log_archive,log_file_to_use,(int)sizeof(log_file_to_use)); if(display_header==TRUE){ /* begin top table */ printf("\n"); printf("\n"); /* left column of top table - info box */ printf("\n"); /* middle column of top table - log file navigation options */ printf("\n"); /* right hand column of top row */ printf("\n"); /* end of top table */ printf("\n"); printf("
    \n"); display_info_table((log_rotation_method==LOG_ROTATION_NONE || log_archive==0)?"Current Event Log":"Archived Event Log",FALSE,¤t_authdata); printf("\n"); snprintf(temp_buffer,sizeof(temp_buffer)-1,"%s?%s",SHOWLOG_CGI,(use_lifo==FALSE)?"oldestfirst&":""); temp_buffer[sizeof(temp_buffer)-1]='\x0'; display_nav_table(temp_buffer,log_archive); printf("\n"); printf("\n"); printf("\n",SHOWLOG_CGI); printf("\n",log_archive); printf(""); printf("",(use_lifo==FALSE)?"checked":""); printf("\n"); printf(""); printf("\n"); printf("\n"); /* display context-sensitive help */ printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("
    Older Entries First:
    \n"); display_context_help(CONTEXTHELP_LOG); printf("
    \n"); printf("
    \n"); printf("

    \n"); } /* display the contents of the log file */ display_log(); document_footer(); /* free allocated memory */ free_memory(); return OK; } void document_header(int use_stylesheet){ char date_time[MAX_DATETIME_LENGTH]; time_t current_time; time_t expire_time; printf("Cache-Control: no-store\r\n"); printf("Pragma: no-cache\r\n"); time(¤t_time); get_time_string(¤t_time,date_time,(int)sizeof(date_time),HTTP_DATE_TIME); printf("Last-Modified: %s\r\n",date_time); expire_time=(time_t)0L; get_time_string(&expire_time,date_time,(int)sizeof(date_time),HTTP_DATE_TIME); printf("Expires: %s\r\n",date_time); printf("Content-type: text/html\r\n\r\n"); if(embedded==TRUE) return; printf("\n"); printf("\n"); printf("\n"); printf("Nagios Log File\n"); printf("\n"); if(use_stylesheet==TRUE){ printf("\n",url_stylesheets_path,COMMON_CSS); printf("\n",url_stylesheets_path,SHOWLOG_CSS); } printf("\n"); printf("\n"); /* include user SSI header */ include_ssi_files(SHOWLOG_CGI,SSI_HEADER); return; } void document_footer(void){ if(embedded==TRUE) return; /* include user SSI footer */ include_ssi_files(SHOWLOG_CGI,SSI_FOOTER); printf("\n"); printf("\n"); return; } int process_cgivars(void){ char **variables; int error=FALSE; int x; variables=getcgivars(); for(x=0;variables[x]!=NULL;x++){ /* do some basic length checking on the variable identifier to prevent buffer overflows */ if(strlen(variables[x])>=MAX_INPUT_BUFFER-1){ continue; } /* we found the archive argument */ else if(!strcmp(variables[x],"archive")){ x++; if(variables[x]==NULL){ error=TRUE; break; } log_archive=atoi(variables[x]); if(log_archive<0) log_archive=0; } /* we found the order argument */ else if(!strcmp(variables[x],"oldestfirst")){ use_lifo=FALSE; } /* we found the embed option */ else if(!strcmp(variables[x],"embedded")) embedded=TRUE; /* we found the noheader option */ else if(!strcmp(variables[x],"noheader")) display_header=FALSE; /* we found the nofrills option */ else if (!strcmp(variables[x],"nofrills")) display_frills=FALSE; /* we found the notimebreaks option */ else if(!strcmp(variables[x],"notimebreaks")) display_timebreaks=FALSE; /* we received an invalid argument */ else error=TRUE; } /* free memory allocated to the CGI variables */ free_cgivars(variables); return error; } /* display the contents of the log file */ int display_log(void){ char *input=NULL; char image[MAX_INPUT_BUFFER]; char image_alt[MAX_INPUT_BUFFER]; time_t t; char *temp_buffer; char date_time[MAX_DATETIME_LENGTH]; int error; mmapfile *thefile; char last_message_date[MAX_INPUT_BUFFER]=""; char current_message_date[MAX_INPUT_BUFFER]=""; struct tm *time_ptr; /* check to see if the user is authorized to view the log file */ if(is_authorized_for_system_information(¤t_authdata)==FALSE){ printf("
    \n"); printf("
    It appears as though you do not have permission to view the log file...


    \n"); printf("
    If you believe this is an error, check the HTTP server authentication requirements for accessing this CGI
    and check the authorization options in your CGI configuration file.
    \n"); printf("
    \n"); return ERROR; } error=FALSE; if(use_lifo==TRUE){ error=read_file_into_lifo(log_file_to_use); if(error!=LIFO_OK){ if(error==LIFO_ERROR_MEMORY){ printf("

    Not enough memory to reverse log file - displaying log in natural order...

    "); error=FALSE; } else error=TRUE; use_lifo=FALSE; } else error=FALSE; } if(use_lifo==FALSE){ if((thefile=mmap_fopen(log_file_to_use))==NULL){ printf("
    \n"); printf("

    Error: Could not open log file '%s' for reading!

    ",log_file_to_use); printf("
    \n"); error=TRUE; } } if(error==FALSE){ printf("

    \n"); while(1){ free(input); if(use_lifo==TRUE){ if((input=pop_lifo())==NULL) break; } else if((input=mmap_fgets(thefile))==NULL) break; strip(input); if(strstr(input," starting...")){ strcpy(image,START_ICON); strcpy(image_alt,START_ICON_ALT); } else if(strstr(input," shutting down...")){ strcpy(image,STOP_ICON); strcpy(image_alt,STOP_ICON_ALT); } else if(strstr(input,"Bailing out")){ strcpy(image,STOP_ICON); strcpy(image_alt,STOP_ICON_ALT); } else if(strstr(input," restarting...")){ strcpy(image,RESTART_ICON); strcpy(image_alt,RESTART_ICON_ALT); } else if(strstr(input,"HOST ALERT:") && strstr(input,";DOWN;")){ strcpy(image,HOST_DOWN_ICON); strcpy(image_alt,HOST_DOWN_ICON_ALT); } else if(strstr(input,"HOST ALERT:") && strstr(input,";UNREACHABLE;")){ strcpy(image,HOST_UNREACHABLE_ICON); strcpy(image_alt,HOST_UNREACHABLE_ICON_ALT); } else if(strstr(input,"HOST ALERT:") && (strstr(input,";RECOVERY;") || strstr(input,";UP;"))){ strcpy(image,HOST_UP_ICON); strcpy(image_alt,HOST_UP_ICON_ALT); } else if(strstr(input,"HOST NOTIFICATION:")){ strcpy(image,HOST_NOTIFICATION_ICON); strcpy(image_alt,HOST_NOTIFICATION_ICON_ALT); } else if(strstr(input,"SERVICE ALERT:") && strstr(input,";CRITICAL;")){ strcpy(image,CRITICAL_ICON); strcpy(image_alt,CRITICAL_ICON_ALT); } else if(strstr(input,"SERVICE ALERT:") && strstr(input,";WARNING;")){ strcpy(image,WARNING_ICON); strcpy(image_alt,WARNING_ICON_ALT); } else if(strstr(input,"SERVICE ALERT:") && strstr(input,";UNKNOWN;")){ strcpy(image,UNKNOWN_ICON); strcpy(image_alt,UNKNOWN_ICON_ALT); } else if(strstr(input,"SERVICE ALERT:") && (strstr(input,";RECOVERY;") || strstr(input,";OK;"))){ strcpy(image,OK_ICON); strcpy(image_alt,OK_ICON_ALT); } else if(strstr(input,"SERVICE NOTIFICATION:")){ strcpy(image,NOTIFICATION_ICON); strcpy(image_alt,NOTIFICATION_ICON_ALT); } else if(strstr(input,"SERVICE EVENT HANDLER:")){ strcpy(image,SERVICE_EVENT_ICON); strcpy(image_alt,SERVICE_EVENT_ICON_ALT); } else if(strstr(input,"HOST EVENT HANDLER:")){ strcpy(image,HOST_EVENT_ICON); strcpy(image_alt,HOST_EVENT_ICON_ALT); } else if(strstr(input,"EXTERNAL COMMAND:")){ strcpy(image,EXTERNAL_COMMAND_ICON); strcpy(image_alt,EXTERNAL_COMMAND_ICON_ALT); } else if(strstr(input,"LOG ROTATION:")){ strcpy(image,LOG_ROTATION_ICON); strcpy(image_alt,LOG_ROTATION_ICON_ALT); } else if(strstr(input,"active mode...")){ strcpy(image,ACTIVE_ICON); strcpy(image_alt,ACTIVE_ICON_ALT); } else if(strstr(input,"standby mode...")){ strcpy(image,STANDBY_ICON); strcpy(image_alt,STANDBY_ICON_ALT); } else if(strstr(input,"SERVICE FLAPPING ALERT:") && strstr(input,";STARTED;")){ strcpy(image,FLAPPING_ICON); strcpy(image_alt,"Service started flapping"); } else if(strstr(input,"SERVICE FLAPPING ALERT:") && strstr(input,";STOPPED;")){ strcpy(image,FLAPPING_ICON); strcpy(image_alt,"Service stopped flapping"); } else if(strstr(input,"SERVICE FLAPPING ALERT:") && strstr(input,";DISABLED;")){ strcpy(image,FLAPPING_ICON); strcpy(image_alt,"Service flap detection disabled"); } else if(strstr(input,"HOST FLAPPING ALERT:") && strstr(input,";STARTED;")){ strcpy(image,FLAPPING_ICON); strcpy(image_alt,"Host started flapping"); } else if(strstr(input,"HOST FLAPPING ALERT:") && strstr(input,";STOPPED;")){ strcpy(image,FLAPPING_ICON); strcpy(image_alt,"Host stopped flapping"); } else if(strstr(input,"HOST FLAPPING ALERT:") && strstr(input,";DISABLED;")){ strcpy(image,FLAPPING_ICON); strcpy(image_alt,"Host flap detection disabled"); } else if(strstr(input,"SERVICE DOWNTIME ALERT:") && strstr(input,";STARTED;")){ strcpy(image,SCHEDULED_DOWNTIME_ICON); strcpy(image_alt,"Service entered a period of scheduled downtime"); } else if(strstr(input,"SERVICE DOWNTIME ALERT:") && strstr(input,";STOPPED;")){ strcpy(image,SCHEDULED_DOWNTIME_ICON); strcpy(image_alt,"Service exited a period of scheduled downtime"); } else if(strstr(input,"SERVICE DOWNTIME ALERT:") && strstr(input,";CANCELLED;")){ strcpy(image,SCHEDULED_DOWNTIME_ICON); strcpy(image_alt,"Service scheduled downtime has been cancelled"); } else if(strstr(input,"HOST DOWNTIME ALERT:") && strstr(input,";STARTED;")){ strcpy(image,SCHEDULED_DOWNTIME_ICON); strcpy(image_alt,"Host entered a period of scheduled downtime"); } else if(strstr(input,"HOST DOWNTIME ALERT:") && strstr(input,";STOPPED;")){ strcpy(image,SCHEDULED_DOWNTIME_ICON); strcpy(image_alt,"Host exited a period of scheduled downtime"); } else if(strstr(input,"HOST DOWNTIME ALERT:") && strstr(input,";CANCELLED;")){ strcpy(image,SCHEDULED_DOWNTIME_ICON); strcpy(image_alt,"Host scheduled downtime has been cancelled"); } else{ strcpy(image,INFO_ICON); strcpy(image_alt,INFO_ICON_ALT); } temp_buffer=strtok(input,"]"); t=(temp_buffer==NULL)?0L:strtoul(temp_buffer+1,NULL,10); time_ptr=localtime(&t); strftime(current_message_date,sizeof(current_message_date),"%B %d, %Y %H:00\n",time_ptr); current_message_date[sizeof(current_message_date)-1]='\x0'; if(strcmp(last_message_date,current_message_date)!=0 && display_timebreaks==TRUE){ printf("
    \n"); printf("
    \n"); printf(""); printf(""); printf("",current_message_date); printf(""); printf("

    %s
    \n"); printf("
    \n"); printf("
    \n"); strncpy(last_message_date,current_message_date,sizeof(last_message_date)); last_message_date[sizeof(last_message_date)-1]='\x0'; } get_time_string(&t,date_time,(int)sizeof(date_time),SHORT_DATE_TIME); strip(date_time); temp_buffer=strtok(NULL,"\n"); if(display_frills==TRUE) printf("%s",url_images_path,image,image_alt,image_alt); printf("[%s] %s
    \n",date_time,(temp_buffer==NULL)?"":temp_buffer); } printf("

    \n"); printf("
    \n"); free(input); if(use_lifo==FALSE) mmap_fclose(thefile); } if(use_lifo==TRUE) free_lifo_memory(); return OK; } nagios-2.6/cgi/status.c0000664000076500007650000050374710512470706014452 0ustar nagiosnagios/************************************************************************** * * STATUS.C - Nagios Status CGI * * Copyright (c) 1999-2006 Ethan Galstad (nagios@nagios.org) * Last Modified: 10-09-2006 * * 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. *************************************************************************/ #include "../include/config.h" #include "../include/common.h" #include "../include/objects.h" #include "../include/comments.h" #include "../include/statusdata.h" #include "../include/cgiutils.h" #include "../include/getcgi.h" #include "../include/cgiauth.h" extern int refresh_rate; extern time_t program_start; extern char main_config_file[MAX_FILENAME_LENGTH]; extern char url_html_path[MAX_FILENAME_LENGTH]; extern char url_docs_path[MAX_FILENAME_LENGTH]; extern char url_images_path[MAX_FILENAME_LENGTH]; extern char url_stylesheets_path[MAX_FILENAME_LENGTH]; extern char url_logo_images_path[MAX_FILENAME_LENGTH]; extern char url_media_path[MAX_FILENAME_LENGTH]; extern char log_file[MAX_FILENAME_LENGTH]; extern char *service_critical_sound; extern char *service_warning_sound; extern char *service_unknown_sound; extern char *host_down_sound; extern char *host_unreachable_sound; extern char *normal_sound; extern int suppress_alert_window; extern host *host_list; extern service *service_list; extern hostgroup *hostgroup_list; extern servicegroup *servicegroup_list; extern hoststatus *hoststatus_list; extern servicestatus *servicestatus_list; #define MAX_MESSAGE_BUFFER 4096 #define DISPLAY_HOSTS 0 #define DISPLAY_HOSTGROUPS 1 #define DISPLAY_SERVICEGROUPS 2 #define STYLE_OVERVIEW 0 #define STYLE_DETAIL 1 #define STYLE_SUMMARY 2 #define STYLE_GRID 3 #define STYLE_HOST_DETAIL 4 /* HOSTSORT structure */ typedef struct hostsort_struct{ hoststatus *hststatus; struct hostsort_struct *next; }hostsort; /* SERVICESORT structure */ typedef struct servicesort_struct{ servicestatus *svcstatus; struct servicesort_struct *next; }servicesort; hostsort *hostsort_list=NULL; servicesort *servicesort_list=NULL; int sort_services(int,int); /* sorts services */ int sort_hosts(int,int); /* sorts hosts */ int compare_servicesort_entries(int,int,servicesort *,servicesort *); /* compares service sort entries */ int compare_hostsort_entries(int,int,hostsort *,hostsort *); /* compares host sort entries */ void free_servicesort_list(void); void free_hostsort_list(void); void show_host_status_totals(void); void show_service_status_totals(void); void show_service_detail(void); void show_host_detail(void); void show_servicegroup_overviews(void); void show_servicegroup_overview(servicegroup *); void show_servicegroup_summaries(void); void show_servicegroup_summary(servicegroup *,int); void show_servicegroup_host_totals_summary(servicegroup *); void show_servicegroup_service_totals_summary(servicegroup *); void show_servicegroup_grids(void); void show_servicegroup_grid(servicegroup *); void show_hostgroup_overviews(void); void show_hostgroup_overview(hostgroup *); void show_servicegroup_hostgroup_member_overview(hoststatus *,int,void *); void show_servicegroup_hostgroup_member_service_status_totals(char *,void *); void show_hostgroup_summaries(void); void show_hostgroup_summary(hostgroup *,int); void show_hostgroup_host_totals_summary(hostgroup *); void show_hostgroup_service_totals_summary(hostgroup *); void show_hostgroup_grids(void); void show_hostgroup_grid(hostgroup *); void show_filters(void); int passes_host_properties_filter(hoststatus *); int passes_service_properties_filter(servicestatus *); void document_header(int); void document_footer(void); int process_cgivars(void); authdata current_authdata; time_t current_time; char alert_message[MAX_MESSAGE_BUFFER]; char *host_name=NULL; char *hostgroup_name=NULL; char *servicegroup_name=NULL; char *service_filter=NULL; int host_alert=FALSE; int show_all_hosts=TRUE; int show_all_hostgroups=TRUE; int show_all_servicegroups=TRUE; int display_type=DISPLAY_HOSTS; int overview_columns=3; int max_grid_width=8; int group_style_type=STYLE_OVERVIEW; int navbar_search=FALSE; int service_status_types=SERVICE_PENDING|SERVICE_OK|SERVICE_UNKNOWN|SERVICE_WARNING|SERVICE_CRITICAL; int all_service_status_types=SERVICE_PENDING|SERVICE_OK|SERVICE_UNKNOWN|SERVICE_WARNING|SERVICE_CRITICAL; int host_status_types=HOST_PENDING|HOST_UP|HOST_DOWN|HOST_UNREACHABLE; int all_host_status_types=HOST_PENDING|HOST_UP|HOST_DOWN|HOST_UNREACHABLE; int all_service_problems=SERVICE_UNKNOWN|SERVICE_WARNING|SERVICE_CRITICAL; int all_host_problems=HOST_DOWN|HOST_UNREACHABLE; unsigned long host_properties=0L; unsigned long service_properties=0L; int sort_type=SORT_NONE; int sort_option=SORT_HOSTNAME; int problem_hosts_down=0; int problem_hosts_unreachable=0; int problem_services_critical=0; int problem_services_warning=0; int problem_services_unknown=0; int embedded=FALSE; int display_header=TRUE; int main(void){ int result=OK; char *sound=NULL; host *temp_host=NULL; hostgroup *temp_hostgroup=NULL; servicegroup *temp_servicegroup=NULL; time(¤t_time); /* get the arguments passed in the URL */ process_cgivars(); /* reset internal variables */ reset_cgi_vars(); /* read the CGI configuration file */ result=read_cgi_config_file(get_cgi_config_location()); if(result==ERROR){ document_header(FALSE); cgi_config_file_error(get_cgi_config_location()); document_footer(); return ERROR; } /* read the main configuration file */ result=read_main_config_file(main_config_file); if(result==ERROR){ document_header(FALSE); main_config_file_error(main_config_file); document_footer(); return ERROR; } /* read all object configuration data */ result=read_all_object_configuration_data(main_config_file,READ_ALL_OBJECT_DATA); if(result==ERROR){ document_header(FALSE); object_data_error(); document_footer(); return ERROR; } /* read all status data */ result=read_all_status_data(get_cgi_config_location(),READ_ALL_STATUS_DATA); if(result==ERROR){ document_header(FALSE); status_data_error(); document_footer(); free_memory(); return ERROR; } document_header(TRUE); /* read in all host and service comments */ read_comment_data(get_cgi_config_location()); /* get authentication information */ get_authentication_information(¤t_authdata); /* if a navbar search was performed, find the host by name, address or partial name */ if(navbar_search==TRUE){ if((temp_host=find_host(host_name))==NULL){ for(temp_host=host_list;temp_host!=NULL;temp_host=temp_host->next){ if(is_authorized_for_host(temp_host,¤t_authdata)==FALSE) continue; if(!strcmp(host_name,temp_host->address)){ free(host_name); host_name=strdup(temp_host->name); break; } } if(temp_host==NULL){ for(temp_host=host_list;temp_host!=NULL;temp_host=temp_host->next){ if(is_authorized_for_host(temp_host,¤t_authdata)==FALSE) continue; if((strstr(temp_host->name,host_name)==temp_host->name) || !strncasecmp(temp_host->name,host_name,strlen(host_name))){ free(host_name); host_name=strdup(temp_host->name); break; } } } } /* last effort, search hostgroups then servicegroups */ if(temp_host==NULL){ if((temp_hostgroup=find_hostgroup(host_name))!=NULL){ display_type=DISPLAY_HOSTGROUPS; show_all_hostgroups=FALSE; free(host_name); hostgroup_name=strdup(temp_hostgroup->group_name); } else if((temp_servicegroup=find_servicegroup(host_name))!=NULL){ display_type=DISPLAY_SERVICEGROUPS; show_all_servicegroups=FALSE; free(host_name); servicegroup_name=strdup(temp_servicegroup->group_name); } } } if(display_header==TRUE){ /* begin top table */ printf("\n"); printf("\n"); /* left column of the first row */ printf("\n"); /* middle column of top row */ printf("\n"); /* right hand column of top row */ printf("\n"); /* display context-sensitive help */ printf("\n"); /* end of top table */ printf("\n"); printf("
    \n"); /* info table */ display_info_table("Current Network Status",TRUE,¤t_authdata); printf("\n"); printf("\n"); printf("\n"); printf("\n"); show_host_status_totals(); printf("\n"); show_service_status_totals(); printf("\n"); if(display_type==DISPLAY_HOSTS) display_context_help(CONTEXTHELP_STATUS_DETAIL); else if(display_type==DISPLAY_SERVICEGROUPS){ if(group_style_type==STYLE_HOST_DETAIL) display_context_help(CONTEXTHELP_STATUS_DETAIL); else if(group_style_type==STYLE_OVERVIEW) display_context_help(CONTEXTHELP_STATUS_SGOVERVIEW); else if(group_style_type==STYLE_SUMMARY) display_context_help(CONTEXTHELP_STATUS_SGSUMMARY); else if(group_style_type==STYLE_GRID) display_context_help(CONTEXTHELP_STATUS_SGGRID); } else{ if(group_style_type==STYLE_HOST_DETAIL) display_context_help(CONTEXTHELP_STATUS_HOST_DETAIL); else if(group_style_type==STYLE_OVERVIEW) display_context_help(CONTEXTHELP_STATUS_HGOVERVIEW); else if(group_style_type==STYLE_SUMMARY) display_context_help(CONTEXTHELP_STATUS_HGSUMMARY); else if(group_style_type==STYLE_GRID) display_context_help(CONTEXTHELP_STATUS_HGGRID); } printf("
    \n"); } /* embed sound tag if necessary... */ if(problem_hosts_unreachable>0 && host_unreachable_sound!=NULL) sound=host_unreachable_sound; else if(problem_hosts_down>0 && host_down_sound!=NULL) sound=host_down_sound; else if(problem_services_critical>0 && service_critical_sound!=NULL) sound=service_critical_sound; else if(problem_services_warning>0 && service_warning_sound!=NULL) sound=service_warning_sound; else if(problem_services_unknown>0 && service_unknown_sound!=NULL) sound=service_unknown_sound; else if(problem_services_unknown==0 && problem_services_warning==0 && problem_services_critical==0 && problem_hosts_down==0 && problem_hosts_unreachable==0 && normal_sound!=NULL) sound=normal_sound; if(sound!=NULL){ printf(""); printf("",url_media_path,sound); printf(""); printf(""); printf(""); } /* bottom portion of screen - service or hostgroup detail */ if(display_type==DISPLAY_HOSTS) show_service_detail(); else if(display_type==DISPLAY_SERVICEGROUPS){ if(group_style_type==STYLE_OVERVIEW) show_servicegroup_overviews(); else if(group_style_type==STYLE_SUMMARY) show_servicegroup_summaries(); else if(group_style_type==STYLE_GRID) show_servicegroup_grids(); else show_service_detail(); } else{ if(group_style_type==STYLE_OVERVIEW) show_hostgroup_overviews(); else if(group_style_type==STYLE_SUMMARY) show_hostgroup_summaries(); else if(group_style_type==STYLE_GRID) show_hostgroup_grids(); else if(group_style_type==STYLE_HOST_DETAIL) show_host_detail(); else show_service_detail(); } document_footer(); /* free all allocated memory */ free_memory(); free_comment_data(); /* free memory allocated to the sort lists */ free_servicesort_list(); free_hostsort_list(); return OK; } void document_header(int use_stylesheet){ char date_time[MAX_DATETIME_LENGTH]; time_t expire_time; printf("Cache-Control: no-store\r\n"); printf("Pragma: no-cache\r\n"); printf("Refresh: %d\r\n",refresh_rate); get_time_string(¤t_time,date_time,(int)sizeof(date_time),HTTP_DATE_TIME); printf("Last-Modified: %s\r\n",date_time); expire_time=(time_t)0L; get_time_string(&expire_time,date_time,(int)sizeof(date_time),HTTP_DATE_TIME); printf("Expires: %s\r\n",date_time); printf("Content-type: text/html\r\n\r\n"); if(embedded==TRUE) return; printf("\n"); printf("\n"); printf("\n"); printf("Current Network Status\n"); printf("\n"); if(use_stylesheet==TRUE){ printf("",url_stylesheets_path,COMMON_CSS); printf("",url_stylesheets_path,STATUS_CSS); } printf("\n"); printf("\n"); /* include user SSI header */ include_ssi_files(STATUS_CGI,SSI_HEADER); return; } void document_footer(void){ if(embedded==TRUE) return; /* include user SSI footer */ include_ssi_files(STATUS_CGI,SSI_FOOTER); printf("\n"); printf("\n"); return; } int process_cgivars(void){ char **variables; int error=FALSE; int x; variables=getcgivars(); for(x=0;variables[x]!=NULL;x++){ /* do some basic length checking on the variable identifier to prevent buffer overflows */ if(strlen(variables[x])>=MAX_INPUT_BUFFER-1){ x++; continue; } /* we found the navbar search argument */ else if(!strcmp(variables[x],"navbarsearch")){ x++; if(variables[x]==NULL){ error=TRUE; break; } navbar_search=TRUE; } /* we found the hostgroup argument */ else if(!strcmp(variables[x],"hostgroup")){ display_type=DISPLAY_HOSTGROUPS; x++; if(variables[x]==NULL){ error=TRUE; break; } hostgroup_name=strdup(variables[x]); if(hostgroup_name!=NULL && !strcmp(hostgroup_name,"all")) show_all_hostgroups=TRUE; else show_all_hostgroups=FALSE; } /* we found the servicegroup argument */ else if(!strcmp(variables[x],"servicegroup")){ display_type=DISPLAY_SERVICEGROUPS; x++; if(variables[x]==NULL){ error=TRUE; break; } servicegroup_name=strdup(variables[x]); if(servicegroup_name!=NULL && !strcmp(servicegroup_name,"all")) show_all_servicegroups=TRUE; else show_all_servicegroups=FALSE; } /* we found the host argument */ else if(!strcmp(variables[x],"host")){ display_type=DISPLAY_HOSTS; x++; if(variables[x]==NULL){ error=TRUE; break; } host_name=strdup(variables[x]); if(host_name!=NULL && !strcmp(host_name,"all")) show_all_hosts=TRUE; else show_all_hosts=FALSE; } /* we found the columns argument */ else if(!strcmp(variables[x],"columns")){ x++; if(variables[x]==NULL){ error=TRUE; break; } overview_columns=atoi(variables[x]); if(overview_columns<=0) overview_columns=1; } /* we found the service status type argument */ else if(!strcmp(variables[x],"servicestatustypes")){ x++; if(variables[x]==NULL){ error=TRUE; break; } service_status_types=atoi(variables[x]); } /* we found the host status type argument */ else if(!strcmp(variables[x],"hoststatustypes")){ x++; if(variables[x]==NULL){ error=TRUE; break; } host_status_types=atoi(variables[x]); } /* we found the service properties argument */ else if(!strcmp(variables[x],"serviceprops")){ x++; if(variables[x]==NULL){ error=TRUE; break; } service_properties=strtoul(variables[x],NULL,10); } /* we found the host properties argument */ else if(!strcmp(variables[x],"hostprops")){ x++; if(variables[x]==NULL){ error=TRUE; break; } host_properties=strtoul(variables[x],NULL,10); } /* we found the host or service group style argument */ else if(!strcmp(variables[x],"style")){ x++; if(variables[x]==NULL){ error=TRUE; break; } if(!strcmp(variables[x],"overview")) group_style_type=STYLE_OVERVIEW; else if(!strcmp(variables[x],"detail")) group_style_type=STYLE_DETAIL; else if(!strcmp(variables[x],"summary")) group_style_type=STYLE_SUMMARY; else if(!strcmp(variables[x],"grid")) group_style_type=STYLE_GRID; else if(!strcmp(variables[x],"hostdetail")) group_style_type=STYLE_HOST_DETAIL; else group_style_type=STYLE_DETAIL; } /* we found the sort type argument */ else if(!strcmp(variables[x],"sorttype")){ x++; if(variables[x]==NULL){ error=TRUE; break; } sort_type=atoi(variables[x]); } /* we found the sort option argument */ else if(!strcmp(variables[x],"sortoption")){ x++; if(variables[x]==NULL){ error=TRUE; break; } sort_option=atoi(variables[x]); } /* we found the embed option */ else if(!strcmp(variables[x],"embedded")) embedded=TRUE; /* we found the noheader option */ else if(!strcmp(variables[x],"noheader")) display_header=FALSE; /* servicefilter cgi var */ else if(!strcmp(variables[x],"servicefilter")){ x++; if(variables[x]==NULL){ error=TRUE; break; } service_filter=strdup(variables[x]); } } /* free memory allocated to the CGI variables */ free_cgivars(variables); return error; } /* display table with service status totals... */ void show_service_status_totals(void){ int total_ok=0; int total_warning=0; int total_unknown=0; int total_critical=0; int total_pending=0; int total_services=0; int total_problems=0; servicestatus *temp_servicestatus; service *temp_service; host *temp_host; int count_service; /* check the status of all services... */ for(temp_servicestatus=servicestatus_list;temp_servicestatus!=NULL;temp_servicestatus=temp_servicestatus->next){ /* find the host and service... */ temp_host=find_host(temp_servicestatus->host_name); temp_service=find_service(temp_servicestatus->host_name,temp_servicestatus->description); /* make sure user has rights to see this service... */ if(is_authorized_for_service(temp_service,¤t_authdata)==FALSE) continue; count_service=0; if(display_type==DISPLAY_HOSTS && (show_all_hosts==TRUE || !strcmp(host_name,temp_servicestatus->host_name))) count_service=1; else if(display_type==DISPLAY_SERVICEGROUPS && (show_all_servicegroups==TRUE || (is_service_member_of_servicegroup(find_servicegroup(servicegroup_name),temp_service)==TRUE))) count_service=1; else if(display_type==DISPLAY_HOSTGROUPS && (show_all_hostgroups==TRUE || (is_host_member_of_hostgroup(find_hostgroup(hostgroup_name),temp_host)==TRUE))) count_service=1; if(count_service){ if(temp_servicestatus->status==SERVICE_CRITICAL){ total_critical++; if(temp_servicestatus->problem_has_been_acknowledged==FALSE && temp_servicestatus->checks_enabled==TRUE && temp_servicestatus->notifications_enabled==TRUE && temp_servicestatus->scheduled_downtime_depth==0) problem_services_critical++; } else if(temp_servicestatus->status==SERVICE_WARNING){ total_warning++; if(temp_servicestatus->problem_has_been_acknowledged==FALSE && temp_servicestatus->checks_enabled==TRUE && temp_servicestatus->notifications_enabled==TRUE && temp_servicestatus->scheduled_downtime_depth==0) problem_services_warning++; } else if(temp_servicestatus->status==SERVICE_UNKNOWN){ total_unknown++; if(temp_servicestatus->problem_has_been_acknowledged==FALSE && temp_servicestatus->checks_enabled==TRUE && temp_servicestatus->notifications_enabled==TRUE && temp_servicestatus->scheduled_downtime_depth==0) problem_services_unknown++; } else if(temp_servicestatus->status==SERVICE_OK) total_ok++; else if(temp_servicestatus->status==SERVICE_PENDING) total_pending++; else total_ok++; } } total_services=total_ok+total_unknown+total_warning+total_critical+total_pending; total_problems=total_unknown+total_warning+total_critical; printf("
    Service Status Totals
    \n"); printf("\n"); printf("\n"); printf("
    \n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); /* total services ok */ printf("\n",(total_ok>0)?"OK":"",total_ok); /* total services in warning state */ printf("\n",(total_warning>0)?"WARNING":"",total_warning); /* total services in unknown state */ printf("\n",(total_unknown>0)?"UNKNOWN":"",total_unknown); /* total services in critical state */ printf("\n",(total_critical>0)?"CRITICAL":"",total_critical); /* total services in pending state */ printf("\n",(total_pending>0)?"PENDING":"",total_pending); printf("\n"); printf("
    "); printf("",host_status_types); printf("Ok"); printf("",host_status_types); printf("Warning"); printf("",host_status_types); printf("Unknown"); printf("",host_status_types); printf("Critical"); printf("",host_status_types); printf("Pending
    %d%d%d%d%d
    \n"); printf("
    \n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); /* total service problems */ printf("\n",(total_problems>0)?"PROBLEMS":"",total_problems); /* total services */ printf("\n",total_services); printf("\n"); printf("
    "); printf("",host_status_types); printf("All Problems"); printf("",host_status_types); printf("All Types
    %d%d
    \n"); printf("
    \n"); printf("
    \n"); return; } /* display a table with host status totals... */ void show_host_status_totals(void){ int total_up=0; int total_down=0; int total_unreachable=0; int total_pending=0; int total_hosts=0; int total_problems=0; hoststatus *temp_hoststatus; host *temp_host; servicestatus *temp_servicestatus; service *temp_service; int count_host; /* check the status of all hosts... */ for(temp_hoststatus=hoststatus_list;temp_hoststatus!=NULL;temp_hoststatus=temp_hoststatus->next){ /* find the host... */ temp_host=find_host(temp_hoststatus->host_name); /* make sure user has rights to view this host */ if(is_authorized_for_host(temp_host,¤t_authdata)==FALSE) continue; count_host=0; if(display_type==DISPLAY_HOSTS && (show_all_hosts==TRUE || !strcmp(host_name,temp_hoststatus->host_name))) count_host=1; else if(display_type==DISPLAY_SERVICEGROUPS){ if(show_all_servicegroups==TRUE) count_host=1; else{ for(temp_servicestatus=servicestatus_list;temp_servicestatus!=NULL;temp_servicestatus=temp_servicestatus->next){ if(strcmp(temp_servicestatus->host_name,temp_hoststatus->host_name)) continue; temp_service=find_service(temp_servicestatus->host_name,temp_servicestatus->description); if(is_authorized_for_service(temp_service,¤t_authdata)==FALSE) continue; count_host=1; break; } } } else if(display_type==DISPLAY_HOSTGROUPS && (show_all_hostgroups==TRUE || (is_host_member_of_hostgroup(find_hostgroup(hostgroup_name),temp_host)==TRUE))) count_host=1; if(count_host){ if(temp_hoststatus->status==HOST_UP) total_up++; else if(temp_hoststatus->status==HOST_DOWN){ total_down++; if(temp_hoststatus->problem_has_been_acknowledged==FALSE && temp_hoststatus->notifications_enabled==TRUE && temp_hoststatus->checks_enabled==TRUE && temp_hoststatus->scheduled_downtime_depth==0) problem_hosts_down++; } else if(temp_hoststatus->status==HOST_UNREACHABLE){ total_unreachable++; if(temp_hoststatus->problem_has_been_acknowledged==FALSE && temp_hoststatus->notifications_enabled==TRUE && temp_hoststatus->checks_enabled==TRUE && temp_hoststatus->scheduled_downtime_depth==0) problem_hosts_unreachable++; } else if(temp_hoststatus->status==HOST_PENDING) total_pending++; else total_up++; } } total_hosts=total_up+total_down+total_unreachable+total_pending; total_problems=total_down+total_unreachable; printf("
    Host Status Totals
    \n"); printf("\n"); printf("\n"); printf("
    \n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); /* total hosts up */ printf("\n",(total_up>0)?"UP":"",total_up); /* total hosts down */ printf("\n",(total_down>0)?"DOWN":"",total_down); /* total hosts unreachable */ printf("\n",(total_unreachable>0)?"UNREACHABLE":"",total_unreachable); /* total hosts pending */ printf("\n",(total_pending>0)?"PENDING":"",total_pending); printf("\n"); printf("
    "); printf("",HOST_UP); printf("Up"); printf("",HOST_DOWN); printf("Down"); printf("",HOST_UNREACHABLE); printf("Unreachable"); printf("",HOST_PENDING); printf("Pending
    %d%d%d%d
    \n"); printf("
    \n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); /* total hosts with problems */ printf("\n",(total_problems>0)?"PROBLEMS":"",total_problems); /* total hosts */ printf("\n",total_hosts); printf("\n"); printf("
    "); printf("",HOST_DOWN|HOST_UNREACHABLE); printf("All Problems"); printf(""); printf("All Types
    %d%d
    \n"); printf("
    \n"); printf("
    \n"); return; } /* display a detailed listing of the status of all services... */ void show_service_detail(void){ regex_t preg; time_t t; char date_time[MAX_DATETIME_LENGTH]; char state_duration[48]; char status[MAX_INPUT_BUFFER]; char temp_buffer[MAX_INPUT_BUFFER]; char temp_url[MAX_INPUT_BUFFER]; char *status_class=""; char *status_bg_class=""; char *host_status_bg_class=""; char *last_host=""; int new_host=FALSE; servicestatus *temp_status=NULL; hostgroup *temp_hostgroup=NULL; servicegroup *temp_servicegroup=NULL; hostextinfo *temp_hostextinfo=NULL; serviceextinfo *temp_serviceextinfo=NULL; hoststatus *temp_hoststatus=NULL; host *temp_host=NULL; service *temp_service=NULL; int odd=0; int total_comments=0; int user_has_seen_something=FALSE; servicesort *temp_servicesort=NULL; int use_sort=FALSE; int result=OK; int first_entry=TRUE; int days; int hours; int minutes; int seconds; int duration_error=FALSE; int total_entries=0; int show_service=FALSE; /* sort the service list if necessary */ if(sort_type!=SORT_NONE){ result=sort_services(sort_type,sort_option); if(result==ERROR) use_sort=FALSE; else use_sort=TRUE; } else use_sort=FALSE; printf("

    \n"); printf("\n"); printf("\n"); printf(""); printf("\n"); printf("\n"); printf("\n"); printf("
    \n"); if(display_header==TRUE) show_filters(); printf("\n"); printf("
    Service Status Details For "); if(display_type==DISPLAY_HOSTS){ if(show_all_hosts==TRUE) printf("All Hosts"); else printf("Host '%s'",host_name); } else if(display_type==DISPLAY_SERVICEGROUPS){ if(show_all_servicegroups==TRUE) printf("All Service Groups"); else printf("Service Group '%s'",servicegroup_name); } else{ if(show_all_hostgroups==TRUE) printf("All Host Groups"); else printf("Host Group '%s'",hostgroup_name); } printf("
    \n"); if(use_sort==TRUE){ printf("
    Entries sorted by "); if(sort_option==SORT_HOSTNAME) printf("host name"); else if(sort_option==SORT_SERVICENAME) printf("service name"); else if(sort_option==SORT_SERVICESTATUS) printf("service status"); else if(sort_option==SORT_LASTCHECKTIME) printf("last check time"); else if(sort_option==SORT_CURRENTATTEMPT) printf("attempt number"); else if(sort_option==SORT_STATEDURATION) printf("state duration"); printf(" (%s)\n",(sort_type==SORT_ASCENDING)?"ascending":"descending"); printf("
    \n"); } if(service_filter!=NULL) printf("
    Filtered By Services Matching \'%s\'
    ",service_filter); printf("
    "); printf("
    \n"); snprintf(temp_url,sizeof(temp_url)-1,"%s?",STATUS_CGI); temp_url[sizeof(temp_url)-1]='\x0'; if(display_type==DISPLAY_HOSTS) snprintf(temp_buffer,sizeof(temp_buffer)-1,"host=%s",host_name); else if(display_type==DISPLAY_SERVICEGROUPS) snprintf(temp_buffer,sizeof(temp_buffer)-1,"servicegroup=%s&style=detail",servicegroup_name); else snprintf(temp_buffer,sizeof(temp_buffer)-1,"hostgroup=%s&style=detail",hostgroup_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; strncat(temp_url,temp_buffer,sizeof(temp_url)-strlen(temp_url)-1); temp_url[sizeof(temp_url)-1]='\x0'; if(service_status_types!=all_service_status_types){ snprintf(temp_buffer,sizeof(temp_buffer)-1,"&servicestatustypes=%d",service_status_types); temp_buffer[sizeof(temp_buffer)-1]='\x0'; strncat(temp_url,temp_buffer,sizeof(temp_url)-strlen(temp_url)-1); temp_url[sizeof(temp_url)-1]='\x0'; } if(host_status_types!=all_host_status_types){ snprintf(temp_buffer,sizeof(temp_buffer)-1,"&hoststatustypes=%d",host_status_types); temp_buffer[sizeof(temp_buffer)-1]='\x0'; strncat(temp_url,temp_buffer,sizeof(temp_url)-strlen(temp_url)-1); temp_url[sizeof(temp_url)-1]='\x0'; } if(service_properties!=0){ snprintf(temp_buffer,sizeof(temp_buffer)-1,"&serviceprops=%lu",service_properties); temp_buffer[sizeof(temp_buffer)-1]='\x0'; strncat(temp_url,temp_buffer,sizeof(temp_url)-strlen(temp_url)-1); temp_url[sizeof(temp_url)-1]='\x0'; } if(host_properties!=0){ snprintf(temp_buffer,sizeof(temp_buffer)-1,"&hostprops=%lu",host_properties); temp_buffer[sizeof(temp_buffer)-1]='\x0'; strncat(temp_url,temp_buffer,sizeof(temp_url)-strlen(temp_url)-1); temp_url[sizeof(temp_url)-1]='\x0'; } /* the main list of services */ printf("\n"); printf("\n"); printf("",temp_url,SORT_ASCENDING,SORT_HOSTNAME,url_images_path,UP_ARROW_ICON,temp_url,SORT_DESCENDING,SORT_HOSTNAME,url_images_path,DOWN_ARROW_ICON); printf("",temp_url,SORT_ASCENDING,SORT_SERVICENAME,url_images_path,UP_ARROW_ICON,temp_url,SORT_DESCENDING,SORT_SERVICENAME,url_images_path,DOWN_ARROW_ICON); printf("",temp_url,SORT_ASCENDING,SORT_SERVICESTATUS,url_images_path,UP_ARROW_ICON,temp_url,SORT_DESCENDING,SORT_SERVICESTATUS,url_images_path,DOWN_ARROW_ICON); printf("",temp_url,SORT_ASCENDING,SORT_LASTCHECKTIME,url_images_path,UP_ARROW_ICON,temp_url,SORT_DESCENDING,SORT_LASTCHECKTIME,url_images_path,DOWN_ARROW_ICON); printf("",temp_url,SORT_ASCENDING,SORT_STATEDURATION,url_images_path,UP_ARROW_ICON,temp_url,SORT_DESCENDING,SORT_STATEDURATION,url_images_path,DOWN_ARROW_ICON); printf("",temp_url,SORT_ASCENDING,SORT_CURRENTATTEMPT,url_images_path,UP_ARROW_ICON,temp_url,SORT_DESCENDING,SORT_CURRENTATTEMPT,url_images_path,DOWN_ARROW_ICON); printf("\n"); printf("\n"); if(service_filter!=NULL) regcomp(&preg,service_filter,0); temp_hostgroup=find_hostgroup(hostgroup_name); temp_servicegroup=find_servicegroup(servicegroup_name); /* check all services... */ while(1){ /* get the next service to display */ if(use_sort==TRUE){ if(first_entry==TRUE) temp_servicesort=servicesort_list; else temp_servicesort=temp_servicesort->next; if(temp_servicesort==NULL) break; temp_status=temp_servicesort->svcstatus; } else{ if(first_entry==TRUE) temp_status=servicestatus_list; else temp_status=temp_status->next; } if(temp_status==NULL) break; first_entry=FALSE; /* find the service */ temp_service=find_service(temp_status->host_name,temp_status->description); /* if we couldn't find the service, go to the next service */ if(temp_service==NULL) continue; /* find the host */ temp_host=find_host(temp_service->host_name); /* make sure user has rights to see this... */ if(is_authorized_for_service(temp_service,¤t_authdata)==FALSE) continue; user_has_seen_something=TRUE; /* get the host status information */ temp_hoststatus=find_hoststatus(temp_service->host_name); /* see if we should display services for hosts with tis type of status */ if(!(host_status_types & temp_hoststatus->status)) continue; /* see if we should display this type of service status */ if(!(service_status_types & temp_status->status)) continue; /* check host properties filter */ if(passes_host_properties_filter(temp_hoststatus)==FALSE) continue; /* check service properties filter */ if(passes_service_properties_filter(temp_status)==FALSE) continue; /* servicefilter cgi var */ if(service_filter!=NULL) if(regexec(&preg,temp_status->description,0,NULL,0)) continue; show_service=FALSE; if(display_type==DISPLAY_HOSTS){ if(show_all_hosts==TRUE) show_service=TRUE; else if(!strcmp(host_name,temp_status->host_name)) show_service=TRUE; } else if(display_type==DISPLAY_HOSTGROUPS){ if(show_all_hostgroups==TRUE) show_service=TRUE; else if(is_host_member_of_hostgroup(temp_hostgroup,temp_host)==TRUE) show_service=TRUE; } else if(display_type==DISPLAY_SERVICEGROUPS){ if(show_all_servicegroups==TRUE) show_service=TRUE; else if(is_service_member_of_servicegroup(temp_servicegroup,temp_service)==TRUE) show_service=TRUE; } if(show_service==TRUE){ if(strcmp(last_host,temp_status->host_name)) new_host=TRUE; else new_host=FALSE; if(new_host==TRUE){ if(strcmp(last_host,"")){ printf("\n"); printf("\n"); } } if(odd) odd=0; else odd=1; /* keep track of total number of services we're displaying */ total_entries++; /* get the last service check time */ t=temp_status->last_check; get_time_string(&t,date_time,(int)sizeof(date_time),SHORT_DATE_TIME); if((unsigned long)temp_status->last_check==0L) strcpy(date_time,"N/A"); if(temp_status->status==SERVICE_PENDING){ strncpy(status,"PENDING",sizeof(status)); status_class="PENDING"; status_bg_class=(odd)?"Even":"Odd"; } else if(temp_status->status==SERVICE_OK){ strncpy(status,"OK",sizeof(status)); status_class="OK"; status_bg_class=(odd)?"Even":"Odd"; } else if(temp_status->status==SERVICE_WARNING){ strncpy(status,"WARNING",sizeof(status)); status_class="WARNING"; if(temp_status->problem_has_been_acknowledged==TRUE) status_bg_class="BGWARNINGACK"; else if(temp_status->scheduled_downtime_depth>0) status_bg_class="BGWARNINGSCHED"; else status_bg_class="BGWARNING"; } else if(temp_status->status==SERVICE_UNKNOWN){ strncpy(status,"UNKNOWN",sizeof(status)); status_class="UNKNOWN"; if(temp_status->problem_has_been_acknowledged==TRUE) status_bg_class="BGUNKNOWNACK"; else if(temp_status->scheduled_downtime_depth>0) status_bg_class="BGUNKNOWNSCHED"; else status_bg_class="BGUNKNOWN"; } else if(temp_status->status==SERVICE_CRITICAL){ strncpy(status,"CRITICAL",sizeof(status)); status_class="CRITICAL"; if(temp_status->problem_has_been_acknowledged==TRUE) status_bg_class="BGCRITICALACK"; else if(temp_status->scheduled_downtime_depth>0) status_bg_class="BGCRITICALSCHED"; else status_bg_class="BGCRITICAL"; } status[sizeof(status)-1]='\x0'; printf("\n"); /* host name column */ if(new_host==TRUE){ /* find extended information for this host */ temp_hostextinfo=find_hostextinfo(temp_status->host_name); if(temp_hoststatus->status==HOST_DOWN){ if(temp_hoststatus->problem_has_been_acknowledged==TRUE) host_status_bg_class="HOSTDOWNACK"; else if(temp_hoststatus->scheduled_downtime_depth>0) host_status_bg_class="HOSTDOWNSCHED"; else host_status_bg_class="HOSTDOWN"; } else if(temp_hoststatus->status==HOST_UNREACHABLE){ if(temp_hoststatus->problem_has_been_acknowledged==TRUE) host_status_bg_class="HOSTUNREACHABLEACK"; else if(temp_hoststatus->scheduled_downtime_depth>0) host_status_bg_class="HOSTUNREACHABLESCHED"; else host_status_bg_class="HOSTUNREACHABLE"; } else host_status_bg_class=(odd)?"Even":"Odd"; printf("\n"); /* service name column */ printf("\n"); /* state duration calculation... */ t=0; duration_error=FALSE; if(temp_status->last_state_change==(time_t)0){ if(program_start>current_time) duration_error=TRUE; else t=current_time-program_start; } else{ if(temp_status->last_state_change>current_time) duration_error=TRUE; else t=current_time-temp_status->last_state_change; } get_time_breakdown((unsigned long)t,&days,&hours,&minutes,&seconds); if(duration_error==TRUE) snprintf(state_duration,sizeof(state_duration)-1,"???"); else snprintf(state_duration,sizeof(state_duration)-1,"%2dd %2dh %2dm %2ds%s",days,hours,minutes,seconds,(temp_status->last_state_change==(time_t)0)?"+":""); state_duration[sizeof(state_duration)-1]='\x0'; /* the rest of the columns... */ printf("\n",status_class,status); printf("\n",status_bg_class,date_time); printf("\n",status_bg_class,state_duration); printf("\n",status_bg_class,temp_status->current_attempt,temp_status->max_attempts); printf("\n",status_bg_class,(temp_status->plugin_output==NULL)?"":temp_status->plugin_output); printf("\n"); last_host=temp_status->host_name; } } printf("
    Host Sort by host name (ascending)Sort by host name (descending)Service Sort by service name (ascending)Sort by service name (descending)Status Sort by service status (ascending)Sort by service status (descending)Last Check Sort by last check time (ascending)Sort by last check time (descending)Duration Sort by state duration (ascending)Sort by state duration time (descending)Attempt Sort by current attempt (ascending)Sort by current attempt (descending)Status Information
    ",host_status_bg_class); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("
    \n"); printf("\n"); printf("\n"); printf("\n",host_status_bg_class,EXTINFO_CGI,DISPLAY_HOST_INFO,url_encode(temp_status->host_name),temp_status->host_name); printf("\n"); printf("
    %s
    \n"); printf("
    \n"); printf("\n"); printf("\n"); total_comments=number_of_host_comments(temp_host->name); if(temp_hoststatus->problem_has_been_acknowledged==TRUE){ printf("",EXTINFO_CGI,DISPLAY_HOST_INFO,url_encode(temp_status->host_name),url_images_path,ACKNOWLEDGEMENT_ICON,STATUS_ICON_WIDTH,STATUS_ICON_HEIGHT); } if(total_comments>0) printf("",EXTINFO_CGI,DISPLAY_HOST_INFO,url_encode(temp_status->host_name),url_images_path,COMMENT_ICON,STATUS_ICON_WIDTH,STATUS_ICON_HEIGHT,total_comments,(total_comments==1)?"":"s",total_comments,(total_comments==1)?"":"s"); if(temp_hoststatus->notifications_enabled==FALSE){ printf("",EXTINFO_CGI,DISPLAY_HOST_INFO,url_encode(temp_status->host_name),url_images_path,NOTIFICATIONS_DISABLED_ICON,STATUS_ICON_WIDTH,STATUS_ICON_HEIGHT); } if(temp_hoststatus->checks_enabled==FALSE){ printf("",EXTINFO_CGI,DISPLAY_HOST_INFO,url_encode(temp_status->host_name),url_images_path,DISABLED_ICON,STATUS_ICON_WIDTH,STATUS_ICON_HEIGHT); } if(temp_hoststatus->is_flapping==TRUE){ printf("",EXTINFO_CGI,DISPLAY_HOST_INFO,url_encode(temp_status->host_name),url_images_path,FLAPPING_ICON,STATUS_ICON_WIDTH,STATUS_ICON_HEIGHT); } if(temp_hoststatus->scheduled_downtime_depth>0){ printf("",EXTINFO_CGI,DISPLAY_HOST_INFO,url_encode(temp_status->host_name),url_images_path,SCHEDULED_DOWNTIME_ICON,STATUS_ICON_WIDTH,STATUS_ICON_HEIGHT); } if(temp_hostextinfo!=NULL){ if(temp_hostextinfo->notes_url!=NULL){ printf("\n"); } if(temp_hostextinfo->action_url!=NULL){ printf("\n"); } if(temp_hostextinfo->icon_image!=NULL){ printf("\n"); } } printf("\n"); printf("
    This host problem has been acknowledgedThis host has %d comment%s associated with itNotifications for this host have been disabledChecks of this host have been disabledThis host is flapping between statesThis host is currently in a period of scheduled downtime"); printf(""); printf("%s",url_images_path,NOTES_ICON,STATUS_ICON_WIDTH,STATUS_ICON_HEIGHT,"View Extra Host Notes","View Extra Host Notes"); printf(""); printf(""); printf(""); printf("%s",url_images_path,ACTION_ICON,STATUS_ICON_WIDTH,STATUS_ICON_HEIGHT,"Perform Extra Host Actions","Perform Extra Host Actions"); printf(""); printf(""); printf("",EXTINFO_CGI,DISPLAY_HOST_INFO,url_encode(temp_status->host_name)); printf("%s",STATUS_ICON_WIDTH,STATUS_ICON_HEIGHT,(temp_hostextinfo->icon_image_alt==NULL)?"":temp_hostextinfo->icon_image_alt,(temp_hostextinfo->icon_image_alt==NULL)?"":temp_hostextinfo->icon_image_alt); printf(""); printf("
    \n"); printf("
    \n"); } else printf("
    "); printf("",status_bg_class); printf(""); printf(""); printf("\n"); printf("\n"); printf(""); printf("
    "); printf("\n"); printf("\n"); printf("",url_encode(temp_status->description),temp_status->description); printf("\n"); printf("
    %s
    \n"); printf("
    \n",status_bg_class); printf("\n"); printf("\n"); total_comments=number_of_service_comments(temp_service->host_name,temp_service->description); if(total_comments>0){ printf("",url_encode(temp_status->description),url_images_path,COMMENT_ICON,STATUS_ICON_WIDTH,STATUS_ICON_HEIGHT,total_comments,(total_comments==1)?"":"s",total_comments,(total_comments==1)?"":"s"); } if(temp_status->problem_has_been_acknowledged==TRUE){ printf("",url_encode(temp_status->description),url_images_path,ACKNOWLEDGEMENT_ICON,STATUS_ICON_WIDTH,STATUS_ICON_HEIGHT); } if(temp_status->checks_enabled==FALSE && temp_status->accept_passive_service_checks==FALSE){ printf("",url_encode(temp_status->description),url_images_path,DISABLED_ICON,STATUS_ICON_WIDTH,STATUS_ICON_HEIGHT); } else if(temp_status->checks_enabled==FALSE){ printf("",url_encode(temp_status->description),url_images_path,PASSIVE_ONLY_ICON,STATUS_ICON_WIDTH,STATUS_ICON_HEIGHT); } if(temp_status->notifications_enabled==FALSE){ printf("",url_encode(temp_status->description),url_images_path,NOTIFICATIONS_DISABLED_ICON,STATUS_ICON_WIDTH,STATUS_ICON_HEIGHT); } if(temp_status->is_flapping==TRUE){ printf("",url_encode(temp_status->description),url_images_path,FLAPPING_ICON,STATUS_ICON_WIDTH,STATUS_ICON_HEIGHT); } if(temp_status->scheduled_downtime_depth>0){ printf("",url_encode(temp_status->description),url_images_path,SCHEDULED_DOWNTIME_ICON,STATUS_ICON_WIDTH,STATUS_ICON_HEIGHT); } temp_serviceextinfo=find_serviceextinfo(temp_service->host_name,temp_service->description); if(temp_serviceextinfo!=NULL){ if(temp_serviceextinfo->notes_url!=NULL){ printf("\n"); } if(temp_serviceextinfo->action_url!=NULL){ printf("\n"); } if(temp_serviceextinfo->icon_image!=NULL){ printf("\n"); } } printf("\n"); printf("
    This service has %d comment%s associated with itThis service problem has been acknowledgedActive and passive checks have been disabled for this serviceActive checks of the service have been disabled - only passive checks are being acceptedNotifications for this service have been disabledThis service is flapping between statesThis service is currently in a period of scheduled downtime"); printf(""); printf("%s",url_images_path,NOTES_ICON,STATUS_ICON_WIDTH,STATUS_ICON_HEIGHT,"View Extra Service Notes","View Extra Service Notes"); printf(""); printf(""); printf(""); printf("%s",url_images_path,ACTION_ICON,STATUS_ICON_WIDTH,STATUS_ICON_HEIGHT,"Perform Extra Service Actions","Perform Extra Service Actions"); printf(""); printf(""); printf("",url_encode(temp_service->description)); printf("%s",STATUS_ICON_WIDTH,STATUS_ICON_HEIGHT,(temp_serviceextinfo->icon_image_alt==NULL)?"":temp_serviceextinfo->icon_image_alt,(temp_serviceextinfo->icon_image_alt==NULL)?"":temp_serviceextinfo->icon_image_alt); printf(""); printf("
    \n"); printf("
    "); printf("
    %s%s%s%d/%d%s 
    \n"); /* if user couldn't see anything, print out some helpful info... */ if(user_has_seen_something==FALSE){ if(servicestatus_list!=NULL){ printf("

    It appears as though you do not have permission to view information for any of the services you requested...

    \n"); printf("

    If you believe this is an error, check the HTTP server authentication requirements for accessing this CGI
    "); printf("and check the authorization options in your CGI configuration file.

    \n"); } else{ printf("

    There doesn't appear to be any service status information in the status log...

    \n"); printf("Make sure that Nagios is running and that you have specified the location of you status log correctly in the configuration files.

    \n"); } } else printf("
    %d Matching Service Entries Displayed
    \n",total_entries); return; } /* display a detailed listing of the status of all hosts... */ void show_host_detail(void){ time_t t; char date_time[MAX_DATETIME_LENGTH]; char state_duration[48]; char status[MAX_INPUT_BUFFER]; char temp_buffer[MAX_INPUT_BUFFER]; char temp_url[MAX_INPUT_BUFFER]; char *status_class=""; char *status_bg_class=""; hoststatus *temp_status=NULL; hostgroup *temp_hostgroup=NULL; hostextinfo *temp_hostextinfo=NULL; host *temp_host=NULL; hostsort *temp_hostsort=NULL; int odd=0; int total_comments=0; int user_has_seen_something=FALSE; int use_sort=FALSE; int result=OK; int first_entry=TRUE; int days; int hours; int minutes; int seconds; int duration_error=FALSE; int total_entries=0; /* sort the host list if necessary */ if(sort_type!=SORT_NONE){ result=sort_hosts(sort_type,sort_option); if(result==ERROR) use_sort=FALSE; else use_sort=TRUE; } else use_sort=FALSE; printf("

    \n"); printf("\n"); printf("\n"); printf(""); printf("\n"); printf("\n"); printf("\n"); printf("
    \n"); show_filters(); printf("\n"); printf("
    Host Status Details For "); if(show_all_hostgroups==TRUE) printf("All Host Groups"); else printf("Host Group '%s'",hostgroup_name); printf("
    \n"); if(use_sort==TRUE){ printf("
    Entries sorted by "); if(sort_option==SORT_HOSTNAME) printf("host name"); else if(sort_option==SORT_HOSTSTATUS) printf("host status"); else if(sort_option==SORT_LASTCHECKTIME) printf("last check time"); else if(sort_option==SORT_CURRENTATTEMPT) printf("attempt number"); else if(sort_option==SORT_STATEDURATION) printf("state duration"); printf(" (%s)\n",(sort_type==SORT_ASCENDING)?"ascending":"descending"); printf("
    \n"); } printf("
    "); printf("
    \n"); snprintf(temp_url,sizeof(temp_url)-1,"%s?",STATUS_CGI); temp_url[sizeof(temp_url)-1]='\x0'; snprintf(temp_buffer,sizeof(temp_buffer)-1,"hostgroup=%s&style=hostdetail",hostgroup_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; strncat(temp_url,temp_buffer,sizeof(temp_url)-strlen(temp_url)-1); temp_url[sizeof(temp_url)-1]='\x0'; if(service_status_types!=all_service_status_types){ snprintf(temp_buffer,sizeof(temp_buffer)-1,"&servicestatustypes=%d",service_status_types); temp_buffer[sizeof(temp_buffer)-1]='\x0'; strncat(temp_url,temp_buffer,sizeof(temp_url)-strlen(temp_url)-1); temp_url[sizeof(temp_url)-1]='\x0'; } if(host_status_types!=all_host_status_types){ snprintf(temp_buffer,sizeof(temp_buffer)-1,"&hoststatustypes=%d",host_status_types); temp_buffer[sizeof(temp_buffer)-1]='\x0'; strncat(temp_url,temp_buffer,sizeof(temp_url)-strlen(temp_url)-1); temp_url[sizeof(temp_url)-1]='\x0'; } if(service_properties!=0){ snprintf(temp_buffer,sizeof(temp_buffer)-1,"&serviceprops=%lu",service_properties); temp_buffer[sizeof(temp_buffer)-1]='\x0'; strncat(temp_url,temp_buffer,sizeof(temp_url)-strlen(temp_url)-1); temp_url[sizeof(temp_url)-1]='\x0'; } if(host_properties!=0){ snprintf(temp_buffer,sizeof(temp_buffer)-1,"&hostprops=%lu",host_properties); temp_buffer[sizeof(temp_buffer)-1]='\x0'; strncat(temp_url,temp_buffer,sizeof(temp_url)-strlen(temp_url)-1); temp_url[sizeof(temp_url)-1]='\x0'; } /* the main list of hosts */ printf("

    \n"); printf("\n"); printf("\n"); printf("",temp_url,SORT_ASCENDING,SORT_HOSTNAME,url_images_path,UP_ARROW_ICON,temp_url,SORT_DESCENDING,SORT_HOSTNAME,url_images_path,DOWN_ARROW_ICON); printf("",temp_url,SORT_ASCENDING,SORT_HOSTSTATUS,url_images_path,UP_ARROW_ICON,temp_url,SORT_DESCENDING,SORT_HOSTSTATUS,url_images_path,DOWN_ARROW_ICON); printf("",temp_url,SORT_ASCENDING,SORT_LASTCHECKTIME,url_images_path,UP_ARROW_ICON,temp_url,SORT_DESCENDING,SORT_LASTCHECKTIME,url_images_path,DOWN_ARROW_ICON); printf("",temp_url,SORT_ASCENDING,SORT_STATEDURATION,url_images_path,UP_ARROW_ICON,temp_url,SORT_DESCENDING,SORT_STATEDURATION,url_images_path,DOWN_ARROW_ICON); printf("\n"); printf("\n"); /* check all hosts... */ while(1){ /* get the next service to display */ if(use_sort==TRUE){ if(first_entry==TRUE) temp_hostsort=hostsort_list; else temp_hostsort=temp_hostsort->next; if(temp_hostsort==NULL) break; temp_status=temp_hostsort->hststatus; } else{ if(first_entry==TRUE) temp_status=hoststatus_list; else temp_status=temp_status->next; } if(temp_status==NULL) break; first_entry=FALSE; /* find the host */ temp_host=find_host(temp_status->host_name); /* if we couldn't find the host, go to the next status entry */ if(temp_host==NULL) continue; /* make sure user has rights to see this... */ if(is_authorized_for_host(temp_host,¤t_authdata)==FALSE) continue; user_has_seen_something=TRUE; /* see if we should display services for hosts with this type of status */ if(!(host_status_types & temp_status->status)) continue; /* check host properties filter */ if(passes_host_properties_filter(temp_status)==FALSE) continue; /* see if this host is a member of the hostgroup */ if(show_all_hostgroups==FALSE){ temp_hostgroup=find_hostgroup(hostgroup_name); if(temp_hostgroup==NULL) continue; if(is_host_member_of_hostgroup(temp_hostgroup,temp_host)==FALSE) continue; } total_entries++; if(display_type==DISPLAY_HOSTGROUPS){ if(odd) odd=0; else odd=1; /* get the last host check time */ t=temp_status->last_check; get_time_string(&t,date_time,(int)sizeof(date_time),SHORT_DATE_TIME); if((unsigned long)temp_status->last_check==0L) strcpy(date_time,"N/A"); if(temp_status->status==HOST_PENDING){ strncpy(status,"PENDING",sizeof(status)); status_class="PENDING"; status_bg_class=(odd)?"Even":"Odd"; } else if(temp_status->status==HOST_UP){ strncpy(status,"UP",sizeof(status)); status_class="HOSTUP"; status_bg_class=(odd)?"Even":"Odd"; } else if(temp_status->status==HOST_DOWN){ strncpy(status,"DOWN",sizeof(status)); status_class="HOSTDOWN"; if(temp_status->problem_has_been_acknowledged==TRUE) status_bg_class="BGDOWNACK"; else if(temp_status->scheduled_downtime_depth>0) status_bg_class="BGDOWNSCHED"; else status_bg_class="BGDOWN"; } else if(temp_status->status==HOST_UNREACHABLE){ strncpy(status,"UNREACHABLE",sizeof(status)); status_class="HOSTUNREACHABLE"; if(temp_status->problem_has_been_acknowledged==TRUE) status_bg_class="BGUNREACHABLEACK"; else if(temp_status->scheduled_downtime_depth>0) status_bg_class="BGUNREACHABLESCHED"; else status_bg_class="BGUNREACHABLE"; } status[sizeof(status)-1]='\x0'; printf("\n"); /**** host name column ****/ /* find extended information for this host */ temp_hostextinfo=find_hostextinfo(temp_status->host_name); printf("\n"); /* state duration calculation... */ t=0; duration_error=FALSE; if(temp_status->last_state_change==(time_t)0){ if(program_start>current_time) duration_error=TRUE; else t=current_time-program_start; } else{ if(temp_status->last_state_change>current_time) duration_error=TRUE; else t=current_time-temp_status->last_state_change; } get_time_breakdown((unsigned long)t,&days,&hours,&minutes,&seconds); if(duration_error==TRUE) snprintf(state_duration,sizeof(state_duration)-1,"???"); else snprintf(state_duration,sizeof(state_duration)-1,"%2dd %2dh %2dm %2ds%s",days,hours,minutes,seconds,(temp_status->last_state_change==(time_t)0)?"+":""); state_duration[sizeof(state_duration)-1]='\x0'; /* the rest of the columns... */ printf("\n",status_class,status); printf("\n",status_bg_class,date_time); printf("\n",status_bg_class,state_duration); printf("\n",status_bg_class,(temp_status->plugin_output==NULL)?"":temp_status->plugin_output); printf("\n"); } } printf("
    Host Sort by host name (ascending)Sort by host name (descending)Status Sort by host status (ascending)Sort by host status (descending)Last Check Sort by last check time (ascending)Sort by last check time (descending)Duration Sort by state duration (ascending)Sort by state duration time (descending)Status Information
    ",status_class); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("
    \n"); printf("\n"); printf("\n"); printf("\n",status_class,EXTINFO_CGI,DISPLAY_HOST_INFO,url_encode(temp_status->host_name),temp_status->host_name); printf("\n"); printf("
    %s 
    \n"); printf("
    \n"); printf("\n"); printf("\n"); total_comments=number_of_host_comments(temp_host->name); if(temp_status->problem_has_been_acknowledged==TRUE){ printf("",EXTINFO_CGI,DISPLAY_HOST_INFO,url_encode(temp_status->host_name),url_images_path,ACKNOWLEDGEMENT_ICON,STATUS_ICON_WIDTH,STATUS_ICON_HEIGHT); } if(total_comments>0) printf("",EXTINFO_CGI,DISPLAY_HOST_INFO,url_encode(temp_status->host_name),url_images_path,COMMENT_ICON,STATUS_ICON_WIDTH,STATUS_ICON_HEIGHT,total_comments,(total_comments==1)?"":"s",total_comments,(total_comments==1)?"":"s"); if(temp_status->notifications_enabled==FALSE){ printf("",EXTINFO_CGI,DISPLAY_HOST_INFO,url_encode(temp_status->host_name),url_images_path,NOTIFICATIONS_DISABLED_ICON,STATUS_ICON_WIDTH,STATUS_ICON_HEIGHT); } if(temp_status->checks_enabled==FALSE){ printf("",EXTINFO_CGI,DISPLAY_HOST_INFO,url_encode(temp_status->host_name),url_images_path,DISABLED_ICON,STATUS_ICON_WIDTH,STATUS_ICON_HEIGHT); } if(temp_status->is_flapping==TRUE){ printf("",EXTINFO_CGI,DISPLAY_HOST_INFO,url_encode(temp_status->host_name),url_images_path,FLAPPING_ICON,STATUS_ICON_WIDTH,STATUS_ICON_HEIGHT); } if(temp_status->scheduled_downtime_depth>0){ printf("",EXTINFO_CGI,DISPLAY_HOST_INFO,url_encode(temp_status->host_name),url_images_path,SCHEDULED_DOWNTIME_ICON,STATUS_ICON_WIDTH,STATUS_ICON_HEIGHT); } if(temp_hostextinfo!=NULL){ if(temp_hostextinfo->notes_url!=NULL){ printf("\n"); } if(temp_hostextinfo->action_url!=NULL){ printf("\n"); } if(temp_hostextinfo->icon_image!=NULL){ printf("\n"); } } printf("\n",STATUS_CGI,url_encode(temp_status->host_name),url_images_path,STATUS_DETAIL_ICON); printf("\n"); printf("
    This host problem has been acknowledgedThis host has %d comment%s associated with itNotifications for this host have been disabledChecks of this host have been disabledThis host is flapping between statesThis host is currently in a period of scheduled downtime"); printf(""); printf("%s",url_images_path,NOTES_ICON,STATUS_ICON_WIDTH,STATUS_ICON_HEIGHT,"View Extra Host Notes","View Extra Host Notes"); printf(""); printf(""); printf(""); printf("%s",url_images_path,ACTION_ICON,STATUS_ICON_WIDTH,STATUS_ICON_HEIGHT,"Perform Extra Host Actions","Perform Extra Host Actions"); printf(""); printf(""); printf("",EXTINFO_CGI,DISPLAY_HOST_INFO,url_encode(temp_status->host_name)); printf("%s",STATUS_ICON_WIDTH,STATUS_ICON_HEIGHT,(temp_hostextinfo->icon_image_alt==NULL)?"":temp_hostextinfo->icon_image_alt,(temp_hostextinfo->icon_image_alt==NULL)?"":temp_hostextinfo->icon_image_alt); printf(""); printf("View Service Details For This Host
    \n"); printf("
    \n"); printf("
    %s%s%s%s 
    \n"); printf("
    \n"); /* if user couldn't see anything, print out some helpful info... */ if(user_has_seen_something==FALSE){ if(hoststatus_list!=NULL){ printf("

    It appears as though you do not have permission to view information for any of the hosts you requested...

    \n"); printf("

    If you believe this is an error, check the HTTP server authentication requirements for accessing this CGI
    "); printf("and check the authorization options in your CGI configuration file.

    \n"); } else{ printf("

    There doesn't appear to be any host status information in the status log...

    \n"); printf("Make sure that Nagios is running and that you have specified the location of you status log correctly in the configuration files.

    \n"); } } else printf("
    %d Matching Host Entries Displayed
    \n",total_entries); return; } /* show an overview of servicegroup(s)... */ void show_servicegroup_overviews(void){ servicegroup *temp_servicegroup=NULL; int current_column; int user_has_seen_something=FALSE; int servicegroup_error=FALSE; printf("

    \n"); printf("\n"); printf("\n"); printf(""); printf("\n"); printf("\n"); printf("\n"); printf("
    \n"); show_filters(); printf("\n"); printf("
    Service Overview For "); if(show_all_servicegroups==TRUE) printf("All Service Groups"); else printf("Service Group '%s'",servicegroup_name); printf("
    \n"); printf("
    "); printf("
    \n"); printf("

    \n"); /* display status overviews for all servicegroups */ if(show_all_servicegroups==TRUE){ printf("
    \n"); printf("\n"); current_column=1; /* loop through all servicegroups... */ for(temp_servicegroup=servicegroup_list;temp_servicegroup!=NULL;temp_servicegroup=temp_servicegroup->next){ /* make sure the user is authorized to view at least one host in this servicegroup */ if(is_authorized_for_servicegroup(temp_servicegroup,¤t_authdata)==FALSE) continue; if(current_column==1) printf("\n"); printf("\n"); if(current_column==overview_columns) printf("\n"); if(current_column\n"); printf("\n"); } printf("
    \n"); show_servicegroup_overview(temp_servicegroup); user_has_seen_something=TRUE; printf("
    \n"); printf("
    \n"); } /* else display overview for just a specific servicegroup */ else{ temp_servicegroup=find_servicegroup(servicegroup_name); if(temp_servicegroup!=NULL){ printf("

    \n"); printf("

    \n"); printf("
    \n"); if(is_authorized_for_servicegroup(temp_servicegroup,¤t_authdata)==TRUE){ show_servicegroup_overview(temp_servicegroup); user_has_seen_something=TRUE; } printf("
    \n"); printf("
    \n"); printf("

    \n"); } else{ printf("
    Sorry, but service group '%s' doesn't seem to exist...
    ",servicegroup_name); servicegroup_error=TRUE; } } /* if user couldn't see anything, print out some helpful info... */ if(user_has_seen_something==FALSE && servicegroup_error==FALSE){ printf("

    \n"); printf("

    \n"); if(servicegroup_list!=NULL){ printf("
    It appears as though you do not have permission to view information for any of the hosts you requested...
    \n"); printf("
    If you believe this is an error, check the HTTP server authentication requirements for accessing this CGI
    "); printf("and check the authorization options in your CGI configuration file.
    \n"); } else{ printf("
    There are no service groups defined.
    \n"); } printf("
    \n"); printf("

    \n"); } return; } /* shows an overview of a specific servicegroup... */ void show_servicegroup_overview(servicegroup *temp_servicegroup){ servicegroupmember *temp_member; host *temp_host; host *last_host; hoststatus *temp_hoststatus=NULL; int odd=0; printf("
    \n"); printf("%s",STATUS_CGI,url_encode(temp_servicegroup->group_name),temp_servicegroup->alias); printf(" (%s)",EXTINFO_CGI,DISPLAY_SERVICEGROUP_INFO,url_encode(temp_servicegroup->group_name),temp_servicegroup->group_name); printf("
    \n"); printf("
    \n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); /* find all hosts that have services that are members of the servicegroup */ last_host=NULL; for(temp_member=temp_servicegroup->members;temp_member!=NULL;temp_member=temp_member->next){ /* find the host */ temp_host=find_host(temp_member->host_name); if(temp_host==NULL) continue; /* skip this if it isn't a new host... */ if(temp_host==last_host) continue; /* find the host status */ temp_hoststatus=find_hoststatus(temp_host->name); if(temp_hoststatus==NULL) continue; /* make sure we only display hosts of the specified status levels */ if(!(host_status_types & temp_hoststatus->status)) continue; /* make sure we only display hosts that have the desired properties */ if(passes_host_properties_filter(temp_hoststatus)==FALSE) continue; if(odd) odd=0; else odd=1; show_servicegroup_hostgroup_member_overview(temp_hoststatus,odd,temp_servicegroup); last_host=temp_host; } printf("
    HostStatusServicesActions
    \n"); printf("
    \n"); return; } /* show a summary of servicegroup(s)... */ void show_servicegroup_summaries(void){ servicegroup *temp_servicegroup=NULL; int user_has_seen_something=FALSE; int servicegroup_error=FALSE; int odd=0; printf("

    \n"); printf("\n"); printf("\n"); printf(""); printf("\n"); printf("\n"); printf("\n"); printf("
    \n"); show_filters(); printf("\n"); printf("
    Status Summary For "); if(show_all_servicegroups==TRUE) printf("All Service Groups"); else printf("Service Group '%s'",servicegroup_name); printf("
    \n"); printf("
    "); printf("
    \n"); printf("

    \n"); printf("
    \n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); /* display status summary for all servicegroups */ if(show_all_servicegroups==TRUE){ /* loop through all servicegroups... */ for(temp_servicegroup=servicegroup_list;temp_servicegroup!=NULL;temp_servicegroup=temp_servicegroup->next){ /* make sure the user is authorized to view at least one host in this servicegroup */ if(is_authorized_for_servicegroup(temp_servicegroup,¤t_authdata)==FALSE) continue; if(odd==0) odd=1; else odd=0; /* show summary for this servicegroup */ show_servicegroup_summary(temp_servicegroup,odd); user_has_seen_something=TRUE; } } /* else just show summary for a specific servicegroup */ else{ temp_servicegroup=find_servicegroup(servicegroup_name); if(temp_servicegroup==NULL) servicegroup_error=TRUE; else{ show_servicegroup_summary(temp_servicegroup,1); user_has_seen_something=TRUE; } } printf("
    Service GroupHost Status TotalsService Status Totals
    \n"); printf("
    \n"); /* if user couldn't see anything, print out some helpful info... */ if(user_has_seen_something==FALSE && servicegroup_error==FALSE){ printf("

    \n"); if(servicegroup_list!=NULL){ printf("
    It appears as though you do not have permission to view information for any of the hosts you requested...
    \n"); printf("
    If you believe this is an error, check the HTTP server authentication requirements for accessing this CGI
    "); printf("and check the authorization options in your CGI configuration file.
    \n"); } else{ printf("
    There are no service groups defined.
    \n"); } printf("

    \n"); } /* we couldn't find the servicegroup */ else if(servicegroup_error==TRUE){ printf("

    \n"); printf("
    Sorry, but servicegroup '%s' doesn't seem to exist...
    \n",servicegroup_name); printf("

    \n"); } return; } /* displays status summary information for a specific servicegroup */ void show_servicegroup_summary(servicegroup *temp_servicegroup,int odd){ char *status_bg_class=""; if(odd==1) status_bg_class="Even"; else status_bg_class="Odd"; printf("\n",status_bg_class,status_bg_class); printf("%s ",STATUS_CGI,url_encode(temp_servicegroup->group_name),temp_servicegroup->alias); printf("(%s)",EXTINFO_CGI,DISPLAY_SERVICEGROUP_INFO,url_encode(temp_servicegroup->group_name),temp_servicegroup->group_name); printf(""); printf("",status_bg_class); show_servicegroup_host_totals_summary(temp_servicegroup); printf(""); printf("",status_bg_class); show_servicegroup_service_totals_summary(temp_servicegroup); printf(""); printf("\n"); return; } /* shows host total summary information for a specific servicegroup */ void show_servicegroup_host_totals_summary(servicegroup *temp_servicegroup){ servicegroupmember *temp_member; int total_up=0; int total_down=0; int total_unreachable=0; int total_pending=0; hoststatus *temp_hoststatus; host *temp_host; host *last_host; last_host=NULL; for(temp_member=temp_servicegroup->members;temp_member!=NULL;temp_member=temp_member->next){ /* find the host */ temp_host=find_host(temp_member->host_name); if(temp_host==NULL) continue; /* skip this if it isn't a new host... */ if(temp_host==last_host) continue; /* find the host status */ temp_hoststatus=find_hoststatus(temp_host->name); if(temp_hoststatus==NULL) continue; /* make sure we only display hosts of the specified status levels */ if(!(host_status_types & temp_hoststatus->status)) continue; /* make sure we only display hosts that have the desired properties */ if(passes_host_properties_filter(temp_hoststatus)==FALSE) continue; if(temp_hoststatus->status==HOST_UP) total_up++; else if(temp_hoststatus->status==HOST_DOWN) total_down++; else if(temp_hoststatus->status==HOST_UNREACHABLE) total_unreachable++; else total_pending++; last_host=temp_host; } printf("\n"); if(total_up>0) printf("\n",STATUS_CGI,url_encode(temp_servicegroup->group_name),HOST_UP,host_properties,total_up); if(total_down>0) printf("\n",STATUS_CGI,url_encode(temp_servicegroup->group_name),HOST_DOWN,host_properties,total_down); if(total_unreachable>0) printf("\n",STATUS_CGI,url_encode(temp_servicegroup->group_name),HOST_UNREACHABLE,host_properties,total_unreachable); if(total_pending>0) printf("\n",STATUS_CGI,url_encode(temp_servicegroup->group_name),HOST_PENDING,host_properties,total_pending); printf("
    %d UP
    %d DOWN
    %d UNREACHABLE
    %d PENDING
    \n"); if((total_up + total_down + total_unreachable + total_pending)==0) printf("No matching hosts"); return; } /* shows service total summary information for a specific servicegroup */ void show_servicegroup_service_totals_summary(servicegroup *temp_servicegroup){ servicegroupmember *temp_member; int total_ok=0; int total_warning=0; int total_unknown=0; int total_critical=0; int total_pending=0; servicestatus *temp_servicestatus; service *temp_service; hoststatus *temp_hoststatus; /* check all services... */ for(temp_member=temp_servicegroup->members;temp_member!=NULL;temp_member=temp_member->next){ /* find the service */ temp_service=find_service(temp_member->host_name,temp_member->service_description); if(temp_service==NULL) continue; /* find the service status */ temp_servicestatus=find_servicestatus(temp_service->host_name,temp_service->description); if(temp_servicestatus==NULL) continue; /* find the status of the associated host */ temp_hoststatus=find_hoststatus(temp_servicestatus->host_name); if(temp_hoststatus==NULL) continue; /* make sure we only display hosts of the specified status levels */ if(!(host_status_types & temp_hoststatus->status)) continue; /* make sure we only display hosts that have the desired properties */ if(passes_host_properties_filter(temp_hoststatus)==FALSE) continue; /* make sure we only display services of the specified status levels */ if(!(service_status_types & temp_servicestatus->status)) continue; /* make sure we only display services that have the desired properties */ if(passes_service_properties_filter(temp_servicestatus)==FALSE) continue; if(temp_servicestatus->status==SERVICE_CRITICAL) total_critical++; else if(temp_servicestatus->status==SERVICE_WARNING) total_warning++; else if(temp_servicestatus->status==SERVICE_UNKNOWN) total_unknown++; else if(temp_servicestatus->status==SERVICE_OK) total_ok++; else if(temp_servicestatus->status==SERVICE_PENDING) total_pending++; else total_ok++; } printf("\n"); if(total_ok>0) printf("\n",STATUS_CGI,url_encode(temp_servicegroup->group_name),SERVICE_OK,host_status_types,service_properties,host_properties,total_ok); if(total_warning>0) printf("\n",STATUS_CGI,url_encode(temp_servicegroup->group_name),SERVICE_WARNING,host_status_types,service_properties,host_properties,total_warning); if(total_unknown>0) printf("\n",STATUS_CGI,url_encode(temp_servicegroup->group_name),SERVICE_UNKNOWN,host_status_types,service_properties,host_properties,total_unknown); if(total_critical>0) printf("\n",STATUS_CGI,url_encode(temp_servicegroup->group_name),SERVICE_CRITICAL,host_status_types,service_properties,host_properties,total_critical); if(total_pending>0) printf("\n",STATUS_CGI,url_encode(temp_servicegroup->group_name),SERVICE_PENDING,host_status_types,service_properties,host_properties,total_pending); printf("
    %d OK
    %d WARNING
    %d UNKNOWN
    %d CRITICAL
    %d PENDING
    \n"); if((total_ok + total_warning + total_unknown + total_critical + total_pending)==0) printf("No matching services"); return; } /* show a grid layout of servicegroup(s)... */ void show_servicegroup_grids(void){ servicegroup *temp_servicegroup=NULL; int user_has_seen_something=FALSE; int servicegroup_error=FALSE; int odd=0; printf("

    \n"); printf("\n"); printf("\n"); printf(""); printf("\n"); printf("\n"); printf("\n"); printf("
    \n"); show_filters(); printf("\n"); printf("
    Status Grid For "); if(show_all_servicegroups==TRUE) printf("All Service Groups"); else printf("Service Group '%s'",servicegroup_name); printf("
    \n"); printf("
    "); printf("
    \n"); printf("

    \n"); /* display status grids for all servicegroups */ if(show_all_servicegroups==TRUE){ /* loop through all servicegroups... */ for(temp_servicegroup=servicegroup_list;temp_servicegroup!=NULL;temp_servicegroup=temp_servicegroup->next){ /* make sure the user is authorized to view at least one host in this servicegroup */ if(is_authorized_for_servicegroup(temp_servicegroup,¤t_authdata)==FALSE) continue; if(odd==0) odd=1; else odd=0; /* show grid for this servicegroup */ show_servicegroup_grid(temp_servicegroup); user_has_seen_something=TRUE; } } /* else just show grid for a specific servicegroup */ else{ temp_servicegroup=find_servicegroup(servicegroup_name); if(temp_servicegroup==NULL) servicegroup_error=TRUE; else{ show_servicegroup_grid(temp_servicegroup); user_has_seen_something=TRUE; } } /* if user couldn't see anything, print out some helpful info... */ if(user_has_seen_something==FALSE && servicegroup_error==FALSE){ printf("

    \n"); if(servicegroup_list!=NULL){ printf("
    It appears as though you do not have permission to view information for any of the hosts you requested...
    \n"); printf("
    If you believe this is an error, check the HTTP server authentication requirements for accessing this CGI
    "); printf("and check the authorization options in your CGI configuration file.
    \n"); } else{ printf("
    There are no service groups defined.
    \n"); } printf("

    \n"); } /* we couldn't find the servicegroup */ else if(servicegroup_error==TRUE){ printf("

    \n"); printf("
    Sorry, but servicegroup '%s' doesn't seem to exist...
    \n",servicegroup_name); printf("

    \n"); } return; } /* displays status grid for a specific servicegroup */ void show_servicegroup_grid(servicegroup *temp_servicegroup){ char *status_bg_class=""; char *host_status_class=""; char *service_status_class=""; servicegroupmember *temp_member; servicegroupmember *temp_member2; host *temp_host; host *last_host; hoststatus *temp_hoststatus; servicestatus *temp_servicestatus; hostextinfo *temp_hostextinfo; int odd=0; int current_item; printf("

    \n"); printf("

    \n"); printf("
    %s",STATUS_CGI,url_encode(temp_servicegroup->group_name),temp_servicegroup->alias); printf(" (%s)
    ",EXTINFO_CGI,DISPLAY_SERVICEGROUP_INFO,url_encode(temp_servicegroup->group_name),temp_servicegroup->group_name); printf("\n"); printf("\n"); /* find all hosts that have services that are members of the servicegroup */ last_host=NULL; for(temp_member=temp_servicegroup->members;temp_member!=NULL;temp_member=temp_member->next){ /* find the host */ temp_host=find_host(temp_member->host_name); if(temp_host==NULL) continue; /* get the status of the host */ temp_hoststatus=find_hoststatus(temp_host->name); if(temp_hoststatus==NULL) continue; /* skip this if it isn't a new host... */ if(temp_host==last_host) continue; if(odd==1){ status_bg_class="Even"; odd=0; } else{ status_bg_class="Odd"; odd=1; } printf("\n",status_bg_class); if(temp_hoststatus->status==HOST_DOWN) host_status_class="HOSTDOWN"; else if(temp_hoststatus->status==HOST_UNREACHABLE) host_status_class="HOSTUNREACHABLE"; else host_status_class=status_bg_class; printf("\n"); printf("\n"); printf("\n"); last_host=temp_host; } printf("
    HostServicesActions
    ",host_status_class); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("
    \n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("
    ",host_status_class); printf("%s\n",EXTINFO_CGI,DISPLAY_HOST_INFO,url_encode(temp_host->name),temp_host->name); printf("
    \n"); printf("
    \n"); printf("\n"); printf("\n"); temp_hostextinfo=find_hostextinfo(temp_host->name); if(temp_hostextinfo!=NULL){ if(temp_hostextinfo->icon_image!=NULL){ printf("\n"); printf("
    "); printf("\n",EXTINFO_CGI,DISPLAY_HOST_INFO,url_encode(temp_host->name)); printf("%s",STATUS_ICON_WIDTH,STATUS_ICON_HEIGHT,(temp_hostextinfo->icon_image_alt==NULL)?"":temp_hostextinfo->icon_image_alt,(temp_hostextinfo->icon_image_alt==NULL)?"":temp_hostextinfo->icon_image_alt); printf(""); printf("\n"); } } printf("
    \n"); printf("
    \n"); printf("
    ",host_status_class); /* display all services on the host that are part of the hostgroup */ current_item=1; for(temp_member2=temp_member;temp_member2!=NULL;temp_member2=temp_member2->next){ /* bail out if we've reached the end of the services that are associated with this servicegroup */ if(strcmp(temp_member2->host_name,temp_host->name)) break; if(current_item>max_grid_width && max_grid_width>0){ printf("
    \n"); current_item=1; } /* get the status of the service */ temp_servicestatus=find_servicestatus(temp_member2->host_name,temp_member2->service_description); if(temp_servicestatus==NULL) service_status_class="NULL"; else if(temp_servicestatus->status==SERVICE_OK) service_status_class="OK"; else if(temp_servicestatus->status==SERVICE_WARNING) service_status_class="WARNING"; else if(temp_servicestatus->status==SERVICE_UNKNOWN) service_status_class="UNKNOWN"; else if(temp_servicestatus->status==SERVICE_CRITICAL) service_status_class="CRITICAL"; else service_status_class="PENDING"; printf("%s ",url_encode(temp_servicestatus->description),service_status_class,temp_servicestatus->description); current_item++; } /* actions */ printf("
    ",host_status_class); printf("\n",EXTINFO_CGI,DISPLAY_HOST_INFO,url_encode(temp_host->name)); printf("%s",url_images_path,DETAIL_ICON,STATUS_ICON_WIDTH,STATUS_ICON_HEIGHT,"View Extended Information For This Host","View Extended Information For This Host"); printf(""); if(temp_hostextinfo!=NULL){ if(temp_hostextinfo->notes_url!=NULL){ printf(""); printf("%s",url_images_path,NOTES_ICON,STATUS_ICON_WIDTH,STATUS_ICON_HEIGHT,"View Extra Host Notes","View Extra Host Notes"); printf(""); } if(temp_hostextinfo->action_url!=NULL){ printf(""); printf("%s",url_images_path,ACTION_ICON,STATUS_ICON_WIDTH,STATUS_ICON_HEIGHT,"Perform Extra Host Actions","Perform Extra Host Actions"); printf(""); } } printf("View Service Details For This Host\n",STATUS_CGI,url_encode(temp_host->name),url_images_path,STATUS_DETAIL_ICON); #ifdef USE_STATUSMAP printf("%s",STATUSMAP_CGI,url_encode(temp_host->name),url_images_path,STATUSMAP_ICON,STATUS_ICON_WIDTH,STATUS_ICON_HEIGHT,"Locate Host On Map","Locate Host On Map"); #endif printf("
    \n"); printf("
    \n"); printf("

    \n"); return; } /* show an overview of hostgroup(s)... */ void show_hostgroup_overviews(void){ hostgroup *temp_hostgroup=NULL; int current_column; int user_has_seen_something=FALSE; int hostgroup_error=FALSE; printf("

    \n"); printf("\n"); printf("\n"); printf(""); printf("\n"); printf("\n"); printf("\n"); printf("
    \n"); show_filters(); printf("\n"); printf("
    Service Overview For "); if(show_all_hostgroups==TRUE) printf("All Host Groups"); else printf("Host Group '%s'",hostgroup_name); printf("
    \n"); printf("
    "); printf("
    \n"); printf("

    \n"); /* display status overviews for all hostgroups */ if(show_all_hostgroups==TRUE){ printf("
    \n"); printf("\n"); current_column=1; /* loop through all hostgroups... */ for(temp_hostgroup=hostgroup_list;temp_hostgroup!=NULL;temp_hostgroup=temp_hostgroup->next){ /* make sure the user is authorized to view this hostgroup */ if(is_authorized_for_hostgroup(temp_hostgroup,¤t_authdata)==FALSE) continue; if(current_column==1) printf("\n"); printf("\n"); if(current_column==overview_columns) printf("\n"); if(current_column\n"); printf("\n"); } printf("
    \n"); show_hostgroup_overview(temp_hostgroup); user_has_seen_something=TRUE; printf("
    \n"); printf("
    \n"); } /* else display overview for just a specific hostgroup */ else{ temp_hostgroup=find_hostgroup(hostgroup_name); if(temp_hostgroup!=NULL){ printf("

    \n"); printf("

    \n"); printf("
    \n"); if(is_authorized_for_hostgroup(temp_hostgroup,¤t_authdata)==TRUE){ show_hostgroup_overview(temp_hostgroup); user_has_seen_something=TRUE; } printf("
    \n"); printf("
    \n"); printf("

    \n"); } else{ printf("
    Sorry, but host group '%s' doesn't seem to exist...
    ",hostgroup_name); hostgroup_error=TRUE; } } /* if user couldn't see anything, print out some helpful info... */ if(user_has_seen_something==FALSE && hostgroup_error==FALSE){ printf("

    \n"); printf("

    \n"); if(hoststatus_list!=NULL){ printf("
    It appears as though you do not have permission to view information for any of the hosts you requested...
    \n"); printf("
    If you believe this is an error, check the HTTP server authentication requirements for accessing this CGI
    "); printf("and check the authorization options in your CGI configuration file.
    \n"); } else{ printf("
    There doesn't appear to be any host status information in the status log...

    \n"); printf("Make sure that Nagios is running and that you have specified the location of you status log correctly in the configuration files.
    \n"); } printf("
    \n"); printf("

    \n"); } return; } /* shows an overview of a specific hostgroup... */ void show_hostgroup_overview(hostgroup *hstgrp){ hostgroupmember *temp_member; host *temp_host; hoststatus *temp_hoststatus=NULL; int odd=0; /* make sure the user is authorized to view this hostgroup */ if(is_authorized_for_hostgroup(hstgrp,¤t_authdata)==FALSE) return; printf("
    \n"); printf("%s",STATUS_CGI,url_encode(hstgrp->group_name),hstgrp->alias); printf(" (%s)",EXTINFO_CGI,DISPLAY_HOSTGROUP_INFO,url_encode(hstgrp->group_name),hstgrp->group_name); printf("
    \n"); printf("
    \n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); /* find all the hosts that belong to the hostgroup */ for(temp_member=hstgrp->members;temp_member!=NULL;temp_member=temp_member->next){ /* find the host... */ temp_host=find_host(temp_member->host_name); if(temp_host==NULL) continue; /* find the host status */ temp_hoststatus=find_hoststatus(temp_host->name); if(temp_hoststatus==NULL) continue; /* make sure we only display hosts of the specified status levels */ if(!(host_status_types & temp_hoststatus->status)) continue; /* make sure we only display hosts that have the desired properties */ if(passes_host_properties_filter(temp_hoststatus)==FALSE) continue; if(odd) odd=0; else odd=1; show_servicegroup_hostgroup_member_overview(temp_hoststatus,odd,NULL); } printf("
    HostStatusServicesActions
    \n"); printf("
    \n"); return; } /* shows a host status overview... */ void show_servicegroup_hostgroup_member_overview(hoststatus *hststatus,int odd,void *data){ char status[MAX_INPUT_BUFFER]; char *status_bg_class=""; char *status_class=""; hostextinfo *temp_hostextinfo; if(hststatus->status==HOST_PENDING){ strncpy(status,"PENDING",sizeof(status)); status_class="HOSTPENDING"; status_bg_class=(odd)?"Even":"Odd"; } else if(hststatus->status==HOST_UP){ strncpy(status,"UP",sizeof(status)); status_class="HOSTUP"; status_bg_class=(odd)?"Even":"Odd"; } else if(hststatus->status==HOST_DOWN){ strncpy(status,"DOWN",sizeof(status)); status_class="HOSTDOWN"; status_bg_class="HOSTDOWN"; } else if(hststatus->status==HOST_UNREACHABLE){ strncpy(status,"UNREACHABLE",sizeof(status)); status_class="HOSTUNREACHABLE"; status_bg_class="HOSTUNREACHABLE"; } status[sizeof(status)-1]='\x0'; printf("\n",status_bg_class); /* find extended information for this host */ temp_hostextinfo=find_hostextinfo(hststatus->host_name); printf("\n",status_bg_class); printf("\n"); printf("\n",status_bg_class); printf("\n",status_bg_class,STATUS_CGI,url_encode(hststatus->host_name),hststatus->host_name); if(temp_hostextinfo!=NULL){ if(temp_hostextinfo->icon_image!=NULL){ printf("\n",status_bg_class); printf("\n"); } } printf("\n"); printf("
    %s",status_bg_class); printf("",EXTINFO_CGI,DISPLAY_HOST_INFO,url_encode(hststatus->host_name)); printf("%s",STATUS_ICON_WIDTH,STATUS_ICON_HEIGHT,(temp_hostextinfo->icon_image_alt==NULL)?"":temp_hostextinfo->icon_image_alt,(temp_hostextinfo->icon_image_alt==NULL)?"":temp_hostextinfo->icon_image_alt); printf(""); printf("
    \n"); printf("\n"); printf("%s\n",status_class,status); printf("\n",status_bg_class); show_servicegroup_hostgroup_member_service_status_totals(hststatus->host_name,data); printf("\n"); printf("",status_bg_class); printf("View Extended Information For This Host\n",EXTINFO_CGI,DISPLAY_HOST_INFO,url_encode(hststatus->host_name),url_images_path,DETAIL_ICON); if(temp_hostextinfo!=NULL){ if(temp_hostextinfo->notes_url!=NULL){ printf(""); printf("%s",url_images_path,NOTES_ICON,STATUS_ICON_WIDTH,STATUS_ICON_HEIGHT,"View Extra Host Notes","View Extra Host Notes"); printf(""); } if(temp_hostextinfo->action_url!=NULL){ printf(""); printf("%s",url_images_path,ACTION_ICON,STATUS_ICON_WIDTH,STATUS_ICON_HEIGHT,"Perform Extra Host Actions","Perform Extra Host Actions"); printf(""); } } printf("View Service Details For This Host\n",STATUS_CGI,url_encode(hststatus->host_name),url_images_path,STATUS_DETAIL_ICON); #ifdef USE_STATUSMAP printf("%s",STATUSMAP_CGI,url_encode(hststatus->host_name),url_images_path,STATUSMAP_ICON,STATUS_ICON_WIDTH,STATUS_ICON_HEIGHT,"Locate Host On Map","Locate Host On Map"); #endif printf(""); printf("\n"); return; } void show_servicegroup_hostgroup_member_service_status_totals(char *host_name,void *data){ int total_ok=0; int total_warning=0; int total_unknown=0; int total_critical=0; int total_pending=0; servicestatus *temp_servicestatus; service *temp_service; servicegroup *temp_servicegroup=NULL; char temp_buffer[MAX_INPUT_BUFFER]; if(display_type==DISPLAY_SERVICEGROUPS) temp_servicegroup=(servicegroup *)data; /* check all services... */ for(temp_servicestatus=servicestatus_list;temp_servicestatus!=NULL;temp_servicestatus=temp_servicestatus->next){ if(!strcmp(host_name,temp_servicestatus->host_name)){ /* make sure the user is authorized to see this service... */ temp_service=find_service(temp_servicestatus->host_name,temp_servicestatus->description); if(is_authorized_for_service(temp_service,¤t_authdata)==FALSE) continue; if(display_type==DISPLAY_SERVICEGROUPS){ /* is this service a member of the servicegroup? */ if(is_service_member_of_servicegroup(temp_servicegroup,temp_service)==FALSE) continue; } /* make sure we only display services of the specified status levels */ if(!(service_status_types & temp_servicestatus->status)) continue; /* make sure we only display services that have the desired properties */ if(passes_service_properties_filter(temp_servicestatus)==FALSE) continue; if(temp_servicestatus->status==SERVICE_CRITICAL) total_critical++; else if(temp_servicestatus->status==SERVICE_WARNING) total_warning++; else if(temp_servicestatus->status==SERVICE_UNKNOWN) total_unknown++; else if(temp_servicestatus->status==SERVICE_OK) total_ok++; else if(temp_servicestatus->status==SERVICE_PENDING) total_pending++; else total_ok++; } } printf("\n"); if(display_type==DISPLAY_SERVICEGROUPS) snprintf(temp_buffer,sizeof(temp_buffer)-1,"servicegroup=%s&style=detail",url_encode(temp_servicegroup->group_name)); else snprintf(temp_buffer,sizeof(temp_buffer)-1,"host=%s",url_encode(host_name)); temp_buffer[sizeof(temp_buffer)-1]='\x0'; if(total_ok>0) printf("\n",STATUS_CGI,temp_buffer,SERVICE_OK,host_status_types,service_properties,host_properties,total_ok); if(total_warning>0) printf("\n",STATUS_CGI,temp_buffer,SERVICE_WARNING,host_status_types,service_properties,host_properties,total_warning); if(total_unknown>0) printf("\n",STATUS_CGI,temp_buffer,SERVICE_UNKNOWN,host_status_types,service_properties,host_properties,total_unknown); if(total_critical>0) printf("\n",STATUS_CGI,temp_buffer,SERVICE_CRITICAL,host_status_types,service_properties,host_properties,total_critical); if(total_pending>0) printf("\n",STATUS_CGI,temp_buffer,SERVICE_PENDING,host_status_types,service_properties,host_properties,total_pending); printf("
    %d OK
    %d WARNING
    %d UNKNOWN
    %d CRITICAL
    %d PENDING
    \n"); if((total_ok + total_warning + total_unknown + total_critical + total_pending)==0) printf("No matching services"); return; } /* show a summary of hostgroup(s)... */ void show_hostgroup_summaries(void){ hostgroup *temp_hostgroup=NULL; int user_has_seen_something=FALSE; int hostgroup_error=FALSE; int odd=0; printf("

    \n"); printf("\n"); printf("\n"); printf(""); printf("\n"); printf("\n"); printf("\n"); printf("
    \n"); show_filters(); printf("\n"); printf("
    Status Summary For "); if(show_all_hostgroups==TRUE) printf("All Host Groups"); else printf("Host Group '%s'",hostgroup_name); printf("
    \n"); printf("
    "); printf("
    \n"); printf("

    \n"); printf("
    \n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); /* display status summary for all hostgroups */ if(show_all_hostgroups==TRUE){ /* loop through all hostgroups... */ for(temp_hostgroup=hostgroup_list;temp_hostgroup!=NULL;temp_hostgroup=temp_hostgroup->next){ /* make sure the user is authorized to view this hostgroup */ if(is_authorized_for_hostgroup(temp_hostgroup,¤t_authdata)==FALSE) continue; if(odd==0) odd=1; else odd=0; /* show summary for this hostgroup */ show_hostgroup_summary(temp_hostgroup,odd); user_has_seen_something=TRUE; } } /* else just show summary for a specific hostgroup */ else{ temp_hostgroup=find_hostgroup(hostgroup_name); if(temp_hostgroup==NULL) hostgroup_error=TRUE; else{ show_hostgroup_summary(temp_hostgroup,1); user_has_seen_something=TRUE; } } printf("
    Host GroupHost Status TotalsService Status Totals
    \n"); printf("
    \n"); /* if user couldn't see anything, print out some helpful info... */ if(user_has_seen_something==FALSE && hostgroup_error==FALSE){ printf("

    \n"); if(hoststatus_list!=NULL){ printf("
    It appears as though you do not have permission to view information for any of the hosts you requested...
    \n"); printf("
    If you believe this is an error, check the HTTP server authentication requirements for accessing this CGI
    "); printf("and check the authorization options in your CGI configuration file.
    \n"); } else{ printf("
    There doesn't appear to be any host status information in the status log...

    \n"); printf("Make sure that Nagios is running and that you have specified the location of you status log correctly in the configuration files.
    \n"); } printf("

    \n"); } /* we couldn't find the hostgroup */ else if(hostgroup_error==TRUE){ printf("

    \n"); printf("
    Sorry, but hostgroup '%s' doesn't seem to exist...
    \n",hostgroup_name); printf("

    \n"); } return; } /* displays status summary information for a specific hostgroup */ void show_hostgroup_summary(hostgroup *temp_hostgroup,int odd){ char *status_bg_class=""; if(odd==1) status_bg_class="Even"; else status_bg_class="Odd"; printf("\n",status_bg_class,status_bg_class); printf("%s ",STATUS_CGI,url_encode(temp_hostgroup->group_name),temp_hostgroup->alias); printf("(%s)",EXTINFO_CGI,DISPLAY_HOSTGROUP_INFO,url_encode(temp_hostgroup->group_name),temp_hostgroup->group_name); printf(""); printf("",status_bg_class); show_hostgroup_host_totals_summary(temp_hostgroup); printf(""); printf("",status_bg_class); show_hostgroup_service_totals_summary(temp_hostgroup); printf(""); printf("\n"); return; } /* shows host total summary information for a specific hostgroup */ void show_hostgroup_host_totals_summary(hostgroup *temp_hostgroup){ hostgroupmember *temp_member; int total_up=0; int total_down=0; int total_unreachable=0; int total_pending=0; hoststatus *temp_hoststatus; host *temp_host; /* find all the hosts that belong to the hostgroup */ for(temp_member=temp_hostgroup->members;temp_member!=NULL;temp_member=temp_member->next){ /* find the host... */ temp_host=find_host(temp_member->host_name); if(temp_host==NULL) continue; /* find the host status */ temp_hoststatus=find_hoststatus(temp_host->name); if(temp_hoststatus==NULL) continue; /* make sure we only display hosts of the specified status levels */ if(!(host_status_types & temp_hoststatus->status)) continue; /* make sure we only display hosts that have the desired properties */ if(passes_host_properties_filter(temp_hoststatus)==FALSE) continue; if(temp_hoststatus->status==HOST_UP) total_up++; else if(temp_hoststatus->status==HOST_DOWN) total_down++; else if(temp_hoststatus->status==HOST_UNREACHABLE) total_unreachable++; else total_pending++; } printf("\n"); if(total_up>0) printf("\n",STATUS_CGI,url_encode(temp_hostgroup->group_name),HOST_UP,host_properties,total_up); if(total_down>0) printf("\n",STATUS_CGI,url_encode(temp_hostgroup->group_name),HOST_DOWN,host_properties,total_down); if(total_unreachable>0) printf("\n",STATUS_CGI,url_encode(temp_hostgroup->group_name),HOST_UNREACHABLE,host_properties,total_unreachable); if(total_pending>0) printf("\n",STATUS_CGI,url_encode(temp_hostgroup->group_name),HOST_PENDING,host_properties,total_pending); printf("
    %d UP
    %d DOWN
    %d UNREACHABLE
    %d PENDING
    \n"); if((total_up + total_down + total_unreachable + total_pending)==0) printf("No matching hosts"); return; } /* shows service total summary information for a specific hostgroup */ void show_hostgroup_service_totals_summary(hostgroup *temp_hostgroup){ int total_ok=0; int total_warning=0; int total_unknown=0; int total_critical=0; int total_pending=0; servicestatus *temp_servicestatus; hoststatus *temp_hoststatus; host *temp_host; /* check all services... */ for(temp_servicestatus=servicestatus_list;temp_servicestatus!=NULL;temp_servicestatus=temp_servicestatus->next){ /* find the host this service is associated with */ temp_host=find_host(temp_servicestatus->host_name); if(temp_host==NULL) continue; /* see if this service is associated with a host in the specified hostgroup */ if(is_host_member_of_hostgroup(temp_hostgroup,temp_host)==FALSE) continue; /* find the status of the associated host */ temp_hoststatus=find_hoststatus(temp_servicestatus->host_name); if(temp_hoststatus==NULL) continue; /* make sure we only display hosts of the specified status levels */ if(!(host_status_types & temp_hoststatus->status)) continue; /* make sure we only display hosts that have the desired properties */ if(passes_host_properties_filter(temp_hoststatus)==FALSE) continue; /* make sure we only display services of the specified status levels */ if(!(service_status_types & temp_servicestatus->status)) continue; /* make sure we only display services that have the desired properties */ if(passes_service_properties_filter(temp_servicestatus)==FALSE) continue; if(temp_servicestatus->status==SERVICE_CRITICAL) total_critical++; else if(temp_servicestatus->status==SERVICE_WARNING) total_warning++; else if(temp_servicestatus->status==SERVICE_UNKNOWN) total_unknown++; else if(temp_servicestatus->status==SERVICE_OK) total_ok++; else if(temp_servicestatus->status==SERVICE_PENDING) total_pending++; else total_ok++; } printf("\n"); if(total_ok>0) printf("\n",STATUS_CGI,url_encode(temp_hostgroup->group_name),SERVICE_OK,host_status_types,service_properties,host_properties,total_ok); if(total_warning>0) printf("\n",STATUS_CGI,url_encode(temp_hostgroup->group_name),SERVICE_WARNING,host_status_types,service_properties,host_properties,total_warning); if(total_unknown>0) printf("\n",STATUS_CGI,url_encode(temp_hostgroup->group_name),SERVICE_UNKNOWN,host_status_types,service_properties,host_properties,total_unknown); if(total_critical>0) printf("\n",STATUS_CGI,url_encode(temp_hostgroup->group_name),SERVICE_CRITICAL,host_status_types,service_properties,host_properties,total_critical); if(total_pending>0) printf("\n",STATUS_CGI,url_encode(temp_hostgroup->group_name),SERVICE_PENDING,host_status_types,service_properties,host_properties,total_pending); printf("
    %d OK
    %d WARNING
    %d UNKNOWN
    %d CRITICAL
    %d PENDING
    \n"); if((total_ok + total_warning + total_unknown + total_critical + total_pending)==0) printf("No matching services"); return; } /* show a grid layout of hostgroup(s)... */ void show_hostgroup_grids(void){ hostgroup *temp_hostgroup=NULL; int user_has_seen_something=FALSE; int hostgroup_error=FALSE; int odd=0; printf("

    \n"); printf("\n"); printf("\n"); printf(""); printf("\n"); printf("\n"); printf("\n"); printf("
    \n"); show_filters(); printf("\n"); printf("
    Status Grid For "); if(show_all_hostgroups==TRUE) printf("All Host Groups"); else printf("Host Group '%s'",hostgroup_name); printf("
    \n"); printf("
    "); printf("
    \n"); printf("

    \n"); /* display status grids for all hostgroups */ if(show_all_hostgroups==TRUE){ /* loop through all hostgroups... */ for(temp_hostgroup=hostgroup_list;temp_hostgroup!=NULL;temp_hostgroup=temp_hostgroup->next){ /* make sure the user is authorized to view this hostgroup */ if(is_authorized_for_hostgroup(temp_hostgroup,¤t_authdata)==FALSE) continue; if(odd==0) odd=1; else odd=0; /* show grid for this hostgroup */ show_hostgroup_grid(temp_hostgroup); user_has_seen_something=TRUE; } } /* else just show grid for a specific hostgroup */ else{ temp_hostgroup=find_hostgroup(hostgroup_name); if(temp_hostgroup==NULL) hostgroup_error=TRUE; else{ show_hostgroup_grid(temp_hostgroup); user_has_seen_something=TRUE; } } /* if user couldn't see anything, print out some helpful info... */ if(user_has_seen_something==FALSE && hostgroup_error==FALSE){ printf("

    \n"); if(hoststatus_list!=NULL){ printf("
    It appears as though you do not have permission to view information for any of the hosts you requested...
    \n"); printf("
    If you believe this is an error, check the HTTP server authentication requirements for accessing this CGI
    "); printf("and check the authorization options in your CGI configuration file.
    \n"); } else{ printf("
    There doesn't appear to be any host status information in the status log...

    \n"); printf("Make sure that Nagios is running and that you have specified the location of you status log correctly in the configuration files.
    \n"); } printf("

    \n"); } /* we couldn't find the hostgroup */ else if(hostgroup_error==TRUE){ printf("

    \n"); printf("
    Sorry, but hostgroup '%s' doesn't seem to exist...
    \n",hostgroup_name); printf("

    \n"); } return; } /* displays status grid for a specific hostgroup */ void show_hostgroup_grid(hostgroup *temp_hostgroup){ hostgroupmember *temp_member; char *status_bg_class=""; char *host_status_class=""; char *service_status_class=""; host *temp_host; service *temp_service; hoststatus *temp_hoststatus; servicestatus *temp_servicestatus; hostextinfo *temp_hostextinfo; int odd=0; int current_item; printf("

    \n"); printf("

    \n"); printf("
    %s",STATUS_CGI,url_encode(temp_hostgroup->group_name),temp_hostgroup->alias); printf(" (%s)
    ",EXTINFO_CGI,DISPLAY_HOSTGROUP_INFO,url_encode(temp_hostgroup->group_name),temp_hostgroup->group_name); printf("\n"); printf("\n"); /* find all the hosts that belong to the hostgroup */ for(temp_member=temp_hostgroup->members;temp_member!=NULL;temp_member=temp_member->next){ /* find the host... */ temp_host=find_host(temp_member->host_name); if(temp_host==NULL) continue; /* find the host status */ temp_hoststatus=find_hoststatus(temp_host->name); if(temp_hoststatus==NULL) continue; if(odd==1){ status_bg_class="Even"; odd=0; } else{ status_bg_class="Odd"; odd=1; } printf("\n",status_bg_class); /* get the status of the host */ if(temp_hoststatus->status==HOST_DOWN) host_status_class="HOSTDOWN"; else if(temp_hoststatus->status==HOST_UNREACHABLE) host_status_class="HOSTUNREACHABLE"; else host_status_class=status_bg_class; printf("\n"); printf("\n"); /* actions */ printf("\n"); printf("\n"); } printf("
    HostServicesActions
    ",host_status_class); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("
    \n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("
    ",host_status_class); printf("%s\n",EXTINFO_CGI,DISPLAY_HOST_INFO,url_encode(temp_host->name),temp_host->name); printf("
    \n"); printf("
    \n"); printf("\n"); printf("\n"); temp_hostextinfo=find_hostextinfo(temp_host->name); if(temp_hostextinfo!=NULL){ if(temp_hostextinfo->icon_image!=NULL){ printf("\n"); printf("
    "); printf("\n",EXTINFO_CGI,DISPLAY_HOST_INFO,url_encode(temp_host->name)); printf("%s",STATUS_ICON_WIDTH,STATUS_ICON_HEIGHT,(temp_hostextinfo->icon_image_alt==NULL)?"":temp_hostextinfo->icon_image_alt,(temp_hostextinfo->icon_image_alt==NULL)?"":temp_hostextinfo->icon_image_alt); printf(""); printf("\n"); } } printf("\n"); printf("
    \n"); printf("
    \n"); printf("
    ",host_status_class); /* display all services on the host */ current_item=1; for(temp_service=service_list;temp_service;temp_service=temp_service->next){ /* skip this service if it's not associate with the host */ if(strcmp(temp_service->host_name,temp_host->name)) continue; if(current_item>max_grid_width && max_grid_width>0){ printf("
    \n"); current_item=1; } /* get the status of the service */ temp_servicestatus=find_servicestatus(temp_service->host_name,temp_service->description); if(temp_servicestatus==NULL) service_status_class="NULL"; else if(temp_servicestatus->status==SERVICE_OK) service_status_class="OK"; else if(temp_servicestatus->status==SERVICE_WARNING) service_status_class="WARNING"; else if(temp_servicestatus->status==SERVICE_UNKNOWN) service_status_class="UNKNOWN"; else if(temp_servicestatus->status==SERVICE_CRITICAL) service_status_class="CRITICAL"; else service_status_class="PENDING"; printf("%s ",url_encode(temp_servicestatus->description),service_status_class,temp_servicestatus->description); current_item++; } printf("
    ",host_status_class); printf("\n",EXTINFO_CGI,DISPLAY_HOST_INFO,url_encode(temp_host->name)); printf("%s",url_images_path,DETAIL_ICON,STATUS_ICON_WIDTH,STATUS_ICON_HEIGHT,"View Extended Information For This Host","View Extended Information For This Host"); printf(""); if(temp_hostextinfo!=NULL){ if(temp_hostextinfo->notes_url!=NULL){ printf(""); printf("%s",url_images_path,NOTES_ICON,STATUS_ICON_WIDTH,STATUS_ICON_HEIGHT,"View Extra Host Notes","View Extra Host Notes"); printf(""); } if(temp_hostextinfo->action_url!=NULL){ printf(""); printf("%s",url_images_path,ACTION_ICON,STATUS_ICON_WIDTH,STATUS_ICON_HEIGHT,"Perform Extra Host Actions","Perform Extra Host Actions"); printf(""); } } printf("View Service Details For This Host\n",STATUS_CGI,url_encode(temp_host->name),url_images_path,STATUS_DETAIL_ICON); #ifdef USE_STATUSMAP printf("%s",STATUSMAP_CGI,url_encode(temp_host->name),url_images_path,STATUSMAP_ICON,STATUS_ICON_WIDTH,STATUS_ICON_HEIGHT,"Locate Host On Map","Locate Host On Map"); #endif printf("
    \n"); printf("
    \n"); printf("

    \n"); return; } /******************************************************************/ /********** SERVICE SORTING & FILTERING FUNCTIONS ***************/ /******************************************************************/ /* sorts the service list */ int sort_services(int s_type, int s_option){ servicesort *new_servicesort; servicesort *last_servicesort; servicesort *temp_servicesort; servicestatus *temp_svcstatus; if(s_type==SORT_NONE) return ERROR; if(servicestatus_list==NULL) return ERROR; /* sort all services status entries */ for(temp_svcstatus=servicestatus_list;temp_svcstatus!=NULL;temp_svcstatus=temp_svcstatus->next){ /* allocate memory for a new sort structure */ new_servicesort=(servicesort *)malloc(sizeof(servicesort)); if(new_servicesort==NULL) return ERROR; new_servicesort->svcstatus=temp_svcstatus; last_servicesort=servicesort_list; for(temp_servicesort=servicesort_list;temp_servicesort!=NULL;temp_servicesort=temp_servicesort->next){ if(compare_servicesort_entries(s_type,s_option,new_servicesort,temp_servicesort)==TRUE){ new_servicesort->next=temp_servicesort; if(temp_servicesort==servicesort_list) servicesort_list=new_servicesort; else last_servicesort->next=new_servicesort; break; } else last_servicesort=temp_servicesort; } if(servicesort_list==NULL){ new_servicesort->next=NULL; servicesort_list=new_servicesort; } else if(temp_servicesort==NULL){ new_servicesort->next=NULL; last_servicesort->next=new_servicesort; } } return OK; } int compare_servicesort_entries(int s_type, int s_option, servicesort *new_servicesort, servicesort *temp_servicesort){ servicestatus *new_svcstatus; servicestatus *temp_svcstatus; time_t nt; time_t tt; new_svcstatus=new_servicesort->svcstatus; temp_svcstatus=temp_servicesort->svcstatus; if(s_type==SORT_ASCENDING){ if(s_option==SORT_LASTCHECKTIME){ if(new_svcstatus->last_check < temp_svcstatus->last_check) return TRUE; else return FALSE; } else if(s_option==SORT_CURRENTATTEMPT){ if(new_svcstatus->current_attempt < temp_svcstatus->current_attempt) return TRUE; else return FALSE; } else if(s_option==SORT_SERVICESTATUS){ if(new_svcstatus->status <= temp_svcstatus->status) return TRUE; else return FALSE; } else if(s_option==SORT_HOSTNAME){ if(strcasecmp(new_svcstatus->host_name,temp_svcstatus->host_name)<0) return TRUE; else return FALSE; } else if(s_option==SORT_SERVICENAME){ if(strcasecmp(new_svcstatus->description,temp_svcstatus->description)<0) return TRUE; else return FALSE; } else if(s_option==SORT_STATEDURATION){ if(new_svcstatus->last_state_change==(time_t)0) nt=(program_start>current_time)?0:(current_time-program_start); else nt=(new_svcstatus->last_state_change>current_time)?0:(current_time-new_svcstatus->last_state_change); if(temp_svcstatus->last_state_change==(time_t)0) tt=(program_start>current_time)?0:(current_time-program_start); else tt=(temp_svcstatus->last_state_change>current_time)?0:(current_time-temp_svcstatus->last_state_change); if(ntlast_check > temp_svcstatus->last_check) return TRUE; else return FALSE; } else if(s_option==SORT_CURRENTATTEMPT){ if(new_svcstatus->current_attempt > temp_svcstatus->current_attempt) return TRUE; else return FALSE; } else if(s_option==SORT_SERVICESTATUS){ if(new_svcstatus->status > temp_svcstatus->status) return TRUE; else return FALSE; } else if(s_option==SORT_HOSTNAME){ if(strcasecmp(new_svcstatus->host_name,temp_svcstatus->host_name)>0) return TRUE; else return FALSE; } else if(s_option==SORT_SERVICENAME){ if(strcasecmp(new_svcstatus->description,temp_svcstatus->description)>0) return TRUE; else return FALSE; } else if(s_option==SORT_STATEDURATION){ if(new_svcstatus->last_state_change==(time_t)0) nt=(program_start>current_time)?0:(current_time-program_start); else nt=(new_svcstatus->last_state_change>current_time)?0:(current_time-new_svcstatus->last_state_change); if(temp_svcstatus->last_state_change==(time_t)0) tt=(program_start>current_time)?0:(current_time-program_start); else tt=(temp_svcstatus->last_state_change>current_time)?0:(current_time-temp_svcstatus->last_state_change); if(nt>tt) return TRUE; else return FALSE; } } return TRUE; } /* sorts the host list */ int sort_hosts(int s_type, int s_option){ hostsort *new_hostsort; hostsort *last_hostsort; hostsort *temp_hostsort; hoststatus *temp_hststatus; if(s_type==SORT_NONE) return ERROR; if(hoststatus_list==NULL) return ERROR; /* sort all hosts status entries */ for(temp_hststatus=hoststatus_list;temp_hststatus!=NULL;temp_hststatus=temp_hststatus->next){ /* allocate memory for a new sort structure */ new_hostsort=(hostsort *)malloc(sizeof(hostsort)); if(new_hostsort==NULL) return ERROR; new_hostsort->hststatus=temp_hststatus; last_hostsort=hostsort_list; for(temp_hostsort=hostsort_list;temp_hostsort!=NULL;temp_hostsort=temp_hostsort->next){ if(compare_hostsort_entries(s_type,s_option,new_hostsort,temp_hostsort)==TRUE){ new_hostsort->next=temp_hostsort; if(temp_hostsort==hostsort_list) hostsort_list=new_hostsort; else last_hostsort->next=new_hostsort; break; } else last_hostsort=temp_hostsort; } if(hostsort_list==NULL){ new_hostsort->next=NULL; hostsort_list=new_hostsort; } else if(temp_hostsort==NULL){ new_hostsort->next=NULL; last_hostsort->next=new_hostsort; } } return OK; } int compare_hostsort_entries(int s_type, int s_option, hostsort *new_hostsort, hostsort *temp_hostsort){ hoststatus *new_hststatus; hoststatus *temp_hststatus; time_t nt; time_t tt; new_hststatus=new_hostsort->hststatus; temp_hststatus=temp_hostsort->hststatus; if(s_type==SORT_ASCENDING){ if(s_option==SORT_LASTCHECKTIME){ if(new_hststatus->last_check < temp_hststatus->last_check) return TRUE; else return FALSE; } else if(s_option==SORT_HOSTSTATUS){ if(new_hststatus->status <= temp_hststatus->status) return TRUE; else return FALSE; } else if(s_option==SORT_HOSTNAME){ if(strcasecmp(new_hststatus->host_name,temp_hststatus->host_name)<0) return TRUE; else return FALSE; } else if(s_option==SORT_STATEDURATION){ if(new_hststatus->last_state_change==(time_t)0) nt=(program_start>current_time)?0:(current_time-program_start); else nt=(new_hststatus->last_state_change>current_time)?0:(current_time-new_hststatus->last_state_change); if(temp_hststatus->last_state_change==(time_t)0) tt=(program_start>current_time)?0:(current_time-program_start); else tt=(temp_hststatus->last_state_change>current_time)?0:(current_time-temp_hststatus->last_state_change); if(ntlast_check > temp_hststatus->last_check) return TRUE; else return FALSE; } else if(s_option==SORT_HOSTSTATUS){ if(new_hststatus->status > temp_hststatus->status) return TRUE; else return FALSE; } else if(s_option==SORT_HOSTNAME){ if(strcasecmp(new_hststatus->host_name,temp_hststatus->host_name)>0) return TRUE; else return FALSE; } else if(s_option==SORT_STATEDURATION){ if(new_hststatus->last_state_change==(time_t)0) nt=(program_start>current_time)?0:(current_time-program_start); else nt=(new_hststatus->last_state_change>current_time)?0:(current_time-new_hststatus->last_state_change); if(temp_hststatus->last_state_change==(time_t)0) tt=(program_start>current_time)?0:(current_time-program_start); else tt=(temp_hststatus->last_state_change>current_time)?0:(current_time-temp_hststatus->last_state_change); if(nt>tt) return TRUE; else return FALSE; } } return TRUE; } /* free all memory allocated to the servicesort structures */ void free_servicesort_list(void){ servicesort *this_servicesort; servicesort *next_servicesort; /* free memory for the servicesort list */ for(this_servicesort=servicesort_list;this_servicesort!=NULL;this_servicesort=next_servicesort){ next_servicesort=this_servicesort->next; free(this_servicesort); } return; } /* free all memory allocated to the hostsort structures */ void free_hostsort_list(void){ hostsort *this_hostsort; hostsort *next_hostsort; /* free memory for the hostsort list */ for(this_hostsort=hostsort_list;this_hostsort!=NULL;this_hostsort=next_hostsort){ next_hostsort=this_hostsort->next; free(this_hostsort); } return; } /* check host properties filter */ int passes_host_properties_filter(hoststatus *temp_hoststatus){ if((host_properties & HOST_SCHEDULED_DOWNTIME) && temp_hoststatus->scheduled_downtime_depth<=0) return FALSE; if((host_properties & HOST_NO_SCHEDULED_DOWNTIME) && temp_hoststatus->scheduled_downtime_depth>0) return FALSE; if((host_properties & HOST_STATE_ACKNOWLEDGED) && temp_hoststatus->problem_has_been_acknowledged==FALSE) return FALSE; if((host_properties & HOST_STATE_UNACKNOWLEDGED) && temp_hoststatus->problem_has_been_acknowledged==TRUE) return FALSE; if((host_properties & HOST_CHECKS_DISABLED) && temp_hoststatus->checks_enabled==TRUE) return FALSE; if((host_properties & HOST_CHECKS_ENABLED) && temp_hoststatus->checks_enabled==FALSE) return FALSE; if((host_properties & HOST_EVENT_HANDLER_DISABLED) && temp_hoststatus->event_handler_enabled==TRUE) return FALSE; if((host_properties & HOST_EVENT_HANDLER_ENABLED) && temp_hoststatus->event_handler_enabled==FALSE) return FALSE; if((host_properties & HOST_FLAP_DETECTION_DISABLED) && temp_hoststatus->flap_detection_enabled==TRUE) return FALSE; if((host_properties & HOST_FLAP_DETECTION_ENABLED) && temp_hoststatus->flap_detection_enabled==FALSE) return FALSE; if((host_properties & HOST_IS_FLAPPING) && temp_hoststatus->is_flapping==FALSE) return FALSE; if((host_properties & HOST_IS_NOT_FLAPPING) && temp_hoststatus->is_flapping==TRUE) return FALSE; if((host_properties & HOST_NOTIFICATIONS_DISABLED) && temp_hoststatus->notifications_enabled==TRUE) return FALSE; if((host_properties & HOST_NOTIFICATIONS_ENABLED) && temp_hoststatus->notifications_enabled==FALSE) return FALSE; if((host_properties & HOST_PASSIVE_CHECKS_DISABLED) && temp_hoststatus->accept_passive_host_checks==TRUE) return FALSE; if((host_properties & HOST_PASSIVE_CHECKS_ENABLED) && temp_hoststatus->accept_passive_host_checks==FALSE) return FALSE; if((host_properties & HOST_PASSIVE_CHECK) && temp_hoststatus->check_type==HOST_CHECK_ACTIVE) return FALSE; if((host_properties & HOST_ACTIVE_CHECK) && temp_hoststatus->check_type==HOST_CHECK_PASSIVE) return FALSE; return TRUE; } /* check service properties filter */ int passes_service_properties_filter(servicestatus *temp_servicestatus){ if((service_properties & SERVICE_SCHEDULED_DOWNTIME) && temp_servicestatus->scheduled_downtime_depth<=0) return FALSE; if((service_properties & SERVICE_NO_SCHEDULED_DOWNTIME) && temp_servicestatus->scheduled_downtime_depth>0) return FALSE; if((service_properties & SERVICE_STATE_ACKNOWLEDGED) && temp_servicestatus->problem_has_been_acknowledged==FALSE) return FALSE; if((service_properties & SERVICE_STATE_UNACKNOWLEDGED) && temp_servicestatus->problem_has_been_acknowledged==TRUE) return FALSE; if((service_properties & SERVICE_CHECKS_DISABLED) && temp_servicestatus->checks_enabled==TRUE) return FALSE; if((service_properties & SERVICE_CHECKS_ENABLED) && temp_servicestatus->checks_enabled==FALSE) return FALSE; if((service_properties & SERVICE_EVENT_HANDLER_DISABLED) && temp_servicestatus->event_handler_enabled==TRUE) return FALSE; if((service_properties & SERVICE_EVENT_HANDLER_ENABLED) && temp_servicestatus->event_handler_enabled==FALSE) return FALSE; if((service_properties & SERVICE_FLAP_DETECTION_DISABLED) && temp_servicestatus->flap_detection_enabled==TRUE) return FALSE; if((service_properties & SERVICE_FLAP_DETECTION_ENABLED) && temp_servicestatus->flap_detection_enabled==FALSE) return FALSE; if((service_properties & SERVICE_IS_FLAPPING) && temp_servicestatus->is_flapping==FALSE) return FALSE; if((service_properties & SERVICE_IS_NOT_FLAPPING) && temp_servicestatus->is_flapping==TRUE) return FALSE; if((service_properties & SERVICE_NOTIFICATIONS_DISABLED) && temp_servicestatus->notifications_enabled==TRUE) return FALSE; if((service_properties & SERVICE_NOTIFICATIONS_ENABLED) && temp_servicestatus->notifications_enabled==FALSE) return FALSE; if((service_properties & SERVICE_PASSIVE_CHECKS_DISABLED) && temp_servicestatus->accept_passive_service_checks==TRUE) return FALSE; if((service_properties & SERVICE_PASSIVE_CHECKS_ENABLED) && temp_servicestatus->accept_passive_service_checks==FALSE) return FALSE; if((service_properties & SERVICE_PASSIVE_CHECK) && temp_servicestatus->check_type==SERVICE_CHECK_ACTIVE) return FALSE; if((service_properties & SERVICE_ACTIVE_CHECK) && temp_servicestatus->check_type==SERVICE_CHECK_PASSIVE) return FALSE; return TRUE; } /* shows service and host filters in use */ void show_filters(void){ int found=0; /* show filters box if necessary */ if(host_properties!=0L || service_properties!=0L || host_status_types!=all_host_status_types || service_status_types!=all_service_status_types){ printf("\n"); printf(""); printf("
    \n"); printf("\n"); printf(""); printf(""); printf(""); printf(""); printf(""); printf("\n"); printf(""); printf(""); printf(""); printf(""); printf("
    Display Filters:
    Host Status Types:"); if(host_status_types==all_host_status_types) printf("All"); else if(host_status_types==all_host_problems) printf("All problems"); else{ found=0; if(host_status_types & HOST_PENDING){ printf(" Pending"); found=1; } if(host_status_types & HOST_UP){ printf("%s Up",(found==1)?" |":""); found=1; } if(host_status_types & HOST_DOWN){ printf("%s Down",(found==1)?" |":""); found=1; } if(host_status_types & HOST_UNREACHABLE) printf("%s Unreachable",(found==1)?" |":""); } printf("
    Host Properties:"); if(host_properties==0) printf("Any"); else{ found=0; if(host_properties & HOST_SCHEDULED_DOWNTIME){ printf(" In Scheduled Downtime"); found=1; } if(host_properties & HOST_NO_SCHEDULED_DOWNTIME){ printf("%s Not In Scheduled Downtime",(found==1)?" &":""); found=1; } if(host_properties & HOST_STATE_ACKNOWLEDGED){ printf("%s Has Been Acknowledged",(found==1)?" &":""); found=1; } if(host_properties & HOST_STATE_UNACKNOWLEDGED){ printf("%s Has Not Been Acknowledged",(found==1)?" &":""); found=1; } if(host_properties & HOST_CHECKS_DISABLED){ printf("%s Checks Disabled",(found==1)?" &":""); found=1; } if(host_properties & HOST_CHECKS_ENABLED){ printf("%s Checks Enabled",(found==1)?" &":""); found=1; } if(host_properties & HOST_EVENT_HANDLER_DISABLED){ printf("%s Event Handler Disabled",(found==1)?" &":""); found=1; } if(host_properties & HOST_EVENT_HANDLER_ENABLED){ printf("%s Event Handler Enabled",(found==1)?" &":""); found=1; } if(host_properties & HOST_FLAP_DETECTION_DISABLED){ printf("%s Flap Detection Disabled",(found==1)?" &":""); found=1; } if(host_properties & HOST_FLAP_DETECTION_ENABLED){ printf("%s Flap Detection Enabled",(found==1)?" &":""); found=1; } if(host_properties & HOST_IS_FLAPPING){ printf("%s Is Flapping",(found==1)?" &":""); found=1; } if(host_properties & HOST_IS_NOT_FLAPPING){ printf("%s Is Not Flapping",(found==1)?" &":""); found=1; } if(host_properties & HOST_NOTIFICATIONS_DISABLED){ printf("%s Notifications Disabled",(found==1)?" &":""); found=1; } if(host_properties & HOST_NOTIFICATIONS_ENABLED){ printf("%s Notifications Enabled",(found==1)?" &":""); found=1; } if(host_properties & HOST_PASSIVE_CHECKS_DISABLED){ printf("%s Passive Checks Disabled",(found==1)?" &":""); found=1; } if(host_properties & HOST_PASSIVE_CHECKS_ENABLED){ printf("%s Passive Checks Enabled",(found==1)?" &":""); found=1; } if(host_properties & HOST_PASSIVE_CHECK){ printf("%s Passive Checks",(found==1)?" &":""); found=1; } if(host_properties & HOST_ACTIVE_CHECK){ printf("%s Active Checks",(found==1)?" &":""); found=1; } } printf("
    Service Status Types:"); if(service_status_types==all_service_status_types) printf("All"); else if(service_status_types==all_service_problems) printf("All Problems"); else{ found=0; if(service_status_types & SERVICE_PENDING){ printf(" Pending"); found=1; } if(service_status_types & SERVICE_OK){ printf("%s Ok",(found==1)?" |":""); found=1; } if(service_status_types & SERVICE_UNKNOWN){ printf("%s Unknown",(found==1)?" |":""); found=1; } if(service_status_types & SERVICE_WARNING){ printf("%s Warning",(found==1)?" |":""); found=1; } if(service_status_types & SERVICE_CRITICAL){ printf("%s Critical",(found==1)?" |":""); found=1; } } printf("
    Service Properties:"); if(service_properties==0) printf("Any"); else{ found=0; if(service_properties & SERVICE_SCHEDULED_DOWNTIME){ printf(" In Scheduled Downtime"); found=1; } if(service_properties & SERVICE_NO_SCHEDULED_DOWNTIME){ printf("%s Not In Scheduled Downtime",(found==1)?" &":""); found=1; } if(service_properties & SERVICE_STATE_ACKNOWLEDGED){ printf("%s Has Been Acknowledged",(found==1)?" &":""); found=1; } if(service_properties & SERVICE_STATE_UNACKNOWLEDGED){ printf("%s Has Not Been Acknowledged",(found==1)?" &":""); found=1; } if(service_properties & SERVICE_CHECKS_DISABLED){ printf("%s Active Checks Disabled",(found==1)?" &":""); found=1; } if(service_properties & SERVICE_CHECKS_ENABLED){ printf("%s Active Checks Enabled",(found==1)?" &":""); found=1; } if(service_properties & SERVICE_EVENT_HANDLER_DISABLED){ printf("%s Event Handler Disabled",(found==1)?" &":""); found=1; } if(service_properties & SERVICE_EVENT_HANDLER_ENABLED){ printf("%s Event Handler Enabled",(found==1)?" &":""); found=1; } if(service_properties & SERVICE_FLAP_DETECTION_DISABLED){ printf("%s Flap Detection Disabled",(found==1)?" &":""); found=1; } if(service_properties & SERVICE_FLAP_DETECTION_ENABLED){ printf("%s Flap Detection Enabled",(found==1)?" &":""); found=1; } if(service_properties & SERVICE_IS_FLAPPING){ printf("%s Is Flapping",(found==1)?" &":""); found=1; } if(service_properties & SERVICE_IS_NOT_FLAPPING){ printf("%s Is Not Flapping",(found==1)?" &":""); found=1; } if(service_properties & SERVICE_NOTIFICATIONS_DISABLED){ printf("%s Notifications Disabled",(found==1)?" &":""); found=1; } if(service_properties & SERVICE_NOTIFICATIONS_ENABLED){ printf("%s Notifications Enabled",(found==1)?" &":""); found=1; } if(service_properties & SERVICE_PASSIVE_CHECKS_DISABLED){ printf("%s Passive Checks Disabled",(found==1)?" &":""); found=1; } if(service_properties & SERVICE_PASSIVE_CHECKS_ENABLED){ printf("%s Passive Checks Enabled",(found==1)?" &":""); found=1; } if(service_properties & SERVICE_PASSIVE_CHECK){ printf("%s Passive Checks",(found==1)?" &":""); found=1; } if(service_properties & SERVICE_ACTIVE_CHECK){ printf("%s Active Checks",(found==1)?" &":""); found=1; } } printf("
    \n"); printf("
    \n"); } return; } nagios-2.6/cgi/statusmap.c0000664000076500007650000026665110410070302015131 0ustar nagiosnagios/***************************************************************************** * * STATUSMAP.C - Nagios Network Status Map CGI * * Copyright (c) 1999-2006 Ethan Galstad (nagios@nagios.org) * Last Modified: 03-21-2006 * * Description: * * This CGI will create a map of all hosts that are being monitored on your * network. * * 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. * *****************************************************************************/ #include "../include/config.h" #include "../include/common.h" #include "../include/objects.h" #include "../include/statusdata.h" #include "../include/cgiutils.h" #include "../include/getcgi.h" #include "../include/cgiauth.h" #include /* Boutell's GD library function */ #include /* GD library small font definition */ extern int refresh_rate; /*#define DEBUG*/ #define UNKNOWN_GD2_ICON "unknown.gd2" #define UNKNOWN_ICON_IMAGE "unknown.gif" #define NAGIOS_GD2_ICON "nagios.gd2" extern char main_config_file[MAX_FILENAME_LENGTH]; extern char physical_images_path[MAX_FILENAME_LENGTH]; extern char url_images_path[MAX_FILENAME_LENGTH]; extern char url_logo_images_path[MAX_FILENAME_LENGTH]; extern char url_stylesheets_path[MAX_FILENAME_LENGTH]; extern host *host_list; extern hostgroup *hostgroup_list; extern service *service_list; extern hoststatus *hoststatus_list; extern servicestatus *servicestatus_list; extern char *statusmap_background_image; extern int default_statusmap_layout_method; #define DEFAULT_NODE_WIDTH 40 #define DEFAULT_NODE_HEIGHT 65 #define DEFAULT_NODE_VSPACING 15 #define DEFAULT_NODE_HSPACING 45 #define DEFAULT_PROXIMITY_WIDTH 1000 #define DEFAULT_PROXIMITY_HEIGHT 800 #define MINIMUM_PROXIMITY_WIDTH 250 #define MINIMUM_PROXIMITY_HEIGHT 200 #define COORDS_WARNING_WIDTH 650 #define COORDS_WARNING_HEIGHT 60 #define CIRCULAR_DRAWING_RADIUS 100 #define CREATE_HTML 0 #define CREATE_IMAGE 1 #define LAYOUT_USER_SUPPLIED 0 #define LAYOUT_SUBLAYERS 1 #define LAYOUT_COLLAPSED_TREE 2 #define LAYOUT_BALANCED_TREE 3 #define LAYOUT_CIRCULAR 4 #define LAYOUT_CIRCULAR_MARKUP 5 #define LAYOUT_CIRCULAR_BALLOON 6 typedef struct layer_struct{ char *layer_name; struct layer_struct *next; }layer; void document_header(int); void document_footer(void); int process_cgivars(void); void display_page_header(void); void display_map(void); void calculate_host_coords(void); void calculate_total_image_bounds(void); void calculate_canvas_bounds(void); void calculate_canvas_bounds_from_host(char *); void calculate_scaling_factor(void); void find_eligible_hosts(void); void load_background_image(void); void draw_background_image(void); void draw_background_extras(void); void draw_host_links(void); void draw_hosts(void); void draw_host_text(char *,int,int); void draw_text(char *,int,int,int); void write_popup_code(void); void write_host_popup_text(host *); int initialize_graphics(void); gdImagePtr load_image_from_file(char *); void write_graphics(void); void cleanup_graphics(void); void draw_line(int,int,int,int,int); void draw_dotted_line(int,int,int,int,int); void draw_dashed_line(int,int,int,int,int); int is_host_in_layer_list(host *); int add_layer(char *); void free_layer_list(void); void print_layer_url(int); int number_of_host_layer_members(host *,int); int max_child_host_layer_members(host *); int host_child_depth_separation(host *, host *); int max_child_host_drawing_width(host *); int number_of_host_services(host *); void calculate_balanced_tree_coords(host *,int,int); void calculate_circular_coords(void); void calculate_circular_layer_coords(host *,double,double,int,int); void draw_circular_markup(void); void draw_circular_layer_markup(host *,double,double,int,int); char physical_logo_images_path[MAX_FILENAME_LENGTH]; authdata current_authdata; int create_type=CREATE_HTML; gdImagePtr unknown_logo_image=NULL; gdImagePtr logo_image=NULL; gdImagePtr map_image=NULL; gdImagePtr background_image=NULL; int color_white=0; int color_black=0; int color_red=0; int color_lightred=0; int color_green=0; int color_lightgreen=0; int color_blue=0; int color_yellow=0; int color_orange=0; int color_grey=0; int color_lightgrey=0; int show_all_hosts=TRUE; char *host_name="all"; int embedded=FALSE; int display_header=TRUE; int display_popups=TRUE; int use_links=TRUE; int use_text=TRUE; int use_highlights=TRUE; int user_supplied_canvas=FALSE; int user_supplied_scaling=FALSE; int layout_method=LAYOUT_USER_SUPPLIED; int proximity_width=DEFAULT_PROXIMITY_WIDTH; int proximity_height=DEFAULT_PROXIMITY_HEIGHT; int coordinates_were_specified=FALSE; /* were any coordinates specified in extended host information entries? */ int scaled_image_width=0; /* size of the image actually displayed on the screen (after scaling) */ int scaled_image_height=0; int canvas_width=0; /* actual size of the image (or portion thereof) that we are drawing */ int canvas_height=0; int total_image_width=0; /* actual size of the image that would be created if we drew all hosts */ int total_image_height=0; int max_image_width=0; /* max image size the user wants (scaled) */ int max_image_height=0; double scaling_factor=1.0; /* scaling factor to use */ double user_scaling_factor=1.0; /* user-supplied scaling factor */ int background_image_width=0; int background_image_height=0; int canvas_x=0; /* upper left coords of drawing canvas */ int canvas_y=0; int bottom_margin=0; int draw_child_links=FALSE; int draw_parent_links=FALSE; int draw_nagios_icon=FALSE; /* should we drawn the Nagios process icon? */ int nagios_icon_x=0; /* coords of Nagios icon */ int nagios_icon_y=0; extern hostextinfo *hostextinfo_list; extern hoststatus *hoststatus_list; extern time_t program_start; layer *layer_list=NULL; int exclude_layers=TRUE; int all_layers=FALSE; int main(int argc, char **argv){ int result; /* reset internal variables */ reset_cgi_vars(); /* read the CGI configuration file */ result=read_cgi_config_file(get_cgi_config_location()); if(result==ERROR){ document_header(FALSE); if(create_type==CREATE_HTML) cgi_config_file_error(get_cgi_config_location()); document_footer(); return ERROR; } /* defaults from CGI config file */ layout_method=default_statusmap_layout_method; /* get the arguments passed in the URL */ process_cgivars(); /* read the main configuration file */ result=read_main_config_file(main_config_file); if(result==ERROR){ document_header(FALSE); if(create_type==CREATE_HTML) main_config_file_error(main_config_file); document_footer(); return ERROR; } /* read all object configuration data */ result=read_all_object_configuration_data(main_config_file,READ_ALL_OBJECT_DATA); if(result==ERROR){ document_header(FALSE); if(create_type==CREATE_HTML) object_data_error(); document_footer(); return ERROR; } /* read all status data */ result=read_all_status_data(get_cgi_config_location(),READ_ALL_STATUS_DATA); if(result==ERROR){ document_header(FALSE); if(create_type==CREATE_HTML) status_data_error(); document_footer(); free_memory(); return ERROR; } document_header(TRUE); /* get authentication information */ get_authentication_information(¤t_authdata); /* display the network map... */ display_map(); document_footer(); /* free all allocated memory */ free_memory(); free_layer_list(); return OK; } void document_header(int use_stylesheet){ char date_time[MAX_DATETIME_LENGTH]; time_t current_time; time_t expire_time; if(create_type==CREATE_HTML){ printf("Cache-Control: no-store\r\n"); printf("Pragma: no-cache\r\n"); printf("Refresh: %d\r\n",refresh_rate); time(¤t_time); get_time_string(¤t_time,date_time,sizeof(date_time),HTTP_DATE_TIME); printf("Last-Modified: %s\r\n",date_time); expire_time=0L; get_time_string(&expire_time,date_time,sizeof(date_time),HTTP_DATE_TIME); printf("Expires: %s\r\n",date_time); printf("Content-Type: text/html\r\n\r\n"); if(embedded==TRUE) return; printf("\n"); printf("\n"); printf("\n"); printf("Network Map\n"); printf("\n"); if(use_stylesheet==TRUE){ printf("\n",url_stylesheets_path,COMMON_CSS); printf("\n",url_stylesheets_path,STATUSMAP_CSS); } /* write JavaScript code for popup window */ write_popup_code(); printf("\n"); printf("\n"); /* include user SSI header */ include_ssi_files(STATUSMAP_CGI,SSI_HEADER); printf("
    \n"); } else{ printf("Cache-Control: no-store\r\n"); printf("Pragma: no-cache\r\n"); time(¤t_time); get_time_string(¤t_time,date_time,sizeof(date_time),HTTP_DATE_TIME); printf("Last-Modified: %s\r\n",date_time); expire_time=(time_t)0L; get_time_string(&expire_time,date_time,sizeof(date_time),HTTP_DATE_TIME); printf("Expires: %s\r\n",date_time); printf("Content-Type: image/png\r\n\r\n"); } return; } void document_footer(void){ if(embedded==TRUE) return; if(create_type==CREATE_HTML){ /* include user SSI footer */ include_ssi_files(STATUSMAP_CGI,SSI_FOOTER); printf("\n"); printf("\n"); } return; } int process_cgivars(void){ char **variables; int error=FALSE; int x; variables=getcgivars(); for(x=0;variables[x]!=NULL;x++){ /* do some basic length checking on the variable identifier to prevent buffer overflows */ if(strlen(variables[x])>=MAX_INPUT_BUFFER-1){ x++; continue; } /* we found the host argument */ else if(!strcmp(variables[x],"host")){ x++; if(variables[x]==NULL){ error=TRUE; break; } host_name=(char *)malloc(strlen(variables[x])+1); if(host_name==NULL) host_name="all"; else strcpy(host_name,variables[x]); if(!strcmp(host_name,"all")) show_all_hosts=TRUE; else show_all_hosts=FALSE; } /* we found the image creation option */ else if(!strcmp(variables[x],"createimage")){ create_type=CREATE_IMAGE; } /* we found the embed option */ else if(!strcmp(variables[x],"embedded")) embedded=TRUE; /* we found the noheader option */ else if(!strcmp(variables[x],"noheader")) display_header=FALSE; /* we found the canvas origin */ else if(!strcmp(variables[x],"canvas_x")){ x++; if(variables[x]==NULL){ error=TRUE; break; } canvas_x=atoi(variables[x]); user_supplied_canvas=TRUE; } else if(!strcmp(variables[x],"canvas_y")){ x++; if(variables[x]==NULL){ error=TRUE; break; } canvas_y=atoi(variables[x]); user_supplied_canvas=TRUE; } /* we found the canvas size */ else if(!strcmp(variables[x],"canvas_width")){ x++; if(variables[x]==NULL){ error=TRUE; break; } canvas_width=atoi(variables[x]); user_supplied_canvas=TRUE; } else if(!strcmp(variables[x],"canvas_height")){ x++; if(variables[x]==NULL){ error=TRUE; break; } canvas_height=atoi(variables[x]); user_supplied_canvas=TRUE; } else if(!strcmp(variables[x],"proximity_width")){ x++; if(variables[x]==NULL){ error=TRUE; break; } proximity_width=atoi(variables[x]); if(proximity_width<0) proximity_width=DEFAULT_PROXIMITY_WIDTH; } else if(!strcmp(variables[x],"proximity_height")){ x++; if(variables[x]==NULL){ error=TRUE; break; } proximity_height=atoi(variables[x]); if(proximity_height<0) proximity_height=DEFAULT_PROXIMITY_HEIGHT; } /* we found the scaling factor */ else if(!strcmp(variables[x],"scaling_factor")){ x++; if(variables[x]==NULL){ error=TRUE; break; } user_scaling_factor=strtod(variables[x],NULL); if(user_scaling_factor>0.0) user_supplied_scaling=TRUE; } /* we found the max image size */ else if(!strcmp(variables[x],"max_width")){ x++; if(variables[x]==NULL){ error=TRUE; break; } max_image_width=atoi(variables[x]); } else if(!strcmp(variables[x],"max_height")){ x++; if(variables[x]==NULL){ error=TRUE; break; } max_image_height=atoi(variables[x]); } /* we found the layout method option */ else if(!strcmp(variables[x],"layout")){ x++; if(variables[x]==NULL){ error=TRUE; break; } layout_method=atoi(variables[x]); } /* we found the no links argument*/ else if(!strcmp(variables[x],"nolinks")) use_links=FALSE; /* we found the no text argument*/ else if(!strcmp(variables[x],"notext")) use_text=FALSE; /* we found the no highlights argument*/ else if(!strcmp(variables[x],"nohighlights")) use_highlights=FALSE; /* we found the no popups argument*/ else if(!strcmp(variables[x],"nopopups")) display_popups=FALSE; /* we found the layer inclusion/exclusion argument */ else if(!strcmp(variables[x],"layermode")){ x++; if(variables[x]==NULL){ error=TRUE; break; } if(!strcmp(variables[x],"include")) exclude_layers=FALSE; else exclude_layers=TRUE; } /* we found the layer argument */ else if(!strcmp(variables[x],"layer")){ x++; if(variables[x]==NULL){ error=TRUE; break; } add_layer(variables[x]); } } /* free memory allocated to the CGI variables */ free_cgivars(variables); return error; } /* top of page */ void display_page_header(void){ char temp_buffer[MAX_INPUT_BUFFER]; int zoom; int zoom_width, zoom_height; int zoom_width_granularity=0; int zoom_height_granularity=0; int current_zoom_granularity=0; hostgroup *temp_hostgroup; layer *temp_layer; int found=0; if(create_type!=CREATE_HTML) return; if(display_header==TRUE){ /* begin top table */ printf("\n"); printf("\n"); /* left column of the first row */ printf("\n"); /* center column of top row */ printf("\n"); /* right hand column of top row */ printf("\n"); /* end of top table */ printf("\n"); printf("
    \n"); if(show_all_hosts==TRUE) snprintf(temp_buffer,sizeof(temp_buffer)-1,"Network Map For All Hosts"); else snprintf(temp_buffer,sizeof(temp_buffer)-1,"Network Map For Host %s",host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; display_info_table(temp_buffer,TRUE,¤t_authdata); printf("\n"); printf("\n"); printf("\n"); printf("\n"); /* print image size and scaling info */ #ifdef DEBUG printf("

    \n"); printf("[ Raw Image Size: %d x %d pixels | Scaling Factor: %1.2lf | Scaled Image Size: %d x %d pixels ]",canvas_width,canvas_height,scaling_factor,(int)(canvas_width*scaling_factor),(int)(canvas_height*scaling_factor)); printf("

    \n"); printf("

    \n"); printf("[ Canvas_x: %d | Canvas_y: %d | Canvas_width: %d | Canvas_height: %d ]",canvas_x,canvas_y,canvas_width,canvas_height); printf("

    \n"); #endif /* zoom links */ if(user_supplied_canvas==FALSE && strcmp(host_name,"all") && display_header==TRUE){ printf("

    \n"); zoom_width_granularity=((total_image_width-MINIMUM_PROXIMITY_WIDTH)/11); if(zoom_width_granularity==0) zoom_width_granularity=1; zoom_height_granularity=((total_image_height-MINIMUM_PROXIMITY_HEIGHT)/11); if(proximity_width<=0) current_zoom_granularity=0; else current_zoom_granularity=(total_image_width-proximity_width)/zoom_width_granularity; if(current_zoom_granularity>10) current_zoom_granularity=10; printf("\n"); printf("\n"); printf("\n"); for(zoom=0;zoom<=10;zoom++){ zoom_width=total_image_width-(zoom*zoom_width_granularity); zoom_height=total_image_height-(zoom*zoom_height_granularity); printf("\n",url_images_path,(current_zoom_granularity==zoom)?ZOOM2_ICON:ZOOM1_ICON,zoom,zoom); } printf("\n"); printf("\n"); printf("
    Zoom Out  "); printf("%d  Zoom In
    \n"); printf("

    \n"); } printf("
    \n"); printf("\n"); printf("\n"); printf("
    \n"); printf("
    \n",STATUSMAP_CGI); printf("\n",host_name); printf("\n",layout_method); printf("
    \n"); printf("\n"); printf("\n"); printf("\n"); /* printf("\n"); printf("\n"); printf("\n"); printf("\n"); */ printf("\n",max_image_width); printf("\n",max_image_height); printf("\n",proximity_width); printf("\n",proximity_height); printf("\n"); printf("\n"); /* display context-sensitive help */ printf("\n"); printf("
    \n"); printf("Layout Method:
    \n"); printf("\n"); printf("
    \n"); printf("Scaling factor:
    \n"); printf("\n",(user_supplied_scaling==TRUE)?user_scaling_factor:0.0); printf("
    \n"); printf("Max image width:
    \n"); printf("\n",max_image_width); printf("
    \n"); printf("Max image height:
    \n"); printf("\n",max_image_height); printf("
    \n"); printf("Proximity width:
    \n"); printf("\n",proximity_width); printf("
    \n"); printf("Proximity height:
    \n"); printf("\n",proximity_height); printf("
    Drawing Layers:
    \n"); printf("\n"); printf("
    Layer mode:
    "); printf("Include
    \n",(exclude_layers==FALSE)?"CHECKED":""); printf("Exclude\n",(exclude_layers==TRUE)?"CHECKED":""); printf("
    \n"); printf("Suppress popups:
    \n"); printf("\n",(display_popups==FALSE)?"CHECKED":""); printf("
    \n"); printf("\n"); printf("
    \n"); display_context_help(CONTEXTHELP_MAP); printf("
    \n"); printf("\n"); printf("
    \n"); printf("
    \n"); } return; } /* top-level map generation... */ void display_map(void){ load_background_image(); calculate_host_coords(); calculate_total_image_bounds(); calculate_canvas_bounds(); calculate_scaling_factor(); find_eligible_hosts(); /* display page header */ display_page_header(); initialize_graphics(); draw_background_image(); draw_background_extras(); draw_host_links(); if(create_type==CREATE_HTML) printf("\n"); draw_hosts(); if(create_type==CREATE_HTML) printf("\n"); write_graphics(); cleanup_graphics(); /* write the URL location for the image we just generated - the web browser will come and get it... */ if(create_type==CREATE_HTML){ printf("

    \n"); printf("\n",(int)(canvas_width*scaling_factor),(int)(canvas_height*scaling_factor)); printf("

    \n"); } return; } /******************************************************************/ /********************* CALCULATION FUNCTIONS **********************/ /******************************************************************/ /* calculates host drawing coordinates */ void calculate_host_coords(void){ hostextinfo *temp_hostextinfo; host *this_host; host *temp_host; int child_hosts=0; int parent_hosts=0; int max_layer_width=1; int current_child_host=0; int current_parent_host=0; int center_x=0; int offset_x=DEFAULT_NODE_WIDTH/2; int offset_y=DEFAULT_NODE_WIDTH/2; int current_layer=0; int layer_members=0; int current_layer_member=0; int max_drawing_width=0; /******************************/ /***** MANUAL LAYOUT MODE *****/ /******************************/ /* user-supplied coords */ if(layout_method==LAYOUT_USER_SUPPLIED){ /* see which hosts we should draw and calculate drawing coords */ for(temp_hostextinfo=hostextinfo_list;temp_hostextinfo!=NULL;temp_hostextinfo=temp_hostextinfo->next){ if(temp_hostextinfo->have_2d_coords==TRUE) temp_hostextinfo->should_be_drawn=TRUE; else temp_hostextinfo->should_be_drawn=FALSE; } return; } /*****************************/ /***** AUTO-LAYOUT MODES *****/ /*****************************/ /* add empty extended host info entries for all hosts that don't have any */ for(temp_host=host_list;temp_host!=NULL;temp_host=temp_host->next){ /* find the corresponding hostextinfo definition */ temp_hostextinfo=find_hostextinfo(temp_host->name); /* none was found, so add a blank one */ if(temp_hostextinfo==NULL) add_hostextinfo(temp_host->name,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,0,0.0,0.0,0.0,0,0); } /***** DEPTH LAYER MODE *****/ if(layout_method==LAYOUT_SUBLAYERS){ /* find the "main" host we're displaying */ if(show_all_hosts==TRUE) this_host=NULL; else this_host=find_host(host_name); /* find total number of immediate parents/children for this host */ child_hosts=number_of_immediate_child_hosts(this_host); parent_hosts=number_of_immediate_parent_hosts(this_host); if(child_hosts==0 && parent_hosts==0) max_layer_width=1; else max_layer_width=(child_hosts>parent_hosts)?child_hosts:parent_hosts; /* calculate center x coord */ center_x=(((DEFAULT_NODE_WIDTH*max_layer_width)+(DEFAULT_NODE_HSPACING*(max_layer_width-1)))/2)+offset_x; /* coords for Nagios icon if necessary */ if(this_host==NULL || this_host->parent_hosts==NULL){ nagios_icon_x=center_x; nagios_icon_y=offset_y; draw_nagios_icon=TRUE; } /* do we need to draw a link to parent(s)? */ if(this_host!=NULL && is_host_immediate_child_of_host(NULL,this_host)==FALSE){ draw_parent_links=TRUE; offset_y+=DEFAULT_NODE_HEIGHT+DEFAULT_NODE_VSPACING; } /* see which hosts we should draw and calculate drawing coords */ for(temp_hostextinfo=hostextinfo_list;temp_hostextinfo!=NULL;temp_hostextinfo=temp_hostextinfo->next){ /* find the host that matches this entry */ temp_host=find_host(temp_hostextinfo->host_name); if(temp_host==NULL) continue; /* this is an immediate parent of the "main" host we're drawing */ else if(is_host_immediate_parent_of_host(this_host,temp_host)==TRUE){ temp_hostextinfo->should_be_drawn=TRUE; temp_hostextinfo->have_2d_coords=TRUE; temp_hostextinfo->x_2d=center_x-(((parent_hosts*DEFAULT_NODE_WIDTH)+((parent_hosts-1)*DEFAULT_NODE_HSPACING))/2)+(current_parent_host*(DEFAULT_NODE_WIDTH+DEFAULT_NODE_HSPACING))+(DEFAULT_NODE_WIDTH/2); temp_hostextinfo->y_2d=offset_y; current_parent_host++; } /* this is the "main" host we're drawing */ else if(this_host==temp_host){ temp_hostextinfo->should_be_drawn=TRUE; temp_hostextinfo->have_2d_coords=TRUE; temp_hostextinfo->x_2d=center_x; temp_hostextinfo->y_2d=DEFAULT_NODE_HEIGHT+DEFAULT_NODE_VSPACING+offset_y; } /* this is an immediate child of the "main" host we're drawing */ else if(is_host_immediate_child_of_host(this_host,temp_host)==TRUE){ temp_hostextinfo->should_be_drawn=TRUE; temp_hostextinfo->have_2d_coords=TRUE; temp_hostextinfo->x_2d=center_x-(((child_hosts*DEFAULT_NODE_WIDTH)+((child_hosts-1)*DEFAULT_NODE_HSPACING))/2)+(current_child_host*(DEFAULT_NODE_WIDTH+DEFAULT_NODE_HSPACING))+(DEFAULT_NODE_WIDTH/2); if(this_host==NULL) temp_hostextinfo->y_2d=(DEFAULT_NODE_HEIGHT+DEFAULT_NODE_VSPACING)+offset_y; else temp_hostextinfo->y_2d=((DEFAULT_NODE_HEIGHT+DEFAULT_NODE_VSPACING)*2)+offset_y; current_child_host++; if(number_of_immediate_child_hosts(temp_host)>0){ bottom_margin=DEFAULT_NODE_HEIGHT+DEFAULT_NODE_VSPACING; draw_child_links=TRUE; } } /* else do not draw this host */ else{ temp_hostextinfo->should_be_drawn=FALSE; temp_hostextinfo->have_2d_coords=FALSE; } } } /***** COLLAPSED TREE MODE *****/ else if(layout_method==LAYOUT_COLLAPSED_TREE){ /* find the "main" host we're displaying - DO NOT USE THIS (THIS IS THE OLD METHOD) */ /* if(show_all_hosts==TRUE) this_host=NULL; else this_host=find_host(host_name); */ /* always use NULL as the "main" host, screen coords/dimensions are adjusted automatically */ this_host=NULL; /* find total number of immediate parents for this host */ parent_hosts=number_of_immediate_parent_hosts(this_host); /* find the max layer width we have... */ max_layer_width=max_child_host_layer_members(this_host); if(parent_hosts>max_layer_width) max_layer_width=parent_hosts; /* calculate center x coord */ center_x=(((DEFAULT_NODE_WIDTH*max_layer_width)+(DEFAULT_NODE_HSPACING*(max_layer_width-1)))/2)+offset_x; /* coords for Nagios icon if necessary */ if(this_host==NULL || this_host->parent_hosts==NULL){ nagios_icon_x=center_x; nagios_icon_y=offset_y; draw_nagios_icon=TRUE; } /* do we need to draw a link to parent(s)? */ if(this_host!=NULL && is_host_immediate_child_of_host(NULL,this_host)==FALSE){ draw_parent_links=TRUE; offset_y+=DEFAULT_NODE_HEIGHT+DEFAULT_NODE_VSPACING; } /* see which hosts we should draw and calculate drawing coords */ for(temp_hostextinfo=hostextinfo_list;temp_hostextinfo!=NULL;temp_hostextinfo=temp_hostextinfo->next){ /* find the host that matches this entry */ temp_host=find_host(temp_hostextinfo->host_name); if(temp_host==NULL) continue; /* this is an immediate parent of the "main" host we're drawing */ else if(is_host_immediate_parent_of_host(this_host,temp_host)==TRUE){ temp_hostextinfo->should_be_drawn=TRUE; temp_hostextinfo->have_2d_coords=TRUE; temp_hostextinfo->x_2d=center_x-(((parent_hosts*DEFAULT_NODE_WIDTH)+((parent_hosts-1)*DEFAULT_NODE_HSPACING))/2)+(current_parent_host*(DEFAULT_NODE_WIDTH+DEFAULT_NODE_HSPACING))+(DEFAULT_NODE_WIDTH/2); temp_hostextinfo->y_2d=offset_y; current_parent_host++; } /* this is the "main" host we're drawing */ else if(this_host==temp_host){ temp_hostextinfo->should_be_drawn=TRUE; temp_hostextinfo->have_2d_coords=TRUE; temp_hostextinfo->x_2d=center_x; temp_hostextinfo->y_2d=DEFAULT_NODE_HEIGHT+DEFAULT_NODE_VSPACING+offset_y; } /* else do not draw this host (we might if its a child - see below, but assume no for now) */ else{ temp_hostextinfo->should_be_drawn=FALSE; temp_hostextinfo->have_2d_coords=FALSE; } } /* TODO: REORDER CHILD LAYER MEMBERS SO THAT WE MINIMIZE LINK CROSSOVERS FROM PARENT HOSTS */ /* draw hosts in child "layers" */ for(current_layer=1;;current_layer++){ /* how many members in this layer? */ layer_members=number_of_host_layer_members(this_host,current_layer); if(layer_members==0) break; current_layer_member=0; /* see which hosts are members of this layer and calculate drawing coords */ for(temp_hostextinfo=hostextinfo_list;temp_hostextinfo!=NULL;temp_hostextinfo=temp_hostextinfo->next){ /* find the host that matches this entry */ temp_host=find_host(temp_hostextinfo->host_name); if(temp_host==NULL) continue; /* is this host a member of the current child layer? */ if(host_child_depth_separation(this_host,temp_host)==current_layer){ temp_hostextinfo->should_be_drawn=TRUE; temp_hostextinfo->have_2d_coords=TRUE; temp_hostextinfo->x_2d=center_x-(((layer_members*DEFAULT_NODE_WIDTH)+((layer_members-1)*DEFAULT_NODE_HSPACING))/2)+(current_layer_member*(DEFAULT_NODE_WIDTH+DEFAULT_NODE_HSPACING))+(DEFAULT_NODE_WIDTH/2); if(this_host==NULL) temp_hostextinfo->y_2d=((DEFAULT_NODE_HEIGHT+DEFAULT_NODE_VSPACING)*current_layer)+offset_y; else temp_hostextinfo->y_2d=((DEFAULT_NODE_HEIGHT+DEFAULT_NODE_VSPACING)*(current_layer+1))+offset_y; current_layer_member++; } } } } /***** "BALANCED" TREE MODE *****/ else if(layout_method==LAYOUT_BALANCED_TREE){ /* find the "main" host we're displaying - DO NOT USE THIS (THIS IS THE OLD METHOD) */ /* if(show_all_hosts==TRUE) this_host=NULL; else this_host=find_host(host_name); */ /* always use NULL as the "main" host, screen coords/dimensions are adjusted automatically */ this_host=NULL; /* find total number of immediate parents for this host */ parent_hosts=number_of_immediate_parent_hosts(this_host); /* find the max drawing width we have... */ max_drawing_width=max_child_host_drawing_width(this_host); if(parent_hosts>max_drawing_width) max_drawing_width=parent_hosts; /* calculate center x coord */ center_x=(((DEFAULT_NODE_WIDTH*max_drawing_width)+(DEFAULT_NODE_HSPACING*(max_drawing_width-1)))/2)+offset_x; /* coords for Nagios icon if necessary */ if(this_host==NULL || this_host->parent_hosts==NULL){ nagios_icon_x=center_x; nagios_icon_y=offset_y; draw_nagios_icon=TRUE; } /* do we need to draw a link to parent(s)? */ if(this_host!=NULL && is_host_immediate_child_of_host(NULL,this_host)==FALSE){ draw_parent_links=TRUE; offset_y+=DEFAULT_NODE_HEIGHT+DEFAULT_NODE_VSPACING; } /* see which hosts we should draw and calculate drawing coords */ for(temp_hostextinfo=hostextinfo_list;temp_hostextinfo!=NULL;temp_hostextinfo=temp_hostextinfo->next){ /* find the host that matches this entry */ temp_host=find_host(temp_hostextinfo->host_name); if(temp_host==NULL) continue; /* this is an immediate parent of the "main" host we're drawing */ else if(is_host_immediate_parent_of_host(this_host,temp_host)==TRUE){ temp_hostextinfo->should_be_drawn=TRUE; temp_hostextinfo->have_2d_coords=TRUE; temp_hostextinfo->x_2d=center_x-(((parent_hosts*DEFAULT_NODE_WIDTH)+((parent_hosts-1)*DEFAULT_NODE_HSPACING))/2)+(current_parent_host*(DEFAULT_NODE_WIDTH+DEFAULT_NODE_HSPACING))+(DEFAULT_NODE_WIDTH/2); temp_hostextinfo->y_2d=offset_y; current_parent_host++; } /* this is the "main" host we're drawing */ else if(this_host==temp_host){ temp_hostextinfo->should_be_drawn=TRUE; temp_hostextinfo->have_2d_coords=TRUE; temp_hostextinfo->x_2d=center_x; temp_hostextinfo->y_2d=DEFAULT_NODE_HEIGHT+DEFAULT_NODE_VSPACING+offset_y; } /* else do not draw this host (we might if its a child - see below, but assume no for now) */ else{ temp_hostextinfo->should_be_drawn=FALSE; temp_hostextinfo->have_2d_coords=FALSE; } } /* draw all children hosts */ calculate_balanced_tree_coords(this_host,center_x,DEFAULT_NODE_HEIGHT+DEFAULT_NODE_VSPACING+offset_y); } /***** CIRCULAR LAYOUT MODE *****/ else if(layout_method==LAYOUT_CIRCULAR || layout_method==LAYOUT_CIRCULAR_MARKUP || layout_method==LAYOUT_CIRCULAR_BALLOON){ /* draw process icon */ nagios_icon_x=0; nagios_icon_y=0; draw_nagios_icon=TRUE; /* calculate coordinates for all hosts */ calculate_circular_coords(); } return; } /* calculates max possible image dimensions */ void calculate_total_image_bounds(void){ hostextinfo *temp_hostextinfo; total_image_width=0; total_image_height=0; /* check all extended host information entries... */ for(temp_hostextinfo=hostextinfo_list;temp_hostextinfo!=NULL;temp_hostextinfo=temp_hostextinfo->next){ /* only check entries that have 2-D coords specified */ if(temp_hostextinfo->have_2d_coords==FALSE) continue; /* skip hosts we shouldn't be drawing */ if(temp_hostextinfo->should_be_drawn==FALSE) continue; if(temp_hostextinfo->x_2d>total_image_width) total_image_width=temp_hostextinfo->x_2d; if(temp_hostextinfo->y_2d>total_image_height) total_image_height=temp_hostextinfo->y_2d; coordinates_were_specified=TRUE; } /* add some space for icon size and overlapping text... */ if(coordinates_were_specified==TRUE){ total_image_width+=(DEFAULT_NODE_WIDTH*2); total_image_height+=DEFAULT_NODE_HEIGHT; /* add space for bottom margin if necessary */ total_image_height+=bottom_margin; } /* image size should be at least as large as dimensions of background image */ if(total_image_widthtotal_image_width) canvas_x=0; if(canvas_y<=0 || canvas_height>total_image_height) canvas_y=0; /* calculate canvas dimensions */ if(canvas_height<=0) canvas_height=(total_image_height-canvas_y); if(canvas_width<=0) canvas_width=(total_image_width-canvas_x); if(canvas_x+canvas_width>total_image_width) canvas_width=total_image_width-canvas_x; if(canvas_y+canvas_height>total_image_height) canvas_height=total_image_height-canvas_y; return; } /* calculates canvas coordinates/dimensions around a particular host */ void calculate_canvas_bounds_from_host(char *host_name){ hostextinfo *temp_hostextinfo; int zoom_width; int zoom_height; /* find the extended host info */ temp_hostextinfo=find_hostextinfo(host_name); if(temp_hostextinfo==NULL) return; /* make sure we have 2-D coords */ if(temp_hostextinfo->have_2d_coords==FALSE) return; if(max_image_width>0 && proximity_width>max_image_width) zoom_width=max_image_width; else zoom_width=proximity_width; if(max_image_height>0 && proximity_height>max_image_height) zoom_height=max_image_height; else zoom_height=proximity_height; canvas_width=zoom_width; if(canvas_width>=total_image_width) canvas_x=0; else canvas_x=(temp_hostextinfo->x_2d-(zoom_width/2)); canvas_height=zoom_height; if(canvas_height>=total_image_height) canvas_y=0; else canvas_y=(temp_hostextinfo->y_2d-(zoom_height/2)); return; } /* calculates scaling factor used in image generation */ void calculate_scaling_factor(void){ double x_scaling=1.0; double y_scaling=1.0; /* calculate horizontal scaling factor */ if(max_image_width<=0 || canvas_width<=max_image_width) x_scaling=1.0; else x_scaling=(double)((double)max_image_width/(double)canvas_width); /* calculate vertical scaling factor */ if(max_image_height<=0 || canvas_height<=max_image_height) y_scaling=1.0; else y_scaling=(double)((double)max_image_height/(double)canvas_height); /* calculate general scaling factor to use */ if(x_scalingnext){ /* find the host */ temp_host=find_host(temp_hostextinfo->host_name); if(temp_host==NULL) temp_hostextinfo->should_be_drawn=FALSE; /* only include hosts that have 2-D coords supplied */ else if(temp_hostextinfo->have_2d_coords==FALSE) temp_hostextinfo->should_be_drawn=FALSE; /* make sure coords are all positive */ else if(temp_hostextinfo->x_2d<0 || temp_hostextinfo->y_2d<0) temp_hostextinfo->should_be_drawn=FALSE; /* make sure x coordinates fall within canvas bounds */ else if(temp_hostextinfo->x_2d<(canvas_x-DEFAULT_NODE_WIDTH) || temp_hostextinfo->x_2d>(canvas_x+canvas_width)) temp_hostextinfo->should_be_drawn=FALSE; /* make sure y coordinates fall within canvas bounds */ else if(temp_hostextinfo->y_2d<(canvas_y-DEFAULT_NODE_HEIGHT) || temp_hostextinfo->y_2d>(canvas_y+canvas_height)) temp_hostextinfo->should_be_drawn=FALSE; /* see if the user is authorized to view the host */ else if(is_authorized_for_host(temp_host,¤t_authdata)==FALSE) temp_hostextinfo->should_be_drawn=FALSE; /* all checks passed, so we can draw the host! */ else{ temp_hostextinfo->should_be_drawn=TRUE; total_eligible_hosts++; } } return; } /******************************************************************/ /*********************** DRAWING FUNCTIONS ************************/ /******************************************************************/ /* loads background image from file */ void load_background_image(void){ char temp_buffer[MAX_INPUT_BUFFER]; /* bail out if we shouldn't be drawing a background image */ if(layout_method!=LAYOUT_USER_SUPPLIED || statusmap_background_image==NULL) return; snprintf(temp_buffer,sizeof(temp_buffer)-1,"%s%s",physical_images_path,statusmap_background_image); temp_buffer[sizeof(temp_buffer)-1]='\x0'; /* read the background image into memory */ background_image=load_image_from_file(temp_buffer); /* grab background image dimensions for calculating total image width later */ if(background_image!=NULL){ background_image_width=background_image->sx; background_image_height=background_image->sy; } /* if we are just creating the html, we don't need the image anymore */ if(create_type==CREATE_HTML && background_image!=NULL) gdImageDestroy(background_image); return; } /* draws background image on drawing canvas */ void draw_background_image(void){ /* bail out if we shouldn't be drawing a background image */ if(create_type==CREATE_HTML || layout_method!=LAYOUT_USER_SUPPLIED || statusmap_background_image==NULL) return; /* bail out if we don't have an image */ if(background_image==NULL) return; /* copy the background image to the canvas */ gdImageCopy(map_image,background_image,0,0,canvas_x,canvas_y,canvas_width,canvas_height); /* free memory for background image, as we don't need it anymore */ gdImageDestroy(background_image); return; } /* draws background "extras" */ void draw_background_extras(void){ /* bail out if we shouldn't be here */ if(create_type==CREATE_HTML) return; /* circular layout stuff... */ if(layout_method==LAYOUT_CIRCULAR_MARKUP){ /* draw colored sections... */ draw_circular_markup(); } return; } /* draws host links */ void draw_host_links(void){ hostextinfo *temp_hostextinfo; hostextinfo *temp_parent_hostextinfo; host *this_host; host *main_host; host *parent_host; hostsmember *temp_hostsmember; int status_color=color_black; hoststatus *this_hoststatus; hoststatus *parent_hoststatus; int child_in_layer_list=FALSE; int parent_in_layer_list=FALSE; int dotted_line=FALSE; int x=0; int y=0; if(create_type==CREATE_HTML) return; if(use_links==FALSE) return; /* find the "main" host we're drawing */ main_host=find_host(host_name); if(show_all_hosts==TRUE) main_host=NULL; /* check all extended host information entries... */ for(temp_hostextinfo=hostextinfo_list;temp_hostextinfo!=NULL;temp_hostextinfo=temp_hostextinfo->next){ /* find the config entry for this host */ this_host=find_host(temp_hostextinfo->host_name); if(this_host==NULL) continue; /* only draw link if user is authorized to view this host */ if(is_authorized_for_host(this_host,¤t_authdata)==FALSE) continue; /* this is a "root" host, so draw link to Nagios process icon if using auto-layout mode */ if(this_host->parent_hosts==NULL && layout_method!=LAYOUT_USER_SUPPLIED && draw_nagios_icon==TRUE){ x=temp_hostextinfo->x_2d+(DEFAULT_NODE_WIDTH/2)-canvas_x; y=temp_hostextinfo->y_2d+(DEFAULT_NODE_WIDTH/2)-canvas_y; draw_line(x,y,nagios_icon_x+(DEFAULT_NODE_WIDTH/2)-canvas_x,nagios_icon_y+(DEFAULT_NODE_WIDTH/2)-canvas_y,color_black); } /* this is a child of the main host we're drawing in auto-layout mode... */ if(layout_method!=LAYOUT_USER_SUPPLIED && draw_child_links==TRUE && number_of_immediate_child_hosts(this_host)>0 && is_host_immediate_child_of_host(main_host,this_host)==TRUE){ /* determine color to use when drawing links to children */ this_hoststatus=find_hoststatus(temp_hostextinfo->host_name); if(this_hoststatus!=NULL){ if(this_hoststatus->status==HOST_DOWN || this_hoststatus->status==HOST_UNREACHABLE) status_color=color_red; else status_color=color_black; } else status_color=color_black; x=temp_hostextinfo->x_2d+(DEFAULT_NODE_WIDTH/2)-canvas_x; y=(temp_hostextinfo->y_2d+(DEFAULT_NODE_WIDTH)/2)-canvas_y; draw_dashed_line(x,y,x,y+DEFAULT_NODE_HEIGHT+DEFAULT_NODE_VSPACING,status_color); /* draw arrow tips */ draw_line(x,y+DEFAULT_NODE_HEIGHT+DEFAULT_NODE_VSPACING,x-5,y+DEFAULT_NODE_HEIGHT+DEFAULT_NODE_VSPACING-5,color_black); draw_line(x,y+DEFAULT_NODE_HEIGHT+DEFAULT_NODE_VSPACING,x+5,y+DEFAULT_NODE_HEIGHT+DEFAULT_NODE_VSPACING-5,color_black); } /* this is a parent of the main host we're drawing in auto-layout mode... */ if(layout_method!=LAYOUT_USER_SUPPLIED && draw_parent_links==TRUE && is_host_immediate_child_of_host(this_host,main_host)==TRUE){ x=temp_hostextinfo->x_2d+(DEFAULT_NODE_WIDTH/2)-canvas_x; y=temp_hostextinfo->y_2d+(DEFAULT_NODE_WIDTH/2)-canvas_y; draw_dashed_line(x,y,x,y-DEFAULT_NODE_HEIGHT-DEFAULT_NODE_VSPACING,color_black); /* draw arrow tips */ draw_line(x,y-DEFAULT_NODE_HEIGHT-DEFAULT_NODE_VSPACING,x-5,y-DEFAULT_NODE_HEIGHT-DEFAULT_NODE_VSPACING+5,color_black); draw_line(x,y-DEFAULT_NODE_HEIGHT-DEFAULT_NODE_VSPACING,x+5,y-DEFAULT_NODE_HEIGHT-DEFAULT_NODE_VSPACING+5,color_black); } /* draw links to all parent hosts */ for(temp_hostsmember=this_host->parent_hosts;temp_hostsmember!=NULL;temp_hostsmember=temp_hostsmember->next){ /* find extended info entry for this parent host */ temp_parent_hostextinfo=find_hostextinfo(temp_hostsmember->host_name); if(temp_parent_hostextinfo==NULL) continue; /* don't draw the link if we don't have the coords */ if(temp_parent_hostextinfo->have_2d_coords==FALSE || temp_hostextinfo->have_2d_coords==FALSE) continue; /* find the parent host config entry */ parent_host=find_host(temp_parent_hostextinfo->host_name); if(parent_host==NULL) continue; /* only draw link if user is authorized for this parent host */ if(is_authorized_for_host(parent_host,¤t_authdata)==FALSE) continue; /* are the hosts in the layer list? */ child_in_layer_list=is_host_in_layer_list(this_host); parent_in_layer_list=is_host_in_layer_list(parent_host); /* use dotted or solid line? */ /* either the child or parent should not be drawn, so use a dotted line */ if((child_in_layer_list==TRUE && parent_in_layer_list==FALSE) || (child_in_layer_list==FALSE && parent_in_layer_list==TRUE)) dotted_line=TRUE; /* both hosts should not be drawn, so use a dotted line */ else if((child_in_layer_list==FALSE && parent_in_layer_list==FALSE && exclude_layers==FALSE) || (child_in_layer_list==TRUE && parent_in_layer_list==TRUE && exclude_layers==TRUE)) dotted_line=TRUE; /* both hosts should be drawn, so use a solid line */ else dotted_line=FALSE; /* determine color to use when drawing links to parent host */ parent_hoststatus=find_hoststatus(temp_parent_hostextinfo->host_name); if(parent_hoststatus!=NULL){ if(parent_hoststatus->status==HOST_DOWN || parent_hoststatus->status==HOST_UNREACHABLE) status_color=color_red; else status_color=color_black; } else status_color=color_black; /* draw the link */ if(dotted_line==TRUE) draw_dotted_line((temp_hostextinfo->x_2d+(DEFAULT_NODE_WIDTH/2))-canvas_x,(temp_hostextinfo->y_2d+(DEFAULT_NODE_WIDTH)/2)-canvas_y,(temp_parent_hostextinfo->x_2d+(DEFAULT_NODE_WIDTH/2))-canvas_x,(temp_parent_hostextinfo->y_2d+(DEFAULT_NODE_WIDTH/2))-canvas_y,status_color); else draw_line((temp_hostextinfo->x_2d+(DEFAULT_NODE_WIDTH/2))-canvas_x,(temp_hostextinfo->y_2d+(DEFAULT_NODE_WIDTH)/2)-canvas_y,(temp_parent_hostextinfo->x_2d+(DEFAULT_NODE_WIDTH/2))-canvas_x,(temp_parent_hostextinfo->y_2d+(DEFAULT_NODE_WIDTH/2))-canvas_y,status_color); } } return; } /* draws hosts */ void draw_hosts(void){ hostextinfo *temp_hostextinfo; host *temp_host; int x1, x2; int y1, y2; int has_image=FALSE; char image_input_file[MAX_INPUT_BUFFER]; int current_radius=0; int status_color=color_black; hoststatus *temp_hoststatus; int in_layer_list=FALSE; int average_host_services; int host_services; double host_services_ratio; int outer_radius; int inner_radius; int time_color=0; time_t current_time; int translated_x; int translated_y; /* user didn't supply any coordinates for hosts, so display a warning */ if(coordinates_were_specified==FALSE){ if(create_type==CREATE_IMAGE){ draw_text("You have not supplied any host drawing coordinates, so you cannot use this layout method.",(COORDS_WARNING_WIDTH/2),30,color_black); draw_text("Read the FAQs for more information on specifying drawing coordinates or select a different layout method.",(COORDS_WARNING_WIDTH/2),45,color_black); } return; } /* draw Nagios process icon if using auto-layout mode */ if(layout_method!=LAYOUT_USER_SUPPLIED && draw_nagios_icon==TRUE){ /* get coords of bounding box */ x1=nagios_icon_x-canvas_x; x2=x1+DEFAULT_NODE_WIDTH; y1=nagios_icon_y-canvas_y; y2=y1+DEFAULT_NODE_HEIGHT; /* get the name of the image file to open for the logo */ snprintf(image_input_file,sizeof(image_input_file)-1,"%s%s",physical_logo_images_path,NAGIOS_GD2_ICON); image_input_file[sizeof(image_input_file)-1]='\x0'; /* read in the image from file... */ logo_image=load_image_from_file(image_input_file); /* copy the logo image to the canvas image... */ if(logo_image!=NULL){ gdImageCopy(map_image,logo_image,x1,y1,0,0,logo_image->sx,logo_image->sy); gdImageDestroy(logo_image); } /* if we don't have an image, draw a bounding box */ else{ draw_line(x1,y1,x1,y1+DEFAULT_NODE_WIDTH,color_black); draw_line(x1,y1+DEFAULT_NODE_WIDTH,x2,y1+DEFAULT_NODE_WIDTH,color_black); draw_line(x2,y1+DEFAULT_NODE_WIDTH,x2,y1,color_black); draw_line(x2,y1,x1,y1,color_black); } if(create_type==CREATE_IMAGE) draw_text("Nagios Process",x1+(DEFAULT_NODE_WIDTH/2),y1+DEFAULT_NODE_HEIGHT,color_black); } /* calculate average services per host */ average_host_services=4; /* draw all hosts... */ for(temp_hostextinfo=hostextinfo_list;temp_hostextinfo!=NULL;temp_hostextinfo=temp_hostextinfo->next){ /* skip hosts that should not be drawn */ if(temp_hostextinfo->should_be_drawn==FALSE) continue; /* find the host */ temp_host=find_host(temp_hostextinfo->host_name); /* is this host in the layer inclusion/exclusion list? */ in_layer_list=is_host_in_layer_list(temp_host); if((in_layer_list==TRUE && exclude_layers==TRUE) || (in_layer_list==FALSE && exclude_layers==FALSE)) continue; /* get coords of host bounding box */ x1=temp_hostextinfo->x_2d-canvas_x; x2=x1+DEFAULT_NODE_WIDTH; y1=temp_hostextinfo->y_2d-canvas_y; y2=y1+DEFAULT_NODE_HEIGHT; if(create_type==CREATE_IMAGE){ temp_hoststatus=find_hoststatus(temp_hostextinfo->host_name); if(temp_hoststatus!=NULL){ if(temp_hoststatus->status==HOST_DOWN) status_color=color_red; else if(temp_hoststatus->status==HOST_UNREACHABLE) status_color=color_red; else if(temp_hoststatus->status==HOST_UP) status_color=color_green; else if(temp_hoststatus->status==HOST_PENDING) status_color=color_grey; } else status_color=color_black; /* use balloons instead of icons... */ if(layout_method==LAYOUT_CIRCULAR_BALLOON){ /* get the number of services associated with the host */ host_services=number_of_host_services(temp_host); if(average_host_services==0) host_services_ratio=0.0; else host_services_ratio=(double)((double)host_services/(double)average_host_services); /* calculate size of node */ if(host_services_ratio>=2.0) outer_radius=DEFAULT_NODE_WIDTH; else if(host_services_ratio>=1.5) outer_radius=DEFAULT_NODE_WIDTH*0.8; else if(host_services_ratio>=1.0) outer_radius=DEFAULT_NODE_WIDTH*0.6; else if(host_services_ratio>=0.5) outer_radius=DEFAULT_NODE_WIDTH*0.4; else outer_radius=DEFAULT_NODE_WIDTH*0.2; /* calculate width of border */ if(temp_hoststatus==NULL) inner_radius=outer_radius; else if((temp_hoststatus->status==HOST_DOWN || temp_hoststatus->status==HOST_UNREACHABLE) && temp_hoststatus->problem_has_been_acknowledged==FALSE) inner_radius=outer_radius-3; else inner_radius=outer_radius; /* fill node with color based on how long its been in this state... */ gdImageArc(map_image,x1+(DEFAULT_NODE_WIDTH/2),y1+(DEFAULT_NODE_WIDTH/2),outer_radius,outer_radius,0,360,color_blue); /* determine fill color */ time(¤t_time); if(temp_hoststatus==NULL) time_color=color_white; else if(current_time-temp_hoststatus->last_state_change<=900) time_color=color_orange; else if(current_time-temp_hoststatus->last_state_change<=3600) time_color=color_yellow; else time_color=color_white; /* fill node with appropriate time color */ /* the fill function only works with coordinates that are in bounds of the actual image */ translated_x=x1+(DEFAULT_NODE_WIDTH/2); translated_y=y1+(DEFAULT_NODE_WIDTH/2); if(translated_x>0 && translated_y>0 && translated_x=inner_radius;current_radius--) gdImageArc(map_image,x1+(DEFAULT_NODE_WIDTH/2),y1+(DEFAULT_NODE_WIDTH/2),current_radius,current_radius,0,360,status_color); /* draw circles around the selected host (if there is one) */ if(!strcmp(host_name,temp_hostextinfo->host_name) && use_highlights==TRUE){ for(current_radius=DEFAULT_NODE_WIDTH*2;current_radius>0;current_radius-=10) gdImageArc(map_image,x1+(DEFAULT_NODE_WIDTH/2),y1+(DEFAULT_NODE_WIDTH/2),current_radius,current_radius,0,360,status_color); } } /* normal method is to use icons for hosts... */ else{ /* draw a target around root hosts (hosts with no parents) */ if(temp_host!=NULL && use_highlights==TRUE){ if(temp_host->parent_hosts==NULL){ gdImageArc(map_image,x1+(DEFAULT_NODE_WIDTH/2),y1+(DEFAULT_NODE_WIDTH/2),(DEFAULT_NODE_WIDTH*2),(DEFAULT_NODE_WIDTH*2),0,360,status_color); draw_line(x1-(DEFAULT_NODE_WIDTH/2),y1+(DEFAULT_NODE_WIDTH/2),x1+(DEFAULT_NODE_WIDTH*3/2),y1+(DEFAULT_NODE_WIDTH/2),status_color); draw_line(x1+(DEFAULT_NODE_WIDTH/2),y1-(DEFAULT_NODE_WIDTH/2),x1+(DEFAULT_NODE_WIDTH/2),y1+(DEFAULT_NODE_WIDTH*3/2),status_color); } } /* draw circles around the selected host (if there is one) */ if(!strcmp(host_name,temp_hostextinfo->host_name) && use_highlights==TRUE){ for(current_radius=DEFAULT_NODE_WIDTH*2;current_radius>0;current_radius-=10) gdImageArc(map_image,x1+(DEFAULT_NODE_WIDTH/2),y1+(DEFAULT_NODE_WIDTH/2),current_radius,current_radius,0,360,status_color); } if(temp_hostextinfo->statusmap_image!=NULL) has_image=TRUE; else has_image=FALSE; /* load the logo associated with this host */ if(has_image==TRUE){ /* get the name of the image file to open for the logo */ snprintf(image_input_file,sizeof(image_input_file)-1,"%s%s",physical_logo_images_path,temp_hostextinfo->statusmap_image); image_input_file[sizeof(image_input_file)-1]='\x0'; /* read in the logo image from file... */ logo_image=load_image_from_file(image_input_file); /* copy the logo image to the canvas image... */ if(logo_image!=NULL){ gdImageCopy(map_image,logo_image,x1,y1,0,0,logo_image->sx,logo_image->sy); gdImageDestroy(logo_image); } else has_image=FALSE; } /* if the host doesn't have an image associated with it (or the user doesn't have rights to see this host), use the unknown image */ if(has_image==FALSE){ if(unknown_logo_image!=NULL) gdImageCopy(map_image,unknown_logo_image,x1,y1,0,0,unknown_logo_image->sx,unknown_logo_image->sy); else{ /* last ditch effort - draw a host bounding box */ draw_line(x1,y1,x1,y1+DEFAULT_NODE_WIDTH,color_black); draw_line(x1,y1+DEFAULT_NODE_WIDTH,x2,y1+DEFAULT_NODE_WIDTH,color_black); draw_line(x2,y1+DEFAULT_NODE_WIDTH,x2,y1,color_black); draw_line(x2,y1,x1,y1,color_black); } } } /* draw host name, status, etc. */ draw_host_text(temp_hostextinfo->host_name,x1+(DEFAULT_NODE_WIDTH/2),y1+DEFAULT_NODE_HEIGHT); } /* we're creating HTML image map... */ else{ printf("host_name)) printf("href='%s?host=%s' ",STATUS_CGI,url_encode(temp_hostextinfo->host_name)); else{ printf("href='%s?host=%s&layout=%d&max_width=%d&max_height=%d&proximity_width=%d&proximity_height=%d%s%s%s%s%s",STATUSMAP_CGI,url_encode(temp_hostextinfo->host_name),layout_method,max_image_width,max_image_height,proximity_width,proximity_height,(display_header==TRUE)?"":"&noheader",(use_links==FALSE)?"&nolinks":"",(use_text==FALSE)?"¬ext":"",(use_highlights==FALSE)?"&nohighlights":"",(display_popups==FALSE)?"&nopopups":""); if(user_supplied_scaling==TRUE) printf("&scaling_factor=%2.1f",user_scaling_factor); print_layer_url(TRUE); printf("' "); } /* popup text */ if(display_popups==TRUE){ printf("onMouseOver='showPopup(\""); write_host_popup_text(find_host(temp_hostextinfo->host_name)); printf("\",event)' onMouseOut='hidePopup()'"); } printf(">\n"); } } return; } /* draws text */ void draw_text(char *buffer,int x,int y,int text_color){ int string_width=0; int string_height=0; /* write the string to the generated image... */ string_height=gdFontSmall->h; string_width=gdFontSmall->w*strlen(buffer); if(layout_method!=LAYOUT_CIRCULAR_MARKUP) gdImageFilledRectangle(map_image,x-(string_width/2)-2,y-(2*string_height),x+(string_width/2)+2,y-string_height,color_white); gdImageString(map_image,gdFontSmall,x-(string_width/2),y-(2*string_height),(unsigned char *)buffer,text_color); return; } /* draws host text */ void draw_host_text(char *name,int x,int y){ hoststatus *temp_hoststatus; int status_color=color_black; char temp_buffer[MAX_INPUT_BUFFER]; if(use_text==FALSE) return; strncpy(temp_buffer,name,sizeof(temp_buffer)-1); temp_buffer[sizeof(temp_buffer)-1]='\x0'; /* write the host status string to the generated image... */ draw_text(temp_buffer,x,y,color_black); /* find the status entry for this host */ temp_hoststatus=find_hoststatus(name); /* get the status of the host (pending, up, down, or unreachable) */ if(temp_hoststatus!=NULL){ /* draw the status string */ if(temp_hoststatus->status==HOST_DOWN){ strncpy(temp_buffer,"Down",sizeof(temp_buffer)); status_color=color_red; } else if(temp_hoststatus->status==HOST_UNREACHABLE){ strncpy(temp_buffer,"Unreachable",sizeof(temp_buffer)); status_color=color_red; } else if(temp_hoststatus->status==HOST_UP){ strncpy(temp_buffer,"Up",sizeof(temp_buffer)); status_color=color_green; } else if(temp_hoststatus->status==HOST_PENDING){ strncpy(temp_buffer,"Pending",sizeof(temp_buffer)); status_color=color_grey; } else{ strncpy(temp_buffer,"Unknown",sizeof(temp_buffer)); status_color=color_orange; } temp_buffer[sizeof(temp_buffer)-1]='\x0'; /* write the host status string to the generated image... */ draw_text(temp_buffer,x,y+gdFontSmall->h,status_color); } return; } /* writes popup text for a specific host */ void write_host_popup_text(host *hst){ hostextinfo *temp_hostextinfo; hoststatus *temp_status; hostsmember *temp_hostsmember; int service_totals; char date_time[48]; time_t current_time; time_t t; char state_duration[48]; int days; int hours; int minutes; int seconds; if(hst==NULL){ printf("Host data not found"); return; } /* find the status entry for this host */ temp_status=find_hoststatus(hst->name); if(temp_status==NULL){ printf("Host status information not found"); return; } /* strip nasty stuff from plugin output */ sanitize_plugin_output(temp_status->plugin_output); printf(""); temp_hostextinfo=find_hostextinfo(hst->name); if(temp_hostextinfo!=NULL){ printf("",url_logo_images_path,(temp_hostextinfo->icon_image==NULL)?UNKNOWN_ICON_IMAGE:temp_hostextinfo->icon_image); printf("",(temp_hostextinfo->icon_image_alt==NULL)?"":html_encode(temp_hostextinfo->icon_image_alt)); } printf("",html_encode(hst->name)); printf("",html_encode(hst->alias)); printf("",html_encode(hst->address)); printf(""); printf("",(temp_status->plugin_output==NULL)?"":temp_status->plugin_output); current_time=time(NULL); if(temp_status->last_state_change==(time_t)0) t=current_time-program_start; else t=current_time-temp_status->last_state_change; get_time_breakdown((unsigned long)t,&days,&hours,&minutes,&seconds); snprintf(state_duration,sizeof(state_duration)-1,"%2dd %2dh %2dm %2ds%s",days,hours,minutes,seconds,(temp_status->last_state_change==(time_t)0)?"+":""); state_duration[sizeof(state_duration)-1]='\x0'; printf("",state_duration); get_time_string(&temp_status->last_check,date_time,(int)sizeof(date_time),SHORT_DATE_TIME); printf("",(temp_status->last_check==(time_t)0)?"N/A":date_time); get_time_string(&temp_status->last_state_change,date_time,(int)sizeof(date_time),SHORT_DATE_TIME); printf("",(temp_status->last_state_change==(time_t)0)?"N/A":date_time); printf(""); printf(""); printf("
    %s
    Name:%s
    Alias:%s
    Address:%s
    State:"); /* get the status of the host (pending, up, down, or unreachable) */ if(temp_status->status==HOST_DOWN){ printf("Down"); if(temp_status->problem_has_been_acknowledged==TRUE) printf(" (Acknowledged)"); printf(""); } else if(temp_status->status==HOST_UNREACHABLE){ printf("Unreachable"); if(temp_status->problem_has_been_acknowledged==TRUE) printf(" (Acknowledged)"); printf(""); } else if(temp_status->status==HOST_UP) printf("Up"); else if(temp_status->status==HOST_PENDING) printf("Pending"); printf("
    Status Information:%s
    State Duration:%s
    Last Status Check:%s
    Last State Change:%s
    Parent Host(s):"); if(hst->parent_hosts==NULL) printf("None (This is a root host)"); else{ for(temp_hostsmember=hst->parent_hosts;temp_hostsmember!=NULL;temp_hostsmember=temp_hostsmember->next) printf("%s%s",(temp_hostsmember==hst->parent_hosts)?"":", ",html_encode(temp_hostsmember->host_name)); } printf("
    Immediate Child Hosts:"); printf("%d",number_of_immediate_child_hosts(hst)); printf("
    "); printf("
    Services:
    "); service_totals=get_servicestatus_count(hst->name,SERVICE_OK); if(service_totals>0) printf("- %d ok
    ",service_totals); service_totals=get_servicestatus_count(hst->name,SERVICE_CRITICAL); if(service_totals>0) printf("- %d critical
    ",service_totals); service_totals=get_servicestatus_count(hst->name,SERVICE_WARNING); if(service_totals>0) printf("- %d warning
    ",service_totals); service_totals=get_servicestatus_count(hst->name,SERVICE_UNKNOWN); if(service_totals>0) printf("- %d unknown
    ",service_totals); service_totals=get_servicestatus_count(hst->name,SERVICE_PENDING); if(service_totals>0) printf("- %d pending
    ",service_totals); return; } /* draws a solid line */ void draw_line(int x1,int y1,int x2,int y2,int color){ if(create_type==CREATE_HTML) return; gdImageLine(map_image,x1,y1,x2,y2,color); return; } /* draws a dotted line */ void draw_dotted_line(int x1,int y1,int x2,int y2,int color){ int styleDotted[12]; styleDotted[0]=color; styleDotted[1]=gdTransparent; styleDotted[2]=gdTransparent; styleDotted[3]=gdTransparent; styleDotted[4]=gdTransparent; styleDotted[5]=gdTransparent; styleDotted[6]=color; styleDotted[7]=gdTransparent; styleDotted[8]=gdTransparent; styleDotted[9]=gdTransparent; styleDotted[10]=gdTransparent; styleDotted[11]=gdTransparent; /* sets current style to a dashed line */ gdImageSetStyle(map_image,styleDotted,12); /* draws a line (dotted) */ gdImageLine(map_image,x1,y1,x2,y2,gdStyled); return; } /* draws a dashed line */ void draw_dashed_line(int x1,int y1,int x2,int y2,int color){ int styleDashed[12]; styleDashed[0]=color; styleDashed[1]=color; styleDashed[2]=color; styleDashed[3]=color; styleDashed[4]=gdTransparent; styleDashed[5]=gdTransparent; styleDashed[6]=color; styleDashed[7]=color; styleDashed[8]=color; styleDashed[9]=color; styleDashed[10]=gdTransparent; styleDashed[11]=gdTransparent; /* sets current style to a dashed line */ gdImageSetStyle(map_image,styleDashed,12); /* draws a line (dashed) */ gdImageLine(map_image,x1,y1,x2,y2,gdStyled); return; } /******************************************************************/ /*********************** GRAPHICS FUNCTIONS ***********************/ /******************************************************************/ /* initialize graphics */ int initialize_graphics(void){ char image_input_file[MAX_INPUT_BUFFER]; if(create_type==CREATE_HTML) return ERROR; /* allocate buffer for storing image */ map_image=gdImageCreate(canvas_width,canvas_height); if(map_image==NULL) return ERROR; /* allocate colors used for drawing */ color_white=gdImageColorAllocate(map_image,255,255,255); color_black=gdImageColorAllocate(map_image,0,0,0); color_grey=gdImageColorAllocate(map_image,128,128,128); color_lightgrey=gdImageColorAllocate(map_image,210,210,210); color_red=gdImageColorAllocate(map_image,255,0,0); color_lightred=gdImageColorAllocate(map_image,215,175,175); color_green=gdImageColorAllocate(map_image,0,175,0); color_lightgreen=gdImageColorAllocate(map_image,210,255,215); color_blue=gdImageColorAllocate(map_image,0,0,255); color_yellow=gdImageColorAllocate(map_image,255,255,0); color_orange=gdImageColorAllocate(map_image,255,100,25); /* set transparency index */ gdImageColorTransparent(map_image,color_white); /* make sure the graphic is interlaced */ gdImageInterlace(map_image,1); /* get the path where we will be reading logo images from (GD2 format)... */ snprintf(physical_logo_images_path,sizeof(physical_logo_images_path)-1,"%slogos/",physical_images_path); physical_logo_images_path[sizeof(physical_logo_images_path)-1]='\x0'; /* load the unknown icon to use for hosts that don't have pretty images associated with them... */ snprintf(image_input_file,sizeof(image_input_file)-1,"%s%s",physical_logo_images_path,UNKNOWN_GD2_ICON); image_input_file[sizeof(image_input_file)-1]='\x0'; unknown_logo_image=load_image_from_file(image_input_file); return OK; } /* loads a graphic image (GD2, JPG or PNG) from file into memory */ gdImagePtr load_image_from_file(char *filename){ FILE *fp; gdImagePtr im=NULL; char *ext; /* make sure we were passed a file name */ if(filename==NULL) return NULL; /* find the file extension */ if((ext=rindex(filename,'.'))==NULL) return NULL; /* open the file for reading (binary mode) */ fp=fopen(filename,"rb"); if(fp==NULL) return NULL; /* attempt to read files in various formats */ if(!strcasecmp(ext,".png")) im=gdImageCreateFromPng(fp); else if(!strcasecmp(ext,".jpg") || !strcasecmp(ext,".jpeg")) im=gdImageCreateFromJpeg(fp); else if(!strcasecmp(ext,".xbm")) im=gdImageCreateFromXbm(fp); else if(!strcasecmp(ext,".gd2")) im=gdImageCreateFromGd2(fp); else if(!strcasecmp(ext,".gd")) im=gdImageCreateFromGd(fp); /* fall back to GD2 image format */ else im=gdImageCreateFromGd2(fp); /* close the file */ fclose(fp); return im; } /* draw graphics */ void write_graphics(void){ FILE *image_output_file=NULL; if(create_type==CREATE_HTML) return; /* use STDOUT for writing the image data... */ image_output_file=stdout; /* write the image out in PNG format */ gdImagePng(map_image,image_output_file); /* or we could write the image out in JPG format... */ /*gdImageJpeg(map_image,image_output_file,99);*/ return; } /* cleanup graphics resources */ void cleanup_graphics(void){ if(create_type==CREATE_HTML) return; /* free memory allocated to image */ gdImageDestroy(map_image); return; } /******************************************************************/ /************************* MISC FUNCTIONS *************************/ /******************************************************************/ /* write JavaScript code an layer for popup window */ void write_popup_code(void){ char *border_color="#000000"; char *background_color="#ffffcc"; int border=1; int padding=3; int x_offset=3; int y_offset=3; printf("\n"); return; } /* adds a layer to the list in memory */ int add_layer(char *group_name){ layer *new_layer; if(group_name==NULL) return ERROR; /* allocate memory for a new layer */ new_layer=(layer *)malloc(sizeof(layer)); if(new_layer==NULL) return ERROR; new_layer->layer_name=(char *)malloc(strlen(group_name)+1); if(new_layer->layer_name==NULL){ free(new_layer); return ERROR; } strcpy(new_layer->layer_name,group_name); /* add new layer to head of layer list */ new_layer->next=layer_list; layer_list=new_layer; return OK; } /* frees memory allocated to the layer list */ void free_layer_list(void){ layer *this_layer; layer *next_layer; return; for(this_layer=layer_list;layer_list!=NULL;this_layer=next_layer){ next_layer=this_layer->next; free(this_layer->layer_name); free(this_layer); } return; } /* checks to see if a host is in the layer list */ int is_host_in_layer_list(host *hst){ hostgroup *temp_hostgroup; layer *temp_layer; if(hst==NULL) return FALSE; /* check each layer... */ for(temp_layer=layer_list;temp_layer!=NULL;temp_layer=temp_layer->next){ /* find the hostgroup */ temp_hostgroup=find_hostgroup(temp_layer->layer_name); if(temp_hostgroup==NULL) continue; /* is the requested host a member of the hostgroup/layer? */ if(is_host_member_of_hostgroup(temp_hostgroup,hst)==TRUE) return TRUE; } return FALSE; } /* print layer url info */ void print_layer_url(int get_method){ layer *temp_layer; for(temp_layer=layer_list;temp_layer!=NULL;temp_layer=temp_layer->next){ if(get_method==TRUE) printf("&layer=%s",temp_layer->layer_name); else printf("\n",temp_layer->layer_name); } if(get_method==TRUE) printf("&layermode=%s",(exclude_layers==TRUE)?"exclude":"include"); else printf("\n",(exclude_layers==TRUE)?"exclude":"include"); return; } /******************************************************************/ /************************ UTILITY FUNCTIONS ***********************/ /******************************************************************/ /* calculates how many "layers" separate parent and child - used by collapsed tree layout method */ int host_child_depth_separation(host *parent, host *child){ int this_depth=0; int min_depth=0; int have_min_depth=FALSE; host *temp_host; if(child==NULL) return -1; if(parent==child) return 0; if(is_host_immediate_child_of_host(parent,child)==TRUE) return 1; for(temp_host=host_list;temp_host!=NULL;temp_host=temp_host->next){ if(is_host_immediate_child_of_host(parent,temp_host)==TRUE){ this_depth=host_child_depth_separation(temp_host,child); if(this_depth>=0 && (have_min_depth==FALSE || (have_min_depth==TRUE && (this_depthnext){ current_layer=host_child_depth_separation(parent,temp_host); if(current_layer==layer) layer_members++; } return layer_members; } /* calculate max number of members on all "layers" beneath and including parent host - used by collapsed tree layout method */ int max_child_host_layer_members(host *parent){ int current_layer; int max_members=1; int current_members=0; for(current_layer=1;;current_layer++){ current_members=number_of_host_layer_members(parent,current_layer); if(current_members<=0) break; if(current_members>max_members) max_members=current_members; } return max_members; } /* calculate max drawing width for host and children - used by balanced tree layout method */ int max_child_host_drawing_width(host *parent){ host *temp_host; int child_width=0; for(temp_host=host_list;temp_host!=NULL;temp_host=temp_host->next){ if(is_host_immediate_child_of_host(parent,temp_host)==TRUE) child_width+=max_child_host_drawing_width(temp_host); } /* no children, so set width to 1 for this host */ if(child_width==0) return 1; else return child_width; } /* calculates number of services associated with a particular service */ int number_of_host_services(host *hst){ service *temp_service; int total_services=0; if(hst==NULL) return 0; /* check all the services */ for(temp_service=service_list;temp_service!=NULL;temp_service=temp_service->next){ if(!strcmp(temp_service->host_name,hst->name)) total_services++; } return total_services; } /******************************************************************/ /***************** COORDINATE CALCULATION FUNCTIONS ***************/ /******************************************************************/ /* calculates coords of a host's children - used by balanced tree layout method */ void calculate_balanced_tree_coords(host *parent, int x, int y){ int parent_drawing_width; int start_drawing_x; int current_drawing_x; int this_drawing_width; host *temp_host; hostextinfo *temp_hostextinfo; /* calculate total drawing width of parent host */ parent_drawing_width=max_child_host_drawing_width(parent); /* calculate starting x coord */ start_drawing_x=x-(((DEFAULT_NODE_WIDTH*parent_drawing_width)+(DEFAULT_NODE_HSPACING*(parent_drawing_width-1)))/2); current_drawing_x=start_drawing_x; /* calculate coords for children */ for(temp_host=host_list;temp_host!=NULL;temp_host=temp_host->next){ temp_hostextinfo=find_hostextinfo(temp_host->name); if(temp_hostextinfo==NULL) continue; if(is_host_immediate_child_of_host(parent,temp_host)==TRUE){ /* get drawing width of child host */ this_drawing_width=max_child_host_drawing_width(temp_host); temp_hostextinfo->x_2d=current_drawing_x+(((DEFAULT_NODE_WIDTH*this_drawing_width)+(DEFAULT_NODE_HSPACING*(this_drawing_width-1)))/2); temp_hostextinfo->y_2d=y+DEFAULT_NODE_HEIGHT+DEFAULT_NODE_VSPACING; temp_hostextinfo->have_2d_coords=TRUE; temp_hostextinfo->should_be_drawn=TRUE; current_drawing_x+=(this_drawing_width*DEFAULT_NODE_WIDTH)+((this_drawing_width-1)*DEFAULT_NODE_HSPACING)+DEFAULT_NODE_HSPACING; /* recurse into child host ... */ calculate_balanced_tree_coords(temp_host,temp_hostextinfo->x_2d,temp_hostextinfo->y_2d); } } return; } /* calculate coords of all hosts in circular layout method */ void calculate_circular_coords(void){ int min_x=0; int min_y=0; int have_min_x=FALSE; int have_min_y=FALSE; hostextinfo *temp_hostextinfo; /* calculate all host coords, starting with first layer */ calculate_circular_layer_coords(NULL,0.0,360.0,1,CIRCULAR_DRAWING_RADIUS); /* adjust all calculated coords so none are negative in x or y axis... */ /* calculate min x, y coords */ for(temp_hostextinfo=hostextinfo_list;temp_hostextinfo!=NULL;temp_hostextinfo=temp_hostextinfo->next){ if(have_min_x==FALSE || temp_hostextinfo->x_2dx_2d; } if(have_min_y==FALSE || temp_hostextinfo->y_2dy_2d; } } /* offset all drawing coords by the min x,y coords we found */ for(temp_hostextinfo=hostextinfo_list;temp_hostextinfo!=NULL;temp_hostextinfo=temp_hostextinfo->next){ if(min_x<0) temp_hostextinfo->x_2d-=min_x; if(min_y<0) temp_hostextinfo->y_2d-=min_y; } if(min_x<0) nagios_icon_x-=min_x; if(min_y<0) nagios_icon_y-=min_y; for(temp_hostextinfo=hostextinfo_list;temp_hostextinfo!=NULL;temp_hostextinfo=temp_hostextinfo->next){ temp_hostextinfo->x_2d+=(DEFAULT_NODE_WIDTH/2); temp_hostextinfo->y_2d+=(DEFAULT_NODE_HEIGHT/2); } nagios_icon_x+=(DEFAULT_NODE_WIDTH/2); nagios_icon_y+=(DEFAULT_NODE_HEIGHT/2); return; } /* calculates coords of all hosts in a particular "layer" in circular layout method */ void calculate_circular_layer_coords(host *parent, double start_angle, double useable_angle, int layer, int radius){ int parent_drawing_width=0; int this_drawing_width=0; int immediate_children=0; double current_drawing_angle=0.0; double this_drawing_angle=0.0; double available_angle=0.0; double clipped_available_angle=0.0; double average_child_angle=0.0; double x_coord=0.0; double y_coord=0.0; host *temp_host; hostextinfo *temp_hostextinfo; /* get the total number of immediate children to this host */ immediate_children=number_of_immediate_child_hosts(parent); /* bail out if we're done */ if(immediate_children==0) return; /* calculate total drawing "width" of parent host */ parent_drawing_width=max_child_host_drawing_width(parent); /* calculate average angle given to each child host */ average_child_angle=(double)(useable_angle/(double)immediate_children); /* calculate initial drawing angle */ current_drawing_angle=start_angle; /* calculate coords for children */ for(temp_host=host_list;temp_host!=NULL;temp_host=temp_host->next){ temp_hostextinfo=find_hostextinfo(temp_host->name); if(temp_hostextinfo==NULL) continue; if(is_host_immediate_child_of_host(parent,temp_host)==TRUE){ /* get drawing width of child host */ this_drawing_width=max_child_host_drawing_width(temp_host); /* calculate angle this host gets for drawing */ available_angle=useable_angle*((double)this_drawing_width/(double)parent_drawing_width); /* clip available angle if necessary */ /* this isn't really necessary, but helps keep things looking a bit more sane with less potential connection crossover */ clipped_available_angle=360.0/layer; if(available_angle=360.0) this_drawing_angle-=360.0; while(this_drawing_angle<0.0) this_drawing_angle+=360.0; /* calculate drawing coords of this host using good ol' geometry... */ x_coord=-(sin(-this_drawing_angle*(M_PI/180.0))*radius); y_coord=-(sin((90+this_drawing_angle)*(M_PI/180.0))*radius); temp_hostextinfo->x_2d=(int)x_coord; temp_hostextinfo->y_2d=(int)y_coord; temp_hostextinfo->have_2d_coords=TRUE; temp_hostextinfo->should_be_drawn=TRUE; /* recurse into child host ... */ calculate_circular_layer_coords(temp_host,current_drawing_angle+((available_angle-clipped_available_angle)/2),clipped_available_angle,layer+1,radius+CIRCULAR_DRAWING_RADIUS); /* increment current drawing angle */ current_drawing_angle+=available_angle; } } return; } /* draws background "extras" for all hosts in circular markup layout */ void draw_circular_markup(void){ /* calculate all host sections, starting with first layer */ draw_circular_layer_markup(NULL,0.0,360.0,1,CIRCULAR_DRAWING_RADIUS); return; } /* draws background "extras" for all hosts in a particular "layer" in circular markup layout */ void draw_circular_layer_markup(host *parent, double start_angle, double useable_angle, int layer, int radius){ int parent_drawing_width=0; int this_drawing_width=0; int immediate_children=0; double current_drawing_angle=0.0; double available_angle=0.0; double clipped_available_angle=0.0; double average_child_angle=0.0; double x_coord[4]={0.0,0.0,0.0,0.0}; double y_coord[4]={0.0,0.0,0.0,0.0}; host *temp_host; hoststatus *temp_hoststatus; hostextinfo *temp_hostextinfo; int x_offset=0; int y_offset=0; int center_x=0; int center_y=0; int bgcolor=0; double arc_start_angle=0.0; double arc_end_angle=0.0; int translated_x=0; int translated_y=0; /* get the total number of immediate children to this host */ immediate_children=number_of_immediate_child_hosts(parent); /* bail out if we're done */ if(immediate_children==0) return; /* calculate total drawing "width" of parent host */ parent_drawing_width=max_child_host_drawing_width(parent); /* calculate average angle given to each child host */ average_child_angle=(double)(useable_angle/(double)immediate_children); /* calculate initial drawing angle */ current_drawing_angle=start_angle; /* calculate coords for children */ for(temp_host=host_list;temp_host!=NULL;temp_host=temp_host->next){ temp_hostextinfo=find_hostextinfo(temp_host->name); if(temp_hostextinfo==NULL) continue; if(is_host_immediate_child_of_host(parent,temp_host)==TRUE){ /* get drawing width of child host */ this_drawing_width=max_child_host_drawing_width(temp_host); /* calculate angle this host gets for drawing */ available_angle=useable_angle*((double)this_drawing_width/(double)parent_drawing_width); /* clip available angle if necessary */ /* this isn't really necessary, but helps keep things looking a bit more sane with less potential connection crossover */ clipped_available_angle=360.0/layer; if(available_angle1 || layer>1){ /* draw "leftmost" divider */ gdImageLine(map_image,(int)x_coord[0]+x_offset,(int)y_coord[0]+y_offset,(int)x_coord[1]+x_offset,(int)y_coord[1]+y_offset,color_lightgrey); /* draw "rightmost" divider */ gdImageLine(map_image,(int)x_coord[2]+x_offset,(int)y_coord[2]+y_offset,(int)x_coord[3]+x_offset,(int)y_coord[3]+y_offset,color_lightgrey); } /* determine arc drawing angles */ arc_start_angle=current_drawing_angle-90.0; while(arc_start_angle<0.0) arc_start_angle+=360.0; arc_end_angle=arc_start_angle+available_angle; /* draw inner arc */ gdImageArc(map_image,x_offset,y_offset,(radius-(CIRCULAR_DRAWING_RADIUS/2))*2,(radius-(CIRCULAR_DRAWING_RADIUS/2))*2,floor(arc_start_angle),ceil(arc_end_angle),color_lightgrey); /* draw outer arc */ gdImageArc(map_image,x_offset,y_offset,(radius+(CIRCULAR_DRAWING_RADIUS/2))*2,(radius+(CIRCULAR_DRAWING_RADIUS/2))*2,floor(arc_start_angle),ceil(arc_end_angle),color_lightgrey); /* determine center of "slice" and fill with appropriate color */ center_x=-(sin(-(current_drawing_angle+(available_angle/2.0))*(M_PI/180.0))*(radius)); center_y=-(sin((90+current_drawing_angle+(available_angle/2.0))*(M_PI/180.0))*(radius)); translated_x=center_x+x_offset; translated_y=center_y+y_offset; /* determine background color */ temp_hoststatus=find_hoststatus(temp_host->name); if(temp_hoststatus==NULL) bgcolor=color_lightgrey; else if(temp_hoststatus->status==HOST_DOWN || temp_hoststatus->status==HOST_UNREACHABLE) bgcolor=color_lightred; else bgcolor=color_lightgreen; /* fill slice with background color */ /* the fill function only works with coordinates that are in bounds of the actual image */ if(translated_x>0 && translated_y>0 && translated_xError: Could not open CGI configuration file '%s' for reading!

    \n",get_cgi_config_location()); document_footer(); return ERROR; } /* read the main configuration file */ result=read_main_config_file(main_config_file); if(result==ERROR){ printf("

    Error: Could not open main configuration file '%s' for reading!

    \n",main_config_file); document_footer(); return ERROR; } /* read all object configuration data */ result=read_all_object_configuration_data(main_config_file,READ_ALL_OBJECT_DATA); if(result==ERROR){ printf("

    Error: Could not read some or all object configuration data!

    \n"); document_footer(); return ERROR; } /* read all status data */ result=read_all_status_data(get_cgi_config_location(),READ_ALL_STATUS_DATA); if(result==ERROR){ printf("

    Error: Could not read host and service status information!

    \n"); document_footer(); free_memory(); return ERROR; } /* get authentication information */ get_authentication_information(¤t_authdata); /* decide what to display to the user */ if(display_type==DISPLAY_HOST && host_style==DISPLAY_HOST_SERVICES) display_host_services(); else if(display_type==DISPLAY_HOST) display_host(); else if(display_type==DISPLAY_SERVICE) display_service(); else if(display_type==DISPLAY_HOSTGROUP && hostgroup_style==DISPLAY_HOSTGROUP_OVERVIEW) display_hostgroup_overview(); else if(display_type==DISPLAY_HOSTGROUP && hostgroup_style==DISPLAY_HOSTGROUP_SUMMARY) display_hostgroup_summary(); else if(display_type==DISPLAY_PING) display_ping(); else if(display_type==DISPLAY_TRACEROUTE) display_traceroute(); else if(display_type==DISPLAY_QUICKSTATS) display_quick_stats(); else if(display_type==DISPLAY_PROCESS) display_process(); else if(display_type==DISPLAY_ALL_PROBLEMS || display_type==DISPLAY_UNHANDLED_PROBLEMS) display_problems(); else display_index(); document_footer(); /* free all allocated memory */ free_memory(); return OK; } void document_header(void){ char date_time[MAX_DATETIME_LENGTH]; time_t expire_time; time_t current_time; time(¤t_time); printf("Cache-Control: no-store\r\n"); printf("Pragma: no-cache\r\n"); get_time_string(¤t_time,date_time,(int)sizeof(date_time),HTTP_DATE_TIME); printf("Last-Modified: %s\r\n",date_time); expire_time=(time_t)0L; get_time_string(&expire_time,date_time,(int)sizeof(date_time),HTTP_DATE_TIME); printf("Expires: %s\r\n",date_time); printf("Content-type: text/vnd.wap.wml\r\n\r\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); return; } void document_footer(void){ printf("\n"); return; } int process_cgivars(void){ char **variables; int error=FALSE; int x; variables=getcgivars(); for(x=0;variables[x]!=NULL;x++){ /* we found the hostgroup argument */ if(!strcmp(variables[x],"hostgroup")){ display_type=DISPLAY_HOSTGROUP; x++; if(variables[x]==NULL){ error=TRUE; break; } hostgroup_name=(char *)malloc(strlen(variables[x])+1); if(hostgroup_name==NULL) hostgroup_name=""; else strcpy(hostgroup_name,variables[x]); if(!strcmp(hostgroup_name,"all")) show_all_hostgroups=TRUE; else show_all_hostgroups=FALSE; } /* we found the host argument */ else if(!strcmp(variables[x],"host")){ display_type=DISPLAY_HOST; x++; if(variables[x]==NULL){ error=TRUE; break; } host_name=(char *)malloc(strlen(variables[x])+1); if(host_name==NULL) host_name=""; else strcpy(host_name,variables[x]); } /* we found the service argument */ else if(!strcmp(variables[x],"service")){ display_type=DISPLAY_SERVICE; x++; if(variables[x]==NULL){ error=TRUE; break; } service_desc=(char *)malloc(strlen(variables[x])+1); if(service_desc==NULL) service_desc=""; else strcpy(service_desc,variables[x]); } /* we found the hostgroup style argument */ else if(!strcmp(variables[x],"style")){ x++; if(variables[x]==NULL){ error=TRUE; break; } if(!strcmp(variables[x],"overview")) hostgroup_style=DISPLAY_HOSTGROUP_OVERVIEW; else if(!strcmp(variables[x],"summary")) hostgroup_style=DISPLAY_HOSTGROUP_SUMMARY; else if(!strcmp(variables[x],"servicedetail")) host_style=DISPLAY_HOST_SERVICES; else if(!strcmp(variables[x],"processinfo")) display_type=DISPLAY_PROCESS; else if(!strcmp(variables[x],"aprobs")) display_type=DISPLAY_ALL_PROBLEMS; else if(!strcmp(variables[x],"uprobs")) display_type=DISPLAY_UNHANDLED_PROBLEMS; else display_type=DISPLAY_QUICKSTATS; } /* we found the ping argument */ else if(!strcmp(variables[x],"ping")){ display_type=DISPLAY_PING; x++; if(variables[x]==NULL){ error=TRUE; break; } ping_address=(char *)malloc(strlen(variables[x])+1); if(ping_address==NULL) ping_address=""; else strcpy(ping_address,variables[x]); } /* we found the traceroute argument */ else if(!strcmp(variables[x],"traceroute")){ display_type=DISPLAY_TRACEROUTE; x++; if(variables[x]==NULL){ error=TRUE; break; } traceroute_address=(char *)malloc(strlen(variables[x])+1); if(traceroute_address==NULL) traceroute_address=""; else strcpy(traceroute_address,variables[x]); } } /* free memory allocated to the CGI variables */ free_cgivars(variables); return error; } /* main intro screen */ void display_index(void){ /**** MAIN MENU SCREEN (CARD 1) ****/ printf("\n"); printf("

    \n"); printf("Nagios
    WAP Interface
    \n"); printf("Quick Stats
    \n",STATUSWML_CGI); printf("Status Summary
    \n",STATUSWML_CGI); printf("Status Overview
    \n",STATUSWML_CGI); printf("All Problems
    \n",STATUSWML_CGI); printf("Unhandled Problems
    \n",STATUSWML_CGI); printf("Process Info
    \n",STATUSWML_CGI); printf("Tools
    \n"); printf("About
    \n"); printf("

    \n"); printf("
    \n"); /**** TOOLS SCREEN (CARD 2) ****/ printf("\n"); printf("

    \n"); printf("Network Tools:
    \n"); printf("Ping
    \n",STATUSWML_CGI); printf("Traceroute
    \n",STATUSWML_CGI); printf("View Host
    \n"); printf("View Hostgroup
    \n"); printf("

    \n"); printf("
    \n"); /**** ABOUT SCREEN (CARD 3) ****/ printf("\n"); printf("

    \n"); printf("About
    \n"); printf("

    \n"); printf("

    \n"); printf("Nagios %s
    WAP Interface
    \n",PROGRAM_VERSION); printf("Copyright (C) 2001 Ethan Galstad
    \n"); printf("nagios@nagios.org

    \n"); printf("License: GPL

    \n"); printf("Based in part on features found in AskAround's Wireless Network Tools
    \n"); printf("www.askaround.com
    \n"); printf("

    \n"); printf("
    \n"); /**** VIEW HOST SCREEN (CARD 4) ****/ printf("\n"); printf("

    \n"); printf("View Host
    \n"); printf("

    \n"); printf("

    \n"); printf("Host Name:
    \n"); printf("\n"); printf("\n"); printf("\n",STATUSWML_CGI); printf("\n"); printf("

    \n"); printf("
    \n"); /**** VIEW HOSTGROUP SCREEN (CARD 5) ****/ printf("\n"); printf("

    \n"); printf("View Hostgroup
    \n"); printf("

    \n"); printf("

    \n"); printf("Hostgroup Name:
    \n"); printf("\n"); printf("\n"); printf("\n",STATUSWML_CGI); printf("\n"); printf("

    \n"); printf("
    \n"); return; } /* displays process info */ void display_process(void){ /**** MAIN SCREEN (CARD 1) ****/ printf("\n"); printf("

    \n"); printf("Process Info

    \n"); /* check authorization */ if(is_authorized_for_system_information(¤t_authdata)==FALSE){ printf("Error: Not authorized for process info!\n"); printf("

    \n"); printf("
    \n"); return; } if(nagios_process_state==STATE_OK) printf("Nagios process is running
    \n"); else printf("Nagios process may not be running
    \n"); if(enable_notifications==TRUE) printf("Notifications are enabled
    \n"); else printf("Notifications are disabled
    \n"); if(execute_service_checks==TRUE) printf("Check execution is enabled
    \n"); else printf("Check execution is disabled
    \n"); printf("
    \n"); printf("Process Commands\n"); printf("

    \n"); printf("\n"); /**** COMMANDS SCREEN (CARD 2) ****/ printf("\n"); printf("

    \n"); printf("Process Commands
    \n"); if(enable_notifications==FALSE) printf("Enable Notifications
    \n",COMMAND_CGI,CMD_ENABLE_NOTIFICATIONS,CMDMODE_COMMIT); else printf("Disable Notifications
    \n",COMMAND_CGI,CMD_DISABLE_NOTIFICATIONS,CMDMODE_COMMIT); if(execute_service_checks==FALSE) printf("Enable Check Execution
    \n",COMMAND_CGI,CMD_START_EXECUTING_SVC_CHECKS,CMDMODE_COMMIT); else printf("Disable Check Execution
    \n",COMMAND_CGI,CMD_STOP_EXECUTING_SVC_CHECKS,CMDMODE_COMMIT); printf("

    \n"); printf("
    \n"); return; } /* displays quick stats */ void display_quick_stats(void){ host *temp_host; hoststatus *temp_hoststatus; service *temp_service; servicestatus *temp_servicestatus; int hosts_unreachable=0; int hosts_down=0; int hosts_up=0; int hosts_pending=0; int services_critical=0; int services_unknown=0; int services_warning=0; int services_ok=0; int services_pending=0; /**** MAIN SCREEN (CARD 1) ****/ printf("\n"); printf("

    \n"); printf("Quick Stats
    \n"); printf("

    \n"); /* check all hosts */ for(temp_host=host_list;temp_host!=NULL;temp_host=temp_host->next){ if(is_authorized_for_host(temp_host,¤t_authdata)==FALSE) continue; temp_hoststatus=find_hoststatus(temp_host->name); if(temp_hoststatus==NULL) continue; if(temp_hoststatus->status==HOST_UNREACHABLE) hosts_unreachable++; else if(temp_hoststatus->status==HOST_DOWN) hosts_down++; else if(temp_hoststatus->status==HOST_PENDING) hosts_pending++; else hosts_up++; } /* check all services */ for(temp_service=service_list;temp_service!=NULL;temp_service=temp_service->next){ if(is_authorized_for_service(temp_service,¤t_authdata)==FALSE) continue; temp_servicestatus=find_servicestatus(temp_service->host_name,temp_service->description); if(temp_servicestatus==NULL) continue; if(temp_servicestatus->status==SERVICE_CRITICAL) services_critical++; else if(temp_servicestatus->status==SERVICE_UNKNOWN) services_unknown++; else if(temp_servicestatus->status==SERVICE_WARNING) services_warning++; else if(temp_servicestatus->status==SERVICE_PENDING) services_pending++; else services_ok++; } printf("

    \n"); printf("Host Totals:
    \n"); printf("%d UP
    \n",hosts_up); printf("%d DOWN
    \n",hosts_down); printf("%d UNREACHABLE
    \n",hosts_unreachable); printf("%d PENDING
    \n",hosts_pending); printf("
    \n"); printf("Service Totals:
    \n"); printf("%d OK
    \n",services_ok); printf("%d WARNING
    \n",services_warning); printf("%d UNKNOWN
    \n",services_unknown); printf("%d CRITICAL
    \n",services_critical); printf("%d PENDING
    \n",services_pending); printf("

    \n"); printf("
    \n"); return; } /* displays hostgroup status overview */ void display_hostgroup_overview(void){ hostgroup *temp_hostgroup; hostgroupmember *temp_member; host *temp_host; hoststatus *temp_hoststatus; /**** MAIN SCREEN (CARD 1) ****/ printf("\n"); printf("

    \n"); printf("Status Overview

    \n",STATUSWML_CGI,hostgroup_name); /* check all hostgroups */ for(temp_hostgroup=hostgroup_list;temp_hostgroup!=NULL;temp_hostgroup=temp_hostgroup->next){ if(show_all_hostgroups==FALSE && strcmp(temp_hostgroup->group_name,hostgroup_name)) continue; if(is_authorized_for_hostgroup(temp_hostgroup,¤t_authdata)==FALSE) continue; printf("%s\n",temp_hostgroup->alias); printf("\n"); /* check all hosts in this hostgroup */ for(temp_member=temp_hostgroup->members;temp_member!=NULL;temp_member=temp_member->next){ temp_host=find_host(temp_member->host_name); if(temp_host==NULL) continue; if(is_host_member_of_hostgroup(temp_hostgroup,temp_host)==FALSE) continue; temp_hoststatus=find_hoststatus(temp_host->name); if(temp_hoststatus==NULL) continue; printf("",STATUSWML_CGI,temp_host->name); printf("\n",temp_host->name); } printf("
    ",temp_host->name); if(temp_hoststatus->status==HOST_UP) printf("UP"); else if(temp_hoststatus->status==HOST_PENDING) printf("PND"); else if(temp_hoststatus->status==HOST_DOWN) printf("DWN"); else if(temp_hoststatus->status==HOST_UNREACHABLE) printf("UNR"); else printf("???"); printf("%s
    \n"); printf("
    \n"); } if(show_all_hostgroups==FALSE) printf("View All Hostgroups\n",STATUSWML_CGI); printf("

    \n"); printf("
    \n"); return; } /* displays hostgroup status summary */ void display_hostgroup_summary(void){ hostgroup *temp_hostgroup; hostgroupmember *temp_member; host *temp_host; hoststatus *temp_hoststatus; service *temp_service; servicestatus *temp_servicestatus; int hosts_unreachable=0; int hosts_down=0; int hosts_up=0; int hosts_pending=0; int services_critical=0; int services_unknown=0; int services_warning=0; int services_ok=0; int services_pending=0; int found=0; /**** MAIN SCREEN (CARD 1) ****/ printf("\n"); printf("

    \n"); printf("Status Summary

    \n",STATUSWML_CGI,hostgroup_name); /* check all hostgroups */ for(temp_hostgroup=hostgroup_list;temp_hostgroup!=NULL;temp_hostgroup=temp_hostgroup->next){ if(show_all_hostgroups==FALSE && strcmp(temp_hostgroup->group_name,hostgroup_name)) continue; if(is_authorized_for_hostgroup(temp_hostgroup,¤t_authdata)==FALSE) continue; printf("%s\n",temp_hostgroup->group_name,temp_hostgroup->alias,STATUSWML_CGI,temp_hostgroup->group_name); printf("\n"); hosts_up=0; hosts_pending=0; hosts_down=0; hosts_unreachable=0; services_ok=0; services_pending=0; services_warning=0; services_unknown=0; services_critical=0; /* check all hosts in this hostgroup */ for(temp_member=temp_hostgroup->members;temp_member!=NULL;temp_member=temp_member->next){ temp_host=find_host(temp_member->host_name); if(temp_host==NULL) continue; if(is_host_member_of_hostgroup(temp_hostgroup,temp_host)==FALSE) continue; temp_hoststatus=find_hoststatus(temp_host->name); if(temp_hoststatus==NULL) continue; if(temp_hoststatus->status==HOST_UNREACHABLE) hosts_unreachable++; else if(temp_hoststatus->status==HOST_DOWN) hosts_down++; else if(temp_hoststatus->status==HOST_PENDING) hosts_pending++; else hosts_up++; /* check all services on this host */ for(temp_service=service_list;temp_service!=NULL;temp_service=temp_service->next){ if(strcmp(temp_service->host_name,temp_host->name)) continue; if(is_authorized_for_service(temp_service,¤t_authdata)==FALSE) continue; temp_servicestatus=find_servicestatus(temp_service->host_name,temp_service->description); if(temp_servicestatus==NULL) continue; if(temp_servicestatus->status==SERVICE_CRITICAL) services_critical++; else if(temp_servicestatus->status==SERVICE_UNKNOWN) services_unknown++; else if(temp_servicestatus->status==SERVICE_WARNING) services_warning++; else if(temp_servicestatus->status==SERVICE_PENDING) services_pending++; else services_ok++; } } printf("\n"); printf("\n"); printf("
    Hosts:"); found=0; if(hosts_unreachable>0){ printf("%d UNR",hosts_unreachable); found=1; } if(hosts_down>0){ printf("%s%d DWN",(found==1)?", ":"",hosts_down); found=1; } if(hosts_pending>0){ printf("%s%d PND",(found==1)?", ":"",hosts_pending); found=1; } printf("%s%d UP",(found==1)?", ":"",hosts_up); printf("
    Services:"); found=0; if(services_critical>0){ printf("%d CRI",services_critical); found=1; } if(services_warning>0){ printf("%s%d WRN",(found==1)?", ":"",services_warning); found=1; } if(services_unknown>0){ printf("%s%d UNK",(found==1)?", ":"",services_unknown); found=1; } if(services_pending>0){ printf("%s%d PND",(found==1)?", ":"",services_pending); found=1; } printf("%s%d OK",(found==1)?", ":"",services_ok); printf("
    \n"); printf("
    \n"); } if(show_all_hostgroups==FALSE) printf("View All Hostgroups\n",STATUSWML_CGI); printf("

    \n"); printf("
    \n"); return; } /* displays host status */ void display_host(void){ host *temp_host; hoststatus *temp_hoststatus; char last_check[MAX_DATETIME_LENGTH]; int days; int hours; int minutes; int seconds; time_t current_time; time_t t; char state_duration[48]; int found; /**** MAIN SCREEN (CARD 1) ****/ printf("\n"); printf("

    \n"); printf("Host '%s'
    \n",host_name); /* find the host */ temp_host=find_host(host_name); temp_hoststatus=find_hoststatus(host_name); if(temp_host==NULL || temp_hoststatus==NULL){ printf("Error: Could not find host!\n"); printf("

    \n"); printf("
    \n"); return; } /* check authorization */ if(is_authorized_for_host(temp_host,¤t_authdata)==FALSE){ printf("Error: Not authorized for host!\n"); printf("

    \n"); printf("\n"); return; } printf("\n"); printf("\n"); printf("\n",temp_hoststatus->plugin_output); get_time_string(&temp_hoststatus->last_check,last_check,sizeof(last_check)-1,SHORT_DATE_TIME); printf("\n",last_check); current_time=time(NULL); if(temp_hoststatus->last_state_change==(time_t)0) t=current_time-program_start; else t=current_time-temp_hoststatus->last_state_change; get_time_breakdown((unsigned long)t,&days,&hours,&minutes,&seconds); snprintf(state_duration,sizeof(state_duration)-1,"%2dd %2dh %2dm %2ds%s",days,hours,minutes,seconds,(temp_hoststatus->last_state_change==(time_t)0)?"+":""); printf("\n",state_duration); printf("\n"); printf("
    Status:"); if(temp_hoststatus->status==HOST_UP) printf("UP"); else if(temp_hoststatus->status==HOST_PENDING) printf("PENDING"); else if(temp_hoststatus->status==HOST_DOWN) printf("DOWN"); else if(temp_hoststatus->status==HOST_UNREACHABLE) printf("UNREACHABLE"); else printf("?"); printf("
    Info:%s
    Last Check:%s
    Duration:%s
    Properties:"); found=0; if(temp_hoststatus->checks_enabled==FALSE){ printf("%sChecks disabled",(found==1)?", ":""); found=1; } if(temp_hoststatus->notifications_enabled==FALSE){ printf("%sNotifications disabled",(found==1)?", ":""); found=1; } if(temp_hoststatus->problem_has_been_acknowledged==TRUE){ printf("%sProblem acknowledged",(found==1)?", ":""); found=1; } if(temp_hoststatus->scheduled_downtime_depth>0){ printf("%sIn scheduled downtime",(found==1)?", ":""); found=1; } if(found==0) printf("N/A"); printf("
    \n"); printf("
    \n"); printf("View Services\n",STATUSWML_CGI,host_name); printf("Host Commands\n"); printf("

    \n"); printf("\n"); /**** COMMANDS SCREEN (CARD 2) ****/ printf("\n"); printf("

    \n"); printf("Host Commands
    \n"); printf("Ping Host\n",STATUSWML_CGI,temp_host->address); printf("Traceroute\n",STATUSWML_CGI,temp_host->address); if(temp_hoststatus->status!=HOST_UP && temp_hoststatus->status!=HOST_PENDING) printf("Acknowledge Problem\n"); if(temp_hoststatus->checks_enabled==FALSE) printf("Enable Host Checks
    \n",COMMAND_CGI,host_name,CMD_ENABLE_HOST_CHECK,CMDMODE_COMMIT); else printf("Disable Host Checks
    \n",COMMAND_CGI,host_name,CMD_DISABLE_HOST_CHECK,CMDMODE_COMMIT); if(temp_hoststatus->notifications_enabled==FALSE) printf("Enable Host Notifications
    \n",COMMAND_CGI,host_name,CMD_ENABLE_HOST_NOTIFICATIONS,CMDMODE_COMMIT); else printf("Disable Host Notifications
    \n",COMMAND_CGI,host_name,CMD_DISABLE_HOST_NOTIFICATIONS,CMDMODE_COMMIT); printf("Enable All Service Checks
    \n",COMMAND_CGI,host_name,CMD_ENABLE_HOST_SVC_CHECKS,CMDMODE_COMMIT); printf("Disable All Service Checks
    \n",COMMAND_CGI,host_name,CMD_DISABLE_HOST_SVC_CHECKS,CMDMODE_COMMIT); printf("Enable All Service Notifications
    \n",COMMAND_CGI,host_name,CMD_ENABLE_HOST_SVC_NOTIFICATIONS,CMDMODE_COMMIT); printf("Disable All Service Notifications
    \n",COMMAND_CGI,host_name,CMD_DISABLE_HOST_SVC_NOTIFICATIONS,CMDMODE_COMMIT); printf("

    \n"); printf("
    \n"); /**** ACKNOWLEDGEMENT SCREEN (CARD 3) ****/ printf("\n"); printf("

    \n"); printf("Acknowledge Problem
    \n"); printf("

    \n"); printf("

    \n"); printf("Your Name:
    \n"); printf("
    \n"); printf("Comment:
    \n"); printf("\n"); printf("\n"); printf("\n",COMMAND_CGI,host_name,CMD_ACKNOWLEDGE_HOST_PROBLEM,CMDMODE_COMMIT); printf("\n"); printf("

    \n"); printf("
    \n"); return; } /* displays services on a host */ void display_host_services(void){ service *temp_service; servicestatus *temp_servicestatus; /**** MAIN SCREEN (CARD 1) ****/ printf("\n"); printf("

    \n"); printf("Host '%s' Services
    \n",host_name,host_name,STATUSWML_CGI,host_name); printf("\n"); /* check all services */ for(temp_service=service_list;temp_service!=NULL;temp_service=temp_service->next){ if(strcmp(temp_service->host_name,host_name)) continue; if(is_authorized_for_service(temp_service,¤t_authdata)==FALSE) continue; temp_servicestatus=find_servicestatus(temp_service->host_name,temp_service->description); if(temp_servicestatus==NULL) continue; printf("",STATUSWML_CGI,temp_service->host_name,temp_service->description); printf("\n",temp_service->description); } printf("
    ",temp_service->description); if(temp_servicestatus->status==SERVICE_OK) printf("OK"); else if(temp_servicestatus->status==SERVICE_PENDING) printf("PND"); else if(temp_servicestatus->status==SERVICE_WARNING) printf("WRN"); else if(temp_servicestatus->status==SERVICE_UNKNOWN) printf("UNK"); else if(temp_servicestatus->status==SERVICE_CRITICAL) printf("CRI"); else printf("???"); printf("%s
    \n"); printf("

    \n"); printf("
    \n"); return; } /* displays service status */ void display_service(void){ service *temp_service; servicestatus *temp_servicestatus; char last_check[MAX_DATETIME_LENGTH]; int days; int hours; int minutes; int seconds; time_t current_time; time_t t; char state_duration[48]; int found; /**** MAIN SCREEN (CARD 1) ****/ printf("\n"); printf("

    \n"); printf("Service '%s' on host '%s'
    \n",service_desc,host_name); /* find the service */ temp_service=find_service(host_name,service_desc); temp_servicestatus=find_servicestatus(host_name,service_desc); if(temp_service==NULL || temp_servicestatus==NULL){ printf("Error: Could not find service!\n"); printf("

    \n"); printf("
    \n"); return; } /* check authorization */ if(is_authorized_for_service(temp_service,¤t_authdata)==FALSE){ printf("Error: Not authorized for service!\n"); printf("

    \n"); printf("\n"); return; } printf("\n"); printf("\n"); printf("\n",temp_servicestatus->plugin_output); get_time_string(&temp_servicestatus->last_check,last_check,sizeof(last_check)-1,SHORT_DATE_TIME); printf("\n",last_check); current_time=time(NULL); if(temp_servicestatus->last_state_change==(time_t)0) t=current_time-program_start; else t=current_time-temp_servicestatus->last_state_change; get_time_breakdown((unsigned long)t,&days,&hours,&minutes,&seconds); snprintf(state_duration,sizeof(state_duration)-1,"%2dd %2dh %2dm %2ds%s",days,hours,minutes,seconds,(temp_servicestatus->last_state_change==(time_t)0)?"+":""); printf("\n",state_duration); printf("\n"); printf("
    Status:"); if(temp_servicestatus->status==SERVICE_OK) printf("OK"); else if(temp_servicestatus->status==SERVICE_PENDING) printf("PENDING"); else if(temp_servicestatus->status==SERVICE_WARNING) printf("WARNING"); else if(temp_servicestatus->status==SERVICE_UNKNOWN) printf("UNKNOWN"); else if(temp_servicestatus->status==SERVICE_CRITICAL) printf("CRITICAL"); else printf("?"); printf("
    Info:%s
    Last Check:%s
    Duration:%s
    Properties:"); found=0; if(temp_servicestatus->checks_enabled==FALSE){ printf("%sChecks disabled",(found==1)?", ":""); found=1; } if(temp_servicestatus->notifications_enabled==FALSE){ printf("%sNotifications disabled",(found==1)?", ":""); found=1; } if(temp_servicestatus->problem_has_been_acknowledged==TRUE){ printf("%sProblem acknowledged",(found==1)?", ":""); found=1; } if(temp_servicestatus->scheduled_downtime_depth>0){ printf("%sIn scheduled downtime",(found==1)?", ":""); found=1; } if(found==0) printf("N/A"); printf("
    \n"); printf("
    \n"); printf("View Host\n",STATUSWML_CGI,host_name); printf("Svc. Commands\n"); printf("

    \n"); printf("\n"); /**** COMMANDS SCREEN (CARD 2) ****/ printf("\n"); printf("

    \n"); printf("Service Commands
    \n"); if(temp_servicestatus->status!=SERVICE_OK && temp_servicestatus->status!=SERVICE_PENDING) printf("Acknowledge Problem\n"); if(temp_servicestatus->checks_enabled==FALSE) printf("Enable Checks
    \n",COMMAND_CGI,host_name,service_desc,CMD_ENABLE_SVC_CHECK,CMDMODE_COMMIT); else{ printf("Disable Checks
    \n",COMMAND_CGI,host_name,service_desc,CMD_DISABLE_SVC_CHECK,CMDMODE_COMMIT); printf("Schedule Immediate Check
    \n",COMMAND_CGI,host_name,service_desc,CMD_SCHEDULE_SVC_CHECK,CMDMODE_COMMIT); } if(temp_servicestatus->notifications_enabled==FALSE) printf("Enable Notifications
    \n",COMMAND_CGI,host_name,service_desc,CMD_ENABLE_SVC_NOTIFICATIONS,CMDMODE_COMMIT); else printf("Disable Notifications
    \n",COMMAND_CGI,host_name,service_desc,CMD_DISABLE_SVC_NOTIFICATIONS,CMDMODE_COMMIT); printf("

    \n"); printf("
    \n"); /**** ACKNOWLEDGEMENT SCREEN (CARD 3) ****/ printf("\n"); printf("

    \n"); printf("Acknowledge Problem
    \n"); printf("

    \n"); printf("

    \n"); printf("Your Name:
    \n"); printf("
    \n"); printf("Comment:
    \n"); printf("\n"); printf("\n"); printf("\n",COMMAND_CGI,host_name,service_desc,CMD_ACKNOWLEDGE_SVC_PROBLEM,CMDMODE_COMMIT); printf("\n"); printf("

    \n"); printf("
    \n"); return; } /* displays ping results */ void display_ping(void){ char input_buffer[MAX_INPUT_BUFFER]; char buffer[MAX_INPUT_BUFFER]; char *temp_ptr; FILE *fp; int odd=0; int in_macro=FALSE; /**** MAIN SCREEN (CARD 1) ****/ printf("\n"); if(!strcmp(ping_address,"")){ printf("

    \n"); printf("Ping Host
    \n"); printf("

    \n"); printf("

    \n"); printf("Host Name/Address:
    \n"); printf("\n"); printf("\n"); printf("\n",STATUSWML_CGI); printf("\n"); printf("

    \n"); } else{ printf("

    \n"); printf("Results For Ping Of %s:
    \n",ping_address); printf("

    \n"); printf("

    \n"); if(ping_syntax==NULL) printf("ping_syntax in CGI config file is NULL!\n"); else{ /* process macros in the ping syntax */ strcpy(buffer,""); strncpy(input_buffer,ping_syntax,sizeof(input_buffer)-1); input_buffer[strlen(ping_syntax)-1]='\x0'; for(temp_ptr=my_strtok(input_buffer,"$");temp_ptr!=NULL;temp_ptr=my_strtok(NULL,"$")){ if(in_macro==FALSE){ if(strlen(buffer)+strlen(temp_ptr)\n",buffer); } else{ odd=1; printf("%s
    \n",buffer); } } } else printf("Error executing ping!\n"); pclose(fp); } printf("

    \n"); } printf("
    \n"); return; } /* displays traceroute results */ void display_traceroute(void){ char buffer[MAX_INPUT_BUFFER]; FILE *fp; int odd=0; /**** MAIN SCREEN (CARD 1) ****/ printf("\n"); if(!strcmp(traceroute_address,"")){ printf("

    \n"); printf("Traceroute
    \n"); printf("

    \n"); printf("

    \n"); printf("Host Name/Address:
    \n"); printf("\n"); printf("\n"); printf("\n",STATUSWML_CGI); printf("\n"); printf("

    \n"); } else{ printf("

    \n"); printf("Results For Traceroute To %s:
    \n",traceroute_address); printf("

    \n"); printf("

    \n"); snprintf(buffer,sizeof(buffer)-1,"%s %s",TRACEROUTE_COMMAND,traceroute_address); buffer[sizeof(buffer)-1]='\x0'; fp=popen(buffer,"r"); if(fp){ while(1){ fgets(buffer,sizeof(buffer)-1,fp); if(feof(fp)) break; strip(buffer); if(odd){ odd=0; printf("%s
    \n",buffer); } else{ odd=1; printf("%s
    \n",buffer); } } } else printf("Error executing traceroute!\n"); pclose(fp); printf("

    \n"); } printf("
    \n"); return; } /* displays problems */ void display_problems(void){ host *temp_host; service *temp_service; hoststatus *temp_hoststatus; int total_host_problems=0; servicestatus *temp_servicestatus; int total_service_problems=0; /**** MAIN SCREEN (CARD 1) ****/ printf("\n",(display_type==DISPLAY_ALL_PROBLEMS)?"All":"Unhandled"); printf("

    \n"); printf("%s Problems

    \n",(display_type==DISPLAY_ALL_PROBLEMS)?"All":"Unhandled"); printf("Host Problems:\n"); printf("\n"); /* check all hosts */ for(temp_hoststatus=hoststatus_list;temp_hoststatus!=NULL;temp_hoststatus=temp_hoststatus->next){ temp_host=find_host(temp_hoststatus->host_name); if(temp_host==NULL) continue; if(is_authorized_for_host(temp_host,¤t_authdata)==FALSE) continue; if(temp_hoststatus->status==HOST_UP || temp_hoststatus->status==HOST_PENDING) continue; if(display_type==DISPLAY_UNHANDLED_PROBLEMS){ if(temp_hoststatus->problem_has_been_acknowledged==TRUE) continue; if(temp_hoststatus->notifications_enabled==FALSE) continue; if(temp_hoststatus->scheduled_downtime_depth>0) continue; } total_host_problems++; printf("",STATUSWML_CGI,temp_host->name); printf("\n",temp_host->name); } if(total_host_problems==0) printf("\n"); printf("
    ",temp_host->name); if(temp_hoststatus->status==HOST_DOWN) printf("DWN"); else if(temp_hoststatus->status==HOST_UNREACHABLE) printf("UNR"); else printf("???"); printf("%s
    No problems
    \n"); printf("
    \n"); printf("Svc Problems:\n"); printf("\n"); /* check all services */ for(temp_servicestatus=servicestatus_list;temp_servicestatus!=NULL;temp_servicestatus=temp_servicestatus->next){ temp_service=find_service(temp_servicestatus->host_name,temp_servicestatus->description); if(temp_service==NULL) continue; if(is_authorized_for_service(temp_service,¤t_authdata)==FALSE) continue; if(temp_servicestatus->status==SERVICE_OK || temp_servicestatus->status==SERVICE_PENDING) continue; if(display_type==DISPLAY_UNHANDLED_PROBLEMS){ if(temp_servicestatus->problem_has_been_acknowledged==TRUE) continue; if(temp_servicestatus->notifications_enabled==FALSE) continue; if(temp_servicestatus->scheduled_downtime_depth>0) continue; if((temp_hoststatus=find_hoststatus(temp_service->host_name))){ if(temp_hoststatus->scheduled_downtime_depth>0) continue; if(temp_hoststatus->problem_has_been_acknowledged==TRUE) continue; } } total_service_problems++; printf("",STATUSWML_CGI,temp_service->host_name,temp_service->description); printf("\n",temp_service->host_name,temp_service->description); } if(total_service_problems==0) printf("\n"); printf("
    ",temp_servicestatus->description); if(temp_servicestatus->status==SERVICE_CRITICAL) printf("CRI"); else if(temp_servicestatus->status==SERVICE_WARNING) printf("WRN"); else if(temp_servicestatus->status==SERVICE_UNKNOWN) printf("UNK"); else printf("???"); printf("%s/%s
    No problems
    \n"); printf("

    \n"); printf("
    \n"); return; } nagios-2.6/cgi/statuswrl.c0000664000076500007650000011247510412003336015157 0ustar nagiosnagios/***************************************************************************** * * STATUSWRL.C - Nagios 3-D (VRML) Network Status View * * Copyright (c) 1999-2006 Ethan Galstad (nagios@nagios.org) * Last Modified: 03-27-2006 * * Description: * * This CGI will dynamically create a 3-D VRML model of all hosts that are * being monitored on your network. * * 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. * *****************************************************************************/ #include "../include/config.h" #include "../include/common.h" #include "../include/objects.h" #include "../include/statusdata.h" #include "../include/cgiutils.h" #include "../include/getcgi.h" #include "../include/cgiauth.h" extern char main_config_file[MAX_FILENAME_LENGTH]; extern char url_html_path[MAX_FILENAME_LENGTH]; extern char url_images_path[MAX_FILENAME_LENGTH]; extern char url_logo_images_path[MAX_FILENAME_LENGTH]; extern char *statuswrl_include; extern host *host_list; extern service *service_list; extern hostextinfo *hostextinfo_list; extern int default_statuswrl_layout_method; #define NAGIOS_VRML_IMAGE "nagiosvrml.png" #define DEFAULT_NODE_WIDTH 0.5 #define DEFAULT_HORIZONTAL_SPACING 1.0 #define DEFAULT_VERTICAL_SPACING 1.0 /* needed for auto-layout modes */ #define DEFAULT_NODE_HEIGHT 0.5 #define DEFAULT_NODE_HSPACING 1.0 #define DEFAULT_NODE_VSPACING 1.0 #define CIRCULAR_DRAWING_RADIUS 5.0 #define LAYOUT_USER_SUPPLIED 0 #define LAYOUT_COLLAPSED_TREE 2 #define LAYOUT_BALANCED_TREE 3 #define LAYOUT_CIRCULAR 4 void calculate_host_coords(void); void calculate_world_bounds(void); void display_world(void); void write_global_vrml_data(void); void draw_process_icon(void); void draw_host(hostextinfo *); void draw_host_links(void); void draw_host_link(host *,double,double,double,double,double,double); void document_header(void); int process_cgivars(void); int number_of_host_layer_members(host *,int); int max_child_host_layer_members(host *); int host_child_depth_separation(host *, host *); int max_child_host_drawing_width(host *); void calculate_balanced_tree_coords(host *,int,int); void calculate_circular_coords(void); void calculate_circular_layer_coords(host *,double,double,int,int); authdata current_authdata; float link_radius=0.016; float floor_width=0.0; float floor_depth=0.0; double min_z_coord=0.0; double min_x_coord=0.0; double min_y_coord=0.0; double max_z_coord=0.0; double max_x_coord=0.0; double max_y_coord=0.0; double max_world_size=0.0; double nagios_icon_x=0.0; double nagios_icon_y=0.0; int draw_nagios_icon=FALSE; double custom_viewpoint_x=0.0; double custom_viewpoint_y=0.0; double custom_viewpoint_z=0.0; int custom_viewpoint=FALSE; float vertical_spacing=DEFAULT_VERTICAL_SPACING; float horizontal_spacing=DEFAULT_HORIZONTAL_SPACING; float node_width=DEFAULT_NODE_WIDTH; float node_height=DEFAULT_NODE_WIDTH; /* should be the same as the node width */ char *host_name="all"; int show_all_hosts=TRUE; int use_textures=TRUE; int use_text=TRUE; int use_links=TRUE; int layout_method=LAYOUT_USER_SUPPLIED; int coordinates_were_specified=FALSE; /* were drawing coordinates specified with extended host info entries? */ int main(int argc, char **argv){ int result; /* reset internal variables */ reset_cgi_vars(); /* read the CGI configuration file */ result=read_cgi_config_file(get_cgi_config_location()); if(result==ERROR){ document_header(); return ERROR; } /* defaults from CGI config file */ layout_method=default_statuswrl_layout_method; /* get the arguments passed in the URL */ process_cgivars(); document_header(); /* read the main configuration file */ result=read_main_config_file(main_config_file); if(result==ERROR) return ERROR; /* read all object configuration data */ result=read_all_object_configuration_data(main_config_file,READ_ALL_OBJECT_DATA); if(result==ERROR) return ERROR; /* read all status data */ result=read_all_status_data(get_cgi_config_location(),READ_ALL_STATUS_DATA); if(result==ERROR){ free_memory(); return ERROR; } /* get authentication information */ get_authentication_information(¤t_authdata); /* display the 3-D VRML world... */ display_world(); /* free all allocated memory */ free_memory(); return OK; } void document_header(void){ char date_time[MAX_DATETIME_LENGTH]; time_t current_time; time_t expire_time; printf("Cache-Control: no-store\r\n"); printf("Pragma: no-cache\r\n"); time(¤t_time); get_time_string(¤t_time,date_time,sizeof(date_time),HTTP_DATE_TIME); printf("Last-Modified: %s\r\n",date_time); expire_time=0L; get_time_string(&expire_time,date_time,sizeof(date_time),HTTP_DATE_TIME); printf("Expires: %s\r\n",date_time); printf("Content-Type: x-world/x-vrml\r\n\r\n"); return; } int process_cgivars(void){ char **variables; int error=FALSE; int x; variables=getcgivars(); for(x=0;variables[x]!=NULL;x++){ /* do some basic length checking on the variable identifier to prevent buffer overflows */ if(strlen(variables[x])>=MAX_INPUT_BUFFER-1){ x++; continue; } /* we found the host argument */ else if(!strcmp(variables[x],"host")){ x++; if(variables[x]==NULL){ error=TRUE; break; } host_name=(char *)malloc(strlen(variables[x])+1); if(host_name==NULL) host_name="all"; else strcpy(host_name,variables[x]); if(!strcmp(host_name,"all")) show_all_hosts=TRUE; else show_all_hosts=FALSE; } /* we found the no textures argument*/ else if(!strcmp(variables[x],"notextures")) use_textures=FALSE; /* we found the no text argument*/ else if(!strcmp(variables[x],"notext")) use_text=FALSE; /* we found the no links argument*/ else if(!strcmp(variables[x],"nolinks")) use_links=FALSE; /* we found the layout method option */ else if(!strcmp(variables[x],"layout")){ x++; if(variables[x]==NULL){ error=TRUE; break; } layout_method=atoi(variables[x]); } /* we found custom viewpoint coord */ else if(!strcmp(variables[x],"viewx")){ x++; if(variables[x]==NULL){ error=TRUE; break; } custom_viewpoint_x=strtod(variables[x],NULL); custom_viewpoint=TRUE; } else if(!strcmp(variables[x],"viewy")){ x++; if(variables[x]==NULL){ error=TRUE; break; } custom_viewpoint_y=strtod(variables[x],NULL); custom_viewpoint=TRUE; } else if(!strcmp(variables[x],"viewz")){ x++; if(variables[x]==NULL){ error=TRUE; break; } custom_viewpoint_z=strtod(variables[x],NULL); custom_viewpoint=TRUE; } } /* free memory allocated to the CGI variables */ free_cgivars(variables); return error; } /* top-level VRML world generation... */ void display_world(void){ hostextinfo *temp_hostextinfo; /* get the url we will use to grab the logo images... */ snprintf(url_logo_images_path,sizeof(url_logo_images_path),"%slogos/",url_images_path); url_logo_images_path[sizeof(url_logo_images_path)-1]='\x0'; /* calculate host drawing coordinates */ calculate_host_coords(); /* calculate world bounds */ calculate_world_bounds(); /* get the floor dimensions */ if(max_x_coord>0) floor_width=(float)(max_x_coord-min_x_coord)+(node_width*2); else floor_width=(float)(max_x_coord+min_x_coord)+(node_width*2); if(max_z_coord>0) floor_depth=(float)(max_z_coord-min_z_coord)+(node_height*2); else floor_depth=(float)(max_z_coord+min_z_coord)+(node_height*2); /* write global VRML data */ write_global_vrml_data(); /* no coordinates were specified, so display warning message */ if(coordinates_were_specified==FALSE){ printf("\n"); printf("Transform{\n"); printf("translation 0.0 0.0 0.0\n"); printf("children[\n"); printf("Billboard{\n"); printf("children[\n"); printf("Shape{\n"); printf("appearance Appearance {\n"); printf("material Material {\n"); printf("diffuseColor 1 0 0\n"); printf("}\n"); printf("}\n"); printf("geometry Text {\n"); printf("string [ \"Error: You have not supplied any 3-D drawing coordinates.\", \"Read the documentation for more information on supplying\", \"3-D drawing coordinates by defining\", \"extended host information entries in your config files.\" ]\n"); printf("fontStyle FontStyle {\n"); printf("family \"TYPEWRITER\"\n"); printf("size 0.3\n"); printf("justify \"MIDDLE\"\n"); printf("}\n"); printf("}\n"); printf("}\n"); printf("]\n"); printf("}\n"); printf("]\n"); printf("}\n"); } /* coordinates were specified... */ else{ /* draw Nagios icon */ if(layout_method!=LAYOUT_USER_SUPPLIED) draw_process_icon(); /* draw all hosts */ for(temp_hostextinfo=hostextinfo_list;temp_hostextinfo!=NULL;temp_hostextinfo=temp_hostextinfo->next) draw_host(temp_hostextinfo); /* draw host links */ draw_host_links(); } return; } /******************************************************************/ /************************ UTILITY FUNCTIONS ***********************/ /******************************************************************/ /* calculates how many "layers" separate parent and child - used by collapsed tree layout method */ int host_child_depth_separation(host *parent, host *child){ int this_depth=0; int min_depth=0; int have_min_depth=FALSE; host *temp_host; if(child==NULL) return -1; if(parent==child) return 0; if(is_host_immediate_child_of_host(parent,child)==TRUE) return 1; for(temp_host=host_list;temp_host!=NULL;temp_host=temp_host->next){ if(is_host_immediate_child_of_host(parent,temp_host)==TRUE){ this_depth=host_child_depth_separation(temp_host,child); if(this_depth>=0 && (have_min_depth==FALSE || (have_min_depth==TRUE && (this_depthnext){ current_layer=host_child_depth_separation(parent,temp_host); if(current_layer==layer) layer_members++; } return layer_members; } /* calculate max number of members on all "layers" beneath and including parent host - used by collapsed tree layout method */ int max_child_host_layer_members(host *parent){ int current_layer; int max_members=1; int current_members=0; for(current_layer=1;;current_layer++){ current_members=number_of_host_layer_members(parent,current_layer); if(current_members<=0) break; if(current_members>max_members) max_members=current_members; } return max_members; } /* calculate max drawing width for host and children - used by balanced tree layout method */ int max_child_host_drawing_width(host *parent){ host *temp_host; int child_width=0; for(temp_host=host_list;temp_host!=NULL;temp_host=temp_host->next){ if(is_host_immediate_child_of_host(parent,temp_host)==TRUE) child_width+=max_child_host_drawing_width(temp_host); } /* no children, so set width to 1 for this host */ if(child_width==0) return 1; else return child_width; } /******************************************************************/ /********************* CALCULATION FUNCTIONS **********************/ /******************************************************************/ /* calculates host drawing coordinates */ void calculate_host_coords(void){ hostextinfo *temp_hostextinfo; host *this_host; host *temp_host; int parent_hosts=0; int max_layer_width=1; int current_parent_host=0; int center_x=0; int offset_x=DEFAULT_NODE_WIDTH/2; int offset_y=DEFAULT_NODE_WIDTH/2; int current_layer=0; int layer_members=0; int current_layer_member=0; int max_drawing_width=0; /******************************/ /***** MANUAL LAYOUT MODE *****/ /******************************/ /* user-supplied coords */ if(layout_method==LAYOUT_USER_SUPPLIED){ /* see which hosts we should draw (only those with 3-D coords) */ for(temp_hostextinfo=hostextinfo_list;temp_hostextinfo!=NULL;temp_hostextinfo=temp_hostextinfo->next){ if(temp_hostextinfo->have_3d_coords==TRUE) temp_hostextinfo->should_be_drawn=TRUE; else temp_hostextinfo->should_be_drawn=FALSE; } return; } /*****************************/ /***** AUTO-LAYOUT MODES *****/ /*****************************/ /* add empty extended host info entries for all hosts that don't have any */ for(temp_host=host_list;temp_host!=NULL;temp_host=temp_host->next){ /* find the corresponding hostextinfo definition */ temp_hostextinfo=find_hostextinfo(temp_host->name); /* none was found, so add a blank one */ if(temp_hostextinfo==NULL) add_hostextinfo(temp_host->name,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,0,0.0,0.0,0.0,0,0); /* default z coord should 0 for auto-layout modes unless overridden later */ else temp_hostextinfo->z_3d=0.0; } /***** COLLAPSED TREE MODE *****/ if(layout_method==LAYOUT_COLLAPSED_TREE){ /* always use NULL as the "main" host, screen coords/dimensions are adjusted automatically */ this_host=NULL; /* find total number of immediate parents for this host */ parent_hosts=number_of_immediate_parent_hosts(this_host); /* find the max layer width we have... */ max_layer_width=max_child_host_layer_members(this_host); if(parent_hosts>max_layer_width) max_layer_width=parent_hosts; /* calculate center x coord */ center_x=(((DEFAULT_NODE_WIDTH*max_layer_width)+(DEFAULT_NODE_HSPACING*(max_layer_width-1)))/2)+offset_x; /* coords for Nagios icon if necessary */ if(this_host==NULL || this_host->parent_hosts==NULL){ nagios_icon_x=center_x; nagios_icon_y=offset_y; draw_nagios_icon=TRUE; } /* do we need to draw a link to parent(s)? */ if(this_host!=NULL && is_host_immediate_child_of_host(NULL,this_host)==FALSE) offset_y+=DEFAULT_NODE_HEIGHT+DEFAULT_NODE_VSPACING; /* see which hosts we should draw and calculate drawing coords */ for(temp_hostextinfo=hostextinfo_list;temp_hostextinfo!=NULL;temp_hostextinfo=temp_hostextinfo->next){ /* find the host that matches this entry */ temp_host=find_host(temp_hostextinfo->host_name); if(temp_host==NULL) continue; /* this is an immediate parent of the "main" host we're drawing */ else if(is_host_immediate_parent_of_host(this_host,temp_host)==TRUE){ temp_hostextinfo->should_be_drawn=TRUE; temp_hostextinfo->have_3d_coords=TRUE; temp_hostextinfo->x_3d=center_x-(((parent_hosts*DEFAULT_NODE_WIDTH)+((parent_hosts-1)*DEFAULT_NODE_HSPACING))/2)+(current_parent_host*(DEFAULT_NODE_WIDTH+DEFAULT_NODE_HSPACING))+(DEFAULT_NODE_WIDTH/2); temp_hostextinfo->y_3d=offset_y; current_parent_host++; } /* this is the "main" host we're drawing */ else if(this_host==temp_host){ temp_hostextinfo->should_be_drawn=TRUE; temp_hostextinfo->have_3d_coords=TRUE; temp_hostextinfo->x_3d=center_x; temp_hostextinfo->y_3d=DEFAULT_NODE_HEIGHT+DEFAULT_NODE_VSPACING+offset_y; } /* else do not draw this host (we might if its a child - see below, but assume no for now) */ else{ temp_hostextinfo->should_be_drawn=FALSE; temp_hostextinfo->have_3d_coords=FALSE; } } /* TODO: REORDER CHILD LAYER MEMBERS SO THAT WE MINIMIZE LINK CROSSOVERS FROM PARENT HOSTS */ /* draw hosts in child "layers" */ for(current_layer=1;;current_layer++){ /* how many members in this layer? */ layer_members=number_of_host_layer_members(this_host,current_layer); if(layer_members==0) break; current_layer_member=0; /* see which hosts are members of this layer and calculate drawing coords */ for(temp_hostextinfo=hostextinfo_list;temp_hostextinfo!=NULL;temp_hostextinfo=temp_hostextinfo->next){ /* find the host that matches this entry */ temp_host=find_host(temp_hostextinfo->host_name); if(temp_host==NULL) continue; /* is this host a member of the current child layer? */ if(host_child_depth_separation(this_host,temp_host)==current_layer){ temp_hostextinfo->should_be_drawn=TRUE; temp_hostextinfo->have_3d_coords=TRUE; temp_hostextinfo->x_3d=center_x-(((layer_members*DEFAULT_NODE_WIDTH)+((layer_members-1)*DEFAULT_NODE_HSPACING))/2)+(current_layer_member*(DEFAULT_NODE_WIDTH+DEFAULT_NODE_HSPACING))+(DEFAULT_NODE_WIDTH/2); if(this_host==NULL) temp_hostextinfo->y_3d=((DEFAULT_NODE_HEIGHT+DEFAULT_NODE_VSPACING)*current_layer)+offset_y; else temp_hostextinfo->y_3d=((DEFAULT_NODE_HEIGHT+DEFAULT_NODE_VSPACING)*(current_layer+1))+offset_y; current_layer_member++; } } } } /***** "BALANCED" TREE MODE *****/ else if(layout_method==LAYOUT_BALANCED_TREE){ /* always use NULL as the "main" host, screen coords/dimensions are adjusted automatically */ this_host=NULL; /* find total number of immediate parents for this host */ parent_hosts=number_of_immediate_parent_hosts(this_host); /* find the max drawing width we have... */ max_drawing_width=max_child_host_drawing_width(this_host); if(parent_hosts>max_drawing_width) max_drawing_width=parent_hosts; /* calculate center x coord */ center_x=(((DEFAULT_NODE_WIDTH*max_drawing_width)+(DEFAULT_NODE_HSPACING*(max_drawing_width-1)))/2)+offset_x; /* coords for Nagios icon if necessary */ if(this_host==NULL || this_host->parent_hosts==NULL){ nagios_icon_x=center_x; nagios_icon_y=offset_y; draw_nagios_icon=TRUE; } /* do we need to draw a link to parent(s)? */ if(this_host!=NULL && is_host_immediate_child_of_host(NULL,this_host)==FALSE) offset_y+=DEFAULT_NODE_HEIGHT+DEFAULT_NODE_VSPACING; /* see which hosts we should draw and calculate drawing coords */ for(temp_hostextinfo=hostextinfo_list;temp_hostextinfo!=NULL;temp_hostextinfo=temp_hostextinfo->next){ /* find the host that matches this entry */ temp_host=find_host(temp_hostextinfo->host_name); if(temp_host==NULL) continue; /* this is an immediate parent of the "main" host we're drawing */ else if(is_host_immediate_parent_of_host(this_host,temp_host)==TRUE){ temp_hostextinfo->should_be_drawn=TRUE; temp_hostextinfo->have_3d_coords=TRUE; temp_hostextinfo->x_3d=center_x-(((parent_hosts*DEFAULT_NODE_WIDTH)+((parent_hosts-1)*DEFAULT_NODE_HSPACING))/2)+(current_parent_host*(DEFAULT_NODE_WIDTH+DEFAULT_NODE_HSPACING))+(DEFAULT_NODE_WIDTH/2); temp_hostextinfo->y_3d=offset_y; current_parent_host++; } /* this is the "main" host we're drawing */ else if(this_host==temp_host){ temp_hostextinfo->should_be_drawn=TRUE; temp_hostextinfo->have_3d_coords=TRUE; temp_hostextinfo->x_3d=center_x; temp_hostextinfo->y_3d=DEFAULT_NODE_HEIGHT+DEFAULT_NODE_VSPACING+offset_y; } /* else do not draw this host (we might if its a child - see below, but assume no for now) */ else{ temp_hostextinfo->should_be_drawn=FALSE; temp_hostextinfo->have_3d_coords=FALSE; } } /* draw all children hosts */ calculate_balanced_tree_coords(this_host,center_x,DEFAULT_NODE_HEIGHT+DEFAULT_NODE_VSPACING+offset_y); } /***** CIRCULAR LAYOUT MODE *****/ else if(layout_method==LAYOUT_CIRCULAR){ /* draw process icon */ nagios_icon_x=0; nagios_icon_y=0; draw_nagios_icon=TRUE; /* calculate coordinates for all hosts */ calculate_circular_coords(); } return; } /* calculate world dimensions */ void calculate_world_bounds(void){ hostextinfo *temp_hostextinfo; min_x_coord=0.0; min_y_coord=0.0; min_z_coord=0.0; max_x_coord=0.0; max_y_coord=0.0; max_z_coord=0.0; /* check all extended host entries */ for(temp_hostextinfo=hostextinfo_list;temp_hostextinfo!=NULL;temp_hostextinfo=temp_hostextinfo->next){ if(temp_hostextinfo->have_3d_coords==FALSE){ temp_hostextinfo->should_be_drawn=FALSE; continue; } if(temp_hostextinfo->should_be_drawn==FALSE) continue; if(temp_hostextinfo->x_3d < min_x_coord) min_x_coord=temp_hostextinfo->x_3d; else if(temp_hostextinfo->x_3d > max_x_coord) max_x_coord=temp_hostextinfo->x_3d; if(temp_hostextinfo->y_3d < min_y_coord) min_y_coord=temp_hostextinfo->y_3d; else if(temp_hostextinfo->y_3d > max_y_coord) max_y_coord=temp_hostextinfo->y_3d; if(temp_hostextinfo->z_3d < min_z_coord) min_z_coord=temp_hostextinfo->z_3d; else if(temp_hostextinfo->z_3d > max_z_coord) max_z_coord=temp_hostextinfo->z_3d; coordinates_were_specified=TRUE; } /* no drawing coordinates were specified */ if(coordinates_were_specified==FALSE){ min_x_coord=0.0; max_x_coord=0.0; min_y_coord=0.0; max_y_coord=0.0; min_z_coord=0.0; max_z_coord=6.0; } max_world_size=max_x_coord-min_x_coord; if(max_world_size<(max_y_coord-min_y_coord)) max_world_size=max_y_coord-min_y_coord; if(max_world_size<(max_z_coord-min_z_coord)) max_world_size=max_z_coord-min_z_coord; return; } /******************************************************************/ /*********************** DRAWING FUNCTIONS ************************/ /******************************************************************/ /* write global VRML data */ void write_global_vrml_data(void){ hostextinfo *temp_hostextinfo; float visibility_range=0.0; float viewpoint_z=0.0; /* write VRML code header */ printf("#VRML V2.0 utf8\n"); /* write world information */ printf("\n"); printf("WorldInfo{\n"); printf("title \"Nagios 3-D Network Status View\"\n"); printf("info [\"Copyright (c) 1999-2002 Ethan Galstad\"\n"); printf("\"nagios@nagios.org\"]\n"); printf("}\n"); /* background color */ printf("\n"); printf("Background{\n"); printf("skyColor 0.1 0.1 0.15\n"); printf("}\n"); /* calculate visibility range - don't let it get too low */ visibility_range=(max_world_size*2.0); if(visibility_range<25.0) visibility_range=25.0; /* write fog information */ printf("\n"); printf("Fog{\n"); printf("color 0.1 0.1 0.15\n"); printf("fogType \"EXPONENTIAL\"\n"); printf("visibilityRange %2.2f\n",visibility_range); printf("}\n"); /* custom viewpoint */ if(custom_viewpoint==TRUE){ printf("\n"); printf("Viewpoint{\n"); printf("position %2.2f %2.2f %2.2f\n",custom_viewpoint_x,custom_viewpoint_y,custom_viewpoint_z); printf("fieldOfView 0.78\n"); printf("description \"Entry Viewpoint\"\n"); printf("}\n"); } /* host close-up viewpoint */ if(show_all_hosts==FALSE){ temp_hostextinfo=find_hostextinfo(host_name); if(temp_hostextinfo!=NULL && temp_hostextinfo->have_3d_coords==TRUE){ printf("\n"); printf("Viewpoint{\n"); printf("position %2.3f %2.3f %2.3f\n",temp_hostextinfo->x_3d,temp_hostextinfo->y_3d,temp_hostextinfo->z_3d+5.0); printf("fieldOfView 0.78\n"); printf("description \"Host Close-Up Viewpoint\"\n"); printf("}\n"); } } /* calculate z coord for default viewpoint - don't get too close */ viewpoint_z=max_world_size; if(viewpoint_z<10.0) viewpoint_z=10.0; /* default viewpoint */ printf("\n"); printf("Viewpoint{\n"); printf("position %2.2f %2.2f %2.2f\n",min_x_coord+((max_x_coord-min_x_coord)/2.0),min_y_coord+((max_y_coord-min_y_coord)/2.0),viewpoint_z); printf("fieldOfView 0.78\n"); printf("description \"Default Viewpoint\"\n"); printf("}\n"); /* problem timer */ printf("DEF ProblemTimer TimeSensor{\n"); printf("loop TRUE\n"); printf("cycleInterval 5\n"); printf("}\n"); /* host text prototype */ printf("PROTO HostText[\n"); printf("field MFString the_text [\"\"]\n"); printf("field SFColor font_color 0.6 0.6 0.6"); printf("]\n"); printf("{\n"); printf("Billboard{\n"); printf("children[\n"); printf("Shape{\n"); printf("appearance Appearance {\n"); printf("material Material {\n"); printf("diffuseColor IS font_color\n"); printf("}\n"); printf("}\n"); printf("geometry Text {\n"); printf("string IS the_text\n"); printf("fontStyle FontStyle {\n"); printf("family \"TYPEWRITER\"\n"); printf("size 0.1\n"); printf("justify \"MIDDLE\"\n"); printf("}\n"); printf("}\n"); printf("}\n"); printf("]\n"); printf("}\n"); printf("}\n"); /* include user-defined world */ if(statuswrl_include!=NULL && coordinates_were_specified==TRUE && layout_method==LAYOUT_USER_SUPPLIED){ printf("\n"); printf("Inline{\n"); printf("url \"%s%s\"\n",url_html_path,statuswrl_include); printf("}\n"); } return; } /* draws a host */ void draw_host(hostextinfo *temp_hostextinfo){ host *temp_host; hoststatus *temp_hoststatus=NULL; char state_string[16]=""; double x, y, z; char *vrml_safe_hostname=NULL; int a, ch; if(temp_hostextinfo==NULL) return; /* make sure we have the coordinates */ if(temp_hostextinfo->have_3d_coords==FALSE) return; else{ x=temp_hostextinfo->x_3d; y=temp_hostextinfo->y_3d; z=temp_hostextinfo->z_3d; } /* find the config entry for this host */ temp_host=find_host(temp_hostextinfo->host_name); if(temp_host==NULL) return; /* make the host name safe for embedding in VRML */ vrml_safe_hostname=(char *)strdup(temp_host->name); if(vrml_safe_hostname==NULL) return; for(a=0;vrml_safe_hostname[a]!='\x0';a++){ ch=vrml_safe_hostname[a]; if((ch<'a' || ch>'z') && (ch<'A' || ch>'Z') && (ch<'0' || ch>'9')) vrml_safe_hostname[a]='_'; } /* see if user is authorized to view this host */ if(is_authorized_for_host(temp_host,¤t_authdata)==FALSE) return; /* get the status of the host */ temp_hoststatus=find_hoststatus(temp_host->name); printf("\n"); /* host object */ printf("Anchor{\n"); printf("children[\n"); printf("Transform {\n"); printf("translation %2.2f %2.2f %2.2f\n",x,y,z); printf("children [\n"); printf("DEF Host%s Shape{\n",vrml_safe_hostname); printf("appearance Appearance{\n"); printf("material DEF HostMat%s Material{\n",vrml_safe_hostname); if(temp_hoststatus==NULL) printf("emissiveColor 0.2 0.2 0.2\ndiffuseColor 0.2 0.2 0.2\n"); else if(temp_hoststatus->status==HOST_UP) printf("emissiveColor 0.2 1.0 0.2\ndiffuseColor 0.2 1.0 0.2\n"); else printf("emissiveColor 1.0 0.2 0.2\ndiffuseColor 1.0 0.2 0.2\n"); printf("transparency 0.4\n"); printf("}\n"); if(use_textures==TRUE && temp_hostextinfo->vrml_image!=NULL){ printf("texture ImageTexture{\n"); printf("url \"%s%s\"\n",url_logo_images_path,temp_hostextinfo->vrml_image); printf("}\n"); } printf("}\n"); printf("geometry Box{\n"); printf("size %2.2f %2.2f %2.2f\n",node_width,node_width,node_width); printf("}\n"); printf("}\n"); printf("]\n"); printf("}\n"); printf("]\n"); printf("description \"View status details for host '%s' (%s)\"\n",temp_host->name,temp_host->alias); printf("url \"%s?host=%s\"\n",STATUS_CGI,temp_host->name); printf("}\n"); /* draw status text */ if(use_text==TRUE){ printf("\n"); printf("Transform{\n"); printf("translation %2.3f %2.3f %2.3f\n",x,y+DEFAULT_NODE_WIDTH,z); printf("children[\n"); printf("HostText{\n"); if(temp_hoststatus!=NULL){ if(temp_hoststatus->status==HOST_UP) printf("font_color 0 1 0\n"); else if(temp_hoststatus->status==HOST_DOWN || temp_hoststatus->status==HOST_UNREACHABLE) printf("font_color 1 0 0\n"); } printf("the_text [\"%s\", \"%s\", ",temp_host->name,temp_host->alias); if(temp_hoststatus==NULL) strcpy(state_string,"UNKNOWN"); else{ if(temp_hoststatus->status==HOST_DOWN) strcpy(state_string,"DOWN"); else if(temp_hoststatus->status==HOST_UNREACHABLE) strcpy(state_string,"UNREACHABLE"); else if(temp_hoststatus->status==HOST_PENDING) strcpy(state_string,"PENDING"); else strcpy(state_string,"UP"); } printf("\"%s\"]\n",state_string); printf("}\n"); printf("]\n"); printf("}\n"); } /* host is down or unreachable, so make it fade in and out */ if(temp_hoststatus!=NULL && (temp_hoststatus->status==HOST_DOWN || temp_hoststatus->status==HOST_UNREACHABLE)) printf("ROUTE ProblemTimer.fraction_changed TO HostMat%s.set_transparency\n",vrml_safe_hostname); free(vrml_safe_hostname); return; } /* draw links between hosts */ void draw_host_links(void){ hostextinfo *child_hostextinfo; hostextinfo *parent_hostextinfo; host *parent_host; host *child_host; if(use_links==FALSE) return; for(child_hostextinfo=hostextinfo_list;child_hostextinfo!=NULL;child_hostextinfo=child_hostextinfo->next){ if(child_hostextinfo->have_3d_coords==FALSE) continue; child_host=find_host(child_hostextinfo->host_name); if(child_host==NULL) continue; /* check authorization */ if(is_authorized_for_host(child_host,¤t_authdata)==FALSE) continue; /* draw a link from this host to all of its parent hosts */ for(parent_host=host_list;parent_host!=NULL;parent_host=parent_host->next){ if(is_host_immediate_child_of_host(child_host,parent_host)==TRUE){ parent_hostextinfo=find_hostextinfo(parent_host->name); if(parent_hostextinfo==NULL) continue; if(parent_hostextinfo->have_3d_coords==FALSE) continue; /* check authorization */ if(is_authorized_for_host(parent_host,¤t_authdata)==FALSE) continue; /* draw the link between the child and parent hosts */ draw_host_link(parent_host,parent_hostextinfo->x_3d,parent_hostextinfo->y_3d,parent_hostextinfo->z_3d,child_hostextinfo->x_3d,child_hostextinfo->y_3d,child_hostextinfo->z_3d); } } } return; } /* draws a link from a parent host to a child host */ void draw_host_link(host *hst,double x0, double y0, double z0, double x1, double y1, double z1){ printf("\n"); if(hst!=NULL) printf("# Host '%s' LINK\n",hst->name); printf("Shape{\n"); printf("appearance DEF MATslategrey_0_ Appearance {\n"); printf("material Material {\n"); printf("diffuseColor 0.6 0.6 0.6\n"); printf("ambientIntensity 0.5\n"); printf("emissiveColor 0.6 0.6 0.6\n"); printf("}\n"); printf("}\n"); printf("geometry IndexedLineSet{\n"); printf("coord Coordinate{\n"); printf("point [ %2.3f %2.3f %2.3f, %2.3f %2.3f %2.3f ]\n",x0,y0,z0,x1,y1,z1); printf("}\n"); printf("coordIndex [ 0,1,-1 ]\n"); printf("}\n"); printf("}\n"); return; } /* draw process icon */ void draw_process_icon(void){ hostextinfo *child_hostextinfo; host *child_host; if(draw_nagios_icon==FALSE) return; /* draw process icon */ printf("\n"); printf("Anchor{\n"); printf("children[\n"); printf("Transform {\n"); printf("translation %2.2f %2.2f %2.2f\n",nagios_icon_x,nagios_icon_y,0.0); printf("children [\n"); printf("DEF ProcessNode Shape{\n"); printf("appearance Appearance{\n"); printf("material Material{\n"); printf("emissiveColor 0.5 0.5 0.5\n"); printf("diffuseColor 0.5 0.5 0.5\n"); printf("transparency 0.2\n"); printf("}\n"); if(use_textures==TRUE){ printf("texture ImageTexture{\n"); printf("url \"%s%s\"\n",url_logo_images_path,NAGIOS_VRML_IMAGE); printf("}\n"); } printf("}\n"); printf("geometry Box{\n"); printf("size %2.2f %2.2f %2.2f\n",node_width*3.0,node_width*3.0,node_width*3.0); printf("}\n"); printf("}\n"); printf("]\n"); printf("}\n"); printf("]\n"); printf("description \"View Nagios Process Information\"\n"); printf("url \"%s?type=%d\"\n",EXTINFO_CGI,DISPLAY_PROCESS_INFO); printf("}\n"); if(use_links==FALSE) return; /* draw links to immediate child hosts */ for(child_hostextinfo=hostextinfo_list;child_hostextinfo!=NULL;child_hostextinfo=child_hostextinfo->next){ if(child_hostextinfo->have_3d_coords==FALSE) continue; child_host=find_host(child_hostextinfo->host_name); if(child_host==NULL) continue; /* check authorization */ if(is_authorized_for_host(child_host,¤t_authdata)==FALSE) continue; /* draw a link to the host */ if(is_host_immediate_child_of_host(NULL,child_host)==TRUE) draw_host_link(NULL,nagios_icon_x,nagios_icon_y,0.0,child_hostextinfo->x_3d,child_hostextinfo->y_3d,child_hostextinfo->z_3d); } return; } /******************************************************************/ /***************** COORDINATE CALCULATION FUNCTIONS ***************/ /******************************************************************/ /* calculates coords of a host's children - used by balanced tree layout method */ void calculate_balanced_tree_coords(host *parent, int x, int y){ int parent_drawing_width; int start_drawing_x; int current_drawing_x; int this_drawing_width; host *temp_host; hostextinfo *temp_hostextinfo; /* calculate total drawing width of parent host */ parent_drawing_width=max_child_host_drawing_width(parent); /* calculate starting x coord */ start_drawing_x=x-(((DEFAULT_NODE_WIDTH*parent_drawing_width)+(DEFAULT_NODE_HSPACING*(parent_drawing_width-1)))/2); current_drawing_x=start_drawing_x; /* calculate coords for children */ for(temp_host=host_list;temp_host!=NULL;temp_host=temp_host->next){ temp_hostextinfo=find_hostextinfo(temp_host->name); if(temp_hostextinfo==NULL) continue; if(is_host_immediate_child_of_host(parent,temp_host)==TRUE){ /* get drawing width of child host */ this_drawing_width=max_child_host_drawing_width(temp_host); temp_hostextinfo->x_3d=current_drawing_x+(((DEFAULT_NODE_WIDTH*this_drawing_width)+(DEFAULT_NODE_HSPACING*(this_drawing_width-1)))/2); temp_hostextinfo->y_3d=y+DEFAULT_NODE_HEIGHT+DEFAULT_NODE_VSPACING; temp_hostextinfo->have_3d_coords=TRUE; temp_hostextinfo->should_be_drawn=TRUE; current_drawing_x+=(this_drawing_width*DEFAULT_NODE_WIDTH)+((this_drawing_width-1)*DEFAULT_NODE_HSPACING)+DEFAULT_NODE_HSPACING; /* recurse into child host ... */ calculate_balanced_tree_coords(temp_host,temp_hostextinfo->x_3d,temp_hostextinfo->y_3d); } } return; } /* calculate coords of all hosts in circular layout method */ void calculate_circular_coords(void){ /* calculate all host coords, starting with first layer */ calculate_circular_layer_coords(NULL,0.0,360.0,1,CIRCULAR_DRAWING_RADIUS); return; } /* calculates coords of all hosts in a particular "layer" in circular layout method */ void calculate_circular_layer_coords(host *parent, double start_angle, double useable_angle, int layer, int radius){ int parent_drawing_width=0; int this_drawing_width=0; int immediate_children=0; double current_drawing_angle=0.0; double this_drawing_angle=0.0; double available_angle=0.0; double clipped_available_angle=0.0; double average_child_angle=0.0; double x_coord=0.0; double y_coord=0.0; host *temp_host; hostextinfo *temp_hostextinfo; /* get the total number of immediate children to this host */ immediate_children=number_of_immediate_child_hosts(parent); /* bail out if we're done */ if(immediate_children==0) return; /* calculate total drawing "width" of parent host */ parent_drawing_width=max_child_host_drawing_width(parent); /* calculate average angle given to each child host */ average_child_angle=(double)(useable_angle/(double)immediate_children); /* calculate initial drawing angle */ current_drawing_angle=start_angle; /* calculate coords for children */ for(temp_host=host_list;temp_host!=NULL;temp_host=temp_host->next){ temp_hostextinfo=find_hostextinfo(temp_host->name); if(temp_hostextinfo==NULL) continue; if(is_host_immediate_child_of_host(parent,temp_host)==TRUE){ /* get drawing width of child host */ this_drawing_width=max_child_host_drawing_width(temp_host); /* calculate angle this host gets for drawing */ available_angle=useable_angle*((double)this_drawing_width/(double)parent_drawing_width); /* clip available angle if necessary */ /* this isn't really necessary, but helps keep things looking a bit more sane with less potential connection crossover */ clipped_available_angle=360.0/layer; if(available_angle=360.0) this_drawing_angle-=360.0; while(this_drawing_angle<0.0) this_drawing_angle+=360.0; /* calculate drawing coords of this host using good ol' geometry... */ x_coord=-(sin(-this_drawing_angle*(M_PI/180.0))*radius); y_coord=-(sin((90+this_drawing_angle)*(M_PI/180.0))*radius); temp_hostextinfo->x_3d=(int)x_coord; temp_hostextinfo->y_3d=(int)y_coord; temp_hostextinfo->have_3d_coords=TRUE; temp_hostextinfo->should_be_drawn=TRUE; /* recurse into child host ... */ calculate_circular_layer_coords(temp_host,current_drawing_angle+((available_angle-clipped_available_angle)/2),clipped_available_angle,layer+1,radius+CIRCULAR_DRAWING_RADIUS); /* increment current drawing angle */ current_drawing_angle+=available_angle; } } return; } nagios-2.6/cgi/summary.c0000664000076500007650000026257110410070302014602 0ustar nagiosnagios/************************************************************************** * * SUMMARY.C - Nagios Alert Summary CGI * * Copyright (c) 2002-2006 Ethan Galstad (nagios@nagios.org) * Last Modified: 03-21-2006 * * 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. *************************************************************************/ #include "../include/config.h" #include "../include/common.h" #include "../include/objects.h" #include "../include/comments.h" #include "../include/statusdata.h" #include "../include/cgiutils.h" #include "../include/getcgi.h" #include "../include/cgiauth.h" extern char main_config_file[MAX_FILENAME_LENGTH]; extern char url_images_path[MAX_FILENAME_LENGTH]; extern char url_stylesheets_path[MAX_FILENAME_LENGTH]; extern host *host_list; extern hostgroup *hostgroup_list; extern service *service_list; extern servicegroup *servicegroup_list; extern int log_rotation_method; /* output types */ #define HTML_OUTPUT 0 #define CSV_OUTPUT 1 /* custom report types */ #define REPORT_NONE 0 #define REPORT_RECENT_ALERTS 1 #define REPORT_ALERT_TOTALS 2 #define REPORT_TOP_ALERTS 3 #define REPORT_HOSTGROUP_ALERT_TOTALS 4 #define REPORT_HOST_ALERT_TOTALS 5 #define REPORT_SERVICE_ALERT_TOTALS 6 #define REPORT_SERVICEGROUP_ALERT_TOTALS 7 /* standard report types */ #define SREPORT_NONE 0 #define SREPORT_RECENT_ALERTS 1 #define SREPORT_RECENT_HOST_ALERTS 2 #define SREPORT_RECENT_SERVICE_ALERTS 3 #define SREPORT_TOP_HOST_ALERTS 4 #define SREPORT_TOP_SERVICE_ALERTS 5 /* standard report times */ #define TIMEPERIOD_CUSTOM 0 #define TIMEPERIOD_TODAY 1 #define TIMEPERIOD_YESTERDAY 2 #define TIMEPERIOD_THISWEEK 3 #define TIMEPERIOD_LASTWEEK 4 #define TIMEPERIOD_THISMONTH 5 #define TIMEPERIOD_LASTMONTH 6 #define TIMEPERIOD_THISQUARTER 7 #define TIMEPERIOD_LASTQUARTER 8 #define TIMEPERIOD_THISYEAR 9 #define TIMEPERIOD_LASTYEAR 10 #define TIMEPERIOD_LAST24HOURS 11 #define TIMEPERIOD_LAST7DAYS 12 #define TIMEPERIOD_LAST31DAYS 13 #define AE_SOFT_STATE 1 #define AE_HARD_STATE 2 #define AE_HOST_ALERT 1 #define AE_SERVICE_ALERT 2 #define AE_HOST_PRODUCER 1 #define AE_SERVICE_PRODUCER 2 #define AE_HOST_DOWN 1 #define AE_HOST_UNREACHABLE 2 #define AE_HOST_UP 4 #define AE_SERVICE_WARNING 8 #define AE_SERVICE_UNKNOWN 16 #define AE_SERVICE_CRITICAL 32 #define AE_SERVICE_OK 64 typedef struct archived_event_struct{ time_t time_stamp; int event_type; int entry_type; char *host_name; char *service_description; int state; int state_type; char *event_info; struct archived_event_struct *next; }archived_event; typedef struct alert_producer_struct{ int producer_type; char *host_name; char *service_description; int total_alerts; struct alert_producer_struct *next; }alert_producer; void read_archived_event_data(void); void scan_log_file_for_archived_event_data(char *); void convert_timeperiod_to_times(int); void compute_report_times(void); void determine_standard_report_options(void); void add_archived_event(int,time_t,int,int,char *,char *,char *); alert_producer *find_producer(int,char *,char *); alert_producer *add_producer(int,char *,char *); void free_event_list(void); void free_producer_list(void); void display_report(void); void display_recent_alerts(void); void display_alert_totals(void); void display_hostgroup_alert_totals(void); void display_specific_hostgroup_alert_totals(hostgroup *); void display_servicegroup_alert_totals(void); void display_specific_servicegroup_alert_totals(servicegroup *); void display_host_alert_totals(void); void display_specific_host_alert_totals(host *); void display_service_alert_totals(void); void display_specific_service_alert_totals(service *); void display_top_alerts(void); void document_header(int); void document_footer(void); int process_cgivars(void); archived_event *event_list=NULL; alert_producer *producer_list=NULL; authdata current_authdata; time_t t1; time_t t2; int start_second=0; int start_minute=0; int start_hour=0; int start_day=1; int start_month=1; int start_year=2000; int end_second=0; int end_minute=0; int end_hour=24; int end_day=1; int end_month=1; int end_year=2000; int compute_time_from_parts=FALSE; int timeperiod_type=TIMEPERIOD_CUSTOM; int state_types=AE_HARD_STATE+AE_SOFT_STATE; int alert_types=AE_HOST_ALERT+AE_SERVICE_ALERT; int host_states=AE_HOST_UP+AE_HOST_DOWN+AE_HOST_UNREACHABLE; int service_states=AE_SERVICE_OK+AE_SERVICE_WARNING+AE_SERVICE_UNKNOWN+AE_SERVICE_CRITICAL; int show_all_hostgroups=TRUE; int show_all_servicegroups=TRUE; int show_all_hosts=TRUE; char *target_hostgroup_name=""; char *target_servicegroup_name=""; char *target_host_name=""; hostgroup *target_hostgroup=NULL; servicegroup *target_servicegroup=NULL; host *target_host=NULL; int earliest_archive=0; int item_limit=25; int total_items=0; int embedded=FALSE; int display_header=TRUE; int output_format=HTML_OUTPUT; int display_type=REPORT_RECENT_ALERTS; int standard_report=SREPORT_NONE; int generate_report=FALSE; int main(int argc, char **argv){ int result=OK; char temp_buffer[MAX_INPUT_BUFFER]; char start_timestring[MAX_DATETIME_LENGTH]; char end_timestring[MAX_DATETIME_LENGTH]; host *temp_host; int days, hours, minutes, seconds; hostgroup *temp_hostgroup; servicegroup *temp_servicegroup; time_t t3; time_t current_time; struct tm *t; int x; /* reset internal CGI variables */ reset_cgi_vars(); /* read the CGI configuration file */ result=read_cgi_config_file(get_cgi_config_location()); if(result==ERROR){ document_header(FALSE); cgi_config_file_error(get_cgi_config_location()); document_footer(); return ERROR; } /* read the main configuration file */ result=read_main_config_file(main_config_file); if(result==ERROR){ document_header(FALSE); main_config_file_error(main_config_file); document_footer(); return ERROR; } /* read all object configuration data */ result=read_all_object_configuration_data(main_config_file,READ_ALL_OBJECT_DATA); if(result==ERROR){ document_header(FALSE); object_data_error(); document_footer(); return ERROR; } /* initialize report time period to last 24 hours */ time(&t2); t1=(time_t)(t2-(60*60*24)); /* get the arguments passed in the URL */ process_cgivars(); document_header(TRUE); /* get authentication information */ get_authentication_information(¤t_authdata); if(standard_report!=SREPORT_NONE) determine_standard_report_options(); if(compute_time_from_parts==TRUE) compute_report_times(); /* make sure times are sane, otherwise swap them */ if(t2\n"); printf("\n"); /* left column of the first row */ printf("\n"); snprintf(temp_buffer,sizeof(temp_buffer)-1,"Alert Summary Report"); temp_buffer[sizeof(temp_buffer)-1]='\x0'; display_info_table(temp_buffer,FALSE,¤t_authdata); printf("\n"); /* center column of top row */ printf("\n"); if(generate_report==TRUE){ printf("
    \n"); if(display_type==REPORT_TOP_ALERTS) printf("Top Alert Producers"); else if(display_type==REPORT_ALERT_TOTALS || display_type==REPORT_HOSTGROUP_ALERT_TOTALS || display_type==REPORT_SERVICEGROUP_ALERT_TOTALS || display_type==REPORT_HOST_ALERT_TOTALS || display_type==REPORT_SERVICE_ALERT_TOTALS) printf("Alert Totals"); else printf("Most Recent Alerts"); if(show_all_hostgroups==FALSE) printf(" For Hostgroup '%s'",target_hostgroup_name); else if(show_all_servicegroups==FALSE) printf(" For Servicegroup '%s'",target_servicegroup_name); else if(show_all_hosts==FALSE) printf(" For Host '%s'",target_host_name); printf("
    \n"); printf("
    \n"); get_time_string(&t1,start_timestring,sizeof(start_timestring)-1,SHORT_DATE_TIME); get_time_string(&t2,end_timestring,sizeof(end_timestring)-1,SHORT_DATE_TIME); printf("
    %s to %s
    \n",start_timestring,end_timestring); get_time_breakdown((time_t)(t2-t1),&days,&hours,&minutes,&seconds); printf("
    Duration: %dd %dh %dm %ds
    \n",days,hours,minutes,seconds); } printf("\n"); /* right hand column of top row */ printf("\n"); if(generate_report==TRUE){ printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); /* display context-sensitive help */ printf("\n"); printf("
    Report Options Summary:
    Alert Types:\n"); if(alert_types & AE_HOST_ALERT) printf("Host"); if(alert_types & AE_SERVICE_ALERT) printf("%sService",(alert_types & AE_HOST_ALERT)?" & ":""); printf(" Alerts
    State Types:"); if(state_types & AE_SOFT_STATE) printf("Soft"); if(state_types & AE_HARD_STATE) printf("%sHard",(state_types & AE_SOFT_STATE)?" & ":""); printf(" States
    Host States:"); x=0; if(host_states & AE_HOST_UP){ printf("Up"); x=1; } if(host_states & AE_HOST_DOWN){ printf("%sDown",(x==1)?", ":""); x=1; } if(host_states & AE_HOST_UNREACHABLE) printf("%sUnreachable",(x==1)?", ":""); if(x==0) printf("None"); printf("
    Service States:"); x=0; if(service_states & AE_SERVICE_OK){ printf("Ok"); x=1; } if(service_states & AE_SERVICE_WARNING){ printf("%sWarning",(x==1)?", ":""); x=1; } if(service_states & AE_SERVICE_UNKNOWN){ printf("%sUnknown",(x==1)?", ":""); x=1; } if(service_states & AE_SERVICE_CRITICAL) printf("%sCritical",(x==1)?", ":""); if(x==0) printf("None"); printf("
    \n"); printf("
    \n",SUMMARY_CGI); printf("\n"); printf("
    \n"); printf("
    \n"); if(display_type==REPORT_TOP_ALERTS) display_context_help(CONTEXTHELP_SUMMARY_ALERT_PRODUCERS); else if(display_type==REPORT_ALERT_TOTALS) display_context_help(CONTEXTHELP_SUMMARY_ALERT_TOTALS); else if(display_type==REPORT_HOSTGROUP_ALERT_TOTALS) display_context_help(CONTEXTHELP_SUMMARY_HOSTGROUP_ALERT_TOTALS); else if(display_type==REPORT_HOST_ALERT_TOTALS) display_context_help(CONTEXTHELP_SUMMARY_HOST_ALERT_TOTALS); else if(display_type==REPORT_SERVICE_ALERT_TOTALS) display_context_help(CONTEXTHELP_SUMMARY_SERVICE_ALERT_TOTALS); else if(display_type==REPORT_SERVICEGROUP_ALERT_TOTALS) display_context_help(CONTEXTHELP_SUMMARY_SERVICEGROUP_ALERT_TOTALS); else display_context_help(CONTEXTHELP_SUMMARY_RECENT_ALERTS); printf("
    \n"); } else{ printf("\n"); printf("\n"); printf("
    \n"); display_context_help(CONTEXTHELP_SUMMARY_MENU); printf("
    \n"); } printf("\n"); /* end of top table */ printf("\n"); printf("\n"); } /*********************************/ /****** GENERATE THE REPORT ******/ /*********************************/ if(generate_report==TRUE){ read_archived_event_data(); display_report(); } /* ask user for report options */ else{ time(¤t_time); t=localtime(¤t_time); start_day=1; start_year=t->tm_year+1900; end_day=t->tm_mday; end_year=t->tm_year+1900; printf("
    Standard Reports:
    \n"); printf("
    \n"); printf("
    \n",SUMMARY_CGI); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("
    Report Type:\n"); printf("\n"); printf("
    \n"); printf("
    \n"); printf("
    \n"); printf("
    Custom Report Options:
    \n"); printf("
    \n"); printf("
    \n",SUMMARY_CGI); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf(""); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf(""); printf("\n"); printf("\n"); printf("\n"); printf(""); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("
    Report Type:\n"); printf("\n"); printf("
    Report Period:\n"); printf("\n"); printf("
    If Custom Report Period...
    Start Date (Inclusive):"); printf("\n "); printf(" ",start_day); printf("",start_year); printf("\n"); printf("\n"); printf("\n"); printf("
    End Date (Inclusive):"); printf("\n "); printf(" ",end_day); printf("",end_year); printf("\n"); printf("\n"); printf("\n"); printf("

    Limit To Hostgroup:\n"); printf("\n"); printf("
    Limit To Servicegroup:\n"); printf("\n"); printf("
    Limit To Host:\n"); printf("\n"); printf("
    Alert Types:\n"); printf("\n"); printf("
    State Types:\n"); printf("\n"); printf("
    Host States:\n"); printf("\n"); printf("
    Service States:\n"); printf("\n"); printf("
    Max List Items:\n"); printf("\n",item_limit); printf("
    \n"); printf("
    \n"); printf("
    \n"); } document_footer(); /* free all other allocated memory */ free_memory(); free_event_list(); free_producer_list(); return OK; } void document_header(int use_stylesheet){ char date_time[MAX_DATETIME_LENGTH]; time_t current_time; time_t expire_time; printf("Cache-Control: no-store\r\n"); printf("Pragma: no-cache\r\n"); time(¤t_time); get_time_string(¤t_time,date_time,sizeof(date_time),HTTP_DATE_TIME); printf("Last-Modified: %s\r\n",date_time); expire_time=(time_t)0; get_time_string(&expire_time,date_time,sizeof(date_time),HTTP_DATE_TIME); printf("Expires: %s\r\n",date_time); if(output_format==HTML_OUTPUT) printf("Content-type: text/html\r\n\r\n"); else{ printf("Content-type: text/plain\r\n\r\n"); return; } if(embedded==TRUE || output_format==CSV_OUTPUT) return; printf("\n"); printf("\n"); printf("\n"); printf("Nagios Event Summary\n"); printf("\n"); if(use_stylesheet==TRUE){ printf("\n",url_stylesheets_path,COMMON_CSS); printf("\n",url_stylesheets_path,SUMMARY_CSS); } printf("\n"); printf("\n"); /* include user SSI header */ include_ssi_files(SUMMARY_CGI,SSI_HEADER); return; } void document_footer(void){ if(output_format!=HTML_OUTPUT) return; if(embedded==TRUE) return; /* include user SSI footer */ include_ssi_files(SUMMARY_CGI,SSI_FOOTER); printf("\n"); printf("\n"); return; } int process_cgivars(void){ char **variables; int error=FALSE; int x; variables=getcgivars(); for(x=0;variables[x]!=NULL;x++){ /* do some basic length checking on the variable identifier to prevent buffer overflows */ if(strlen(variables[x])>=MAX_INPUT_BUFFER-1){ x++; continue; } /* we found first time argument */ else if(!strcmp(variables[x],"t1")){ x++; if(variables[x]==NULL){ error=TRUE; break; } t1=(time_t)strtoul(variables[x],NULL,10); timeperiod_type=TIMEPERIOD_CUSTOM; compute_time_from_parts=FALSE; } /* we found first time argument */ else if(!strcmp(variables[x],"t2")){ x++; if(variables[x]==NULL){ error=TRUE; break; } t2=(time_t)strtoul(variables[x],NULL,10); timeperiod_type=TIMEPERIOD_CUSTOM; compute_time_from_parts=FALSE; } /* we found the standard timeperiod argument */ else if(!strcmp(variables[x],"timeperiod")){ x++; if(variables[x]==NULL){ error=TRUE; break; } if(!strcmp(variables[x],"today")) timeperiod_type=TIMEPERIOD_TODAY; else if(!strcmp(variables[x],"yesterday")) timeperiod_type=TIMEPERIOD_YESTERDAY; else if(!strcmp(variables[x],"thisweek")) timeperiod_type=TIMEPERIOD_THISWEEK; else if(!strcmp(variables[x],"lastweek")) timeperiod_type=TIMEPERIOD_LASTWEEK; else if(!strcmp(variables[x],"thismonth")) timeperiod_type=TIMEPERIOD_THISMONTH; else if(!strcmp(variables[x],"lastmonth")) timeperiod_type=TIMEPERIOD_LASTMONTH; else if(!strcmp(variables[x],"thisquarter")) timeperiod_type=TIMEPERIOD_THISQUARTER; else if(!strcmp(variables[x],"lastquarter")) timeperiod_type=TIMEPERIOD_LASTQUARTER; else if(!strcmp(variables[x],"thisyear")) timeperiod_type=TIMEPERIOD_THISYEAR; else if(!strcmp(variables[x],"lastyear")) timeperiod_type=TIMEPERIOD_LASTYEAR; else if(!strcmp(variables[x],"last24hours")) timeperiod_type=TIMEPERIOD_LAST24HOURS; else if(!strcmp(variables[x],"last7days")) timeperiod_type=TIMEPERIOD_LAST7DAYS; else if(!strcmp(variables[x],"last31days")) timeperiod_type=TIMEPERIOD_LAST31DAYS; else if(!strcmp(variables[x],"custom")) timeperiod_type=TIMEPERIOD_CUSTOM; else continue; convert_timeperiod_to_times(timeperiod_type); compute_time_from_parts=FALSE; } /* we found the embed option */ else if(!strcmp(variables[x],"embedded")) embedded=TRUE; /* we found the noheader option */ else if(!strcmp(variables[x],"noheader")) display_header=FALSE; /* we found time argument */ else if(!strcmp(variables[x],"smon")){ x++; if(variables[x]==NULL){ error=TRUE; break; } if(timeperiod_type!=TIMEPERIOD_CUSTOM) continue; start_month=atoi(variables[x]); timeperiod_type=TIMEPERIOD_CUSTOM; compute_time_from_parts=TRUE; } /* we found time argument */ else if(!strcmp(variables[x],"sday")){ x++; if(variables[x]==NULL){ error=TRUE; break; } if(timeperiod_type!=TIMEPERIOD_CUSTOM) continue; start_day=atoi(variables[x]); timeperiod_type=TIMEPERIOD_CUSTOM; compute_time_from_parts=TRUE; } /* we found time argument */ else if(!strcmp(variables[x],"syear")){ x++; if(variables[x]==NULL){ error=TRUE; break; } if(timeperiod_type!=TIMEPERIOD_CUSTOM) continue; start_year=atoi(variables[x]); timeperiod_type=TIMEPERIOD_CUSTOM; compute_time_from_parts=TRUE; } /* we found time argument */ else if(!strcmp(variables[x],"smin")){ x++; if(variables[x]==NULL){ error=TRUE; break; } if(timeperiod_type!=TIMEPERIOD_CUSTOM) continue; start_minute=atoi(variables[x]); timeperiod_type=TIMEPERIOD_CUSTOM; compute_time_from_parts=TRUE; } /* we found time argument */ else if(!strcmp(variables[x],"ssec")){ x++; if(variables[x]==NULL){ error=TRUE; break; } if(timeperiod_type!=TIMEPERIOD_CUSTOM) continue; start_second=atoi(variables[x]); timeperiod_type=TIMEPERIOD_CUSTOM; compute_time_from_parts=TRUE; } /* we found time argument */ else if(!strcmp(variables[x],"shour")){ x++; if(variables[x]==NULL){ error=TRUE; break; } if(timeperiod_type!=TIMEPERIOD_CUSTOM) continue; start_hour=atoi(variables[x]); timeperiod_type=TIMEPERIOD_CUSTOM; compute_time_from_parts=TRUE; } /* we found time argument */ else if(!strcmp(variables[x],"emon")){ x++; if(variables[x]==NULL){ error=TRUE; break; } if(timeperiod_type!=TIMEPERIOD_CUSTOM) continue; end_month=atoi(variables[x]); timeperiod_type=TIMEPERIOD_CUSTOM; compute_time_from_parts=TRUE; } /* we found time argument */ else if(!strcmp(variables[x],"eday")){ x++; if(variables[x]==NULL){ error=TRUE; break; } if(timeperiod_type!=TIMEPERIOD_CUSTOM) continue; end_day=atoi(variables[x]); timeperiod_type=TIMEPERIOD_CUSTOM; compute_time_from_parts=TRUE; } /* we found time argument */ else if(!strcmp(variables[x],"eyear")){ x++; if(variables[x]==NULL){ error=TRUE; break; } if(timeperiod_type!=TIMEPERIOD_CUSTOM) continue; end_year=atoi(variables[x]); timeperiod_type=TIMEPERIOD_CUSTOM; compute_time_from_parts=TRUE; } /* we found time argument */ else if(!strcmp(variables[x],"emin")){ x++; if(variables[x]==NULL){ error=TRUE; break; } if(timeperiod_type!=TIMEPERIOD_CUSTOM) continue; end_minute=atoi(variables[x]); timeperiod_type=TIMEPERIOD_CUSTOM; compute_time_from_parts=TRUE; } /* we found time argument */ else if(!strcmp(variables[x],"esec")){ x++; if(variables[x]==NULL){ error=TRUE; break; } if(timeperiod_type!=TIMEPERIOD_CUSTOM) continue; end_second=atoi(variables[x]); timeperiod_type=TIMEPERIOD_CUSTOM; compute_time_from_parts=TRUE; } /* we found time argument */ else if(!strcmp(variables[x],"ehour")){ x++; if(variables[x]==NULL){ error=TRUE; break; } if(timeperiod_type!=TIMEPERIOD_CUSTOM) continue; end_hour=atoi(variables[x]); timeperiod_type=TIMEPERIOD_CUSTOM; compute_time_from_parts=TRUE; } /* we found the item limit argument */ else if(!strcmp(variables[x],"limit")){ x++; if(variables[x]==NULL){ error=TRUE; break; } item_limit=atoi(variables[x]); } /* we found the state types argument */ else if(!strcmp(variables[x],"statetypes")){ x++; if(variables[x]==NULL){ error=TRUE; break; } state_types=atoi(variables[x]); } /* we found the alert types argument */ else if(!strcmp(variables[x],"alerttypes")){ x++; if(variables[x]==NULL){ error=TRUE; break; } alert_types=atoi(variables[x]); } /* we found the host states argument */ else if(!strcmp(variables[x],"hoststates")){ x++; if(variables[x]==NULL){ error=TRUE; break; } host_states=atoi(variables[x]); } /* we found the service states argument */ else if(!strcmp(variables[x],"servicestates")){ x++; if(variables[x]==NULL){ error=TRUE; break; } service_states=atoi(variables[x]); } /* we found the generate report argument */ else if(!strcmp(variables[x],"report")){ x++; if(variables[x]==NULL){ error=TRUE; break; } generate_report=(atoi(variables[x])>0)?TRUE:FALSE; } /* we found the display type argument */ else if(!strcmp(variables[x],"displaytype")){ x++; if(variables[x]==NULL){ error=TRUE; break; } display_type=atoi(variables[x]); } /* we found the standard report argument */ else if(!strcmp(variables[x],"standardreport")){ x++; if(variables[x]==NULL){ error=TRUE; break; } standard_report=atoi(variables[x]); } /* we found the hostgroup argument */ else if(!strcmp(variables[x],"hostgroup")){ x++; if(variables[x]==NULL){ error=TRUE; break; } target_hostgroup_name=(char *)malloc(strlen(variables[x])+1); if(target_hostgroup_name==NULL) target_hostgroup_name=""; else strcpy(target_hostgroup_name,variables[x]); if(!strcmp(target_hostgroup_name,"all")) show_all_hostgroups=TRUE; else{ show_all_hostgroups=FALSE; target_hostgroup=find_hostgroup(target_hostgroup_name); } } /* we found the servicegroup argument */ else if(!strcmp(variables[x],"servicegroup")){ x++; if(variables[x]==NULL){ error=TRUE; break; } target_servicegroup_name=(char *)malloc(strlen(variables[x])+1); if(target_servicegroup_name==NULL) target_servicegroup_name=""; else strcpy(target_servicegroup_name,variables[x]); if(!strcmp(target_servicegroup_name,"all")) show_all_servicegroups=TRUE; else{ show_all_servicegroups=FALSE; target_servicegroup=find_servicegroup(target_servicegroup_name); } } /* we found the host argument */ else if(!strcmp(variables[x],"host")){ x++; if(variables[x]==NULL){ error=TRUE; break; } target_host_name=(char *)malloc(strlen(variables[x])+1); if(target_host_name==NULL) target_host_name=""; else strcpy(target_host_name,variables[x]); if(!strcmp(target_host_name,"all")) show_all_hosts=TRUE; else{ show_all_hosts=FALSE; target_host=find_host(target_host_name); } } } /* free memory allocated to the CGI variables */ free_cgivars(variables); return error; } /* reads log files for archived event data */ void read_archived_event_data(void){ char filename[MAX_FILENAME_LENGTH]; int oldest_archive=0; int newest_archive=0; int current_archive=0; /* determine oldest archive to use when scanning for data */ oldest_archive=determine_archive_to_use_from_time(t1); /* determine most recent archive to use when scanning for data */ newest_archive=determine_archive_to_use_from_time(t2); if(oldest_archivet2) continue; /* host alerts */ if(strstr(input,"HOST ALERT:")){ /* get host name */ temp_buffer=my_strtok(NULL,":"); temp_buffer=my_strtok(NULL,";"); strncpy(entry_host_name,(temp_buffer==NULL)?"":temp_buffer+1,sizeof(entry_host_name)); entry_host_name[sizeof(entry_host_name)-1]='\x0'; /* state type */ if(strstr(input,";SOFT;")) state_type=AE_SOFT_STATE; else state_type=AE_HARD_STATE; /* get the plugin output */ temp_buffer=my_strtok(NULL,";"); temp_buffer=my_strtok(NULL,";"); temp_buffer=my_strtok(NULL,";"); plugin_output=my_strtok(NULL,"\n"); /* state */ if(strstr(input,";DOWN;")) state=AE_HOST_DOWN; else if(strstr(input,";UNREACHABLE;")) state=AE_HOST_UNREACHABLE; else if(strstr(input,";RECOVERY") || strstr(input,";UP;")) state=AE_HOST_UP; else continue; add_archived_event(AE_HOST_ALERT,time_stamp,state,state_type,entry_host_name,NULL,plugin_output); } /* service alerts */ if(strstr(input,"SERVICE ALERT:")){ /* get host name */ temp_buffer=my_strtok(NULL,":"); temp_buffer=my_strtok(NULL,";"); strncpy(entry_host_name,(temp_buffer==NULL)?"":temp_buffer+1,sizeof(entry_host_name)); entry_host_name[sizeof(entry_host_name)-1]='\x0'; /* get service description */ temp_buffer=my_strtok(NULL,";"); strncpy(entry_svc_description,(temp_buffer==NULL)?"":temp_buffer,sizeof(entry_svc_description)); entry_svc_description[sizeof(entry_svc_description)-1]='\x0'; /* state type */ if(strstr(input,";SOFT;")) state_type=AE_SOFT_STATE; else state_type=AE_HARD_STATE; /* get the plugin output */ temp_buffer=my_strtok(NULL,";"); temp_buffer=my_strtok(NULL,";"); temp_buffer=my_strtok(NULL,";"); plugin_output=my_strtok(NULL,"\n"); /* state */ if(strstr(input,";WARNING;")) state=AE_SERVICE_WARNING; else if(strstr(input,";UNKNOWN;")) state=AE_SERVICE_UNKNOWN; else if(strstr(input,";CRITICAL;")) state=AE_SERVICE_CRITICAL; else if(strstr(input,";RECOVERY") || strstr(input,";OK;")) state=AE_SERVICE_OK; else continue; add_archived_event(AE_SERVICE_ALERT,time_stamp,state,state_type,entry_host_name,entry_svc_description,plugin_output); } } /* free memory and close the file */ free(input); free(input2); mmap_fclose(thefile); return; } void convert_timeperiod_to_times(int type){ time_t current_time; struct tm *t; /* get the current time */ time(¤t_time); t=localtime(¤t_time); t->tm_sec=0; t->tm_min=0; t->tm_hour=0; switch(type){ case TIMEPERIOD_LAST24HOURS: t1=current_time-(60*60*24); t2=current_time; break; case TIMEPERIOD_TODAY: t1=mktime(t); t2=current_time; break; case TIMEPERIOD_YESTERDAY: t1=(time_t)(mktime(t)-(60*60*24)); t2=(time_t)mktime(t); break; case TIMEPERIOD_THISWEEK: t1=(time_t)(mktime(t)-(60*60*24*t->tm_wday)); t2=current_time; break; case TIMEPERIOD_LASTWEEK: t1=(time_t)(mktime(t)-(60*60*24*t->tm_wday)-(60*60*24*7)); t2=(time_t)(mktime(t)-(60*60*24*t->tm_wday)); break; case TIMEPERIOD_THISMONTH: t->tm_mday=1; t1=mktime(t); t2=current_time; break; case TIMEPERIOD_LASTMONTH: t->tm_mday=1; t2=mktime(t); if(t->tm_mon==0){ t->tm_mon=11; t->tm_year--; } else t->tm_mon--; t1=mktime(t); break; case TIMEPERIOD_THISQUARTER: /* not implemented */ break; case TIMEPERIOD_LASTQUARTER: /* not implemented */ break; case TIMEPERIOD_THISYEAR: t->tm_mon=0; t->tm_mday=1; t1=mktime(t); t2=current_time; break; case TIMEPERIOD_LASTYEAR: t->tm_mon=0; t->tm_mday=1; t2=mktime(t); t->tm_year--; t1=mktime(t); break; case TIMEPERIOD_LAST7DAYS: t2=current_time; t1=current_time-(7*24*60*60); break; case TIMEPERIOD_LAST31DAYS: t2=current_time; t1=current_time-(31*24*60*60); break; default: break; } return; } void compute_report_times(void){ time_t current_time; struct tm *st; struct tm *et; /* get the current time */ time(¤t_time); st=localtime(¤t_time); st->tm_sec=start_second; st->tm_min=start_minute; st->tm_hour=start_hour; st->tm_mday=start_day; st->tm_mon=start_month-1; st->tm_year=start_year-1900; t1=mktime(st); et=localtime(¤t_time); et->tm_sec=end_second; et->tm_min=end_minute; et->tm_hour=end_hour; et->tm_mday=end_day; et->tm_mon=end_month-1; et->tm_year=end_year-1900; t2=mktime(et); } void free_event_list(void){ archived_event *this_event=NULL; archived_event *next_event=NULL; for(this_event=event_list;this_event!=NULL;){ next_event=this_event->next; if(this_event->host_name!=NULL) free(this_event->host_name); if(this_event->service_description!=NULL) free(this_event->service_description); if(this_event->event_info!=NULL) free(this_event->event_info); free(this_event); this_event=next_event; } event_list=NULL; return; } /* adds an archived event entry to the list in memory */ void add_archived_event(int event_type, time_t time_stamp, int entry_type, int state_type, char *host_name, char *svc_description, char *event_info){ archived_event *last_event=NULL; archived_event *temp_event=NULL; archived_event *new_event=NULL; service *temp_service=NULL; host *temp_host; /* check timestamp sanity */ if(time_stampt2) return; /* check alert type (host or service alert) */ if(!(alert_types & event_type)) return; /* check state type (soft or hard state) */ if(!(state_types & state_type)) return; /* check state (host or service state) */ if(event_type==AE_HOST_ALERT){ if(!(host_states & entry_type)) return; } else{ if(!(service_states & entry_type)) return; } /* find the host this entry is associated with */ temp_host=find_host(host_name); /* check hostgroup match (valid filter for all reports) */ if(show_all_hostgroups==FALSE && is_host_member_of_hostgroup(target_hostgroup,temp_host)==FALSE) return; /* check host match (valid filter for some reports) */ if(show_all_hosts==FALSE && (display_type==REPORT_RECENT_ALERTS || display_type==REPORT_HOST_ALERT_TOTALS || display_type==REPORT_SERVICE_ALERT_TOTALS)){ if(target_host==NULL || temp_host==NULL) return; if(strcmp(target_host->name,temp_host->name)) return; } /* check servicegroup math (valid filter for all reports) */ if(event_type==AE_SERVICE_ALERT){ temp_service=find_service(host_name,svc_description); if(show_all_servicegroups==FALSE && is_service_member_of_servicegroup(target_servicegroup,temp_service)==FALSE) return; } else{ if(show_all_servicegroups==FALSE && is_host_member_of_servicegroup(target_servicegroup,temp_host)==FALSE) return; } /* check authorization */ if(event_type==AE_SERVICE_ALERT){ if(is_authorized_for_service(temp_service,¤t_authdata)==FALSE) return; } else{ if(is_authorized_for_host(temp_host,¤t_authdata)==FALSE) return; } #ifdef DEBUG if(event_type==AE_HOST_ALERT) printf("Adding host alert (%s) @ %lu
    \n",host_name,(unsigned long)time_stamp); else printf("Adding service alert (%s/%s) @ %lu
    \n",host_name,svc_description,(unsigned long)time_stamp); #endif /* allocate memory for the new entry */ new_event=(archived_event *)malloc(sizeof(archived_event)); if(new_event==NULL) return; /* allocate memory for the host name */ if(host_name!=NULL){ new_event->host_name=(char *)malloc(strlen(host_name)+1); if(new_event->host_name!=NULL) strcpy(new_event->host_name,host_name); } else new_event->host_name=NULL; /* allocate memory for the service description */ if(svc_description!=NULL){ new_event->service_description=(char *)malloc(strlen(svc_description)+1); if(new_event->service_description!=NULL) strcpy(new_event->service_description,svc_description); } else new_event->service_description=NULL; /* allocate memory for the event info */ if(event_info!=NULL){ new_event->event_info=(char *)malloc(strlen(event_info)+1); if(new_event->event_info!=NULL) strcpy(new_event->event_info,event_info); } else new_event->event_info=NULL; new_event->event_type=event_type; new_event->time_stamp=time_stamp; new_event->entry_type=entry_type; new_event->state_type=state_type; /* add the new entry to the list in memory, sorted by time */ last_event=event_list; for(temp_event=event_list;temp_event!=NULL;temp_event=temp_event->next){ if(new_event->time_stamp>=temp_event->time_stamp){ new_event->next=temp_event; if(temp_event==event_list) event_list=new_event; else last_event->next=new_event; break; } else last_event=temp_event; } if(event_list==NULL){ new_event->next=NULL; event_list=new_event; } else if(temp_event==NULL){ new_event->next=NULL; last_event->next=new_event; } total_items++; return; } /* determines standard report options */ void determine_standard_report_options(void){ /* report over last 7 days */ convert_timeperiod_to_times(TIMEPERIOD_LAST7DAYS); compute_time_from_parts=FALSE; /* common options */ state_types=AE_HARD_STATE; item_limit=25; /* report-specific options */ switch(standard_report){ case SREPORT_RECENT_ALERTS: display_type=REPORT_RECENT_ALERTS; alert_types=AE_HOST_ALERT+AE_SERVICE_ALERT; host_states=AE_HOST_UP+AE_HOST_DOWN+AE_HOST_UNREACHABLE; service_states=AE_SERVICE_OK+AE_SERVICE_WARNING+AE_SERVICE_UNKNOWN+AE_SERVICE_CRITICAL; break; case SREPORT_RECENT_HOST_ALERTS: display_type=REPORT_RECENT_ALERTS; alert_types=AE_HOST_ALERT; host_states=AE_HOST_UP+AE_HOST_DOWN+AE_HOST_UNREACHABLE; break; case SREPORT_RECENT_SERVICE_ALERTS: display_type=REPORT_RECENT_ALERTS; alert_types=AE_SERVICE_ALERT; service_states=AE_SERVICE_OK+AE_SERVICE_WARNING+AE_SERVICE_UNKNOWN+AE_SERVICE_CRITICAL; break; case SREPORT_TOP_HOST_ALERTS: display_type=REPORT_TOP_ALERTS; alert_types=AE_HOST_ALERT; host_states=AE_HOST_UP+AE_HOST_DOWN+AE_HOST_UNREACHABLE; break; case SREPORT_TOP_SERVICE_ALERTS: display_type=REPORT_TOP_ALERTS; alert_types=AE_SERVICE_ALERT; service_states=AE_SERVICE_OK+AE_SERVICE_WARNING+AE_SERVICE_UNKNOWN+AE_SERVICE_CRITICAL; break; default: break; } return; } /* displays report */ void display_report(void){ switch(display_type){ case REPORT_ALERT_TOTALS: display_alert_totals(); break; case REPORT_HOSTGROUP_ALERT_TOTALS: display_hostgroup_alert_totals(); break; case REPORT_HOST_ALERT_TOTALS: display_host_alert_totals(); break; case REPORT_SERVICEGROUP_ALERT_TOTALS: display_servicegroup_alert_totals(); break; case REPORT_SERVICE_ALERT_TOTALS: display_service_alert_totals(); break; case REPORT_TOP_ALERTS: display_top_alerts(); break; default: display_recent_alerts(); break; } return; } /* displays recent alerts */ void display_recent_alerts(void){ archived_event *temp_event; int current_item=0; int odd=0; char *bgclass=""; char *status_bgclass=""; char *status=""; char date_time[MAX_DATETIME_LENGTH]; printf("
    \n"); if(item_limit<=0 || total_items<=item_limit || total_items==0) printf("
    Displaying all %d matching alerts\n",total_items); else printf("
    Displaying most recent %d of %d total matching alerts\n",item_limit,total_items); printf("
    \n"); printf("\n"); printf("\n"); for(temp_event=event_list;temp_event!=NULL;temp_event=temp_event->next,current_item++){ if(current_item>=item_limit && item_limit>0) break; if(odd){ odd=0; bgclass="Odd"; } else{ odd=1; bgclass="Even"; } printf("",bgclass); get_time_string(&temp_event->time_stamp,date_time,(int)sizeof(date_time),SHORT_DATE_TIME); printf("",bgclass,date_time); printf("",bgclass,(temp_event->event_type==AE_HOST_ALERT)?"Host Alert":"Service Alert"); printf("",bgclass,EXTINFO_CGI,DISPLAY_HOST_INFO,url_encode(temp_event->host_name),temp_event->host_name); if(temp_event->event_type==AE_HOST_ALERT) printf("",bgclass); else{ printf("",url_encode(temp_event->service_description),temp_event->service_description); } switch(temp_event->entry_type){ case AE_HOST_UP: status_bgclass="hostUP"; status="UP"; break; case AE_HOST_DOWN: status_bgclass="hostDOWN"; status="DOWN"; break; case AE_HOST_UNREACHABLE: status_bgclass="hostUNREACHABLE"; status="UNREACHABLE"; break; case AE_SERVICE_OK: status_bgclass="serviceOK"; status="OK"; break; case AE_SERVICE_WARNING: status_bgclass="serviceWARNING"; status="WARNING"; break; case AE_SERVICE_UNKNOWN: status_bgclass="serviceUNKNOWN"; status="UNKNOWN"; break; case AE_SERVICE_CRITICAL: status_bgclass="serviceCRITICAL"; status="CRITICAL"; break; default: status_bgclass=bgclass; status="???"; break; } printf("",status_bgclass,status); printf("",bgclass,(temp_event->state_type==AE_SOFT_STATE)?"SOFT":"HARD"); printf("",bgclass,temp_event->event_info); printf("\n"); } printf("
    TimeAlert TypeHostServiceStateState TypeInformation
    %s%s%sN/A%s%s%s%s
    \n"); printf("
    \n"); return; } /* displays alerts totals */ void display_alert_totals(void){ int hard_host_up_alerts=0; int soft_host_up_alerts=0; int hard_host_down_alerts=0; int soft_host_down_alerts=0; int hard_host_unreachable_alerts=0; int soft_host_unreachable_alerts=0; int hard_service_ok_alerts=0; int soft_service_ok_alerts=0; int hard_service_warning_alerts=0; int soft_service_warning_alerts=0; int hard_service_unknown_alerts=0; int soft_service_unknown_alerts=0; int hard_service_critical_alerts=0; int soft_service_critical_alerts=0; archived_event *temp_event; /************************/ /**** OVERALL TOTALS ****/ /************************/ /* process all events */ for(temp_event=event_list;temp_event!=NULL;temp_event=temp_event->next){ /* host alerts */ if(temp_event->event_type==AE_HOST_ALERT){ if(temp_event->state_type==AE_SOFT_STATE){ if(temp_event->entry_type==AE_HOST_UP) soft_host_up_alerts++; else if(temp_event->entry_type==AE_HOST_DOWN) soft_host_down_alerts++; else if(temp_event->entry_type==AE_HOST_UNREACHABLE) soft_host_unreachable_alerts++; } else{ if(temp_event->entry_type==AE_HOST_UP) hard_host_up_alerts++; else if(temp_event->entry_type==AE_HOST_DOWN) hard_host_down_alerts++; else if(temp_event->entry_type==AE_HOST_UNREACHABLE) hard_host_unreachable_alerts++; } } /* service alerts */ else{ if(temp_event->state_type==AE_SOFT_STATE){ if(temp_event->entry_type==AE_SERVICE_OK) soft_service_ok_alerts++; else if(temp_event->entry_type==AE_SERVICE_WARNING) soft_service_warning_alerts++; else if(temp_event->entry_type==AE_SERVICE_UNKNOWN) soft_service_unknown_alerts++; else if(temp_event->entry_type==AE_SERVICE_CRITICAL) soft_service_critical_alerts++; } else{ if(temp_event->entry_type==AE_SERVICE_OK) hard_service_ok_alerts++; else if(temp_event->entry_type==AE_SERVICE_WARNING) hard_service_warning_alerts++; else if(temp_event->entry_type==AE_SERVICE_UNKNOWN) hard_service_unknown_alerts++; else if(temp_event->entry_type==AE_SERVICE_CRITICAL) hard_service_critical_alerts++; } } } printf("
    \n"); printf("
    \n"); printf("
    Overall Totals
    \n"); printf("
    \n"); printf("
    \n"); printf("\n"); printf("\n"); if(alert_types & AE_HOST_ALERT){ printf("\n"); } if(alert_types & AE_SERVICE_ALERT){ printf("\n"); } printf("\n"); printf("
    \n"); printf("
    Host Alerts
    \n"); printf("
    \n"); printf("\n"); printf("\n"); printf("\n",soft_host_up_alerts,hard_host_up_alerts,soft_host_up_alerts+hard_host_up_alerts); printf("\n",soft_host_down_alerts,hard_host_down_alerts,soft_host_down_alerts+hard_host_down_alerts); printf("\n",soft_host_unreachable_alerts,hard_host_unreachable_alerts,soft_host_unreachable_alerts+hard_host_unreachable_alerts); printf("\n",soft_host_up_alerts+soft_host_down_alerts+soft_host_unreachable_alerts,hard_host_up_alerts+hard_host_down_alerts+hard_host_unreachable_alerts,soft_host_up_alerts+hard_host_up_alerts+soft_host_down_alerts+hard_host_down_alerts+soft_host_unreachable_alerts+hard_host_unreachable_alerts); printf("
    StateSoft AlertsHard AlertsTotal Alerts
    UP%d%d%d
    DOWN%d%d%d
    UNREACHABLE%d%d%d
    All States%d%d%d
    \n"); printf("
    \n"); printf("
    \n"); printf("
    Service Alerts
    \n"); printf("
    \n"); printf("\n"); printf("\n"); printf("\n",soft_service_ok_alerts,hard_service_ok_alerts,soft_service_ok_alerts+hard_service_ok_alerts); printf("\n",soft_service_warning_alerts,hard_service_warning_alerts,soft_service_warning_alerts+hard_service_warning_alerts); printf("\n",soft_service_unknown_alerts,hard_service_unknown_alerts,soft_service_unknown_alerts+hard_service_unknown_alerts); printf("\n",soft_service_critical_alerts,hard_service_critical_alerts,soft_service_critical_alerts+hard_service_critical_alerts); printf("\n",soft_service_ok_alerts+soft_service_warning_alerts+soft_service_unknown_alerts+soft_service_critical_alerts,hard_service_ok_alerts+hard_service_warning_alerts+hard_service_unknown_alerts+hard_service_critical_alerts,soft_service_ok_alerts+soft_service_warning_alerts+soft_service_unknown_alerts+soft_service_critical_alerts+hard_service_ok_alerts+hard_service_warning_alerts+hard_service_unknown_alerts+hard_service_critical_alerts); printf("
    StateSoft AlertsHard AlertsTotal Alerts
    OK%d%d%d
    WARNING%d%d%d
    UNKNOWN%d%d%d
    CRITICAL%d%d%d
    All States%d%d%d
    \n"); printf("
    \n"); printf("
    \n"); printf("
    \n"); printf("
    \n"); return; } /* displays hostgroup alert totals */ void display_hostgroup_alert_totals(void){ hostgroup *temp_hostgroup; /**************************/ /**** HOSTGROUP TOTALS ****/ /**************************/ printf("
    \n"); printf("
    \n"); printf("
    Totals By Hostgroup
    \n"); if(show_all_hostgroups==FALSE) display_specific_hostgroup_alert_totals(target_hostgroup); else{ for(temp_hostgroup=hostgroup_list;temp_hostgroup!=NULL;temp_hostgroup=temp_hostgroup->next) display_specific_hostgroup_alert_totals(temp_hostgroup); } printf("
    \n"); return; } /* displays alert totals for a specific hostgroup */ void display_specific_hostgroup_alert_totals(hostgroup *grp){ int hard_host_up_alerts=0; int soft_host_up_alerts=0; int hard_host_down_alerts=0; int soft_host_down_alerts=0; int hard_host_unreachable_alerts=0; int soft_host_unreachable_alerts=0; int hard_service_ok_alerts=0; int soft_service_ok_alerts=0; int hard_service_warning_alerts=0; int soft_service_warning_alerts=0; int hard_service_unknown_alerts=0; int soft_service_unknown_alerts=0; int hard_service_critical_alerts=0; int soft_service_critical_alerts=0; archived_event *temp_event; host *temp_host; if(grp==NULL) return; /* make sure the user is authorized to view this hostgroup */ if(is_authorized_for_hostgroup(grp,¤t_authdata)==FALSE) return; /* process all events */ for(temp_event=event_list;temp_event!=NULL;temp_event=temp_event->next){ temp_host=find_host(temp_event->host_name); if(is_host_member_of_hostgroup(grp,temp_host)==FALSE) continue; /* host alerts */ if(temp_event->event_type==AE_HOST_ALERT){ if(temp_event->state_type==AE_SOFT_STATE){ if(temp_event->entry_type==AE_HOST_UP) soft_host_up_alerts++; else if(temp_event->entry_type==AE_HOST_DOWN) soft_host_down_alerts++; else if(temp_event->entry_type==AE_HOST_UNREACHABLE) soft_host_unreachable_alerts++; } else{ if(temp_event->entry_type==AE_HOST_UP) hard_host_up_alerts++; else if(temp_event->entry_type==AE_HOST_DOWN) hard_host_down_alerts++; else if(temp_event->entry_type==AE_HOST_UNREACHABLE) hard_host_unreachable_alerts++; } } /* service alerts */ else{ if(temp_event->state_type==AE_SOFT_STATE){ if(temp_event->entry_type==AE_SERVICE_OK) soft_service_ok_alerts++; else if(temp_event->entry_type==AE_SERVICE_WARNING) soft_service_warning_alerts++; else if(temp_event->entry_type==AE_SERVICE_UNKNOWN) soft_service_unknown_alerts++; else if(temp_event->entry_type==AE_SERVICE_CRITICAL) soft_service_critical_alerts++; } else{ if(temp_event->entry_type==AE_SERVICE_OK) hard_service_ok_alerts++; else if(temp_event->entry_type==AE_SERVICE_WARNING) hard_service_warning_alerts++; else if(temp_event->entry_type==AE_SERVICE_UNKNOWN) hard_service_unknown_alerts++; else if(temp_event->entry_type==AE_SERVICE_CRITICAL) hard_service_critical_alerts++; } } } printf("
    \n"); printf("
    \n"); printf("\n"); printf("\n",grp->group_name,grp->alias); printf("\n"); if(alert_types & AE_HOST_ALERT){ printf("\n"); } if(alert_types & AE_SERVICE_ALERT){ printf("\n"); } printf("\n"); printf("
    Hostgroup '%s' (%s)
    \n"); printf("
    Host Alerts
    \n"); printf("
    \n"); printf("\n"); printf("\n"); printf("\n",soft_host_up_alerts,hard_host_up_alerts,soft_host_up_alerts+hard_host_up_alerts); printf("\n",soft_host_down_alerts,hard_host_down_alerts,soft_host_down_alerts+hard_host_down_alerts); printf("\n",soft_host_unreachable_alerts,hard_host_unreachable_alerts,soft_host_unreachable_alerts+hard_host_unreachable_alerts); printf("\n",soft_host_up_alerts+soft_host_down_alerts+soft_host_unreachable_alerts,hard_host_up_alerts+hard_host_down_alerts+hard_host_unreachable_alerts,soft_host_up_alerts+hard_host_up_alerts+soft_host_down_alerts+hard_host_down_alerts+soft_host_unreachable_alerts+hard_host_unreachable_alerts); printf("
    StateSoft AlertsHard AlertsTotal Alerts
    UP%d%d%d
    DOWN%d%d%d
    UNREACHABLE%d%d%d
    All States%d%d%d
    \n"); printf("
    \n"); printf("
    \n"); printf("
    Service Alerts
    \n"); printf("
    \n"); printf("\n"); printf("\n"); printf("\n",soft_service_ok_alerts,hard_service_ok_alerts,soft_service_ok_alerts+hard_service_ok_alerts); printf("\n",soft_service_warning_alerts,hard_service_warning_alerts,soft_service_warning_alerts+hard_service_warning_alerts); printf("\n",soft_service_unknown_alerts,hard_service_unknown_alerts,soft_service_unknown_alerts+hard_service_unknown_alerts); printf("\n",soft_service_critical_alerts,hard_service_critical_alerts,soft_service_critical_alerts+hard_service_critical_alerts); printf("\n",soft_service_ok_alerts+soft_service_warning_alerts+soft_service_unknown_alerts+soft_service_critical_alerts,hard_service_ok_alerts+hard_service_warning_alerts+hard_service_unknown_alerts+hard_service_critical_alerts,soft_service_ok_alerts+soft_service_warning_alerts+soft_service_unknown_alerts+soft_service_critical_alerts+hard_service_ok_alerts+hard_service_warning_alerts+hard_service_unknown_alerts+hard_service_critical_alerts); printf("
    StateSoft AlertsHard AlertsTotal Alerts
    OK%d%d%d
    WARNING%d%d%d
    UNKNOWN%d%d%d
    CRITICAL%d%d%d
    All States%d%d%d
    \n"); printf("
    \n"); printf("
    \n"); printf("
    \n"); return; } /* displays host alert totals */ void display_host_alert_totals(void){ host *temp_host; /*********************/ /**** HOST TOTALS ****/ /*********************/ printf("
    \n"); printf("
    \n"); printf("
    Totals By Host
    \n"); if(show_all_hosts==FALSE) display_specific_host_alert_totals(target_host); else{ for(temp_host=host_list;temp_host!=NULL;temp_host=temp_host->next) display_specific_host_alert_totals(temp_host); } printf("
    \n"); return; } /* displays alert totals for a specific host */ void display_specific_host_alert_totals(host *hst){ int hard_host_up_alerts=0; int soft_host_up_alerts=0; int hard_host_down_alerts=0; int soft_host_down_alerts=0; int hard_host_unreachable_alerts=0; int soft_host_unreachable_alerts=0; int hard_service_ok_alerts=0; int soft_service_ok_alerts=0; int hard_service_warning_alerts=0; int soft_service_warning_alerts=0; int hard_service_unknown_alerts=0; int soft_service_unknown_alerts=0; int hard_service_critical_alerts=0; int soft_service_critical_alerts=0; archived_event *temp_event; if(hst==NULL) return; /* make sure the user is authorized to view this host */ if(is_authorized_for_host(hst,¤t_authdata)==FALSE) return; if(show_all_hostgroups==FALSE && target_hostgroup!=NULL){ if(is_host_member_of_hostgroup(target_hostgroup,hst)==FALSE) return; } /* process all events */ for(temp_event=event_list;temp_event!=NULL;temp_event=temp_event->next){ if(strcmp(temp_event->host_name,hst->name)) continue; /* host alerts */ if(temp_event->event_type==AE_HOST_ALERT){ if(temp_event->state_type==AE_SOFT_STATE){ if(temp_event->entry_type==AE_HOST_UP) soft_host_up_alerts++; else if(temp_event->entry_type==AE_HOST_DOWN) soft_host_down_alerts++; else if(temp_event->entry_type==AE_HOST_UNREACHABLE) soft_host_unreachable_alerts++; } else{ if(temp_event->entry_type==AE_HOST_UP) hard_host_up_alerts++; else if(temp_event->entry_type==AE_HOST_DOWN) hard_host_down_alerts++; else if(temp_event->entry_type==AE_HOST_UNREACHABLE) hard_host_unreachable_alerts++; } } /* service alerts */ else{ if(temp_event->state_type==AE_SOFT_STATE){ if(temp_event->entry_type==AE_SERVICE_OK) soft_service_ok_alerts++; else if(temp_event->entry_type==AE_SERVICE_WARNING) soft_service_warning_alerts++; else if(temp_event->entry_type==AE_SERVICE_UNKNOWN) soft_service_unknown_alerts++; else if(temp_event->entry_type==AE_SERVICE_CRITICAL) soft_service_critical_alerts++; } else{ if(temp_event->entry_type==AE_SERVICE_OK) hard_service_ok_alerts++; else if(temp_event->entry_type==AE_SERVICE_WARNING) hard_service_warning_alerts++; else if(temp_event->entry_type==AE_SERVICE_UNKNOWN) hard_service_unknown_alerts++; else if(temp_event->entry_type==AE_SERVICE_CRITICAL) hard_service_critical_alerts++; } } } printf("
    \n"); printf("
    \n"); printf("\n"); printf("\n",hst->name,hst->alias); printf("\n"); if(alert_types & AE_HOST_ALERT){ printf("\n"); } if(alert_types & AE_SERVICE_ALERT){ printf("\n"); } printf("\n"); printf("
    Host '%s' (%s)
    \n"); printf("
    Host Alerts
    \n"); printf("
    \n"); printf("\n"); printf("\n"); printf("\n",soft_host_up_alerts,hard_host_up_alerts,soft_host_up_alerts+hard_host_up_alerts); printf("\n",soft_host_down_alerts,hard_host_down_alerts,soft_host_down_alerts+hard_host_down_alerts); printf("\n",soft_host_unreachable_alerts,hard_host_unreachable_alerts,soft_host_unreachable_alerts+hard_host_unreachable_alerts); printf("\n",soft_host_up_alerts+soft_host_down_alerts+soft_host_unreachable_alerts,hard_host_up_alerts+hard_host_down_alerts+hard_host_unreachable_alerts,soft_host_up_alerts+hard_host_up_alerts+soft_host_down_alerts+hard_host_down_alerts+soft_host_unreachable_alerts+hard_host_unreachable_alerts); printf("
    StateSoft AlertsHard AlertsTotal Alerts
    UP%d%d%d
    DOWN%d%d%d
    UNREACHABLE%d%d%d
    All States%d%d%d
    \n"); printf("
    \n"); printf("
    \n"); printf("
    Service Alerts
    \n"); printf("
    \n"); printf("\n"); printf("\n"); printf("\n",soft_service_ok_alerts,hard_service_ok_alerts,soft_service_ok_alerts+hard_service_ok_alerts); printf("\n",soft_service_warning_alerts,hard_service_warning_alerts,soft_service_warning_alerts+hard_service_warning_alerts); printf("\n",soft_service_unknown_alerts,hard_service_unknown_alerts,soft_service_unknown_alerts+hard_service_unknown_alerts); printf("\n",soft_service_critical_alerts,hard_service_critical_alerts,soft_service_critical_alerts+hard_service_critical_alerts); printf("\n",soft_service_ok_alerts+soft_service_warning_alerts+soft_service_unknown_alerts+soft_service_critical_alerts,hard_service_ok_alerts+hard_service_warning_alerts+hard_service_unknown_alerts+hard_service_critical_alerts,soft_service_ok_alerts+soft_service_warning_alerts+soft_service_unknown_alerts+soft_service_critical_alerts+hard_service_ok_alerts+hard_service_warning_alerts+hard_service_unknown_alerts+hard_service_critical_alerts); printf("
    StateSoft AlertsHard AlertsTotal Alerts
    OK%d%d%d
    WARNING%d%d%d
    UNKNOWN%d%d%d
    CRITICAL%d%d%d
    All States%d%d%d
    \n"); printf("
    \n"); printf("
    \n"); printf("
    \n"); return; } /* displays servicegroup alert totals */ void display_servicegroup_alert_totals(void){ servicegroup *temp_servicegroup; /**************************/ /**** SERVICEGROUP TOTALS ****/ /**************************/ printf("
    \n"); printf("
    \n"); printf("
    Totals By Servicegroup
    \n"); if(show_all_servicegroups==FALSE) display_specific_servicegroup_alert_totals(target_servicegroup); else{ for(temp_servicegroup=servicegroup_list;temp_servicegroup!=NULL;temp_servicegroup=temp_servicegroup->next) display_specific_servicegroup_alert_totals(temp_servicegroup); } printf("
    \n"); return; } /* displays alert totals for a specific servicegroup */ void display_specific_servicegroup_alert_totals(servicegroup *grp){ int hard_host_up_alerts=0; int soft_host_up_alerts=0; int hard_host_down_alerts=0; int soft_host_down_alerts=0; int hard_host_unreachable_alerts=0; int soft_host_unreachable_alerts=0; int hard_service_ok_alerts=0; int soft_service_ok_alerts=0; int hard_service_warning_alerts=0; int soft_service_warning_alerts=0; int hard_service_unknown_alerts=0; int soft_service_unknown_alerts=0; int hard_service_critical_alerts=0; int soft_service_critical_alerts=0; archived_event *temp_event; host *temp_host; service *temp_service; if(grp==NULL) return; /* make sure the user is authorized to view this servicegroup */ if(is_authorized_for_servicegroup(grp,¤t_authdata)==FALSE) return; /* process all events */ for(temp_event=event_list;temp_event!=NULL;temp_event=temp_event->next){ if(temp_event->event_type==AE_HOST_ALERT){ temp_host=find_host(temp_event->host_name); if(is_host_member_of_servicegroup(grp,temp_host)==FALSE) continue; } else{ temp_service=find_service(temp_event->host_name,temp_event->service_description); if(is_service_member_of_servicegroup(grp,temp_service)==FALSE) continue; } /* host alerts */ if(temp_event->event_type==AE_HOST_ALERT){ if(temp_event->state_type==AE_SOFT_STATE){ if(temp_event->entry_type==AE_HOST_UP) soft_host_up_alerts++; else if(temp_event->entry_type==AE_HOST_DOWN) soft_host_down_alerts++; else if(temp_event->entry_type==AE_HOST_UNREACHABLE) soft_host_unreachable_alerts++; } else{ if(temp_event->entry_type==AE_HOST_UP) hard_host_up_alerts++; else if(temp_event->entry_type==AE_HOST_DOWN) hard_host_down_alerts++; else if(temp_event->entry_type==AE_HOST_UNREACHABLE) hard_host_unreachable_alerts++; } } /* service alerts */ else{ if(temp_event->state_type==AE_SOFT_STATE){ if(temp_event->entry_type==AE_SERVICE_OK) soft_service_ok_alerts++; else if(temp_event->entry_type==AE_SERVICE_WARNING) soft_service_warning_alerts++; else if(temp_event->entry_type==AE_SERVICE_UNKNOWN) soft_service_unknown_alerts++; else if(temp_event->entry_type==AE_SERVICE_CRITICAL) soft_service_critical_alerts++; } else{ if(temp_event->entry_type==AE_SERVICE_OK) hard_service_ok_alerts++; else if(temp_event->entry_type==AE_SERVICE_WARNING) hard_service_warning_alerts++; else if(temp_event->entry_type==AE_SERVICE_UNKNOWN) hard_service_unknown_alerts++; else if(temp_event->entry_type==AE_SERVICE_CRITICAL) hard_service_critical_alerts++; } } } printf("
    \n"); printf("
    \n"); printf("\n"); printf("\n",grp->group_name,grp->alias); printf("\n"); if(alert_types & AE_HOST_ALERT){ printf("\n"); } if(alert_types & AE_SERVICE_ALERT){ printf("\n"); } printf("\n"); printf("
    Servicegroup '%s' (%s)
    \n"); printf("
    Host Alerts
    \n"); printf("
    \n"); printf("\n"); printf("\n"); printf("\n",soft_host_up_alerts,hard_host_up_alerts,soft_host_up_alerts+hard_host_up_alerts); printf("\n",soft_host_down_alerts,hard_host_down_alerts,soft_host_down_alerts+hard_host_down_alerts); printf("\n",soft_host_unreachable_alerts,hard_host_unreachable_alerts,soft_host_unreachable_alerts+hard_host_unreachable_alerts); printf("\n",soft_host_up_alerts+soft_host_down_alerts+soft_host_unreachable_alerts,hard_host_up_alerts+hard_host_down_alerts+hard_host_unreachable_alerts,soft_host_up_alerts+hard_host_up_alerts+soft_host_down_alerts+hard_host_down_alerts+soft_host_unreachable_alerts+hard_host_unreachable_alerts); printf("
    StateSoft AlertsHard AlertsTotal Alerts
    UP%d%d%d
    DOWN%d%d%d
    UNREACHABLE%d%d%d
    All States%d%d%d
    \n"); printf("
    \n"); printf("
    \n"); printf("
    Service Alerts
    \n"); printf("
    \n"); printf("\n"); printf("\n"); printf("\n",soft_service_ok_alerts,hard_service_ok_alerts,soft_service_ok_alerts+hard_service_ok_alerts); printf("\n",soft_service_warning_alerts,hard_service_warning_alerts,soft_service_warning_alerts+hard_service_warning_alerts); printf("\n",soft_service_unknown_alerts,hard_service_unknown_alerts,soft_service_unknown_alerts+hard_service_unknown_alerts); printf("\n",soft_service_critical_alerts,hard_service_critical_alerts,soft_service_critical_alerts+hard_service_critical_alerts); printf("\n",soft_service_ok_alerts+soft_service_warning_alerts+soft_service_unknown_alerts+soft_service_critical_alerts,hard_service_ok_alerts+hard_service_warning_alerts+hard_service_unknown_alerts+hard_service_critical_alerts,soft_service_ok_alerts+soft_service_warning_alerts+soft_service_unknown_alerts+soft_service_critical_alerts+hard_service_ok_alerts+hard_service_warning_alerts+hard_service_unknown_alerts+hard_service_critical_alerts); printf("
    StateSoft AlertsHard AlertsTotal Alerts
    OK%d%d%d
    WARNING%d%d%d
    UNKNOWN%d%d%d
    CRITICAL%d%d%d
    All States%d%d%d
    \n"); printf("
    \n"); printf("
    \n"); printf("
    \n"); return; } /* displays service alert totals */ void display_service_alert_totals(void){ service *temp_service; /************************/ /**** SERVICE TOTALS ****/ /************************/ printf("
    \n"); printf("
    \n"); printf("
    Totals By Service
    \n"); for(temp_service=service_list;temp_service!=NULL;temp_service=temp_service->next) display_specific_service_alert_totals(temp_service); printf("
    \n"); return; } /* displays alert totals for a specific service */ void display_specific_service_alert_totals(service *svc){ int hard_service_ok_alerts=0; int soft_service_ok_alerts=0; int hard_service_warning_alerts=0; int soft_service_warning_alerts=0; int hard_service_unknown_alerts=0; int soft_service_unknown_alerts=0; int hard_service_critical_alerts=0; int soft_service_critical_alerts=0; archived_event *temp_event; host *temp_host; if(svc==NULL) return; /* make sure the user is authorized to view this service */ if(is_authorized_for_service(svc,¤t_authdata)==FALSE) return; if(show_all_hostgroups==FALSE && target_hostgroup!=NULL){ temp_host=find_host(svc->host_name); if(is_host_member_of_hostgroup(target_hostgroup,temp_host)==FALSE) return; } if(show_all_hosts==FALSE && target_host!=NULL){ if(strcmp(target_host->name,svc->host_name)) return; } /* process all events */ for(temp_event=event_list;temp_event!=NULL;temp_event=temp_event->next){ if(temp_event->event_type!=AE_SERVICE_ALERT) continue; if(strcmp(temp_event->host_name,svc->host_name) || strcmp(temp_event->service_description,svc->description)) continue; /* service alerts */ if(temp_event->state_type==AE_SOFT_STATE){ if(temp_event->entry_type==AE_SERVICE_OK) soft_service_ok_alerts++; else if(temp_event->entry_type==AE_SERVICE_WARNING) soft_service_warning_alerts++; else if(temp_event->entry_type==AE_SERVICE_UNKNOWN) soft_service_unknown_alerts++; else if(temp_event->entry_type==AE_SERVICE_CRITICAL) soft_service_critical_alerts++; } else{ if(temp_event->entry_type==AE_SERVICE_OK) hard_service_ok_alerts++; else if(temp_event->entry_type==AE_SERVICE_WARNING) hard_service_warning_alerts++; else if(temp_event->entry_type==AE_SERVICE_UNKNOWN) hard_service_unknown_alerts++; else if(temp_event->entry_type==AE_SERVICE_CRITICAL) hard_service_critical_alerts++; } } printf("
    \n"); printf("
    \n"); printf("\n"); printf("\n",svc->description,svc->host_name); printf("\n"); if(alert_types & AE_SERVICE_ALERT){ printf("\n"); } printf("\n"); printf("
    Service '%s' on Host '%s'
    \n"); printf("
    Service Alerts
    \n"); printf("
    \n"); printf("\n"); printf("\n"); printf("\n",soft_service_ok_alerts,hard_service_ok_alerts,soft_service_ok_alerts+hard_service_ok_alerts); printf("\n",soft_service_warning_alerts,hard_service_warning_alerts,soft_service_warning_alerts+hard_service_warning_alerts); printf("\n",soft_service_unknown_alerts,hard_service_unknown_alerts,soft_service_unknown_alerts+hard_service_unknown_alerts); printf("\n",soft_service_critical_alerts,hard_service_critical_alerts,soft_service_critical_alerts+hard_service_critical_alerts); printf("\n",soft_service_ok_alerts+soft_service_warning_alerts+soft_service_unknown_alerts+soft_service_critical_alerts,hard_service_ok_alerts+hard_service_warning_alerts+hard_service_unknown_alerts+hard_service_critical_alerts,soft_service_ok_alerts+soft_service_warning_alerts+soft_service_unknown_alerts+soft_service_critical_alerts+hard_service_ok_alerts+hard_service_warning_alerts+hard_service_unknown_alerts+hard_service_critical_alerts); printf("
    StateSoft AlertsHard AlertsTotal Alerts
    OK%d%d%d
    WARNING%d%d%d
    UNKNOWN%d%d%d
    CRITICAL%d%d%d
    All States%d%d%d
    \n"); printf("
    \n"); printf("
    \n"); printf("
    \n"); return; } /* find a specific alert producer */ alert_producer *find_producer(int type, char *hname, char *sdesc){ alert_producer *temp_producer; for(temp_producer=producer_list;temp_producer!=NULL;temp_producer=temp_producer->next){ if(temp_producer->producer_type!=type) continue; if(hname!=NULL && strcmp(hname,temp_producer->host_name)) continue; if(sdesc!=NULL && strcmp(sdesc,temp_producer->service_description)) continue; return temp_producer; } return NULL; } /* adds a new producer to the list in memory */ alert_producer *add_producer(int producer_type, char *host_name, char *service_description){ alert_producer *new_producer=NULL; /* allocate memory for the new entry */ new_producer=(alert_producer *)malloc(sizeof(alert_producer)); if(new_producer==NULL) return NULL; /* allocate memory for the host name */ if(host_name!=NULL){ new_producer->host_name=(char *)malloc(strlen(host_name)+1); if(new_producer->host_name!=NULL) strcpy(new_producer->host_name,host_name); } else new_producer->host_name=NULL; /* allocate memory for the service description */ if(service_description!=NULL){ new_producer->service_description=(char *)malloc(strlen(service_description)+1); if(new_producer->service_description!=NULL) strcpy(new_producer->service_description,service_description); } else new_producer->service_description=NULL; new_producer->producer_type=producer_type; new_producer->total_alerts=0; /* add the new entry to the list in memory, sorted by time */ new_producer->next=producer_list; producer_list=new_producer; return new_producer; } void free_producer_list(void){ alert_producer *this_producer=NULL; alert_producer *next_producer=NULL; for(this_producer=producer_list;this_producer!=NULL;){ next_producer=this_producer->next; if(this_producer->host_name!=NULL) free(this_producer->host_name); if(this_producer->service_description!=NULL) free(this_producer->service_description); free(this_producer); this_producer=next_producer; } producer_list=NULL; return; } /* displays top alerts */ void display_top_alerts(void){ archived_event *temp_event=NULL; alert_producer *temp_producer=NULL; alert_producer *next_producer=NULL; alert_producer *last_producer=NULL; alert_producer *new_producer=NULL; alert_producer *temp_list=NULL; int producer_type=AE_HOST_PRODUCER; int current_item=0; int odd=0; char *bgclass=""; /* process all events */ for(temp_event=event_list;temp_event!=NULL;temp_event=temp_event->next){ producer_type=(temp_event->event_type==AE_HOST_ALERT)?AE_HOST_PRODUCER:AE_SERVICE_PRODUCER; /* see if we already have a record for the producer */ temp_producer=find_producer(producer_type,temp_event->host_name,temp_event->service_description); /* if not, add a record */ if(temp_producer==NULL) temp_producer=add_producer(producer_type,temp_event->host_name,temp_event->service_description); /* producer record could not be added */ if(temp_producer==NULL) continue; /* update stats for producer */ temp_producer->total_alerts++; } /* sort the producer list by total alerts (descending) */ total_items=0; temp_list=NULL; for(new_producer=producer_list;new_producer!=NULL;){ next_producer=new_producer->next; last_producer=temp_list; for(temp_producer=temp_list;temp_producer!=NULL;temp_producer=temp_producer->next){ if(new_producer->total_alerts>=temp_producer->total_alerts){ new_producer->next=temp_producer; if(temp_producer==temp_list) temp_list=new_producer; else last_producer->next=new_producer; break; } else last_producer=temp_producer; } if(temp_list==NULL){ new_producer->next=NULL; temp_list=new_producer; } else if(temp_producer==NULL){ new_producer->next=NULL; last_producer->next=new_producer; } new_producer=next_producer; total_items++; } producer_list=temp_list; printf("
    \n"); if(item_limit<=0 || total_items<=item_limit || total_items==0) printf("
    Displaying all %d matching alert producers\n",total_items); else printf("
    Displaying top %d of %d total matching alert producers\n",item_limit,total_items); printf("
    \n"); printf("\n"); printf("\n"); /* display top producers */ for(temp_producer=producer_list;temp_producer!=NULL;temp_producer=temp_producer->next){ if(current_item>=item_limit && item_limit>0) break; current_item++; if(odd){ odd=0; bgclass="Odd"; } else{ odd=1; bgclass="Even"; } printf("",bgclass); printf("",bgclass,current_item); printf("",bgclass,(temp_producer->producer_type==AE_HOST_PRODUCER)?"Host":"Service"); printf("",bgclass,EXTINFO_CGI,DISPLAY_HOST_INFO,url_encode(temp_producer->host_name),temp_producer->host_name); if(temp_producer->producer_type==AE_HOST_PRODUCER) printf("",bgclass); else{ printf("",url_encode(temp_producer->service_description),temp_producer->service_description); } printf("",bgclass,temp_producer->total_alerts); printf("\n"); } printf("
    RankProducer TypeHostServiceTotal Alerts
    #%d%s%sN/A%s%d
    \n"); printf("
    \n"); return; } nagios-2.6/cgi/tac.c0000664000076500007650000016026410472630126013666 0ustar nagiosnagios/*********************************************************************** * * TAC.C - Nagios Tactical Monitoring Overview CGI * * Copyright (c) 2001-2006 Ethan Galstad (nagios@nagios.org) * Last Modified: 08-22-2006 * * This CGI program will display the contents of the Nagios * log file. * * 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. ***********************************************************************/ #include "../include/config.h" #include "../include/common.h" #include "../include/objects.h" #include "../include/statusdata.h" #include "../include/getcgi.h" #include "../include/cgiutils.h" #include "../include/cgiauth.h" #define HEALTH_WARNING_PERCENTAGE 90 #define HEALTH_CRITICAL_PERCENTAGE 75 /* HOSTOUTAGE structure */ typedef struct hostoutage_struct{ host *hst; int affected_child_hosts; struct hostoutage_struct *next; }hostoutage; extern char main_config_file[MAX_FILENAME_LENGTH]; extern char url_images_path[MAX_FILENAME_LENGTH]; extern char url_stylesheets_path[MAX_FILENAME_LENGTH]; extern char url_media_path[MAX_FILENAME_LENGTH]; extern int refresh_rate; extern char *service_critical_sound; extern char *service_warning_sound; extern char *service_unknown_sound; extern char *host_down_sound; extern char *host_unreachable_sound; extern char *normal_sound; extern host *host_list; extern hostgroup *hostgroup_list; extern hoststatus *hoststatus_list; extern servicestatus *servicestatus_list; extern int enable_notifications; extern int execute_service_checks; extern int accept_passive_service_checks; extern int enable_event_handlers; extern int enable_flap_detection; extern int nagios_process_state; void analyze_status_data(void); void display_tac_overview(void); void find_hosts_causing_outages(void); void calculate_outage_effect_of_host(host *,int *); int is_route_to_host_blocked(host *); int number_of_host_services(host *); void add_hostoutage(host *); void free_hostoutage_list(void); void document_header(int); void document_footer(void); int process_cgivars(void); authdata current_authdata; int embedded=FALSE; int display_header=FALSE; hostoutage *hostoutage_list=NULL; int total_blocking_outages=0; int total_nonblocking_outages=0; int total_service_health=0; int total_host_health=0; int potential_service_health=0; int potential_host_health=0; double percent_service_health=0.0; double percent_host_health=0.0; int total_hosts=0; int total_services=0; int total_active_service_checks=0; int total_active_host_checks=0; int total_passive_service_checks=0; int total_passive_host_checks=0; double min_service_execution_time=-1.0; double max_service_execution_time=-1.0; double total_service_execution_time=0.0; double average_service_execution_time=-1.0; double min_host_execution_time=-1.0; double max_host_execution_time=-1.0; double total_host_execution_time=0.0; double average_host_execution_time=-1.0; double min_service_latency=-1.0; double max_service_latency=-1.0; double total_service_latency=0.0; double average_service_latency=-1.0; double min_host_latency=-1.0; double max_host_latency=-1.0; double total_host_latency=0.0; double average_host_latency=-1.0; int flapping_services=0; int flapping_hosts=0; int flap_disabled_services=0; int flap_disabled_hosts=0; int notification_disabled_services=0; int notification_disabled_hosts=0; int event_handler_disabled_services=0; int event_handler_disabled_hosts=0; int active_checks_disabled_services=0; int active_checks_disabled_hosts=0; int passive_checks_disabled_services=0; int passive_checks_disabled_hosts=0; int hosts_pending=0; int hosts_pending_disabled=0; int hosts_up_disabled=0; int hosts_up_unacknowledged=0; int hosts_up=0; int hosts_down_scheduled=0; int hosts_down_acknowledged=0; int hosts_down_disabled=0; int hosts_down_unacknowledged=0; int hosts_down=0; int hosts_unreachable_scheduled=0; int hosts_unreachable_acknowledged=0; int hosts_unreachable_disabled=0; int hosts_unreachable_unacknowledged=0; int hosts_unreachable=0; int services_pending=0; int services_pending_disabled=0; int services_ok_disabled=0; int services_ok_unacknowledged=0; int services_ok=0; int services_warning_host_problem=0; int services_warning_scheduled=0; int services_warning_acknowledged=0; int services_warning_disabled=0; int services_warning_unacknowledged=0; int services_warning=0; int services_unknown_host_problem=0; int services_unknown_scheduled=0; int services_unknown_acknowledged=0; int services_unknown_disabled=0; int services_unknown_unacknowledged=0; int services_unknown=0; int services_critical_host_problem=0; int services_critical_scheduled=0; int services_critical_acknowledged=0; int services_critical_disabled=0; int services_critical_unacknowledged=0; int services_critical=0; int main(void){ int result=OK; char *sound=NULL; /* get the CGI variables passed in the URL */ process_cgivars(); /* reset internal variables */ reset_cgi_vars(); /* read the CGI configuration file */ result=read_cgi_config_file(get_cgi_config_location()); if(result==ERROR){ document_header(FALSE); cgi_config_file_error(get_cgi_config_location()); document_footer(); return ERROR; } /* read the main configuration file */ result=read_main_config_file(main_config_file); if(result==ERROR){ document_header(FALSE); main_config_file_error(main_config_file); document_footer(); return ERROR; } /* read all object configuration data */ result=read_all_object_configuration_data(main_config_file,READ_ALL_OBJECT_DATA); if(result==ERROR){ document_header(FALSE); object_data_error(); document_footer(); return ERROR; } /* read all status data */ result=read_all_status_data(get_cgi_config_location(),READ_ALL_STATUS_DATA); if(result==ERROR){ document_header(FALSE); status_data_error(); document_footer(); free_memory(); return ERROR; } document_header(TRUE); /* get authentication information */ get_authentication_information(¤t_authdata); if(display_header==TRUE){ /* begin top table */ printf("\n"); printf("\n"); /* left column of top table - info box */ printf("\n"); /* middle column of top table - log file navigation options */ printf("\n"); /* right hand column of top row */ printf("\n"); /* end of top table */ printf("\n"); printf("
    \n"); display_info_table("Tactical Status Overview",TRUE,¤t_authdata); printf("\n"); printf("\n"); printf("
    \n"); printf("

    \n"); } /* analyze current host and service status data for tac overview */ analyze_status_data(); /* find all hosts that are causing network outages */ find_hosts_causing_outages(); /* embed sound tag if necessary... */ if(hosts_unreachable_unacknowledged > 0 && host_unreachable_sound!=NULL) sound=host_unreachable_sound; else if(hosts_down_unacknowledged > 0 && host_down_sound!=NULL) sound=host_down_sound; else if(services_critical_unacknowledged > 0 && service_critical_sound!=NULL) sound=service_critical_sound; else if(services_warning_unacknowledged > 0 && service_warning_sound!=NULL) sound=service_warning_sound; else if(services_unknown_unacknowledged==0 && services_warning_unacknowledged==0 && services_critical_unacknowledged==0 && hosts_down_unacknowledged==0 && hosts_unreachable_unacknowledged==0 && normal_sound!=NULL) sound=normal_sound; if(sound!=NULL){ printf(""); printf("",url_media_path,sound); printf(""); printf(""); printf(""); } /**** display main tac screen ****/ display_tac_overview(); document_footer(); /* free memory allocated to the host outage list */ free_hostoutage_list(); /* free allocated memory */ free_memory(); return OK; } void document_header(int use_stylesheet){ char date_time[MAX_DATETIME_LENGTH]; time_t current_time; time_t expire_time; printf("Cache-Control: no-store\r\n"); printf("Pragma: no-cache\r\n"); printf("Refresh: %d\r\n",refresh_rate); time(¤t_time); get_time_string(¤t_time,date_time,(int)sizeof(date_time),HTTP_DATE_TIME); printf("Last-Modified: %s\r\n",date_time); expire_time=(time_t)0L; get_time_string(&expire_time,date_time,(int)sizeof(date_time),HTTP_DATE_TIME); printf("Expires: %s\r\n",date_time); printf("Content-type: text/html\r\n\r\n"); if(embedded==TRUE) return; printf("\n"); printf("\n"); printf("\n"); printf("Nagios Tactical Monitoring Overview\n"); printf("\n"); if(use_stylesheet==TRUE){ printf("\n",url_stylesheets_path,COMMON_CSS); printf("\n",url_stylesheets_path,TAC_CSS); } printf("\n"); printf("\n"); /* include user SSI header */ include_ssi_files(TAC_CGI,SSI_HEADER); return; } void document_footer(void){ if(embedded==TRUE) return; /* include user SSI footer */ include_ssi_files(TAC_CGI,SSI_FOOTER); printf("\n"); printf("\n"); return; } int process_cgivars(void){ char **variables; int error=FALSE; int x; variables=getcgivars(); for(x=0;variables[x]!=NULL;x++){ /* do some basic length checking on the variable identifier to prevent buffer overflows */ if(strlen(variables[x])>=MAX_INPUT_BUFFER-1){ continue; } /* we found the embed option */ else if(!strcmp(variables[x],"embedded")) embedded=TRUE; /* we found the noheader option */ else if(!strcmp(variables[x],"noheader")) display_header=FALSE; /* we received an invalid argument */ else error=TRUE; } /* free memory allocated to the CGI variables */ free_cgivars(variables); return error; } void analyze_status_data(void){ servicestatus *temp_servicestatus; service *temp_service; hoststatus *temp_hoststatus; host *temp_host; int problem=TRUE; /* check all services */ for(temp_servicestatus=servicestatus_list;temp_servicestatus!=NULL;temp_servicestatus=temp_servicestatus->next){ /* see if user is authorized to view this service */ temp_service=find_service(temp_servicestatus->host_name,temp_servicestatus->description); if(is_authorized_for_service(temp_service,¤t_authdata)==FALSE) continue; /******** CHECK FEATURES *******/ /* check flapping */ if(temp_servicestatus->flap_detection_enabled==FALSE) flap_disabled_services++; else if(temp_servicestatus->is_flapping==TRUE) flapping_services++; /* check notifications */ if(temp_servicestatus->notifications_enabled==FALSE) notification_disabled_services++; /* check event handler */ if(temp_servicestatus->event_handler_enabled==FALSE) event_handler_disabled_services++; /* active check execution */ if(temp_servicestatus->checks_enabled==FALSE) active_checks_disabled_services++; /* passive check acceptance */ if(temp_servicestatus->accept_passive_service_checks==FALSE) passive_checks_disabled_services++; /********* CHECK STATUS ********/ problem=TRUE; if(temp_servicestatus->status==SERVICE_OK){ if(temp_servicestatus->checks_enabled==FALSE) services_ok_disabled++; else services_ok_unacknowledged++; services_ok++; } else if(temp_servicestatus->status==SERVICE_WARNING){ temp_hoststatus=find_hoststatus(temp_servicestatus->host_name); if(temp_hoststatus!=NULL && (temp_hoststatus->status==HOST_DOWN || temp_hoststatus->status==HOST_UNREACHABLE)){ services_warning_host_problem++; problem=FALSE; } if(temp_servicestatus->scheduled_downtime_depth>0){ services_warning_scheduled++; problem=FALSE; } if(temp_servicestatus->problem_has_been_acknowledged==TRUE){ services_warning_acknowledged++; problem=FALSE; } if(temp_servicestatus->checks_enabled==FALSE){ services_warning_disabled++; problem=FALSE; } if(problem==TRUE) services_warning_unacknowledged++; services_warning++; } else if(temp_servicestatus->status==SERVICE_UNKNOWN){ temp_hoststatus=find_hoststatus(temp_servicestatus->host_name); if(temp_hoststatus!=NULL && (temp_hoststatus->status==HOST_DOWN || temp_hoststatus->status==HOST_UNREACHABLE)){ services_unknown_host_problem++; problem=FALSE; } if(temp_servicestatus->scheduled_downtime_depth>0){ services_unknown_scheduled++; problem=FALSE; } if(temp_servicestatus->problem_has_been_acknowledged==TRUE){ services_unknown_acknowledged++; problem=FALSE; } if(temp_servicestatus->checks_enabled==FALSE){ services_unknown_disabled++; problem=FALSE; } if(problem==TRUE) services_unknown_unacknowledged++; services_unknown++; } else if(temp_servicestatus->status==SERVICE_CRITICAL){ temp_hoststatus=find_hoststatus(temp_servicestatus->host_name); if(temp_hoststatus!=NULL && (temp_hoststatus->status==HOST_DOWN || temp_hoststatus->status==HOST_UNREACHABLE)){ services_critical_host_problem++; problem=FALSE; } if(temp_servicestatus->scheduled_downtime_depth>0){ services_critical_scheduled++; problem=FALSE; } if(temp_servicestatus->problem_has_been_acknowledged==TRUE){ services_critical_acknowledged++; problem=FALSE; } if(temp_servicestatus->checks_enabled==FALSE){ services_critical_disabled++; problem=FALSE; } if(problem==TRUE) services_critical_unacknowledged++; services_critical++; } else if(temp_servicestatus->status==SERVICE_PENDING){ if(temp_servicestatus->checks_enabled==FALSE) services_pending_disabled++; services_pending++; } /* get health stats */ if(temp_servicestatus->status==SERVICE_OK) total_service_health+=2; else if(temp_servicestatus->status==SERVICE_WARNING || temp_servicestatus->status==SERVICE_UNKNOWN) total_service_health++; if(temp_servicestatus->status!=SERVICE_PENDING) potential_service_health+=2; /* calculate execution time and latency stats */ if(temp_servicestatus->check_type==SERVICE_CHECK_ACTIVE){ total_active_service_checks++; if(min_service_latency==-1.0 || temp_servicestatus->latencylatency; if(max_service_latency==-1.0 || temp_servicestatus->latency>max_service_latency) max_service_latency=temp_servicestatus->latency; if(min_service_execution_time==-1.0 || temp_servicestatus->execution_timeexecution_time; if(max_service_execution_time==-1.0 || temp_servicestatus->execution_time>max_service_execution_time) max_service_execution_time=temp_servicestatus->execution_time; total_service_latency+=temp_servicestatus->latency; total_service_execution_time+=temp_servicestatus->execution_time; } else total_passive_service_checks++; total_services++; } /* check all hosts */ for(temp_hoststatus=hoststatus_list;temp_hoststatus!=NULL;temp_hoststatus=temp_hoststatus->next){ /* see if user is authorized to view this host */ temp_host=find_host(temp_hoststatus->host_name); if(is_authorized_for_host(temp_host,¤t_authdata)==FALSE) continue; /******** CHECK FEATURES *******/ /* check flapping */ if(temp_hoststatus->flap_detection_enabled==FALSE) flap_disabled_hosts++; else if(temp_hoststatus->is_flapping==TRUE) flapping_hosts++; /* check notifications */ if(temp_hoststatus->notifications_enabled==FALSE) notification_disabled_hosts++; /* check event handler */ if(temp_hoststatus->event_handler_enabled==FALSE) event_handler_disabled_hosts++; /* active check execution */ if(temp_hoststatus->checks_enabled==FALSE) active_checks_disabled_hosts++; /* passive check acceptance */ if(temp_hoststatus->accept_passive_host_checks==FALSE) passive_checks_disabled_hosts++; /********* CHECK STATUS ********/ problem=TRUE; if(temp_hoststatus->status==HOST_UP){ if(temp_hoststatus->checks_enabled==FALSE) hosts_up_disabled++; else hosts_up_unacknowledged++; hosts_up++; } else if(temp_hoststatus->status==HOST_DOWN){ if(temp_hoststatus->scheduled_downtime_depth>0){ hosts_down_scheduled++; problem=FALSE; } if(temp_hoststatus->problem_has_been_acknowledged==TRUE){ hosts_down_acknowledged++; problem=FALSE; } if(temp_hoststatus->checks_enabled==FALSE){ hosts_down_disabled++; problem=FALSE; } if(problem==TRUE) hosts_down_unacknowledged++; hosts_down++; } else if(temp_hoststatus->status==HOST_UNREACHABLE){ if(temp_hoststatus->scheduled_downtime_depth>0){ hosts_unreachable_scheduled++; problem=FALSE; } if(temp_hoststatus->problem_has_been_acknowledged==TRUE){ hosts_unreachable_acknowledged++; problem=FALSE; } if(temp_hoststatus->checks_enabled==FALSE){ hosts_unreachable_disabled++; problem=FALSE; } if(problem==TRUE) hosts_unreachable_unacknowledged++; hosts_unreachable++; } else if(temp_hoststatus->status==HOST_PENDING){ if(temp_hoststatus->checks_enabled==FALSE) hosts_pending_disabled++; hosts_pending++; } /* get health stats */ if(temp_hoststatus->status==HOST_UP) total_host_health++; if(temp_hoststatus->status!=HOST_PENDING) potential_host_health++; /* check type stats */ if(temp_hoststatus->check_type==HOST_CHECK_ACTIVE){ total_active_host_checks++; if(min_host_latency==-1.0 || temp_hoststatus->latencylatency; if(max_host_latency==-1.0 || temp_hoststatus->latency>max_host_latency) max_host_latency=temp_hoststatus->latency; if(min_host_execution_time==-1.0 || temp_hoststatus->execution_timeexecution_time; if(max_host_execution_time==-1.0 || temp_hoststatus->execution_time>max_host_execution_time) max_host_execution_time=temp_hoststatus->execution_time; total_host_latency+=temp_hoststatus->latency; total_host_execution_time+=temp_hoststatus->execution_time; } else total_passive_host_checks++; total_hosts++; } /* calculate service health */ if(potential_service_health==0) percent_service_health=0.0; else percent_service_health=((double)total_service_health/(double)potential_service_health)*100.0; /* calculate host health */ if(potential_host_health==0) percent_host_health=0.0; else percent_host_health=((double)total_host_health/(double)potential_host_health)*100.0; /* calculate service latency */ if(total_service_latency==0L) average_service_latency=0.0; else average_service_latency=((double)total_service_latency/(double)total_active_service_checks); /* calculate host latency */ if(total_host_latency==0L) average_host_latency=0.0; else average_host_latency=((double)total_host_latency/(double)total_active_host_checks); /* calculate service execution time */ if(total_service_execution_time==0.0) average_service_execution_time=0.0; else average_service_execution_time=((double)total_service_execution_time/(double)total_active_service_checks); /* calculate host execution time */ if(total_host_execution_time==0.0) average_host_execution_time=0.0; else average_host_execution_time=((double)total_host_execution_time/(double)total_active_host_checks); return; } /* determine what hosts are causing network outages */ void find_hosts_causing_outages(void){ hoststatus *temp_hoststatus; hostoutage *temp_hostoutage; host *temp_host; /* user must be authorized for all hosts in order to see outages */ if(is_authorized_for_all_hosts(¤t_authdata)==FALSE) return; /* check all hosts */ for(temp_hoststatus=hoststatus_list;temp_hoststatus!=NULL;temp_hoststatus=temp_hoststatus->next){ /* check only hosts that are not up and not pending */ if(temp_hoststatus->status!=HOST_UP && temp_hoststatus->status!=HOST_PENDING){ /* find the host entry */ temp_host=find_host(temp_hoststatus->host_name); if(temp_host==NULL) continue; /* if the route to this host is not blocked, it is a causing an outage */ if(is_route_to_host_blocked(temp_host)==FALSE) add_hostoutage(temp_host); } } /* check all hosts that are causing problems and calculate the extent of the problem */ for(temp_hostoutage=hostoutage_list;temp_hostoutage!=NULL;temp_hostoutage=temp_hostoutage->next){ /* calculate the outage effect of this particular hosts */ calculate_outage_effect_of_host(temp_hostoutage->hst,&temp_hostoutage->affected_child_hosts); if(temp_hostoutage->affected_child_hosts>1) total_blocking_outages++; else total_nonblocking_outages++; } return; } /* adds a host outage entry */ void add_hostoutage(host *hst){ hostoutage *new_hostoutage; /* allocate memory for a new structure */ new_hostoutage=(hostoutage *)malloc(sizeof(hostoutage)); if(new_hostoutage==NULL) return; new_hostoutage->hst=hst; new_hostoutage->affected_child_hosts=0; /* add the structure to the head of the list in memory */ new_hostoutage->next=hostoutage_list; hostoutage_list=new_hostoutage; return; } /* frees all memory allocated to the host outage list */ void free_hostoutage_list(void){ hostoutage *this_hostoutage; hostoutage *next_hostoutage; for(this_hostoutage=hostoutage_list;this_hostoutage!=NULL;this_hostoutage=next_hostoutage){ next_hostoutage=this_hostoutage->next; free(this_hostoutage); } return; } /* calculates network outage effect of a particular host being down or unreachable */ void calculate_outage_effect_of_host(host *hst, int *affected_hosts){ int total_child_hosts_affected=0; int temp_child_hosts_affected=0; host *temp_host; /* find all child hosts of this host */ for(temp_host=host_list;temp_host!=NULL;temp_host=temp_host->next){ /* skip this host if it is not a child */ if(is_host_immediate_child_of_host(hst,temp_host)==FALSE) continue; /* calculate the outage effect of the child */ calculate_outage_effect_of_host(temp_host,&temp_child_hosts_affected); /* keep a running total of outage effects */ total_child_hosts_affected+=temp_child_hosts_affected; } *affected_hosts=total_child_hosts_affected+1; return; } /* tests whether or not a host is "blocked" by upstream parents (host is already assumed to be down or unreachable) */ int is_route_to_host_blocked(host *hst){ hostsmember *temp_hostsmember; hoststatus *temp_hoststatus; /* if the host has no parents, it is not being blocked by anyone */ if(hst->parent_hosts==NULL) return FALSE; /* check all parent hosts */ for(temp_hostsmember=hst->parent_hosts;temp_hostsmember!=NULL;temp_hostsmember=temp_hostsmember->next){ /* find the parent host's status */ temp_hoststatus=find_hoststatus(temp_hostsmember->host_name); if(temp_hoststatus==NULL) continue; /* at least one parent it up (or pending), so this host is not blocked */ if(temp_hoststatus->status==HOST_UP || temp_hoststatus->status==HOST_PENDING) return FALSE; } return TRUE; } void display_tac_overview(void){ char host_health_image[16]; char service_health_image[16]; printf("

    \n"); printf("\n"); printf("\n"); /* left column */ printf("\n"); /* right column */ printf("\n"); printf("\n"); printf("
    \n"); display_info_table("Tactical Monitoring Overview",TRUE,¤t_authdata); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("
    \n"); /* display context-sensitive help */ display_context_help(CONTEXTHELP_TAC); printf("\n"); printf("\n"); printf("\n"); printf("\n",EXTINFO_CGI,DISPLAY_PERFORMANCE); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("
     Monitoring Performance
    \n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("
    \n"); printf("\n"); printf("\n"); printf("",EXTINFO_CGI,DISPLAY_PERFORMANCE); printf("\n",EXTINFO_CGI,DISPLAY_PERFORMANCE,min_service_execution_time,max_service_execution_time,average_service_execution_time); printf("\n"); printf("\n"); printf("",EXTINFO_CGI,DISPLAY_PERFORMANCE); printf("\n",EXTINFO_CGI,DISPLAY_PERFORMANCE,min_service_latency,max_service_latency,average_service_latency); printf("\n"); printf("\n"); printf("",EXTINFO_CGI,DISPLAY_PERFORMANCE); printf("\n",EXTINFO_CGI,DISPLAY_PERFORMANCE,min_host_execution_time,max_host_execution_time,average_host_execution_time); printf("\n"); printf("\n"); printf("",EXTINFO_CGI,DISPLAY_PERFORMANCE); printf("\n",EXTINFO_CGI,DISPLAY_PERFORMANCE,min_host_latency,max_host_latency,average_host_latency); printf("\n"); printf("\n"); printf("",STATUS_CGI,SERVICE_ACTIVE_CHECK); printf("\n",STATUS_CGI,HOST_ACTIVE_CHECK,total_active_host_checks,STATUS_CGI,SERVICE_ACTIVE_CHECK,total_active_service_checks); printf("\n"); printf("\n"); printf("",STATUS_CGI,SERVICE_PASSIVE_CHECK); printf("\n",STATUS_CGI,HOST_PASSIVE_CHECK,total_passive_host_checks,STATUS_CGI,SERVICE_PASSIVE_CHECK,total_passive_service_checks); printf("\n"); printf("
    Service Check Execution Time:%.2f / %.2f / %.3f sec
    Service Check Latency:%.2f / %.2f / %.3f sec
    Host Check Execution Time:%.2f / %.2f / %.3f sec
    Host Check Latency:%.2f / %.2f / %2.3f sec
    # Active Host / Service Checks:%d / %d
    # Passive Host / Service Checks:%d / %d
    \n"); printf("
    \n"); printf("
    \n"); printf("
    \n"); printf("
    \n"); printf("

    \n"); printf("
    \n"); printf("
    \n"); printf("\n"); printf("\n"); printf("\n"); /* right column */ printf("\n"); printf("\n"); printf("\n"); printf("
    \n"); /******* OUTAGES ********/ printf("

    \n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("
     Network Outages
    ",OUTAGES_CGI); if(is_authorized_for_all_hosts(¤t_authdata)==FALSE) printf("N/A"); else printf("%d Outages",total_blocking_outages); printf("
    \n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("
        \n"); printf("\n"); if(total_blocking_outages>0) printf("\n",OUTAGES_CGI,total_blocking_outages); /* if(total_nonblocking_outages>0) printf("\n",OUTAGES_CGI,total_nonblocking_outages); */ printf("
    %d Blocking Outages
    %d Nonblocking Outages
    \n"); printf("
    \n"); printf("
    \n"); printf("

    \n"); printf("
    \n"); if(percent_host_health\n"); printf("
    \n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("
     Network Health
    \n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("
    \n"); printf("\n"); printf("\n"); printf(""); printf("\n",url_images_path,host_health_image,(percent_host_health<5.0)?5:(int)percent_host_health,percent_host_health,percent_host_health); printf("\n"); printf("\n"); printf(""); printf("\n",url_images_path,service_health_image,(percent_service_health<5.0)?5:(int)percent_service_health,percent_service_health,percent_service_health); printf("\n"); printf("
    Host Health:%2.1f%% Health
    Service Health:%2.1f%% Health
    \n"); printf("
    \n"); printf("
    \n"); printf("
    \n"); printf("\n"); printf("\n"); printf("\n"); /******* HOSTS ********/ printf("

    \n"); printf("\n"); printf("\n"); printf("\n"); printf("\n",STATUS_CGI,HOST_DOWN,hosts_down); printf("\n",STATUS_CGI,HOST_UNREACHABLE,hosts_unreachable); printf("\n",STATUS_CGI,HOST_UP,hosts_up); printf("\n",STATUS_CGI,HOST_PENDING,hosts_pending); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("
     Hosts
    %d Down%d Unreachable%d Up%d Pending
    \n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("
        \n"); printf("\n"); if(hosts_down_unacknowledged>0) printf("\n",STATUS_CGI,HOST_DOWN,HOST_NO_SCHEDULED_DOWNTIME|HOST_STATE_UNACKNOWLEDGED|HOST_CHECKS_ENABLED,hosts_down_unacknowledged); if(hosts_down_scheduled>0) printf("\n",STATUS_CGI,HOST_DOWN,HOST_SCHEDULED_DOWNTIME,hosts_down_scheduled); if(hosts_down_acknowledged>0) printf("\n",STATUS_CGI,HOST_DOWN,HOST_STATE_ACKNOWLEDGED,hosts_down_acknowledged); if(hosts_down_disabled>0) printf("\n",STATUS_CGI,HOST_DOWN,HOST_CHECKS_DISABLED,hosts_down_disabled); printf("
    %d Unhandled Problems
    %d Scheduled
    %d Acknowledged
    %d Disabled
    \n"); printf("
    \n"); printf("
    \n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("
      \n"); printf("\n"); if(hosts_unreachable_unacknowledged>0) printf("\n",STATUS_CGI,HOST_UNREACHABLE,HOST_NO_SCHEDULED_DOWNTIME|HOST_STATE_UNACKNOWLEDGED|HOST_CHECKS_ENABLED,hosts_unreachable_unacknowledged); if(hosts_unreachable_scheduled>0) printf("\n",STATUS_CGI,HOST_UNREACHABLE,HOST_SCHEDULED_DOWNTIME,hosts_unreachable_scheduled); if(hosts_unreachable_acknowledged>0) printf("\n",STATUS_CGI,HOST_UNREACHABLE,HOST_STATE_ACKNOWLEDGED,hosts_unreachable_acknowledged); if(hosts_unreachable_disabled>0) printf("\n",STATUS_CGI,HOST_UNREACHABLE,HOST_CHECKS_DISABLED,hosts_unreachable_disabled); printf("
    %d Unhandled Problems
    %d Scheduled
    %d Acknowledged
    %d Disabled
    \n"); printf("
    \n"); printf("
    \n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("
      \n"); printf("\n"); if(hosts_up_disabled>0) printf("\n",STATUS_CGI,HOST_UP,HOST_CHECKS_DISABLED,hosts_up_disabled); printf("
    %d Disabled
    \n"); printf("
    \n"); printf("
    \n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("
      \n"); printf("\n"); if(hosts_pending_disabled>0) printf("\n",STATUS_CGI,HOST_PENDING,HOST_CHECKS_DISABLED,hosts_pending_disabled); printf("
    %d Disabled
    \n"); printf("
    \n"); printf("
    \n"); /* printf("\n"); printf("\n"); */ printf("

    \n"); /*printf("
    \n");*/ /******* SERVICES ********/ printf("

    \n"); printf("\n"); printf("\n"); printf("\n"); printf("\n",STATUS_CGI,SERVICE_CRITICAL,services_critical); printf("\n",STATUS_CGI,SERVICE_WARNING,services_warning); printf("\n",STATUS_CGI,SERVICE_UNKNOWN,services_unknown); printf("\n",STATUS_CGI,SERVICE_OK,services_ok); printf("\n",STATUS_CGI,SERVICE_PENDING,services_pending); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("
     Services
    %d Critical%d Warning%d Unknown%d Ok%d Pending
    \n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("
        \n"); printf("\n"); if(services_critical_unacknowledged>0) printf("\n",STATUS_CGI,SERVICE_CRITICAL,HOST_UP|HOST_PENDING,SERVICE_NO_SCHEDULED_DOWNTIME|SERVICE_STATE_UNACKNOWLEDGED|SERVICE_CHECKS_ENABLED,services_critical_unacknowledged); if(services_critical_host_problem>0) printf("\n",STATUS_CGI,SERVICE_CRITICAL,HOST_DOWN|HOST_UNREACHABLE,services_critical_host_problem); if(services_critical_scheduled>0) printf("\n",STATUS_CGI,SERVICE_CRITICAL,SERVICE_SCHEDULED_DOWNTIME,services_critical_scheduled); if(services_critical_acknowledged>0) printf("\n",STATUS_CGI,SERVICE_CRITICAL,SERVICE_STATE_ACKNOWLEDGED,services_critical_acknowledged); if(services_critical_disabled>0) printf("\n",STATUS_CGI,SERVICE_CRITICAL,SERVICE_CHECKS_DISABLED,services_critical_disabled); printf("
    %d Unhandled Problems
    %d on Problem Hosts
    %d Scheduled
    %d Acknowledged
    %d Disabled
    \n"); printf("
    \n"); printf("
    \n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("
      \n"); printf("\n"); if(services_warning_unacknowledged>0) printf("\n",STATUS_CGI,SERVICE_WARNING,HOST_UP|HOST_PENDING,SERVICE_NO_SCHEDULED_DOWNTIME|SERVICE_STATE_UNACKNOWLEDGED|SERVICE_CHECKS_ENABLED,services_warning_unacknowledged); if(services_warning_host_problem>0) printf("\n",STATUS_CGI,SERVICE_WARNING,HOST_DOWN|HOST_UNREACHABLE,services_warning_host_problem); if(services_warning_scheduled>0) printf("\n",STATUS_CGI,SERVICE_WARNING,SERVICE_SCHEDULED_DOWNTIME,services_warning_scheduled); if(services_warning_acknowledged>0) printf("\n",STATUS_CGI,SERVICE_WARNING,SERVICE_STATE_ACKNOWLEDGED,services_warning_acknowledged); if(services_warning_disabled>0) printf("\n",STATUS_CGI,SERVICE_WARNING,SERVICE_CHECKS_DISABLED,services_warning_disabled); printf("
    %d Unhandled Problems
    %d on Problem Hosts
    %d Scheduled
    %d Acknowledged
    %d Disabled
    \n"); printf("
    \n"); printf("
    \n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("
      \n"); printf("\n"); if(services_unknown_unacknowledged>0) printf("\n",STATUS_CGI,SERVICE_UNKNOWN,HOST_UP|HOST_PENDING,SERVICE_NO_SCHEDULED_DOWNTIME|SERVICE_STATE_UNACKNOWLEDGED|SERVICE_CHECKS_ENABLED,services_unknown_unacknowledged); if(services_unknown_host_problem>0) printf("\n",STATUS_CGI,SERVICE_UNKNOWN,HOST_DOWN|HOST_UNREACHABLE,services_unknown_host_problem); if(services_unknown_scheduled>0) printf("\n",STATUS_CGI,SERVICE_UNKNOWN,SERVICE_SCHEDULED_DOWNTIME,services_unknown_scheduled); if(services_unknown_acknowledged>0) printf("\n",STATUS_CGI,SERVICE_UNKNOWN,SERVICE_STATE_ACKNOWLEDGED,services_unknown_acknowledged); if(services_unknown_disabled>0) printf("\n",STATUS_CGI,SERVICE_UNKNOWN,SERVICE_CHECKS_DISABLED,services_unknown_disabled); printf("
    %d Unhandled Problems
    %d on Problem Hosts
    %d Scheduled
    %d Acknowledged
    %d Disabled
    \n"); printf("
    \n"); printf("
    \n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("
      \n"); printf("\n"); if(services_ok_disabled>0) printf("\n",STATUS_CGI,SERVICE_OK,SERVICE_CHECKS_DISABLED,services_ok_disabled); printf("
    %d Disabled
    \n"); printf("
    \n"); printf("
    \n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("
      \n"); printf("\n"); if(services_pending_disabled>0) printf("\n",STATUS_CGI,SERVICE_PENDING,SERVICE_CHECKS_DISABLED,services_pending_disabled); printf("
    %d Disabled
    \n"); printf("
    \n"); printf("
    \n"); printf("

    \n"); /*printf("
    \n");*/ /******* MONITORING FEATURES ********/ printf("

    \n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("
     Monitoring Features
    Flap DetectionNotificationsEvent HandlersActive ChecksPassive Checks
    \n"); printf("\n"); printf("\n"); printf("\n",COMMAND_CGI,(enable_flap_detection==TRUE)?CMD_DISABLE_FLAP_DETECTION:CMD_ENABLE_FLAP_DETECTION,url_images_path,(enable_flap_detection==TRUE)?TAC_ENABLED_ICON:TAC_DISABLED_ICON,(enable_flap_detection==TRUE)?"Enabled":"Disabled",(enable_flap_detection==TRUE)?"Enabled":"Disabled"); printf("\n"); if(enable_flap_detection==TRUE){ printf("\n"); } else printf("\n"); printf("\n"); printf("
    Flap Detection %s \n"); printf("\n"); if(flap_disabled_services>0) printf("\n",STATUS_CGI,SERVICE_FLAP_DETECTION_DISABLED,flap_disabled_services,(flap_disabled_services==1)?"":"s"); else printf("\n"); if(flapping_services>0) printf("\n",STATUS_CGI,SERVICE_IS_FLAPPING,flapping_services,(flapping_services==1)?"":"s"); else printf("\n"); if(flap_disabled_hosts>0) printf("\n",STATUS_CGI,HOST_FLAP_DETECTION_DISABLED,flap_disabled_hosts,(flap_disabled_hosts==1)?"":"s"); else printf("\n"); if(flapping_hosts>0) printf("\n",STATUS_CGI,HOST_IS_FLAPPING,flapping_hosts,(flapping_hosts==1)?"":"s"); else printf("\n"); printf("
    %d Service%s Disabled
    All Services Enabled
    %d Service%s Flapping
    No Services Flapping
    %d Host%s Disabled
    All Hosts Enabled
    %d Host%s Flapping
    No Hosts Flapping
    \n"); printf("
    N/A
    \n"); printf("
    \n"); printf("\n"); printf("\n"); printf("\n",COMMAND_CGI,(enable_notifications==TRUE)?CMD_DISABLE_NOTIFICATIONS:CMD_ENABLE_NOTIFICATIONS,url_images_path,(enable_notifications==TRUE)?TAC_ENABLED_ICON:TAC_DISABLED_ICON,(enable_notifications==TRUE)?"Enabled":"Disabled",(enable_notifications==TRUE)?"Enabled":"Disabled"); printf("\n"); if(enable_notifications==TRUE){ printf("\n"); } else printf("\n"); printf("\n"); printf("
    Notifications %s \n"); printf("\n"); if(notification_disabled_services>0) printf("\n",STATUS_CGI,SERVICE_NOTIFICATIONS_DISABLED,notification_disabled_services,(notification_disabled_services==1)?"":"s"); else printf("\n"); if(notification_disabled_hosts>0) printf("\n",STATUS_CGI,HOST_NOTIFICATIONS_DISABLED,notification_disabled_hosts,(notification_disabled_hosts==1)?"":"s"); else printf("\n"); printf("
    %d Service%s Disabled
    All Services Enabled
    %d Host%s Disabled
    All Hosts Enabled
    \n"); printf("
    N/A
    \n"); printf("
    \n"); printf("\n"); printf("\n"); printf("\n",COMMAND_CGI,(enable_event_handlers==TRUE)?CMD_DISABLE_EVENT_HANDLERS:CMD_ENABLE_EVENT_HANDLERS,url_images_path,(enable_event_handlers==TRUE)?TAC_ENABLED_ICON:TAC_DISABLED_ICON,(enable_event_handlers==TRUE)?"Enabled":"Disabled",(enable_event_handlers==TRUE)?"Enabled":"Disabled"); printf("\n"); if(enable_event_handlers==TRUE){ printf("\n"); } else printf("\n"); printf("\n"); printf("
    Event Handlers %s \n"); printf("\n"); if(event_handler_disabled_services>0) printf("\n",STATUS_CGI,SERVICE_EVENT_HANDLER_DISABLED,event_handler_disabled_services,(event_handler_disabled_services==1)?"":"s"); else printf("\n"); if(event_handler_disabled_hosts>0) printf("\n",STATUS_CGI,HOST_EVENT_HANDLER_DISABLED,event_handler_disabled_hosts,(event_handler_disabled_hosts==1)?"":"s"); else printf("\n"); printf("
    %d Service%s Disabled
    All Services Enabled
    %d Host%s Disabled
    All Hosts Enabled
    \n"); printf("
    N/A
    \n"); printf("
    \n"); printf("\n"); printf("\n"); printf("\n",EXTINFO_CGI,DISPLAY_PROCESS_INFO,url_images_path,(execute_service_checks==TRUE)?TAC_ENABLED_ICON:TAC_DISABLED_ICON,(execute_service_checks==TRUE)?"Enabled":"Disabled",(execute_service_checks==TRUE)?"Enabled":"Disabled"); printf("\n"); if(execute_service_checks==TRUE){ printf("\n"); } else printf("\n"); printf("\n"); printf("
    Active Checks %s \n"); printf("\n"); if(active_checks_disabled_services>0) printf("\n",STATUS_CGI,SERVICE_CHECKS_DISABLED,active_checks_disabled_services,(active_checks_disabled_services==1)?"":"s"); else printf("\n"); if(active_checks_disabled_hosts>0) printf("\n",STATUS_CGI,HOST_CHECKS_DISABLED,active_checks_disabled_hosts,(active_checks_disabled_hosts==1)?"":"s"); else printf("\n"); printf("
    %d Service%s Disabled
    All Services Enabled
    %d Host%s Disabled
    All Hosts Enabled
    \n"); printf("
    N/A
    \n"); printf("
    \n"); printf("\n"); printf("\n"); printf("\n",EXTINFO_CGI,DISPLAY_PROCESS_INFO,url_images_path,(accept_passive_service_checks==TRUE)?TAC_ENABLED_ICON:TAC_DISABLED_ICON,(accept_passive_service_checks==TRUE)?"Enabled":"Disabled",(accept_passive_service_checks==TRUE)?"Enabled":"Disabled"); printf("\n"); if(accept_passive_service_checks==TRUE){ printf("\n"); } else printf("\n"); printf("\n"); printf("
    Passive Checks %s \n"); printf("\n"); if(passive_checks_disabled_services>0) printf("\n",STATUS_CGI,SERVICE_PASSIVE_CHECKS_DISABLED,passive_checks_disabled_services,(passive_checks_disabled_services==1)?"":"s"); else printf("\n"); if(passive_checks_disabled_hosts>0) printf("\n",STATUS_CGI,HOST_PASSIVE_CHECKS_DISABLED,passive_checks_disabled_hosts,(passive_checks_disabled_hosts==1)?"":"s"); else printf("\n"); printf("
    %d Service%s Disabled
    All Services Enabled
    %d Host%s Disabled
    All Hosts Enabled
    \n"); printf("
    N/A
    \n"); printf("
    \n"); printf("

    \n"); return; } nagios-2.6/cgi/trends.c0000664000076500007650000026527610410070303014412 0ustar nagiosnagios/************************************************************************** * * TRENDS.C - Nagios State Trends CGI * * Copyright (c) 1999-2006 Ethan Galstad (nagios@nagios.org) * Last Modified: 03-21-2006 * * 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. *************************************************************************/ #include "../include/config.h" #include "../include/common.h" #include "../include/objects.h" #include "../include/comments.h" #include "../include/statusdata.h" #include "../include/cgiutils.h" #include "../include/getcgi.h" #include "../include/cgiauth.h" #include /* Boutell's GD library function */ #include /* GD library small font definition */ /*#define DEBUG 1*/ extern char main_config_file[MAX_FILENAME_LENGTH]; extern char url_images_path[MAX_FILENAME_LENGTH]; extern char url_stylesheets_path[MAX_FILENAME_LENGTH]; extern char physical_images_path[MAX_FILENAME_LENGTH]; extern int log_rotation_method; extern host *host_list; extern service *service_list; /* archived state types */ #define AS_CURRENT_STATE -1 /* special case for initial assumed state */ #define AS_NO_DATA 0 #define AS_PROGRAM_END 1 #define AS_PROGRAM_START 2 #define AS_HOST_UP 3 #define AS_HOST_DOWN 4 #define AS_HOST_UNREACHABLE 5 #define AS_SVC_OK 6 #define AS_SVC_UNKNOWN 7 #define AS_SVC_WARNING 8 #define AS_SVC_CRITICAL 9 #define AS_SOFT_STATE 1 #define AS_HARD_STATE 2 /* display types */ #define DISPLAY_HOST_TRENDS 0 #define DISPLAY_SERVICE_TRENDS 1 #define DISPLAY_NO_TRENDS 2 /* input types */ #define GET_INPUT_NONE 0 #define GET_INPUT_TARGET_TYPE 1 #define GET_INPUT_HOST_TARGET 2 #define GET_INPUT_SERVICE_TARGET 3 #define GET_INPUT_OPTIONS 4 /* modes */ #define CREATE_HTML 0 #define CREATE_IMAGE 1 /* standard report times */ #define TIMEPERIOD_CUSTOM 0 #define TIMEPERIOD_TODAY 1 #define TIMEPERIOD_YESTERDAY 2 #define TIMEPERIOD_THISWEEK 3 #define TIMEPERIOD_LASTWEEK 4 #define TIMEPERIOD_THISMONTH 5 #define TIMEPERIOD_LASTMONTH 6 #define TIMEPERIOD_THISQUARTER 7 #define TIMEPERIOD_LASTQUARTER 8 #define TIMEPERIOD_THISYEAR 9 #define TIMEPERIOD_LASTYEAR 10 #define TIMEPERIOD_LAST24HOURS 11 #define TIMEPERIOD_LAST7DAYS 12 #define TIMEPERIOD_LAST31DAYS 13 #define MIN_TIMESTAMP_SPACING 10 #define MAX_ARCHIVE_SPREAD 65 #define MAX_ARCHIVE 65 #define MAX_ARCHIVE_BACKTRACKS 60 authdata current_authdata; typedef struct archived_state_struct{ time_t time_stamp; int entry_type; int processed_state; int state_type; char *state_info; struct archived_state_struct *next; }archived_state; archived_state *as_list=NULL; time_t t1; time_t t2; int start_second=0; int start_minute=0; int start_hour=0; int start_day=1; int start_month=1; int start_year=2000; int end_second=0; int end_minute=0; int end_hour=24; int end_day=1; int end_month=1; int end_year=2000; int display_type=DISPLAY_NO_TRENDS; int mode=CREATE_HTML; int input_type=GET_INPUT_NONE; int timeperiod_type=TIMEPERIOD_LAST24HOURS; int compute_time_from_parts=FALSE; int display_popups=TRUE; int use_map=TRUE; int small_image=FALSE; int embedded=FALSE; int display_header=TRUE; int assume_initial_states=TRUE; int assume_state_retention=TRUE; int assume_states_during_notrunning=TRUE; int include_soft_states=FALSE; char *host_name=""; char *svc_description=""; void graph_all_trend_data(void); void graph_trend_data(int,int,time_t,time_t,time_t,char *); void draw_timestamps(void); void draw_timestamp(int,time_t); void draw_time_breakdowns(void); void draw_horizontal_grid_lines(void); void draw_dashed_line(int,int,int,int,int); int convert_host_state_to_archived_state(int); int convert_service_state_to_archived_state(int); void add_archived_state(int,int,time_t,char *); void free_archived_state_list(void); void read_archived_state_data(void); void scan_log_file_for_archived_state_data(char *); void convert_timeperiod_to_times(int); void compute_report_times(void); void get_time_breakdown_string(unsigned long,unsigned long,char *,char *buffer,int); void document_header(int); void document_footer(void); int process_cgivars(void); void write_popup_code(void); gdImagePtr trends_image=0; int color_white=0; int color_black=0; int color_red=0; int color_darkred=0; int color_green=0; int color_darkgreen=0; int color_yellow=0; int color_orange=0; FILE *image_file=NULL; int image_width=600; int image_height=300; #define HOST_DRAWING_WIDTH 498 #define HOST_DRAWING_HEIGHT 70 #define HOST_DRAWING_X_OFFSET 116 #define HOST_DRAWING_Y_OFFSET 55 #define SVC_DRAWING_WIDTH 498 #define SVC_DRAWING_HEIGHT 90 #define SVC_DRAWING_X_OFFSET 116 #define SVC_DRAWING_Y_OFFSET 55 #define SMALL_HOST_DRAWING_WIDTH 500 #define SMALL_HOST_DRAWING_HEIGHT 20 #define SMALL_HOST_DRAWING_X_OFFSET 0 #define SMALL_HOST_DRAWING_Y_OFFSET 0 #define SMALL_SVC_DRAWING_WIDTH 500 #define SMALL_SVC_DRAWING_HEIGHT 20 #define SMALL_SVC_DRAWING_X_OFFSET 0 #define SMALL_SVC_DRAWING_Y_OFFSET 0 int drawing_width=0; int drawing_height=0; int drawing_x_offset=0; int drawing_y_offset=0; int last_known_state=AS_NO_DATA; int zoom_factor=4; int backtrack_archives=2; int earliest_archive=0; time_t earliest_time; time_t latest_time; int earliest_state=AS_NO_DATA; int latest_state=AS_NO_DATA; int initial_assumed_host_state=AS_NO_DATA; int initial_assumed_service_state=AS_NO_DATA; unsigned long time_up=0L; unsigned long time_down=0L; unsigned long time_unreachable=0L; unsigned long time_ok=0L; unsigned long time_warning=0L; unsigned long time_unknown=0L; unsigned long time_critical=0L; int main(int argc, char **argv){ int result=OK; char temp_buffer[MAX_INPUT_BUFFER]; char image_template[MAX_INPUT_BUFFER]; char start_time[MAX_INPUT_BUFFER]; char end_time[MAX_INPUT_BUFFER]; int string_width; int string_height; char start_timestring[MAX_INPUT_BUFFER]; char end_timestring[MAX_INPUT_BUFFER]; host *temp_host; service *temp_service; int is_authorized=TRUE; int found=FALSE; int days,hours,minutes,seconds; char *first_service=NULL; time_t t3; time_t current_time; struct tm *t; /* reset internal CGI variables */ reset_cgi_vars(); /* read the CGI configuration file */ result=read_cgi_config_file(get_cgi_config_location()); if(result==ERROR){ if(mode==CREATE_HTML){ document_header(FALSE); cgi_config_file_error(get_cgi_config_location()); document_footer(); } return ERROR; } /* read the main configuration file */ result=read_main_config_file(main_config_file); if(result==ERROR){ if(mode==CREATE_HTML){ document_header(FALSE); main_config_file_error(main_config_file); document_footer(); } return ERROR; } /* initialize time period to last 24 hours */ time(¤t_time); t2=current_time; t1=(time_t)(current_time-(60*60*24)); /* default number of backtracked archives */ switch(log_rotation_method){ case LOG_ROTATION_MONTHLY: backtrack_archives=1; break; case LOG_ROTATION_WEEKLY: backtrack_archives=2; break; case LOG_ROTATION_DAILY: backtrack_archives=4; break; case LOG_ROTATION_HOURLY: backtrack_archives=8; break; default: backtrack_archives=2; break; } /* get the arguments passed in the URL */ process_cgivars(); /* get authentication information */ get_authentication_information(¤t_authdata); /* read all object configuration data */ result=read_all_object_configuration_data(main_config_file,READ_ALL_OBJECT_DATA); if(result==ERROR){ if(mode==CREATE_HTML){ document_header(FALSE); object_data_error(); document_footer(); } return ERROR; } /* read all status data */ result=read_all_status_data(get_cgi_config_location(),READ_ALL_STATUS_DATA); if(result==ERROR){ if(mode==CREATE_HTML){ document_header(FALSE); status_data_error(); document_footer(); } return ERROR; } document_header(TRUE); if(compute_time_from_parts==TRUE) compute_report_times(); /* make sure times are sane, otherwise swap them */ if(t2current_time){ t2=current_time; if(t1>t2) t1=t2-(60*60*24); } if(mode==CREATE_HTML && display_header==TRUE){ /* begin top table */ printf("\n"); printf("\n"); /* left column of the first row */ printf("\n"); /* center column of top row */ printf("\n"); /* right hand column of top row */ printf("\n"); /* end of top table */ printf("\n"); printf("
    \n"); if(display_type==DISPLAY_HOST_TRENDS) snprintf(temp_buffer,sizeof(temp_buffer)-1,"Host State Trends"); else if(display_type==DISPLAY_SERVICE_TRENDS) snprintf(temp_buffer,sizeof(temp_buffer)-1,"Service State Trends"); else snprintf(temp_buffer,sizeof(temp_buffer)-1,"Host and Service State Trends"); temp_buffer[sizeof(temp_buffer)-1]='\x0'; display_info_table(temp_buffer,FALSE,¤t_authdata); if(display_type!=DISPLAY_NO_TRENDS && input_type==GET_INPUT_NONE){ printf("\n"); printf("\n"); printf("\n"); } printf("\n"); if(display_type!=DISPLAY_NO_TRENDS && input_type==GET_INPUT_NONE){ printf("
    \n"); if(display_type==DISPLAY_HOST_TRENDS) printf("Host '%s'",host_name); else if(display_type==DISPLAY_SERVICE_TRENDS) printf("Service '%s' On Host '%s'",svc_description,host_name); printf("
    \n"); printf("
    \n"); printf("%s State Trends\n",url_images_path,TRENDS_ICON,(display_type==DISPLAY_HOST_TRENDS)?"Host":"Service",(display_type==DISPLAY_HOST_TRENDS)?"Host":"Service"); printf("
    \n"); get_time_string(&t1,start_timestring,sizeof(start_timestring)-1,SHORT_DATE_TIME); get_time_string(&t2,end_timestring,sizeof(end_timestring)-1,SHORT_DATE_TIME); printf("
    %s to %s
    \n",start_timestring,end_timestring); get_time_breakdown((time_t)(t2-t1),&days,&hours,&minutes,&seconds); printf("
    Duration: %dd %dh %dm %ds
    \n",days,hours,minutes,seconds); } printf("
    \n"); printf("\n"); if(display_type!=DISPLAY_NO_TRENDS && input_type==GET_INPUT_NONE){ printf("\n",TRENDS_CGI); if(display_popups==FALSE) printf("\n"); if(use_map==FALSE) printf("\n"); printf("\n",(unsigned long)t1); printf("\n",(unsigned long)t2); printf("\n",host_name); if(display_type==DISPLAY_SERVICE_TRENDS) printf("\n",svc_description); printf("\n",(assume_initial_states==TRUE)?"yes":"no"); printf("\n",(assume_state_retention==TRUE)?"yes":"no"); printf("\n",(assume_states_during_notrunning==TRUE)?"yes":"no"); printf("\n",(include_soft_states==TRUE)?"yes":"no"); printf("\n",(display_type==DISPLAY_HOST_TRENDS)?"host":"service"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); } /* display context-sensitive help */ printf("\n"); printf("
    First assumed %s state:Backtracked archives:
    "); if(display_type==DISPLAY_HOST_TRENDS){ printf("",initial_assumed_service_state); printf("",initial_assumed_host_state); printf("\n"); printf("\n"); printf("\n",backtrack_archives); printf("
    Report period:Zoom factor:
    \n"); printf("\n"); printf("\n"); printf("\n"); printf("
    \n"); printf("\n"); printf("\n"); printf("
    \n"); if(display_type!=DISPLAY_NO_TRENDS && input_type==GET_INPUT_NONE){ if(display_type==DISPLAY_HOST_TRENDS) display_context_help(CONTEXTHELP_TRENDS_HOST); else display_context_help(CONTEXTHELP_TRENDS_SERVICE); } else if(display_type==DISPLAY_NO_TRENDS || input_type!=GET_INPUT_NONE){ if(input_type==GET_INPUT_NONE) display_context_help(CONTEXTHELP_TRENDS_MENU1); else if(input_type==GET_INPUT_TARGET_TYPE) display_context_help(CONTEXTHELP_TRENDS_MENU1); else if(input_type==GET_INPUT_HOST_TARGET) display_context_help(CONTEXTHELP_TRENDS_MENU2); else if(input_type==GET_INPUT_SERVICE_TARGET) display_context_help(CONTEXTHELP_TRENDS_MENU3); else if(input_type==GET_INPUT_OPTIONS) display_context_help(CONTEXTHELP_TRENDS_MENU4); } printf("
    \n"); printf("
    \n"); } #ifndef DEBUG /* check authorization... */ if(display_type==DISPLAY_HOST_TRENDS){ temp_host=find_host(host_name); if(temp_host==NULL || is_authorized_for_host(temp_host,¤t_authdata)==FALSE) is_authorized=FALSE; } else if(display_type==DISPLAY_SERVICE_TRENDS){ temp_service=find_service(host_name,svc_description); if(temp_service==NULL || is_authorized_for_service(temp_service,¤t_authdata)==FALSE) is_authorized=FALSE; } if(is_authorized==FALSE){ if(mode==CREATE_HTML) printf("

    It appears as though you are not authorized to view information for the specified %s...

    \n",(display_type==DISPLAY_HOST_TRENDS)?"host":"service"); document_footer(); free_memory(); return ERROR; } #endif /* set drawing parameters, etc */ if(small_image==TRUE){ image_height=20; image_width=500; } else{ image_height=300; image_width=600; } if(display_type==DISPLAY_HOST_TRENDS){ if(small_image==TRUE){ drawing_width=SMALL_HOST_DRAWING_WIDTH; drawing_height=SMALL_HOST_DRAWING_HEIGHT; drawing_x_offset=SMALL_HOST_DRAWING_X_OFFSET; drawing_y_offset=SMALL_HOST_DRAWING_Y_OFFSET; } else{ drawing_width=HOST_DRAWING_WIDTH; drawing_height=HOST_DRAWING_HEIGHT; drawing_x_offset=HOST_DRAWING_X_OFFSET; drawing_y_offset=HOST_DRAWING_Y_OFFSET; } } else if(display_type==DISPLAY_SERVICE_TRENDS){ if(small_image==TRUE){ drawing_width=SMALL_SVC_DRAWING_WIDTH; drawing_height=SMALL_SVC_DRAWING_HEIGHT; drawing_x_offset=SMALL_SVC_DRAWING_X_OFFSET; drawing_y_offset=SMALL_SVC_DRAWING_Y_OFFSET; } else{ drawing_width=SVC_DRAWING_WIDTH; drawing_height=SVC_DRAWING_HEIGHT; drawing_x_offset=SVC_DRAWING_X_OFFSET; drawing_y_offset=SVC_DRAWING_Y_OFFSET; } } /* last known state should always be initially set to indeterminate! */ last_known_state=AS_NO_DATA; /* initialize PNG image */ if(display_type!=DISPLAY_NO_TRENDS && mode==CREATE_IMAGE){ if(small_image==TRUE){ trends_image=gdImageCreate(image_width,image_height); if(trends_image==NULL){ #ifdef DEBUG printf("Error: Could not allocate memory for image\n"); #endif return ERROR; } } else{ if(display_type==DISPLAY_HOST_TRENDS) snprintf(image_template,sizeof(image_template)-1,"%s/trendshost.png",physical_images_path); else snprintf(image_template,sizeof(image_template)-1,"%s/trendssvc.png",physical_images_path); image_template[sizeof(image_template)-1]='\x0'; /* allocate buffer for storing image */ trends_image=NULL; image_file=fopen(image_template,"r"); if(image_file!=NULL){ trends_image=gdImageCreateFromPng(image_file); fclose(image_file); } if(trends_image==NULL) trends_image=gdImageCreate(image_width,image_height); if(trends_image==NULL){ #ifdef DEBUG printf("Error: Could not allocate memory for image\n"); #endif return ERROR; } } /* allocate colors used for drawing */ color_white=gdImageColorAllocate(trends_image,255,255,255); color_black=gdImageColorAllocate(trends_image,0,0,0); color_red=gdImageColorAllocate(trends_image,255,0,0); color_darkred=gdImageColorAllocate(trends_image,128,0,0); color_green=gdImageColorAllocate(trends_image,0,210,0); color_darkgreen=gdImageColorAllocate(trends_image,0,128,0); color_yellow=gdImageColorAllocate(trends_image,176,178,20); color_orange=gdImageColorAllocate(trends_image,255,100,25); /* set transparency index */ gdImageColorTransparent(trends_image,color_white); /* make sure the graphic is interlaced */ gdImageInterlace(trends_image,1); if(small_image==FALSE){ /* title */ snprintf(start_time,sizeof(start_time)-1,"%s",ctime(&t1)); start_time[sizeof(start_time)-1]='\x0'; start_time[strlen(start_time)-1]='\x0'; snprintf(end_time,sizeof(end_time)-1,"%s",ctime(&t2)); end_time[sizeof(end_time)-1]='\x0'; end_time[strlen(end_time)-1]='\x0'; string_height=gdFontSmall->h; if(display_type==DISPLAY_HOST_TRENDS) snprintf(temp_buffer,sizeof(temp_buffer)-1,"State History For Host '%s'",host_name); else snprintf(temp_buffer,sizeof(temp_buffer)-1,"State History For Service '%s' On Host '%s'",svc_description,host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; string_width=gdFontSmall->w*strlen(temp_buffer); gdImageString(trends_image,gdFontSmall,(drawing_width/2)-(string_width/2)+drawing_x_offset,string_height,(unsigned char *)temp_buffer,color_black); snprintf(temp_buffer,sizeof(temp_buffer)-1,"%s to %s",start_time,end_time); temp_buffer[sizeof(temp_buffer)-1]='\x0'; string_width=gdFontSmall->w*strlen(temp_buffer); gdImageString(trends_image,gdFontSmall,(drawing_width/2)-(string_width/2)+drawing_x_offset,(string_height*2)+5,(unsigned char *)temp_buffer,color_black); /* first time stamp */ snprintf(temp_buffer,sizeof(temp_buffer)-1,"%s",start_time); temp_buffer[sizeof(temp_buffer)-1]='\x0'; string_width=gdFontSmall->w*strlen(temp_buffer); gdImageStringUp(trends_image,gdFontSmall,drawing_x_offset-(string_height/2),drawing_y_offset+drawing_height+string_width+5,(unsigned char *)temp_buffer,color_black); } } if(display_type!=DISPLAY_NO_TRENDS && input_type==GET_INPUT_NONE){ if(mode==CREATE_IMAGE || (mode==CREATE_HTML && use_map==TRUE)){ /* read in all necessary archived state data */ read_archived_state_data(); /* graph archived state trend data */ graph_all_trend_data(); } /* print URL to image */ if(mode==CREATE_HTML){ printf("

    \n"); printf("
    \n"); printf("\n"); printf("
    \n"); } if(mode==CREATE_IMAGE || (mode==CREATE_HTML && use_map==TRUE)){ /* draw timestamps */ draw_timestamps(); /* draw horizontal lines */ draw_horizontal_grid_lines(); /* draw state time breakdowns */ draw_time_breakdowns(); } if(mode==CREATE_IMAGE){ /* use STDOUT for writing the image data... */ image_file=stdout; #ifndef DEBUG /* write the image to file */ gdImagePng(trends_image,image_file); #endif #ifdef DEBUG image_file=fopen("trends.png","w"); if(image_file==NULL) printf("Could not open trends.png for writing!\n"); else{ gdImagePng(trends_image,image_file); fclose(image_file); } #endif /* free memory allocated to image */ gdImageDestroy(trends_image); } } /* show user a selection of hosts and services to choose from... */ if(display_type==DISPLAY_NO_TRENDS || input_type!=GET_INPUT_NONE){ /* ask the user for what host they want a report for */ if(input_type==GET_INPUT_HOST_TARGET){ printf("

    \n"); printf("
    Step 2: Select Host
    \n"); printf("

    \n"); printf("

    \n"); printf("\n"); printf("\n",TRENDS_CGI); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("
    Host:\n"); printf("\n"); printf("
    \n"); printf("\n"); printf("
    \n"); printf("

    \n"); } /* ask the user for what service they want a report for */ else if(input_type==GET_INPUT_SERVICE_TARGET){ printf("\n"); printf("

    \n"); printf("
    Step 2: Select Service
    \n"); printf("

    \n"); printf("

    \n"); printf("\n"); printf("\n",TRENDS_CGI); printf("\n"); printf("\n",(first_service==NULL)?"unknown":first_service); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("
    Service:\n"); printf("\n"); printf("
    \n"); printf("\n"); printf("
    \n"); printf("

    \n"); } /* ask the user for report range and options */ else if(input_type==GET_INPUT_OPTIONS){ time(¤t_time); t=localtime(¤t_time); start_day=1; start_year=t->tm_year+1900; end_day=t->tm_mday; end_year=t->tm_year+1900; printf("

    \n"); printf("
    Step 3: Select Report Options
    \n"); printf("

    \n"); printf("

    \n"); printf("\n"); printf("\n",TRENDS_CGI); printf("\n",host_name); if(display_type==DISPLAY_SERVICE_TRENDS) printf("\n",svc_description); printf("\n"); printf("\n"); printf("\n"); printf(""); printf("\n"); printf("\n"); printf("\n"); printf(""); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n",(display_type==DISPLAY_HOST_TRENDS)?"Host":"Service"); printf("\n"); printf("\n"); printf("\n"); printf(""); printf("\n"); printf("\n"); printf("\n"); printf("
    Report period:\n"); printf("\n"); printf("
    If Custom Report Period...
    Start Date (Inclusive):"); printf("\n "); printf(" ",start_day); printf("",start_year); printf("\n"); printf("\n"); printf("\n"); printf("
    End Date (Inclusive):"); printf("\n "); printf(" ",end_day); printf("",end_year); printf("\n"); printf("\n"); printf("\n"); printf("

    Assume Initial States:\n"); printf("\n"); printf("
    Assume State Retention:\n"); printf("\n"); printf("
    Assume States During Program Downtime:\n"); printf("\n"); printf("
    Include Soft States:\n"); printf("\n"); printf("
    First Assumed %s State:\n"); if(display_type==DISPLAY_HOST_TRENDS){ printf("\n"); printf("
    Backtracked Archives (To Scan For Initial States):\n"); printf("\n",backtrack_archives); printf("
    Suppress image map:
    Suppress popups:
    \n"); printf("

    \n"); /* printf("

    \n"); printf("Note: Choosing the 'suppress image map' option will make the report run approximately twice as fast as it would otherwise, but it will prevent you from being able to zoom in on specific time periods.\n"); printf("

    \n"); */ } /* as the user whether they want a graph for a host or service */ else{ printf("

    \n"); printf("
    Step 1: Select Report Type
    \n"); printf("

    \n"); printf("

    \n"); printf("\n"); printf("\n",TRENDS_CGI); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("
    Type:\n"); printf("\n"); printf("
    \n"); printf("\n"); printf("
    \n"); printf("

    \n"); } } document_footer(); /* free memory allocated to the archived state data list */ free_archived_state_list(); /* free all other allocated memory */ free_memory(); return OK; } void document_header(int use_stylesheet){ char date_time[MAX_DATETIME_LENGTH]; time_t current_time; time_t expire_time; if(mode==CREATE_HTML){ printf("Cache-Control: no-store\r\n"); printf("Pragma: no-cache\r\n"); time(¤t_time); get_time_string(¤t_time,date_time,sizeof(date_time),HTTP_DATE_TIME); printf("Last-Modified: %s\r\n",date_time); expire_time=(time_t)0; get_time_string(&expire_time,date_time,sizeof(date_time),HTTP_DATE_TIME); printf("Expires: %s\r\n",date_time); printf("Content-type: text/html\r\n\r\n"); if(embedded==TRUE) return; printf("\n"); printf("\n"); printf("\n"); printf("Nagios Trends\n"); printf("\n"); if(use_stylesheet==TRUE){ printf("\n",url_stylesheets_path,COMMON_CSS); printf("\n",url_stylesheets_path,TRENDS_CSS); } /* write JavaScript code for popup window */ if(display_type!=DISPLAY_NO_TRENDS) write_popup_code(); printf("\n"); printf("\n"); /* include user SSI header */ include_ssi_files(TRENDS_CGI,SSI_HEADER); printf("
    \n"); } else{ printf("Cache-Control: no-store\r\n"); printf("Pragma: no-cache\r\n"); time(¤t_time); get_time_string(¤t_time,date_time,sizeof(date_time),HTTP_DATE_TIME); printf("Last-Modified: %s\r\n",date_time); expire_time=(time_t)0L; get_time_string(&expire_time,date_time,sizeof(date_time),HTTP_DATE_TIME); printf("Expires: %s\r\n",date_time); printf("Content-Type: image/png\r\n\r\n"); } return; } void document_footer(void){ if(embedded==TRUE) return; if(mode==CREATE_HTML){ /* include user SSI footer */ include_ssi_files(TRENDS_CGI,SSI_FOOTER); printf("\n"); printf("\n"); } return; } int process_cgivars(void){ char **variables; int error=FALSE; int x; variables=getcgivars(); for(x=0;variables[x]!=NULL;x++){ /* do some basic length checking on the variable identifier to prevent buffer overflows */ if(strlen(variables[x])>=MAX_INPUT_BUFFER-1){ x++; continue; } /* we found the host argument */ else if(!strcmp(variables[x],"host")){ x++; if(variables[x]==NULL){ error=TRUE; break; } host_name=(char *)malloc(strlen(variables[x])+1); if(host_name==NULL) host_name=""; else strcpy(host_name,variables[x]); display_type=DISPLAY_HOST_TRENDS; } /* we found the node width argument */ else if(!strcmp(variables[x],"service")){ x++; if(variables[x]==NULL){ error=TRUE; break; } svc_description=(char *)malloc(strlen(variables[x])+1); if(svc_description==NULL) svc_description=""; else strcpy(svc_description,variables[x]); display_type=DISPLAY_SERVICE_TRENDS; } /* we found first time argument */ else if(!strcmp(variables[x],"t1")){ x++; if(variables[x]==NULL){ error=TRUE; break; } t1=(time_t)strtoul(variables[x],NULL,10); timeperiod_type=TIMEPERIOD_CUSTOM; } /* we found first time argument */ else if(!strcmp(variables[x],"t2")){ x++; if(variables[x]==NULL){ error=TRUE; break; } t2=(time_t)strtoul(variables[x],NULL,10); timeperiod_type=TIMEPERIOD_CUSTOM; } /* we found the image creation option */ else if(!strcmp(variables[x],"createimage")){ mode=CREATE_IMAGE; } /* we found the assume initial states option */ else if(!strcmp(variables[x],"assumeinitialstates")){ x++; if(variables[x]==NULL){ error=TRUE; break; } if(!strcmp(variables[x],"yes")) assume_initial_states=TRUE; else assume_initial_states=FALSE; } /* we found the initial assumed host state option */ else if(!strcmp(variables[x],"initialassumedhoststate")){ x++; if(variables[x]==NULL){ error=TRUE; break; } initial_assumed_host_state=atoi(variables[x]); } /* we found the initial assumed service state option */ else if(!strcmp(variables[x],"initialassumedservicestate")){ x++; if(variables[x]==NULL){ error=TRUE; break; } initial_assumed_service_state=atoi(variables[x]); } /* we found the assume state during program not running option */ else if(!strcmp(variables[x],"assumestatesduringnotrunning")){ x++; if(variables[x]==NULL){ error=TRUE; break; } if(!strcmp(variables[x],"yes")) assume_states_during_notrunning=TRUE; else assume_states_during_notrunning=FALSE; } /* we found the assume state retention option */ else if(!strcmp(variables[x],"assumestateretention")){ x++; if(variables[x]==NULL){ error=TRUE; break; } if(!strcmp(variables[x],"yes")) assume_state_retention=TRUE; else assume_state_retention=FALSE; } /* we found the include soft states option */ else if(!strcmp(variables[x],"includesoftstates")){ x++; if(variables[x]==NULL){ error=TRUE; break; } if(!strcmp(variables[x],"yes")) include_soft_states=TRUE; else include_soft_states=FALSE; } /* we found the zoom factor argument */ else if(!strcmp(variables[x],"zoom")){ x++; if(variables[x]==NULL){ error=TRUE; break; } zoom_factor=atoi(variables[x]); if(zoom_factor==0) zoom_factor=1; } /* we found the backtrack archives argument */ else if(!strcmp(variables[x],"backtrack")){ x++; if(variables[x]==NULL){ error=TRUE; break; } backtrack_archives=atoi(variables[x]); if(backtrack_archives<0) backtrack_archives=0; if(backtrack_archives>MAX_ARCHIVE_BACKTRACKS) backtrack_archives=MAX_ARCHIVE_BACKTRACKS; } /* we found the standard timeperiod argument */ else if(!strcmp(variables[x],"timeperiod")){ x++; if(variables[x]==NULL){ error=TRUE; break; } if(!strcmp(variables[x],"today")) timeperiod_type=TIMEPERIOD_TODAY; else if(!strcmp(variables[x],"yesterday")) timeperiod_type=TIMEPERIOD_YESTERDAY; else if(!strcmp(variables[x],"thisweek")) timeperiod_type=TIMEPERIOD_THISWEEK; else if(!strcmp(variables[x],"lastweek")) timeperiod_type=TIMEPERIOD_LASTWEEK; else if(!strcmp(variables[x],"thismonth")) timeperiod_type=TIMEPERIOD_THISMONTH; else if(!strcmp(variables[x],"lastmonth")) timeperiod_type=TIMEPERIOD_LASTMONTH; else if(!strcmp(variables[x],"thisquarter")) timeperiod_type=TIMEPERIOD_THISQUARTER; else if(!strcmp(variables[x],"lastquarter")) timeperiod_type=TIMEPERIOD_LASTQUARTER; else if(!strcmp(variables[x],"thisyear")) timeperiod_type=TIMEPERIOD_THISYEAR; else if(!strcmp(variables[x],"lastyear")) timeperiod_type=TIMEPERIOD_LASTYEAR; else if(!strcmp(variables[x],"last24hours")) timeperiod_type=TIMEPERIOD_LAST24HOURS; else if(!strcmp(variables[x],"last7days")) timeperiod_type=TIMEPERIOD_LAST7DAYS; else if(!strcmp(variables[x],"last31days")) timeperiod_type=TIMEPERIOD_LAST31DAYS; else if(!strcmp(variables[x],"custom")) timeperiod_type=TIMEPERIOD_CUSTOM; else continue; convert_timeperiod_to_times(timeperiod_type); } /* we found time argument */ else if(!strcmp(variables[x],"smon")){ x++; if(variables[x]==NULL){ error=TRUE; break; } if(timeperiod_type!=TIMEPERIOD_CUSTOM) continue; start_month=atoi(variables[x]); timeperiod_type=TIMEPERIOD_CUSTOM; compute_time_from_parts=TRUE; } /* we found time argument */ else if(!strcmp(variables[x],"sday")){ x++; if(variables[x]==NULL){ error=TRUE; break; } if(timeperiod_type!=TIMEPERIOD_CUSTOM) continue; start_day=atoi(variables[x]); timeperiod_type=TIMEPERIOD_CUSTOM; compute_time_from_parts=TRUE; } /* we found time argument */ else if(!strcmp(variables[x],"syear")){ x++; if(variables[x]==NULL){ error=TRUE; break; } if(timeperiod_type!=TIMEPERIOD_CUSTOM) continue; start_year=atoi(variables[x]); timeperiod_type=TIMEPERIOD_CUSTOM; compute_time_from_parts=TRUE; } /* we found time argument */ else if(!strcmp(variables[x],"smin")){ x++; if(variables[x]==NULL){ error=TRUE; break; } if(timeperiod_type!=TIMEPERIOD_CUSTOM) continue; start_minute=atoi(variables[x]); timeperiod_type=TIMEPERIOD_CUSTOM; compute_time_from_parts=TRUE; } /* we found time argument */ else if(!strcmp(variables[x],"ssec")){ x++; if(variables[x]==NULL){ error=TRUE; break; } if(timeperiod_type!=TIMEPERIOD_CUSTOM) continue; start_second=atoi(variables[x]); timeperiod_type=TIMEPERIOD_CUSTOM; compute_time_from_parts=TRUE; } /* we found time argument */ else if(!strcmp(variables[x],"shour")){ x++; if(variables[x]==NULL){ error=TRUE; break; } if(timeperiod_type!=TIMEPERIOD_CUSTOM) continue; start_hour=atoi(variables[x]); timeperiod_type=TIMEPERIOD_CUSTOM; compute_time_from_parts=TRUE; } /* we found time argument */ else if(!strcmp(variables[x],"emon")){ x++; if(variables[x]==NULL){ error=TRUE; break; } if(timeperiod_type!=TIMEPERIOD_CUSTOM) continue; end_month=atoi(variables[x]); timeperiod_type=TIMEPERIOD_CUSTOM; compute_time_from_parts=TRUE; } /* we found time argument */ else if(!strcmp(variables[x],"eday")){ x++; if(variables[x]==NULL){ error=TRUE; break; } if(timeperiod_type!=TIMEPERIOD_CUSTOM) continue; end_day=atoi(variables[x]); timeperiod_type=TIMEPERIOD_CUSTOM; compute_time_from_parts=TRUE; } /* we found time argument */ else if(!strcmp(variables[x],"eyear")){ x++; if(variables[x]==NULL){ error=TRUE; break; } if(timeperiod_type!=TIMEPERIOD_CUSTOM) continue; end_year=atoi(variables[x]); timeperiod_type=TIMEPERIOD_CUSTOM; compute_time_from_parts=TRUE; } /* we found time argument */ else if(!strcmp(variables[x],"emin")){ x++; if(variables[x]==NULL){ error=TRUE; break; } if(timeperiod_type!=TIMEPERIOD_CUSTOM) continue; end_minute=atoi(variables[x]); timeperiod_type=TIMEPERIOD_CUSTOM; compute_time_from_parts=TRUE; } /* we found time argument */ else if(!strcmp(variables[x],"esec")){ x++; if(variables[x]==NULL){ error=TRUE; break; } if(timeperiod_type!=TIMEPERIOD_CUSTOM) continue; end_second=atoi(variables[x]); timeperiod_type=TIMEPERIOD_CUSTOM; compute_time_from_parts=TRUE; } /* we found time argument */ else if(!strcmp(variables[x],"ehour")){ x++; if(variables[x]==NULL){ error=TRUE; break; } if(timeperiod_type!=TIMEPERIOD_CUSTOM) continue; end_hour=atoi(variables[x]); timeperiod_type=TIMEPERIOD_CUSTOM; compute_time_from_parts=TRUE; } /* we found the embed option */ else if(!strcmp(variables[x],"embedded")) embedded=TRUE; /* we found the noheader option */ else if(!strcmp(variables[x],"noheader")) display_header=FALSE; /* we found the nopopups option */ else if(!strcmp(variables[x],"nopopups")) display_popups=FALSE; /* we found the nomap option */ else if(!strcmp(variables[x],"nomap")){ display_popups=FALSE; use_map=FALSE; } /* we found the input option */ else if(!strcmp(variables[x],"input")){ x++; if(variables[x]==NULL){ error=TRUE; break; } if(!strcmp(variables[x],"gethost")) input_type=GET_INPUT_HOST_TARGET; else if(!strcmp(variables[x],"getservice")) input_type=GET_INPUT_SERVICE_TARGET; else if(!strcmp(variables[x],"getoptions")) input_type=GET_INPUT_OPTIONS; else input_type=GET_INPUT_TARGET_TYPE; } /* we found the small image option */ else if(!strcmp(variables[x],"smallimage")) small_image=TRUE; } /* free memory allocated to the CGI variables */ free_cgivars(variables); return error; } /* top level routine for graphic all trend data */ void graph_all_trend_data(void){ archived_state *temp_as; archived_state *last_as; time_t a; time_t b; time_t current_time; int current_state=AS_NO_DATA; int have_some_real_data=FALSE; hoststatus *hststatus=NULL; servicestatus *svcstatus=NULL; unsigned long wobble=300; int first_real_state=AS_NO_DATA; time_t initial_assumed_time; int initial_assumed_state=AS_SVC_OK; int error=FALSE; time(¤t_time); /* if left hand of graph is after current time, we can't do anything at all.... */ if(t1>current_time) return; /* find current state for host or service */ if(display_type==DISPLAY_HOST_TRENDS) hststatus=find_hoststatus(host_name); else svcstatus=find_servicestatus(host_name,svc_description); /************************************/ /* INSERT CURRENT STATE (IF WE CAN) */ /************************************/ /* if current time DOES NOT fall within graph bounds, so we can't do anything as far as assuming current state */ /* the "wobble" value is necessary because when the CGI is called to do the PNG generation, t2 will actually be less that current_time by a bit */ /* if we don't have any data, assume current state (if possible) */ if(as_list==NULL && current_time>t1 && current_time<(t2+wobble)){ /* we don't have any historical information, but the current time falls within the reporting period, so use */ /* the current status of the host/service as the starting data */ if(display_type==DISPLAY_HOST_TRENDS){ if(hststatus!=NULL){ if(hststatus->status==HOST_DOWN) last_known_state=AS_HOST_DOWN; else if(hststatus->status==HOST_UNREACHABLE) last_known_state=AS_HOST_UNREACHABLE; else last_known_state=AS_HOST_UP; /* add a dummy archived state item, so something can get graphed */ add_archived_state(last_known_state,AS_HARD_STATE,t1,"Current Host State Assumed (Faked Log Entry)"); /* use the current state as the last known real state */ first_real_state=last_known_state; } } else{ if(svcstatus!=NULL){ if(svcstatus->status==SERVICE_OK) last_known_state=AS_SVC_OK; else if(svcstatus->status==SERVICE_WARNING) last_known_state=AS_SVC_WARNING; else if(svcstatus->status==SERVICE_CRITICAL) last_known_state=AS_SVC_CRITICAL; else if(svcstatus->status==SERVICE_UNKNOWN) last_known_state=AS_SVC_UNKNOWN; /* add a dummy archived state item, so something can get graphed */ add_archived_state(last_known_state,AS_HARD_STATE,t1,"Current Service State Assumed (Faked Log Entry)"); /* use the current state as the last known real state */ first_real_state=last_known_state; } } } /******************************************/ /* INSERT FIRST ASSUMED STATE (IF WE CAN) */ /******************************************/ if((display_type==DISPLAY_HOST_TRENDS && initial_assumed_host_state!=AS_NO_DATA) || (display_type==DISPLAY_SERVICE_TRENDS && initial_assumed_service_state!=AS_NO_DATA)){ /* see if its okay to assume initial state for this subject */ error=FALSE; if(display_type==DISPLAY_SERVICE_TRENDS){ if(initial_assumed_service_state!=AS_SVC_OK && initial_assumed_service_state!=AS_SVC_WARNING && initial_assumed_service_state!=AS_SVC_UNKNOWN && initial_assumed_service_state!=AS_SVC_CRITICAL && initial_assumed_service_state!=AS_CURRENT_STATE) error=TRUE; else initial_assumed_state=initial_assumed_service_state; if(initial_assumed_service_state==AS_CURRENT_STATE && svcstatus==NULL) error=TRUE; } else{ if(initial_assumed_host_state!=AS_HOST_UP && initial_assumed_host_state!=AS_HOST_DOWN && initial_assumed_host_state!=AS_HOST_UNREACHABLE && initial_assumed_host_state!=AS_CURRENT_STATE) error=TRUE; else initial_assumed_state=initial_assumed_host_state; if(initial_assumed_host_state==AS_CURRENT_STATE && hststatus==NULL) error=TRUE; } /* get the current state if applicable */ if(((display_type==DISPLAY_HOST_TRENDS && initial_assumed_host_state==AS_CURRENT_STATE) || (display_type==DISPLAY_SERVICE_TRENDS && initial_assumed_service_state==AS_CURRENT_STATE)) && error==FALSE){ if(display_type==DISPLAY_HOST_TRENDS){ switch(hststatus->status){ case HOST_DOWN: initial_assumed_state=AS_HOST_DOWN; break; case HOST_UNREACHABLE: initial_assumed_state=AS_HOST_UNREACHABLE; break; case HOST_UP: initial_assumed_state=AS_HOST_UP; break; default: error=TRUE; break; } } else{ switch(svcstatus->status){ case SERVICE_OK: initial_assumed_state=AS_SVC_OK; break; case SERVICE_WARNING: initial_assumed_state=AS_SVC_WARNING; break; case SERVICE_UNKNOWN: initial_assumed_state=AS_SVC_UNKNOWN; break; case SERVICE_CRITICAL: initial_assumed_state=AS_SVC_CRITICAL; break; default: error=TRUE; break; } } } if(error==FALSE){ /* add this assumed state entry before any entries in the list and <= t1 */ if(as_list==NULL) initial_assumed_time=t1; else if(as_list->time_stamp>t1) initial_assumed_time=t1; else initial_assumed_time=as_list->time_stamp-1; if(display_type==DISPLAY_HOST_TRENDS) add_archived_state(initial_assumed_state,AS_HARD_STATE,initial_assumed_time,"First Host State Assumed (Faked Log Entry)"); else add_archived_state(initial_assumed_state,AS_HARD_STATE,initial_assumed_time,"First Service State Assumed (Faked Log Entry)"); } } /**************************************/ /* BAIL OUT IF WE DON'T HAVE ANYTHING */ /**************************************/ have_some_real_data=FALSE; for(temp_as=as_list;temp_as!=NULL;temp_as=temp_as->next){ if(temp_as->entry_type!=AS_NO_DATA && temp_as->entry_type!=AS_PROGRAM_START && temp_as->entry_type!=AS_PROGRAM_END){ have_some_real_data=TRUE; break; } } if(have_some_real_data==FALSE) return; /* if we're creating the HTML, start map code... */ if(mode==CREATE_HTML) printf("\n"); last_as=NULL; earliest_time=t2; latest_time=t1; #ifdef DEBUG printf("--- BEGINNING/MIDDLE SECTION ---
    \n"); #endif /**********************************/ /* BEGINNING/MIDDLE SECTION */ /**********************************/ for(temp_as=as_list;temp_as!=NULL;temp_as=temp_as->next){ /* keep this as last known state if this is the first entry or if it occurs before the starting point of the graph */ if((temp_as->time_stamp<=t1 || temp_as==as_list) && (temp_as->entry_type!=AS_NO_DATA && temp_as->entry_type!=AS_PROGRAM_END && temp_as->entry_type!=AS_PROGRAM_START)){ last_known_state=temp_as->entry_type; #ifdef DEBUG printf("SETTING LAST KNOWN STATE=%d
    \n",last_known_state); #endif } /* skip this entry if it occurs before the starting point of the graph */ if(temp_as->time_stamp<=t1){ #ifdef DEBUG printf("SKIPPING PRE-EVENT: %d @ %lu
    \n",temp_as->entry_type,temp_as->time_stamp); #endif last_as=temp_as; continue; } /* graph this span if we're not on the first item */ if(last_as!=NULL){ a=last_as->time_stamp; b=temp_as->time_stamp; /* we've already passed the last time displayed in the graph */ if(a>t2) break; /* only graph this data if its on the graph */ else if(b>t1){ /* clip last time if it exceeds graph limits */ if(b>t2) b=t2; /* clip first time if it precedes graph limits */ if(aentry_type; } /* save this time if its the latest we've graphed */ if(b>latest_time){ latest_time=b; latest_state=last_as->entry_type; } /* compute availability times for this chunk */ graph_trend_data(last_as->entry_type,temp_as->entry_type,last_as->time_stamp,a,b,last_as->state_info); /* return if we've reached the end of the graph limits */ if(b>=t2){ last_as=temp_as; break; } } } /* keep track of the last item */ last_as=temp_as; } #ifdef DEBUG printf("--- END SECTION ---
    \n"); #endif /**********************************/ /* END SECTION */ /**********************************/ if(last_as!=NULL){ /* don't process an entry that is beyond the limits of the graph */ if(last_as->time_stampt2) b=t2; a=last_as->time_stamp; if(aentry_type,current_state,a,a,b,last_as->state_info); } } /* if we're creating the HTML, close the map code */ if(mode==CREATE_HTML) printf("
    \n"); return; } /* graphs trend data */ void graph_trend_data(int first_state,int last_state,time_t real_start_time,time_t start_time,time_t end_time,char *state_info){ int start_state; int end_state; int start_pixel=0; int end_pixel=0; int color_to_use=0; int height=0; double start_pixel_ratio; double end_pixel_ratio; char temp_buffer[MAX_INPUT_BUFFER]; char state_string[MAX_INPUT_BUFFER]; char end_timestring[MAX_INPUT_BUFFER]; char start_timestring[MAX_INPUT_BUFFER]; time_t center_time; time_t next_start_time; time_t next_end_time; int days=0; int hours=0; int minutes=0; int seconds=0; /* can't graph if we don't have data... */ if(first_state==AS_NO_DATA || last_state==AS_NO_DATA) return; if(first_state==AS_PROGRAM_START && (last_state==AS_PROGRAM_END || last_state==AS_PROGRAM_START)){ if(assume_initial_states==FALSE) return; } if(first_state==AS_PROGRAM_END){ if(assume_states_during_notrunning==TRUE) first_state=last_known_state; else return; } /* special case if first entry was program start */ if(first_state==AS_PROGRAM_START){ #ifdef DEBUG printf("First state=program start!\n"); #endif if(assume_initial_states==TRUE){ #ifdef DEBUG printf("\tWe are assuming initial states...\n"); #endif if(assume_state_retention==TRUE){ start_state=last_known_state; #ifdef DEBUG printf("\tWe are assuming state retention (%d)...\n",start_state); #endif } else{ #ifdef DEBUG printf("\tWe are NOT assuming state retention...\n"); #endif if(display_type==DISPLAY_HOST_TRENDS) start_state=AS_HOST_UP; else start_state=AS_SVC_OK; } } else{ #ifdef DEBUG printf("We ARE NOT assuming initial states!\n"); #endif return; } } else{ start_state=first_state; last_known_state=first_state; } /* special case if last entry was program stop */ if(last_state==AS_PROGRAM_END) end_state=first_state; else end_state=last_state; #ifdef DEBUG printf("Graphing state %d\n",start_state); printf("\tfrom %s",ctime(&start_time)); printf("\tto %s",ctime(&end_time)); #endif if(start_timet2) end_time=t2; if(end_timet2) return; /* calculate the first and last pixels to use */ if(start_time==t1) start_pixel=0; else{ start_pixel_ratio=((double)(start_time-t1))/((double)(t2-t1)); start_pixel=(int)(start_pixel_ratio*(drawing_width-1)); } if(end_time==t1) end_pixel=0; else{ end_pixel_ratio=((double)(end_time-t1))/((double)(t2-t1)); end_pixel=(int)(end_pixel_ratio*(drawing_width-1)); } #ifdef DEBUG printf("\tPixel %d to %d\n\n",start_pixel,end_pixel); #endif /* we're creating the image, so draw... */ if(mode==CREATE_IMAGE){ /* figure out the color to use for drawing */ switch(start_state){ case AS_HOST_UP: color_to_use=color_green; height=60; break; case AS_HOST_DOWN: color_to_use=color_red; height=40; break; case AS_HOST_UNREACHABLE: color_to_use=color_darkred; height=20; break; case AS_SVC_OK: color_to_use=color_green; height=80; break; case AS_SVC_WARNING: color_to_use=color_yellow; height=60; break; case AS_SVC_UNKNOWN: color_to_use=color_orange; height=40; break; case AS_SVC_CRITICAL: color_to_use=color_red; height=20; break; default: color_to_use=color_black; height=0; break; } /* draw a rectangle */ if(start_state!=AS_NO_DATA) gdImageFilledRectangle(trends_image,start_pixel+drawing_x_offset,drawing_height-height+drawing_y_offset,end_pixel+drawing_x_offset,drawing_height+drawing_y_offset,color_to_use); } /* else we're creating the HTML, so write map area code... */ else{ /* figure out the the state string to use */ switch(start_state){ case AS_HOST_UP: strcpy(state_string,"UP"); height=60; break; case AS_HOST_DOWN: strcpy(state_string,"DOWN"); height=40; break; case AS_HOST_UNREACHABLE: strcpy(state_string,"UNREACHABLE"); height=20; break; case AS_SVC_OK: strcpy(state_string,"OK"); height=80; break; case AS_SVC_WARNING: strcpy(state_string,"WARNING"); height=60; break; case AS_SVC_UNKNOWN: strcpy(state_string,"UNKNOWN"); height=40; break; case AS_SVC_CRITICAL: strcpy(state_string,"CRITICAL"); height=20; break; default: strcpy(state_string,"?"); height=5; break; } /* get the center of this time range */ center_time=start_time+((end_time-start_time)/2); /* determine next start and end time range with zoom factor */ if(zoom_factor>0){ next_start_time=center_time-(((t2-t1)/2)/zoom_factor); next_end_time=center_time+(((t2-t1)/2)/zoom_factor); } else{ next_start_time=center_time+(((t2-t1)/2)*zoom_factor); next_end_time=center_time-(((t2-t1)/2)*zoom_factor); } printf("\n"); } /* calculate time in this state */ switch(start_state){ case AS_HOST_UP: time_up+=(unsigned long)(end_time-start_time); break; case AS_HOST_DOWN: time_down+=(unsigned long)(end_time-start_time); break; case AS_HOST_UNREACHABLE: time_unreachable+=(unsigned long)(end_time-start_time); break; case AS_SVC_OK: time_ok+=(unsigned long)(end_time-start_time); break; case AS_SVC_WARNING: time_warning+=(unsigned long)(end_time-start_time); break; case AS_SVC_UNKNOWN: time_unknown+=(unsigned long)(end_time-start_time); break; case AS_SVC_CRITICAL: time_critical+=(unsigned long)(end_time-start_time); break; default: break; } return; } /* convert current host state to archived state value */ int convert_host_state_to_archived_state(int current_status){ if(current_status==HOST_UP) return AS_HOST_UP; if(current_status==HOST_DOWN) return AS_HOST_DOWN; if(current_status==HOST_UNREACHABLE) return AS_HOST_UNREACHABLE; return AS_NO_DATA; } /* convert current service state to archived state value */ int convert_service_state_to_archived_state(int current_status){ if(current_status==SERVICE_OK) return AS_SVC_OK; if(current_status==SERVICE_UNKNOWN) return AS_SVC_UNKNOWN; if(current_status==SERVICE_WARNING) return AS_SVC_WARNING; if(current_status==SERVICE_CRITICAL) return AS_SVC_CRITICAL; return AS_NO_DATA; } /* adds an archived state entry */ void add_archived_state(int entry_type, int state_type, time_t time_stamp, char *state_info){ archived_state *last_as=NULL; archived_state *temp_as=NULL; archived_state *new_as=NULL; #ifdef DEBUG printf("Added state %d @ %s",state_type,ctime(&time_stamp)); #endif /* allocate memory for the new entry */ new_as=(archived_state *)malloc(sizeof(archived_state)); if(new_as==NULL) return; /* allocate memory fo the state info */ if(state_info!=NULL){ new_as->state_info=(char *)malloc(strlen(state_info)+1); if(new_as->state_info!=NULL) strcpy(new_as->state_info,state_info); } else new_as->state_info=NULL; new_as->entry_type=entry_type; new_as->processed_state=entry_type; new_as->state_type=state_type; new_as->time_stamp=time_stamp; /* add the new entry to the list in memory, sorted by time */ last_as=as_list; for(temp_as=as_list;temp_as!=NULL;temp_as=temp_as->next){ if(new_as->time_stamptime_stamp){ new_as->next=temp_as; if(temp_as==as_list) as_list=new_as; else last_as->next=new_as; break; } else last_as=temp_as; } if(as_list==NULL){ new_as->next=NULL; as_list=new_as; } else if(temp_as==NULL){ new_as->next=NULL; last_as->next=new_as; } return; } /* frees memory allocated to the archived state list */ void free_archived_state_list(void){ archived_state *this_as=NULL; archived_state *next_as=NULL; for(this_as=as_list;this_as!=NULL;){ next_as=this_as->next; if(this_as->state_info!=NULL) free(this_as->state_info); free(this_as); this_as=next_as; } as_list=NULL; return; } /* reads log files for archived state data */ void read_archived_state_data(void){ char filename[MAX_FILENAME_LENGTH]; int newest_archive=0; int oldest_archive=0; int current_archive; #ifdef DEBUG printf("Determining archives to use...\n"); #endif /* determine earliest archive to use */ oldest_archive=determine_archive_to_use_from_time(t1); if(log_rotation_method!=LOG_ROTATION_NONE) oldest_archive+=backtrack_archives; /* determine most recent archive to use */ newest_archive=determine_archive_to_use_from_time(t2); if(oldest_archive\n"); printf("\n"); printf("\n"); return; } /* write timestamps */ void draw_timestamps(void){ int last_timestamp=0; archived_state *temp_as; double start_pixel_ratio; int start_pixel; if(mode!=CREATE_IMAGE) return; /* draw first timestamp */ draw_timestamp(0,t1); last_timestamp=0; for(temp_as=as_list;temp_as!=NULL;temp_as=temp_as->next){ if(temp_as->time_stamptime_stamp>t2) continue; start_pixel_ratio=((double)(temp_as->time_stamp-t1))/((double)(t2-t1)); start_pixel=(int)(start_pixel_ratio*(drawing_width-1)); /* draw start timestamp if possible */ if((start_pixel > last_timestamp+MIN_TIMESTAMP_SPACING) && (start_pixel < drawing_width-1-MIN_TIMESTAMP_SPACING)){ draw_timestamp(start_pixel,temp_as->time_stamp); last_timestamp=start_pixel; } } /* draw last timestamp */ draw_timestamp(drawing_width-1,t2); return; } /* write timestamp below graph */ void draw_timestamp(int ts_pixel, time_t ts_time){ char temp_buffer[MAX_INPUT_BUFFER]; int string_height; int string_width; snprintf(temp_buffer,sizeof(temp_buffer)-1,"%s",ctime(&ts_time)); temp_buffer[sizeof(temp_buffer)-1]='\x0'; temp_buffer[strlen(temp_buffer)-1]='\x0'; string_height=gdFontSmall->h; string_width=gdFontSmall->w*strlen(temp_buffer); if(small_image==FALSE) gdImageStringUp(trends_image,gdFontSmall,ts_pixel+drawing_x_offset-(string_height/2),drawing_y_offset+drawing_height+string_width+5,(unsigned char *)temp_buffer,color_black); /* draw a dashed vertical line at this point */ if(ts_pixel>0 && ts_pixel<(drawing_width-1)) draw_dashed_line(ts_pixel+drawing_x_offset,drawing_y_offset,ts_pixel+drawing_x_offset,drawing_y_offset+drawing_height,color_black); return; } /* draw total state times */ void draw_time_breakdowns(void){ char temp_buffer[MAX_INPUT_BUFFER]; unsigned long total_time=0L; unsigned long total_state_time; unsigned long time_indeterminate=0L; int string_height; if(mode==CREATE_HTML) return; if(small_image==TRUE) return; total_time=(unsigned long)(t2-t1); if(display_type==DISPLAY_HOST_TRENDS) total_state_time=time_up+time_down+time_unreachable; else total_state_time=time_ok+time_warning+time_unknown+time_critical; if(total_state_time>=total_time) time_indeterminate=0L; else time_indeterminate=total_time-total_state_time; string_height=gdFontSmall->h; if(display_type==DISPLAY_HOST_TRENDS){ get_time_breakdown_string(total_time,time_up,"Up",&temp_buffer[0],sizeof(temp_buffer)); gdImageString(trends_image,gdFontSmall,drawing_x_offset+drawing_width+20,drawing_y_offset+5,(unsigned char *)temp_buffer,color_darkgreen); gdImageString(trends_image,gdFontSmall,drawing_x_offset-10-(gdFontSmall->w*2),drawing_y_offset+5,(unsigned char *)"Up",color_darkgreen); get_time_breakdown_string(total_time,time_down,"Down",&temp_buffer[0],sizeof(temp_buffer)); gdImageString(trends_image,gdFontSmall,drawing_x_offset+drawing_width+20,drawing_y_offset+25,(unsigned char *)temp_buffer,color_red); gdImageString(trends_image,gdFontSmall,drawing_x_offset-10-(gdFontSmall->w*4),drawing_y_offset+25,(unsigned char *)"Down",color_red); get_time_breakdown_string(total_time,time_unreachable,"Unreachable",&temp_buffer[0],sizeof(temp_buffer)); gdImageString(trends_image,gdFontSmall,drawing_x_offset+drawing_width+20,drawing_y_offset+45,(unsigned char *)temp_buffer,color_darkred); gdImageString(trends_image,gdFontSmall,drawing_x_offset-10-(gdFontSmall->w*11),drawing_y_offset+45,(unsigned char *)"Unreachable",color_darkred); get_time_breakdown_string(total_time,time_indeterminate,"Indeterminate",&temp_buffer[0],sizeof(temp_buffer)); gdImageString(trends_image,gdFontSmall,drawing_x_offset+drawing_width+20,drawing_y_offset+65,(unsigned char *)temp_buffer,color_black); gdImageString(trends_image,gdFontSmall,drawing_x_offset-10-(gdFontSmall->w*13),drawing_y_offset+65,(unsigned char *)"Indeterminate",color_black); } else{ get_time_breakdown_string(total_time,time_ok,"Ok",&temp_buffer[0],sizeof(temp_buffer)); gdImageString(trends_image,gdFontSmall,drawing_x_offset+drawing_width+20,drawing_y_offset+5,(unsigned char *)temp_buffer,color_darkgreen); gdImageString(trends_image,gdFontSmall,drawing_x_offset-10-(gdFontSmall->w*2),drawing_y_offset+5,(unsigned char *)"Ok",color_darkgreen); get_time_breakdown_string(total_time,time_warning,"Warning",&temp_buffer[0],sizeof(temp_buffer)); gdImageString(trends_image,gdFontSmall,drawing_x_offset+drawing_width+20,drawing_y_offset+25,(unsigned char *)temp_buffer,color_yellow); gdImageString(trends_image,gdFontSmall,drawing_x_offset-10-(gdFontSmall->w*7),drawing_y_offset+25,(unsigned char *)"Warning",color_yellow); get_time_breakdown_string(total_time,time_unknown,"Unknown",&temp_buffer[0],sizeof(temp_buffer)); gdImageString(trends_image,gdFontSmall,drawing_x_offset+drawing_width+20,drawing_y_offset+45,(unsigned char *)temp_buffer,color_orange); gdImageString(trends_image,gdFontSmall,drawing_x_offset-10-(gdFontSmall->w*7),drawing_y_offset+45,(unsigned char *)"Unknown",color_orange); get_time_breakdown_string(total_time,time_critical,"Critical",&temp_buffer[0],sizeof(temp_buffer)); gdImageString(trends_image,gdFontSmall,drawing_x_offset+drawing_width+20,drawing_y_offset+65,(unsigned char *)temp_buffer,color_red); gdImageString(trends_image,gdFontSmall,drawing_x_offset-10-(gdFontSmall->w*8),drawing_y_offset+65,(unsigned char *)"Critical",color_red); get_time_breakdown_string(total_time,time_indeterminate,"Indeterminate",&temp_buffer[0],sizeof(temp_buffer)); gdImageString(trends_image,gdFontSmall,drawing_x_offset+drawing_width+20,drawing_y_offset+85,(unsigned char *)temp_buffer,color_black); gdImageString(trends_image,gdFontSmall,drawing_x_offset-10-(gdFontSmall->w*13),drawing_y_offset+85,(unsigned char *)"Indeterminate",color_black); } return; } void get_time_breakdown_string(unsigned long total_time, unsigned long state_time, char *state_string, char *buffer, int buffer_length){ int days; int hours; int minutes; int seconds; double percent_time; get_time_breakdown(state_time,&days,&hours,&minutes,&seconds); if(total_time==0L) percent_time=0.0; else percent_time=((double)state_time/total_time)*100.0; snprintf(buffer,buffer_length-1,"%-13s: (%.3f%%) %dd %dh %dm %ds",state_string,percent_time,days,hours,minutes,seconds); buffer[buffer_length-1]='\x0'; return; } void convert_timeperiod_to_times(int type){ time_t current_time; struct tm *t; /* get the current time */ time(¤t_time); t=localtime(¤t_time); t->tm_sec=0; t->tm_min=0; t->tm_hour=0; switch(type){ case TIMEPERIOD_LAST24HOURS: t1=current_time-(60*60*24); t2=current_time; break; case TIMEPERIOD_TODAY: t1=mktime(t); t2=current_time; break; case TIMEPERIOD_YESTERDAY: t1=(time_t)(mktime(t)-(60*60*24)); t2=(time_t)mktime(t); break; case TIMEPERIOD_THISWEEK: t1=(time_t)(mktime(t)-(60*60*24*t->tm_wday)); t2=current_time; break; case TIMEPERIOD_LASTWEEK: t1=(time_t)(mktime(t)-(60*60*24*t->tm_wday)-(60*60*24*7)); t2=(time_t)(mktime(t)-(60*60*24*t->tm_wday)); break; case TIMEPERIOD_THISMONTH: t->tm_mday=1; t1=mktime(t); t2=current_time; break; case TIMEPERIOD_LASTMONTH: t->tm_mday=1; t2=mktime(t); if(t->tm_mon==0){ t->tm_mon=11; t->tm_year--; } else t->tm_mon--; t1=mktime(t); break; case TIMEPERIOD_THISQUARTER: break; case TIMEPERIOD_LASTQUARTER: break; case TIMEPERIOD_THISYEAR: t->tm_mon=0; t->tm_mday=1; t1=mktime(t); t2=current_time; break; case TIMEPERIOD_LASTYEAR: t->tm_mon=0; t->tm_mday=1; t2=mktime(t); t->tm_year--; t1=mktime(t); break; case TIMEPERIOD_LAST7DAYS: t2=current_time; t1=current_time-(7*24*60*60); break; case TIMEPERIOD_LAST31DAYS: t2=current_time; t1=current_time-(31*24*60*60); break; default: break; } return; } void compute_report_times(void){ time_t current_time; struct tm *st; struct tm *et; /* get the current time */ time(¤t_time); st=localtime(¤t_time); st->tm_sec=start_second; st->tm_min=start_minute; st->tm_hour=start_hour; st->tm_mday=start_day; st->tm_mon=start_month-1; st->tm_year=start_year-1900; t1=mktime(st); et=localtime(¤t_time); et->tm_sec=end_second; et->tm_min=end_minute; et->tm_hour=end_hour; et->tm_mday=end_day; et->tm_mon=end_month-1; et->tm_year=end_year-1900; t2=mktime(et); } /* draws a dashed line */ void draw_dashed_line(int x1,int y1,int x2,int y2,int color){ int styleDashed[12]; styleDashed[0]=color; styleDashed[1]=color; styleDashed[2]=gdTransparent; styleDashed[3]=gdTransparent; styleDashed[4]=color; styleDashed[5]=color; styleDashed[6]=gdTransparent; styleDashed[7]=gdTransparent; styleDashed[8]=color; styleDashed[9]=color; styleDashed[10]=gdTransparent; styleDashed[11]=gdTransparent; /* sets current style to a dashed line */ gdImageSetStyle(trends_image,styleDashed,12); /* draws a line (dashed) */ gdImageLine(trends_image,x1,y1,x2,y2,gdStyled); return; } /* draws horizontal grid lines */ void draw_horizontal_grid_lines(void){ if(mode==CREATE_HTML) return; if(small_image==TRUE) return; draw_dashed_line(drawing_x_offset,drawing_y_offset+10,drawing_x_offset+drawing_width,drawing_y_offset+10,color_black); draw_dashed_line(drawing_x_offset,drawing_y_offset+30,drawing_x_offset+drawing_width,drawing_y_offset+30,color_black); draw_dashed_line(drawing_x_offset,drawing_y_offset+50,drawing_x_offset+drawing_width,drawing_y_offset+50,color_black); if(display_type==DISPLAY_SERVICE_TRENDS) draw_dashed_line(drawing_x_offset,drawing_y_offset+70,drawing_x_offset+drawing_width,drawing_y_offset+70,color_black); return; } nagios-2.6/.cvsignore0000664000076500007650000000010410326736062014177 0ustar nagiosnagiospkg subst pkginfo Prototype nagios.SPARC.pkg.tar.gz autom4te.cache nagios-2.6/Changelog0000664000076500007650000002616410532717360014026 0ustar nagiosnagios##################### Nagios 2.x Change Log ##################### 2.6 - 11/27/2006 ---------------- * Fix for unscheduled triggered downtime entries * Fix for embedded audio in tac and status CGIs * Fixed bug in nagiostats utility when reporting host/service check latency * Misc code cleanups for compiler warnings * Fixed error when reading empty (zero byte) config files * Default is now to check for orphaned service checks (Francois Caen) * Fixed bug with non-standard CGI config file location in status data (Carson Gaspar) * Fixed bugs and simplified examples in sample config files (Mark Young) 2.5 - 07/13/2006 ---------------- * Bug fix for excluding hidden files from config file processing * Bug fix for incorrect links to trends CGI from notification CGI * Hopefully faster shutdown during host checks * Lock file is now closed just prior to shutdown, instead of when SIGINT is received * Bug fix for segfault during startup due to extended service definition duplication * Bug fix for segfault with wildcards in servicegroup members * Bug fix for segfault when p1.pl file was missing and embedded Perl interpreter was enabled 2.4 - 05/31/2006 ---------------- * Fix for missing include that prevented CGI compilation under Solaris * Better error message reporting in the command CGI (cmd.cgi) * Fix for order of recovery/flapping notifications immediately after end of host/service flapping * Bug fix for potential crash (SIGBUS) of CGIs when reading mmap()'ed status, comment, and downtime files * Added 'install-unstripped' option to Makefile to allow installing unstripped binaries for debugging * Minor bug fix to sample redundancy handle-master-proc-event script 2.3.1 - 05/15/2006 ------------------ * Bug fix for HTTP content_length header integer overflow in CGIs 2.3 - 05/03/2006 ---------------- * Bug fix for negative HTTP content_length header in CGIs * Added missing links for notes_url and action_url to service column of status detail page 2.2 - 04/07/2006 ---------------- * Minor bug fix in availability CGI * Bug fix with temporary file location used for retention data * Fix for segfault that occurred in 2.1 during service flapping notifications 2.1 - 03/27/2006 ---------------- * Changed freshness logic so that passive checks don't immediately go stale after program restart * Bug fix for minor memory leak in object cleanup code * Bug fix for flapping notifications during scheduled downtime * Bug fix for $TOTALHOSTSDOWNUNHANDLED$ macro * Bug fix in sample minimal.cfg file * Bug fix in status CGI when displaying servicegroups * Bug fixes in computation of indeterminate time and scheduled downtime in availability CGI * Bug fix with not deleting all comments associated with a service * Lowered max plugin output length from 348 to 332 chars to run on 64-bit systems without problems * Minor fix to p1.pl for embedded Perl interpreter * Minor fixes to WAP interface (statuswml CGI) * Minor bug fix to VRML interface (statuswrl CGI) * Minor doc updates 2.0 - 02/07/2006 ---------------- * Fix for segfault in timed event queue * Removed length limitations for object vars/vals * Updated config.sub and config.guess to versions from automake-1.9 * Doc updates 2.0rc2 - 01/10/2006 ------------------- * Fix for initialization of embedded Perl interpreter * Fix for potential duplicate membership entry bug in (host/service/contact)groups * Minor documentation updates 2.0rc1 - 12/27/2005 ------------------- * Event broker modifications: - Minor change to log timestamps - Changes to notification, check, event handler, and system command callbacks - Addition of acknowledgement callbacks - Addition of state change callbacks * Minor bug fix to statuswml CGI * Minor spec file updates * Minor include file fix to remove duplicate _REENTRANT definitions affecting embedded Perl * Bug fix in template resolution of contactgroups variable in contact definitions * Fixed bug with comments not expiring (for some reason this was not previously implemented!) * Minor embedded Perl changes * Fixed bug with non-registered objects in wildcard/regex templates * Added configure script option to disable use of nanosleep() in event queue * Improvements to circular path/dependency checks to prevent segfaults * Minor documentation updates 2.0b6 - 11/30/2005 ------------------ * Changed license to specifically state GPL version 2 * Minor fixes to sample nagios.cfg config file * Fix for non-US date formats in command CGI * Spec file updates * Include file modifications for C++ event broker modules * Minor event broker changes (addition of timed event "sleep" data) * Added some sanity checks during write of status data for full partitions * Sample web server config file changes * Doc updates 2.0b5 - 11/14/2005 ------------------ * Typo fix in availability CGI * Minor changes to sample config files * Fixed order of include files in config.h for clean compile on OpenBSD 3.6 * Minor fixes in availability and trends CGIs for assumed states during program downtime * Fixed bug with initial scheduling of active service checks in configs with a large number of passive-only checks * Fixed bugs with scheduling active host and service checks when active checks were disabled globally * Host name search in web interface is now case-insensitive * Fixed bug in times reported by nagiostats utility * Nagios now drops privileges before reading config files for config verification and scheduling info tests * Fixed bug where non-config files would occassionally be processed with config directory recursion * Improvements to init script when stopping Nagios * Minor changes to improve host and service freshness checking * Fixed bug with event handlers and logging during soft host recoveries * Added check for duplicate object names that could adversely affect template resolution * Updated mini EPN (embedded Perl) test modules * A few other misc minor fixes 2.0b4 - 08/02/2005 ------------------ * Memory leak fixes * Fixed log message error at start of flapping * Fixed segfault with invalid servicegroups in service definitions * Non-existent problems can no longer be acknowledged * Privileges will now only attempted be dropped if started as root user * Embedded Perl fixes (to reduce memory leaks) * Sample CGI config file fixes * Added $HOSTCHECKTYPE$ and $SERVICECHECKTYPE$ macros * Fixed bugs in $LASTHOSTCHECK$ macro (and corresponding on-demand macro) * Fixed bugs in status data routines * Fixed bug with NULL hostgroup and servicegroup membership * Fixed bug with config directory recursion being broken * Fixed bug with processing directives in non-registered object definitions * Minor change to event broker API to prevent segfaults from unloaded modules * Updated sample helloworld NEB module to show how to register callback routines 2.0b3 - 04/03/2005 ------------------ * Sample config file fixes * Fixed segfaults in CGIs where plugin output was NULL * Minor fixes to INSTALL documentation * Fixed segfault with mispaired servicegroup memberships * Added $PROCESSSTARTTIME$ macro * If not specified, host address and alias now default to host name * Extended ASCII characters no longer auto-stripped from object names and macros * Added external commands to adjust host and service notification numbers * Init script changes * Fixed bug where passive checks with empty plugin output were being dropped * Fixed bug in state retention routines * Configure script changes to (hopefully) support event broker under AIX 5 * Documentation fixes and updates * Additional MRTG output options in nagiostats utility * Fixed bug in macro processing where commands longer than 1K in length were sometimes being truncated * Fixed bug in initialization of servicedependency definitions * Nagios now aborts at startup if it can't drop privileges * Fixed segfault with adaptive monitoring when changing service check command 2.0b2 - 02/09/2005 ------------------ * Fixed bug with cleaning macro contents * Minor doc updates and fixes * Init script mods * Fixed bug in macro routines * Changed library ordering in GD configure script tests * Increased command buffer from 4K to 32K * Added ability to report on soft problem states in avail and trends CGIs * Fixed bug with hard service problems being reported as soft after host recoveries * Fixed bug with current attempt number during scheduled host checks * Fixed macro processing bug * Fixed bug where GUI didn't show UNREACHABLE hosts properly * Event broker bug fixes * Removed (un)setenv() calls for systems that don't support it * Fixed problem with installing sample config files * Sample config file fix * RPM spec file updates * Embedded Perl fixes (updated p1.pl and mini_epn) 2.0b1 - 12/15/2004 ------------------ * Added triggered downtime * Basic adaptive monitoring features * Added ability to retain scheduling information * Change in hostgroup authorization (need to be authorized for all member hosts) * Host dependencies are now checked before service notifications are sent out * Added on-demand host/service macros (i.e. $VARIABLE:host:service$) * Added notes and action_url directives to extended host/service definitions * Added inherits_parent flag to host and service dependencies * Added servicegroups * Added host freshness checking * Changed way in which initial states are logged * Added timeperiods and state options to escalation definitions * Added hostgroups directive to host definitions * Extended host/service info definitions are now stored in standard object config files * Added regexp matching in object config files (with --enable-regexp-matching option to configure script) * Changed default name of status, comment, downtime, and retention files * Removed DB support for extended data and retention data * Multiple service descriptions can be used in both service dependency and service escalation definitions * Moved contact groups directive from hostgroup definitions to host definitions * Added worker thread to increase buffer size of external command file * Added object_cache_file directive to allow CGI to read cached copy of object definitions * Added DURATION, DURATIONSEC, HOSTDOWNTIME, and SERVICEDOWNTIME macros * Removed hostgroup escalations * Added passive host checks * Event handler commands can now contain arguments * Contact notification commands can now contain arguments (Greg Vickers) * Support for multiple members directives in hostgroup definitions * Directory recursion support added to cfg_dir directives for object data * Host check command can now contain arguments (! separator) (Daniel Riek) * Removed support for "vanilla" command definitions (I doubt they were used) * Added p1_file directive to main config file to specify location of p1.pl (Russell Scibetti) * Added option to reload embedded Perl interpreter after X calls during runtime - useful if you notice embedded Perl leaking memory * Removed older object config support * Removed older extended info config support * CGIs can now determine config file and external command file locations from environment variables (Russell Scibetti) * Other objects now used chained hash for faster lookups as well * Host and services use chained hash for faster lookups (Daniel Drown) * Added support for config file line continuations using \ character * Added check auto-rescheduling option nagios-2.6/INSTALLING0000664000076500007650000000745510532717360013605 0ustar nagiosnagiosNagios Quick-and-Dirty Installation Instructions ------------------------------------------------ I would highly recommend using a web browser to read the documentation and installation instructions in the html/docs directory. They provide a much better overview of how to configure Nagios. *** IMPORTANT *** Plugins are not distributed with the core Nagios distribution. However, plugins are required if you actually want to use Nagios. You'll have to download any plugins you want to use from the main website, compile them, and install them before you can actually start using Nagios. Plugins can be obtained from the downloads page at http://www.nagios.org/. Compiling The Binaries ---------------------- 1) Run the configure script to initialize variables and create a Makefile, etc. ./configure --prefix=PREFIX --with-cgiurl=CGIURL --with-htmurl=HTMURL --with-nagios-user=SOMEUSER --with-nagios-group=SOMEGROUP a) Replace PREFIX with the base directory under which Nagios should be installed. Default is '/usr/local/nagios' b) Replace CGIURL with the base URL that you will be using to access the CGIs. Do NOT include a trailing slash. Default is '/nagios/cgi-bin' c) Replace HTMURL with the base URL that you will be using to access the html documentation and main interface. Default is '/nagios' d) Replace SOMEUSER with the name of the user on your system that will be given permissions to the Nagios directories and files. Default is 'nagios' e) Replace SOMEGROUP with the name of the group on your system that will be given permissions to the Nagios directories and files. Default is 'nagios' Notes: There are also --with-command-user and --with-command-group options that can be specified. These are used when installing the directory that will hold the external command file. For more information on external commands, read the HTML documentation. 2) Compile Nagios and the CGIs with the following command: make all Installing The Binaries ----------------------- 1) Install the binaries and HTML documentations with the following command: make install Creating And Installing Sample Config Files ------------------------------------------- Sample main, resource and CGI configuration files are automatically created in your distribution distribution directory after you run the configure script. The files are named 'nagios.cfg', 'resource.cfg' and 'cgi.cfg' respectively. 1) If you want, you can install the sample config files into the {prefix}/etc directory with the following command: make install-config Installing The Init Script -------------------------- 1) If you want to install and init script for starting Nagios, use the following command: make install-init Everything Else --------------- 1) You'll have to download and install plugins for use with Nagios. Plugins can be obtained from the downloads page at http://www.nagios.org of from the SourceForge project page at http://nagiosplug.sourceforge.net 2) You'll have to edit your main, host, resource, and CGI config files in order to fit your system setup and define what hosts and service you want to monitor. Read the HTML docs on how to do this and look at the sample config files. 3) If you plan on using the CGIs, you'll have to read the HTML documentation on configuring you web server properly and CGI authentication and authorization. These are a must to read! That's it! If you have problems or questions, read all of the HTML documentation, particularly the sections on the configuration files and CGI authentication before reporting problems. Unless you feel that your problem can only be answered by me, try posting a message to the appropriate mailing list. -- Ethan Galstad (nagios@nagios.org) nagios-2.6/LEGAL0000664000076500007650000000101410437364210012742 0ustar nagiosnagios All source code, binaries, documentation, information, and other files contained in this distribution are provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. Nagios and the Nagios logo are trademarks, servicemarks, registered trademarks or registered servicemarks owned by or licensed to Ethan Galstad. All other trademarks, servicemarks, registered trademarks, and registered servicemarks are the property of their respective owner(s). nagios-2.6/LICENSE0000664000076500007650000004312207436604416013220 0ustar nagiosnagios GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 19yy 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) 19yy name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. nagios-2.6/Makefile.in0000664000076500007650000002653010532717360014256 0ustar nagiosnagios############################### # Makefile for Nagios # # Last Modified: 11-27-2006 ############################### # Source code directories SRC_BASE=@srcdir@/base SRC_CGI=@srcdir@/cgi SRC_HTM=@srcdir@/html SRC_MODULE=@srcdir@/module SRC_INCLUDE=@srcdir@/include SRC_COMMON=@srcdir@/common SRC_XDATA=@srcdir@/xdata SRC_CONTRIB=@srcdir@/contrib CC=@CC@ CFLAGS=@CFLAGS@ @DEFS@ LDFLAGS=@LDFLAGS@ @LIBS@ prefix=@prefix@ exec_prefix=@exec_prefix@ LOGDIR=@localstatedir@ CFGDIR=@sysconfdir@ BINDIR=@bindir@ CGIDIR=@sbindir@ HTMLDIR=@datadir@ INSTALL=@INSTALL@ INSTALL_OPTS=@INSTALL_OPTS@ COMMAND_OPTS=@COMMAND_OPTS@ INIT_DIR=@init_dir@ INIT_OPTS=-o root -g root CGICFGDIR=$(CGIDIR) PERLDIR=@PERLDIR@ INSTALLPERLSTUFF=@INSTALLPERLSTUFF@ CGIEXTRAS=@CGIEXTRAS@ SNPRINTF_O=@SNPRINTF_O@ CP=@CP@ @SET_MAKE@ none: @echo "Please supply a command line argument (i.e. 'make all'). Other targets are:" @echo " nagios cgis contrib modules" @echo " clean" @echo " install install-base install-cgis install-html install-config install-init install-commandmode fullinstall" # @echo " uninstall" # FreeBSD make does not support -C option, so we'll use the Apache style... (patch by Stanley Hopcroft 12/27/1999) all: cd $(SRC_BASE) && $(MAKE) cd $(SRC_CGI) && $(MAKE) cd $(SRC_HTM) && $(MAKE) cd $(SRC_MODULE) && $(MAKE) @echo "" @echo "*** Compile finished ***" @echo "" @echo "If the main program and CGIs compiled without any errors, you" @echo "can continue with installing Nagios as follows (type 'make'" @echo "without any arguments for a list of all possible options):" @echo "" @echo " make install" @echo " - This installs the main program, CGIs, and HTML files" @echo "" @echo " make install-init" @echo " - This installs the init script in $(DESTDIR)$(INIT_DIR)" @echo "" @echo " make install-commandmode" @echo " - This installs and configures permissions on the" @echo " directory for holding the external command file" @echo "" @echo " make install-config" @echo " - This installs *SAMPLE* config files in $(DESTDIR)$(CFGDIR)" @echo " You'll have to modify these sample files before you can" @echo " use Nagios. Read the HTML documentation for more info" @echo " on doing this. Pay particular attention to the docs on" @echo " object configuration files, as they determine what/how" @echo " things get monitored!" @echo "" @echo "" @echo "*** Support Notes *******************************************" @echo "" @echo "If you have questions about configuring or running Nagios," @echo "please make sure that you:" @echo "" @echo " - Look at the sample config files" @echo " - Read the HTML documentation" @echo " - Read the FAQs online at http://www.nagios.org/faqs" @echo "" @echo "before you post a question to one of the mailing lists." @echo "Also make sure to include pertinent information that could" @echo "help others help you. This might include:" @echo "" @echo " - What version of Nagios you are using" @echo " - What version of the plugins you are using" @echo " - Relevant snippets from your config files" @echo " - Relevant error messages from the Nagios log file" @echo "" @echo "For those of you who are interested in contract support or" @echo "consulting services for Nagios, please visit:" @echo "" @echo " http://www.nagios.org/contractsupport" @echo "" @echo "*************************************************************" @echo "" @echo "Enjoy." @echo "" nagios: cd $(SRC_BASE) && $(MAKE) config: @echo "Sample config files are automatically generated once you run the" @echo "configure script. You can install the sample config files on your" @echo "system by using the 'make install-config' command." cgis: cd $(SRC_CGI) && $(MAKE) html: cd $(SRC_HTM) && $(MAKE) contrib: cd $(SRC_CONTRIB) && $(MAKE) modules: cd $(SRC_MODULE) && $(MAKE) clean: cd $(SRC_BASE) && $(MAKE) $@ cd $(SRC_CGI) && $(MAKE) $@ cd $(SRC_COMMON) && $(MAKE) $@ cd $(SRC_XDATA) && $(MAKE) $@ cd $(SRC_HTM) && $(MAKE) $@ cd $(SRC_INCLUDE) && $(MAKE) $@ cd $(SRC_CONTRIB) && $(MAKE) $@ cd $(SRC_MODULE) && $(MAKE) $@ rm -f *.cfg core rm -f *~ *.*~ */*~ */*.*~ */*/*~ */*/*.*~ rm -f config.log config.status config.cache distclean: clean cd $(SRC_BASE) && $(MAKE) $@ cd $(SRC_CGI) && $(MAKE) $@ cd $(SRC_COMMON) && $(MAKE) $@ cd $(SRC_XDATA) && $(MAKE) $@ cd $(SRC_HTM) && $(MAKE) $@ cd $(SRC_INCLUDE) && $(MAKE) $@ cd $(SRC_CONTRIB) && $(MAKE) $@ cd $(SRC_MODULE) && $(MAKE) $@ rm -f sample-config/*.cfg sample-config/*.conf sample-config/template-object/*.cfg rm -f daemon-init pkginfo rm -f Makefile subst devclean: distclean install-html: cd $(SRC_HTM) && $(MAKE) install install-base: cd $(SRC_BASE) && $(MAKE) install install-cgis: cd $(SRC_CGI) && $(MAKE) install install: cd $(SRC_BASE) && $(MAKE) $@ cd $(SRC_CGI) && $(MAKE) $@ cd $(SRC_HTM) && $(MAKE) $@ $(MAKE) install-basic install-unstripped: cd $(SRC_BASE) && $(MAKE) $@ cd $(SRC_CGI) && $(MAKE) $@ cd $(SRC_HTM) && $(MAKE) $@ $(MAKE) install-basic install-basic: $(INSTALL) -m 775 $(INSTALL_OPTS) -d $(DESTDIR)$(LOGDIR) $(INSTALL) -m 775 $(INSTALL_OPTS) -d $(DESTDIR)$(LOGDIR)/archives if [ $(INSTALLPERLSTUFF) = yes ]; then \ $(INSTALL) -m 664 $(INSTALL_OPTS) p1.pl $(DESTDIR)$(BINDIR); \ fi; @echo "" @echo "*** Main program, CGIs and HTML files installed ***" @echo "" @echo "You can continue with installing Nagios as follows (type 'make'" @echo "without any arguments for a list of all possible options):" @echo "" @echo " make install-init" @echo " - This installs the init script in $(DESTDIR)$(INIT_DIR)" @echo "" @echo " make install-commandmode" @echo " - This installs and configures permissions on the" @echo " directory for holding the external command file" @echo "" @echo " make install-config" @echo " - This installs *SAMPLE* config files in $(DESTDIR)$(CFGDIR)" @echo " You'll have to modify these sample files before you can" @echo " use Nagios. Read the HTML documentation for more info" @echo " on doing this. Pay particular attention to the docs on" @echo " object configuration files, as they determine what/how" @echo " things get monitored!" @echo "" install-config: $(INSTALL) -m 775 $(INSTALL_OPTS) -d $(DESTDIR)$(CFGDIR) $(INSTALL) -m 664 $(INSTALL_OPTS) sample-config/nagios.cfg $(DESTDIR)$(CFGDIR)/nagios.cfg-sample $(INSTALL) -m 664 $(INSTALL_OPTS) sample-config/cgi.cfg $(DESTDIR)$(CFGDIR)/cgi.cfg-sample $(INSTALL) -m 660 $(INSTALL_OPTS) sample-config/resource.cfg $(DESTDIR)$(CFGDIR)/resource.cfg-sample $(INSTALL) -m 664 $(INSTALL_OPTS) sample-config/template-object/localhost.cfg $(DESTDIR)$(CFGDIR)/localhost.cfg-sample $(INSTALL) -m 664 $(INSTALL_OPTS) sample-config/template-object/commands.cfg $(DESTDIR)$(CFGDIR)/commands.cfg-sample @echo "" @echo "*** Sample config file installed ***" @echo "" @echo "Remember, these are *SAMPLE* config files. You'll need to read" @echo "the documentation for more information on how to actually define" @echo "services, hosts, etc. to fit your particular needs." @echo "" @echo "If you have questions about configuring Nagios properly, please:" @echo " - Look at the sample config files" @echo " - Read the HTML documentation" @echo " - Read the FAQs online at http://www.nagios.org/faqs" @echo "*BEFORE* you post a question to one of the mailing lists." @echo "" install-init: install-daemoninit install-daemoninit: $(INSTALL) -m 755 -d $(INIT_OPTS) $(DESTDIR)$(INIT_DIR) $(INSTALL) -m 774 $(INIT_OPTS) daemon-init $(DESTDIR)$(INIT_DIR)/nagios @echo "" @echo "*** Init script installed ***" @echo "" @echo "You can continue with installing Nagios as follows (type 'make'" @echo "without any arguments for a list of all possible options):" @echo "" @echo " make install-commandmode" @echo " - This installs and configures permissions on the" @echo " directory for holding the external command file" @echo "" @echo " make install-config" @echo " - This installs *SAMPLE* config files in $(DESTDIR)$(CFGDIR)" @echo " You'll have to modify these sample files before you can" @echo " use Nagios. Read the HTML documentation for more info" @echo " on doing this. Pay particular attention to the docs on" @echo " object configuration files, as they determine what/how" @echo " things get monitored!" @echo "" install-commandmode: $(INSTALL) -m 775 $(COMMAND_OPTS) -d $(DESTDIR)$(LOGDIR)/rw chmod g+s $(DESTDIR)$(LOGDIR)/rw @echo "" @echo "*** External command directory configured ***" @echo "" @echo "You can continue with installing Nagios as follows (type 'make'" @echo "without any arguments for a list of all possible options):" @echo "" @echo " make install-config" @echo " - This installs *SAMPLE* config files in $(DESTDIR)$(CFGDIR)" @echo " You'll have to modify these sample files before you can" @echo " use Nagios. Read the HTML documentation for more info" @echo " on doing this. Pay particular attention to the docs on" @echo " object configuration files, as they determine what/how" @echo " things get monitored!" @echo "" fullinstall: install install-init install-commandmode # Uninstall is too destructive if base install directory is /usr, etc. #uninstall: # rm -rf $(DESTDIR)$(BINDIR)/nagios $(DESTDIR)$(CGIDIR)/*.cgi $(DESTDIR)$(CFGDIR)/*.cfg $(DESTDIR)$(HTMLDIR) # # Targets for creating packages on various architectures # # Solaris pkgmk PACKDIR=@PACKDIR@ VERSION=@VERSION@ Prototype: if [ ! -d $(PACKDIR) ] ; then mkdir $(PACKDIR); fi if [ ! -d $(PACKDIR)/etc ] ; then mkdir $(PACKDIR)/etc; fi if [ ! -d $(PACKDIR)/etc/init.d ] ; then mkdir $(PACKDIR)/etc/init.d; fi if [ ! -d $(PACKDIR)/etc/nagios ] ; then mkdir $(PACKDIR)/etc/nagios; fi $(MAKE) all $(MAKE) DESTDIR=$(PACKDIR) INIT_OPTS='' INSTALL_OPTS='' COMMAND_OPTS='' nagios_grp='' nagios_usr='' fullinstall $(INSTALL) -m 644 sample-config/nagios.cfg $(PACKDIR)$(CFGDIR)/nagios.cfg.$(VERSION) $(INSTALL) -m 644 sample-config/cgi.cfg $(PACKDIR)$(CFGDIR)/cgi.cfg.$(VERSION) $(INSTALL) -m 640 sample-config/resource.cfg $(PACKDIR)$(CFGDIR)/resource.cfg.$(VERSION) $(INSTALL) -m 664 sample-config/template-object/bigger.cfg $(PACKDIR)$(CFGDIR)/bigger.cfg.$(VERSION) $(INSTALL) -m 664 sample-config/template-object/minimal.cfg $(PACKDIR)$(CFGDIR)/minimal.cfg.$(VERSION) $(INSTALL) -m 664 sample-config/template-object/checkcommands.cfg $(PACKDIR)$(CFGDIR)/checkcommands.cfg.$(VERSION) $(INSTALL) -m 664 sample-config/template-object/misccommands.cfg $(PACKDIR)$(CFGDIR)/misccommands.cfg.$(VERSION) cd contrib; $(MAKE) all; $(MAKE) DESTDIR=$(PACKDIR) INIT_OPTS='' INSTALL_OPTS='' COMMAND_OPTS='' nagios_grp='' nagios_usr='' install echo i pkginfo> Prototype if [ -f checkinstall ] ; then echo i checkinstall>> Prototype; fi if [ -f preinstall ] ; then echo i preinstall>> Prototype; fi if [ -f postinstall ] ; then echo i postinstall>> Prototype; fi pkgproto $(PACKDIR)=/ | sed -e "s|$(LOGNAME) $(GROUP)$$|root root|" | egrep -v "(s|d) none (/|/etc|/var|/usr|/usr/local) " >> Prototype pkg/nagios/pkgmap: Prototype mkdir $(PACKDIR)/nagios pkgmk -o -r / -f Prototype -d $(PACKDIR) nagios nagios.SPARC.pkg.tar.gz: pkg/nagios/pkgmap cd $(PACKDIR) && tar -cf - nagios | gzip -9 -c > ../nagios.SPARC.pkg.tar.gz pkgset: nagios.SPARC.pkg.tar.gz pkgclean: rm -rf pkg Prototype nagios.SPARC.pkg.tar.gz nagios-2.6/OutputTrap.pm0000664000076500007650000000135107436604416014676 0ustar nagiosnagiospackage OutputTrap; # # Methods for use by tied STDOUT in embedded PERL module. # # Simply redirects STDOUT to a temporary file associated with the # current child/grandchild process. # use strict; # Perl before 5.6 does not seem to have warnings.pm ??? #use warnings; use IO::File; sub TIEHANDLE { my ($class, $fn) = @_; my $handle = new IO::File "> $fn" or die "Cannot open embedded work filei $!\n"; bless { FH => $handle, Value => 0}, $class; } sub PRINT { my $self = shift; my $handle = $self -> {FH}; print $handle join("",@_); } sub PRINTF { my $self = shift; my $fmt = shift; my $handle = $self -> {FH}; printf $handle ($fmt,@_); } sub CLOSE { my $self = shift; my $handle = $self -> {FH}; close $handle; } 1; __END__ nagios-2.6/README0000664000076500007650000000243410532717360013066 0ustar nagiosnagiosNagios 2.x README ----------------- Nagios is a host/service/network monitoring program written in C and released under the GNU General Public License. CGI programs are included to allow you to view the current status, history, etc via a web interface if you so desire. Features: 1) Monitoring of network services (via SMTP, POP3, HTTP, PING, etc). 2) A plugin interface to allow for user-developed service monitoring methods. 3) Notifications when problems occur and get resolved (via email, pager, or user-defined method). 4) Ability to define "event handlers" for proactive problem resolution 5) Web output (current status, notifications, problem history, log file, etc.) 6) Automatic log file rotation/archiving For quick and dirty installation instructions, read the INSTALL file. For more complete instructions and program documentation, use a web browser to read the HTML files in the html/docs directory. If this is your first time using Nagios I would highly recommend reading the HTML documentation. For instructions on upgrading to the current version of Nagios, read the UPGRADING file carefully. Visit the Nagios homepage at http://www.nagios.org for online documentation, new releases, bug reports, information on the mailing lists, etc. -- Ethan Galstad (nagios@nagios.org) nagios-2.6/UPGRADING0000664000076500007650000000110110532717360013437 0ustar nagiosnagiosUPGRADING TO NAGIOS 2.6 ======================= For Nagios 2.x Users: --------------------- If you're upgrading from an earlier version of Nagios 2.x, upgrading is pretty simple. Nothing has changed with the configuration files, so you can simply recompile and install the new binaries and web interface and you'll be good to go. For Nagios 1.x Users: --------------------- If you're upgrading from Nagios 1.0, there will be a few modifications that you'll need to make to your config files. Read the "What's New" section of the HTML documentation for more information. nagios-2.6/config.guess0000775000076500007650000012555210364217474014541 0ustar nagiosnagios#! /bin/sh # Attempt to guess a canonical system name. # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, # 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. timestamp='2006-01-02' # This file 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., 51 Franklin Street - Fifth Floor, Boston, MA # 02110-1301, USA. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Originally written by Per Bothner . # Please send patches to . Submit a context # diff and a properly formatted ChangeLog entry. # # This script attempts to guess a canonical system name similar to # config.sub. If it succeeds, it prints the system name on stdout, and # exits with 0. Otherwise, it exits with 1. # # The plan is that this can be called by configure scripts if you # don't specify an explicit build system type. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] Output the configuration name of the system \`$me' is run on. Operation modes: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" >&2 exit 1 ;; * ) break ;; esac done if test $# != 0; then echo "$me: too many arguments$help" >&2 exit 1 fi trap 'exit 1' 1 2 15 # CC_FOR_BUILD -- compiler used by this script. Note that the use of a # compiler to aid in system detection is discouraged as it requires # temporary files to be created and, as you can see below, it is a # headache to deal with in a portable fashion. # Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still # use `HOST_CC' if defined, but it is deprecated. # Portable tmp directory creation inspired by the Autoconf team. set_cc_for_build=' trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; : ${TMPDIR=/tmp} ; { tmp=`(umask 077 && mktemp -d -q "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; dummy=$tmp/dummy ; tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; case $CC_FOR_BUILD,$HOST_CC,$CC in ,,) echo "int x;" > $dummy.c ; for c in cc gcc c89 c99 ; do if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then CC_FOR_BUILD="$c"; break ; fi ; done ; if test x"$CC_FOR_BUILD" = x ; then CC_FOR_BUILD=no_compiler_found ; fi ;; ,,*) CC_FOR_BUILD=$CC ;; ,*,*) CC_FOR_BUILD=$HOST_CC ;; esac ; set_cc_for_build= ;' # This is needed to find uname on a Pyramid OSx when run in the BSD universe. # (ghazi@noc.rutgers.edu 1994-08-24) if (test -f /.attbin/uname) >/dev/null 2>&1 ; then PATH=$PATH:/.attbin ; export PATH fi UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown # Note: order is significant - the case branches are not exclusive. case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in *:NetBSD:*:*) # NetBSD (nbsd) targets should (where applicable) match one or # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently # switched to ELF, *-*-netbsd* would select the old # object file format. This provides both forward # compatibility and a consistent mechanism for selecting the # object file format. # # Note: NetBSD doesn't particularly care about the vendor # portion of the name. We always set it to "unknown". sysctl="sysctl -n hw.machine_arch" UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ /usr/sbin/$sysctl 2>/dev/null || echo unknown)` case "${UNAME_MACHINE_ARCH}" in armeb) machine=armeb-unknown ;; arm*) machine=arm-unknown ;; sh3el) machine=shl-unknown ;; sh3eb) machine=sh-unknown ;; *) machine=${UNAME_MACHINE_ARCH}-unknown ;; esac # The Operating System including object format, if it has switched # to ELF recently, or will in the future. case "${UNAME_MACHINE_ARCH}" in arm*|i386|m68k|ns32k|sh3*|sparc|vax) eval $set_cc_for_build if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep __ELF__ >/dev/null then # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). # Return netbsd for either. FIX? os=netbsd else os=netbsdelf fi ;; *) os=netbsd ;; esac # The OS release # Debian GNU/NetBSD machines have a different userland, and # thus, need a distinct triplet. However, they do not need # kernel version information, so it can be replaced with a # suitable tag, in the style of linux-gnu. case "${UNAME_VERSION}" in Debian*) release='-gnu' ;; *) release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` ;; esac # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: # contains redundant information, the shorter form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. echo "${machine}-${os}${release}" exit ;; *:OpenBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} exit ;; *:ekkoBSD:*:*) echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} exit ;; *:SolidBSD:*:*) echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} exit ;; macppc:MirBSD:*:*) echo powerppc-unknown-mirbsd${UNAME_RELEASE} exit ;; *:MirBSD:*:*) echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} exit ;; alpha:OSF1:*:*) case $UNAME_RELEASE in *4.0) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` ;; *5.*) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` ;; esac # According to Compaq, /usr/sbin/psrinfo has been available on # OSF/1 and Tru64 systems produced since 1995. I hope that # covers most systems running today. This code pipes the CPU # types through head -n 1, so we only detect the type of CPU 0. ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` case "$ALPHA_CPU_TYPE" in "EV4 (21064)") UNAME_MACHINE="alpha" ;; "EV4.5 (21064)") UNAME_MACHINE="alpha" ;; "LCA4 (21066/21068)") UNAME_MACHINE="alpha" ;; "EV5 (21164)") UNAME_MACHINE="alphaev5" ;; "EV5.6 (21164A)") UNAME_MACHINE="alphaev56" ;; "EV5.6 (21164PC)") UNAME_MACHINE="alphapca56" ;; "EV5.7 (21164PC)") UNAME_MACHINE="alphapca57" ;; "EV6 (21264)") UNAME_MACHINE="alphaev6" ;; "EV6.7 (21264A)") UNAME_MACHINE="alphaev67" ;; "EV6.8CB (21264C)") UNAME_MACHINE="alphaev68" ;; "EV6.8AL (21264B)") UNAME_MACHINE="alphaev68" ;; "EV6.8CX (21264D)") UNAME_MACHINE="alphaev68" ;; "EV6.9A (21264/EV69A)") UNAME_MACHINE="alphaev69" ;; "EV7 (21364)") UNAME_MACHINE="alphaev7" ;; "EV7.9 (21364A)") UNAME_MACHINE="alphaev79" ;; esac # A Pn.n version is a patched version. # A Vn.n version is a released version. # A Tn.n version is a released field test version. # A Xn.n version is an unreleased experimental baselevel. # 1.2 uses "1.2" for uname -r. echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` exit ;; Alpha\ *:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # Should we change UNAME_MACHINE based on the output of uname instead # of the specific Alpha model? echo alpha-pc-interix exit ;; 21064:Windows_NT:50:3) echo alpha-dec-winnt3.5 exit ;; Amiga*:UNIX_System_V:4.0:*) echo m68k-unknown-sysv4 exit ;; *:[Aa]miga[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-amigaos exit ;; *:[Mm]orph[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-morphos exit ;; *:OS/390:*:*) echo i370-ibm-openedition exit ;; *:z/VM:*:*) echo s390-ibm-zvmoe exit ;; *:OS400:*:*) echo powerpc-ibm-os400 exit ;; arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) echo arm-acorn-riscix${UNAME_RELEASE} exit ;; arm:riscos:*:*|arm:RISCOS:*:*) echo arm-unknown-riscos exit ;; SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) echo hppa1.1-hitachi-hiuxmpp exit ;; Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. if test "`(/bin/universe) 2>/dev/null`" = att ; then echo pyramid-pyramid-sysv3 else echo pyramid-pyramid-bsd fi exit ;; NILE*:*:*:dcosx) echo pyramid-pyramid-svr4 exit ;; DRS?6000:unix:4.0:6*) echo sparc-icl-nx6 exit ;; DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) case `/usr/bin/uname -p` in sparc) echo sparc-icl-nx7; exit ;; esac ;; sun4H:SunOS:5.*:*) echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; i86pc:SunOS:5.*:*) echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:6*:*) # According to config.sub, this is the proper way to canonicalize # SunOS6. Hard to guess exactly what SunOS6 will be like, but # it's likely to be more like Solaris than SunOS4. echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:*:*) case "`/usr/bin/arch -k`" in Series*|S4*) UNAME_RELEASE=`uname -v` ;; esac # Japanese Language versions have a version number like `4.1.3-JL'. echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` exit ;; sun3*:SunOS:*:*) echo m68k-sun-sunos${UNAME_RELEASE} exit ;; sun*:*:4.2BSD:*) UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 case "`/bin/arch`" in sun3) echo m68k-sun-sunos${UNAME_RELEASE} ;; sun4) echo sparc-sun-sunos${UNAME_RELEASE} ;; esac exit ;; aushp:SunOS:*:*) echo sparc-auspex-sunos${UNAME_RELEASE} exit ;; # The situation for MiNT is a little confusing. The machine name # can be virtually everything (everything which is not # "atarist" or "atariste" at least should have a processor # > m68000). The system name ranges from "MiNT" over "FreeMiNT" # to the lowercase version "mint" (or "freemint"). Finally # the system name "TOS" denotes a system which is actually not # MiNT. But MiNT is downward compatible to TOS, so this should # be no problem. atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) echo m68k-milan-mint${UNAME_RELEASE} exit ;; hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) echo m68k-hades-mint${UNAME_RELEASE} exit ;; *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) echo m68k-unknown-mint${UNAME_RELEASE} exit ;; m68k:machten:*:*) echo m68k-apple-machten${UNAME_RELEASE} exit ;; powerpc:machten:*:*) echo powerpc-apple-machten${UNAME_RELEASE} exit ;; RISC*:Mach:*:*) echo mips-dec-mach_bsd4.3 exit ;; RISC*:ULTRIX:*:*) echo mips-dec-ultrix${UNAME_RELEASE} exit ;; VAX*:ULTRIX*:*:*) echo vax-dec-ultrix${UNAME_RELEASE} exit ;; 2020:CLIX:*:* | 2430:CLIX:*:*) echo clipper-intergraph-clix${UNAME_RELEASE} exit ;; mips:*:*:UMIPS | mips:*:*:RISCos) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #ifdef __cplusplus #include /* for printf() prototype */ int main (int argc, char *argv[]) { #else int main (argc, argv) int argc; char *argv[]; { #endif #if defined (host_mips) && defined (MIPSEB) #if defined (SYSTYPE_SYSV) printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_SVR4) printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); #endif #endif exit (-1); } EOF $CC_FOR_BUILD -o $dummy $dummy.c && dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && SYSTEM_NAME=`$dummy $dummyarg` && { echo "$SYSTEM_NAME"; exit; } echo mips-mips-riscos${UNAME_RELEASE} exit ;; Motorola:PowerMAX_OS:*:*) echo powerpc-motorola-powermax exit ;; Motorola:*:4.3:PL8-*) echo powerpc-harris-powermax exit ;; Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) echo powerpc-harris-powermax exit ;; Night_Hawk:Power_UNIX:*:*) echo powerpc-harris-powerunix exit ;; m88k:CX/UX:7*:*) echo m88k-harris-cxux7 exit ;; m88k:*:4*:R4*) echo m88k-motorola-sysv4 exit ;; m88k:*:3*:R3*) echo m88k-motorola-sysv3 exit ;; AViiON:dgux:*:*) # DG/UX returns AViiON for all architectures UNAME_PROCESSOR=`/usr/bin/uname -p` if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] then if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ [ ${TARGET_BINARY_INTERFACE}x = x ] then echo m88k-dg-dgux${UNAME_RELEASE} else echo m88k-dg-dguxbcs${UNAME_RELEASE} fi else echo i586-dg-dgux${UNAME_RELEASE} fi exit ;; M88*:DolphinOS:*:*) # DolphinOS (SVR3) echo m88k-dolphin-sysv3 exit ;; M88*:*:R3*:*) # Delta 88k system running SVR3 echo m88k-motorola-sysv3 exit ;; XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) echo m88k-tektronix-sysv3 exit ;; Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) echo m68k-tektronix-bsd exit ;; *:IRIX*:*:*) echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` exit ;; ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' i*86:AIX:*:*) echo i386-ibm-aix exit ;; ia64:AIX:*:*) if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} exit ;; *:AIX:2:3) if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include main() { if (!__power_pc()) exit(1); puts("powerpc-ibm-aix3.2.5"); exit(0); } EOF if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` then echo "$SYSTEM_NAME" else echo rs6000-ibm-aix3.2.5 fi elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then echo rs6000-ibm-aix3.2.4 else echo rs6000-ibm-aix3.2 fi exit ;; *:AIX:*:[45]) IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then IBM_ARCH=rs6000 else IBM_ARCH=powerpc fi if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi echo ${IBM_ARCH}-ibm-aix${IBM_REV} exit ;; *:AIX:*:*) echo rs6000-ibm-aix exit ;; ibmrt:4.4BSD:*|romp-ibm:BSD:*) echo romp-ibm-bsd4.4 exit ;; ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to exit ;; # report: romp-ibm BSD 4.3 *:BOSX:*:*) echo rs6000-bull-bosx exit ;; DPX/2?00:B.O.S.:*:*) echo m68k-bull-sysv3 exit ;; 9000/[34]??:4.3bsd:1.*:*) echo m68k-hp-bsd exit ;; hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) echo m68k-hp-bsd4.4 exit ;; 9000/[34678]??:HP-UX:*:*) HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` case "${UNAME_MACHINE}" in 9000/31? ) HP_ARCH=m68000 ;; 9000/[34]?? ) HP_ARCH=m68k ;; 9000/[678][0-9][0-9]) if [ -x /usr/bin/getconf ]; then sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` case "${sc_cpu_version}" in 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 532) # CPU_PA_RISC2_0 case "${sc_kernel_bits}" in 32) HP_ARCH="hppa2.0n" ;; 64) HP_ARCH="hppa2.0w" ;; '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 esac ;; esac fi if [ "${HP_ARCH}" = "" ]; then eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #define _HPUX_SOURCE #include #include int main () { #if defined(_SC_KERNEL_BITS) long bits = sysconf(_SC_KERNEL_BITS); #endif long cpu = sysconf (_SC_CPU_VERSION); switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0"); break; case CPU_PA_RISC1_1: puts ("hppa1.1"); break; case CPU_PA_RISC2_0: #if defined(_SC_KERNEL_BITS) switch (bits) { case 64: puts ("hppa2.0w"); break; case 32: puts ("hppa2.0n"); break; default: puts ("hppa2.0"); break; } break; #else /* !defined(_SC_KERNEL_BITS) */ puts ("hppa2.0"); break; #endif default: puts ("hppa1.0"); break; } exit (0); } EOF (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` test -z "$HP_ARCH" && HP_ARCH=hppa fi ;; esac if [ ${HP_ARCH} = "hppa2.0w" ] then eval $set_cc_for_build # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler # generating 64-bit code. GNU and HP use different nomenclature: # # $ CC_FOR_BUILD=cc ./config.guess # => hppa2.0w-hp-hpux11.23 # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess # => hppa64-hp-hpux11.23 if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | grep __LP64__ >/dev/null then HP_ARCH="hppa2.0w" else HP_ARCH="hppa64" fi fi echo ${HP_ARCH}-hp-hpux${HPUX_REV} exit ;; ia64:HP-UX:*:*) HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` echo ia64-hp-hpux${HPUX_REV} exit ;; 3050*:HI-UX:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include int main () { long cpu = sysconf (_SC_CPU_VERSION); /* The order matters, because CPU_IS_HP_MC68K erroneously returns true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct results, however. */ if (CPU_IS_PA_RISC (cpu)) { switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; default: puts ("hppa-hitachi-hiuxwe2"); break; } } else if (CPU_IS_HP_MC68K (cpu)) puts ("m68k-hitachi-hiuxwe2"); else puts ("unknown-hitachi-hiuxwe2"); exit (0); } EOF $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && { echo "$SYSTEM_NAME"; exit; } echo unknown-hitachi-hiuxwe2 exit ;; 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) echo hppa1.1-hp-bsd exit ;; 9000/8??:4.3bsd:*:*) echo hppa1.0-hp-bsd exit ;; *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) echo hppa1.0-hp-mpeix exit ;; hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) echo hppa1.1-hp-osf exit ;; hp8??:OSF1:*:*) echo hppa1.0-hp-osf exit ;; i*86:OSF1:*:*) if [ -x /usr/sbin/sysversion ] ; then echo ${UNAME_MACHINE}-unknown-osf1mk else echo ${UNAME_MACHINE}-unknown-osf1 fi exit ;; parisc*:Lites*:*:*) echo hppa1.1-hp-lites exit ;; C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) echo c1-convex-bsd exit ;; C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit ;; C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) echo c34-convex-bsd exit ;; C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) echo c38-convex-bsd exit ;; C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) echo c4-convex-bsd exit ;; CRAY*Y-MP:*:*:*) echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*[A-Z]90:*:*:*) echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ -e 's/\.[^.]*$/.X/' exit ;; CRAY*TS:*:*:*) echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*T3E:*:*:*) echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*SV1:*:*:*) echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; *:UNICOS/mp:*:*) echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; 5000:UNIX_System_V:4.*:*) FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} exit ;; sparc*:BSD/OS:*:*) echo sparc-unknown-bsdi${UNAME_RELEASE} exit ;; *:BSD/OS:*:*) echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} exit ;; *:FreeBSD:*:*) case ${UNAME_MACHINE} in pc98) echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; *) echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; esac exit ;; i*:CYGWIN*:*) echo ${UNAME_MACHINE}-pc-cygwin exit ;; i*:MINGW*:*) echo ${UNAME_MACHINE}-pc-mingw32 exit ;; i*:windows32*:*) # uname -m includes "-pc" on this system. echo ${UNAME_MACHINE}-mingw32 exit ;; i*:PW*:*) echo ${UNAME_MACHINE}-pc-pw32 exit ;; x86:Interix*:[345]*) echo i586-pc-interix${UNAME_RELEASE}|sed -e 's/\..*//' exit ;; [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) echo i${UNAME_MACHINE}-pc-mks exit ;; i*:Windows_NT*:* | Pentium*:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we # UNAME_MACHINE based on the output of uname instead of i386? echo i586-pc-interix exit ;; i*:UWIN*:*) echo ${UNAME_MACHINE}-pc-uwin exit ;; amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) echo x86_64-unknown-cygwin exit ;; p*:CYGWIN*:*) echo powerpcle-unknown-cygwin exit ;; prep*:SunOS:5.*:*) echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; *:GNU:*:*) # the GNU system echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` exit ;; *:GNU/*:*:*) # other systems with GNU libc and userland echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu exit ;; i*86:Minix:*:*) echo ${UNAME_MACHINE}-pc-minix exit ;; arm*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; cris:Linux:*:*) echo cris-axis-linux-gnu exit ;; crisv32:Linux:*:*) echo crisv32-axis-linux-gnu exit ;; frv:Linux:*:*) echo frv-unknown-linux-gnu exit ;; ia64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; m32r*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; m68*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; mips:Linux:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #undef CPU #undef mips #undef mipsel #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) CPU=mipsel #else #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) CPU=mips #else CPU= #endif #endif EOF eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '/^CPU/{s: ::g;p;}'`" test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } ;; mips64:Linux:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #undef CPU #undef mips64 #undef mips64el #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) CPU=mips64el #else #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) CPU=mips64 #else CPU= #endif #endif EOF eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '/^CPU/{s: ::g;p;}'`" test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } ;; or32:Linux:*:*) echo or32-unknown-linux-gnu exit ;; ppc:Linux:*:*) echo powerpc-unknown-linux-gnu exit ;; ppc64:Linux:*:*) echo powerpc64-unknown-linux-gnu exit ;; alpha:Linux:*:*) case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in EV5) UNAME_MACHINE=alphaev5 ;; EV56) UNAME_MACHINE=alphaev56 ;; PCA56) UNAME_MACHINE=alphapca56 ;; PCA57) UNAME_MACHINE=alphapca56 ;; EV6) UNAME_MACHINE=alphaev6 ;; EV67) UNAME_MACHINE=alphaev67 ;; EV68*) UNAME_MACHINE=alphaev68 ;; esac objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} exit ;; parisc:Linux:*:* | hppa:Linux:*:*) # Look for CPU level case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in PA7*) echo hppa1.1-unknown-linux-gnu ;; PA8*) echo hppa2.0-unknown-linux-gnu ;; *) echo hppa-unknown-linux-gnu ;; esac exit ;; parisc64:Linux:*:* | hppa64:Linux:*:*) echo hppa64-unknown-linux-gnu exit ;; s390:Linux:*:* | s390x:Linux:*:*) echo ${UNAME_MACHINE}-ibm-linux exit ;; sh64*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; sh*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; sparc:Linux:*:* | sparc64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; vax:Linux:*:*) echo ${UNAME_MACHINE}-dec-linux-gnu exit ;; x86_64:Linux:*:*) echo x86_64-unknown-linux-gnu exit ;; i*86:Linux:*:*) # The BFD linker knows what the default object file format is, so # first see if it will tell us. cd to the root directory to prevent # problems with other programs or directories called `ld' in the path. # Set LC_ALL=C to ensure ld outputs messages in English. ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \ | sed -ne '/supported targets:/!d s/[ ][ ]*/ /g s/.*supported targets: *// s/ .*// p'` case "$ld_supported_targets" in elf32-i386) TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu" ;; a.out-i386-linux) echo "${UNAME_MACHINE}-pc-linux-gnuaout" exit ;; coff-i386) echo "${UNAME_MACHINE}-pc-linux-gnucoff" exit ;; "") # Either a pre-BFD a.out linker (linux-gnuoldld) or # one that does not give us useful --help. echo "${UNAME_MACHINE}-pc-linux-gnuoldld" exit ;; esac # Determine whether the default compiler is a.out or elf eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include #ifdef __ELF__ # ifdef __GLIBC__ # if __GLIBC__ >= 2 LIBC=gnu # else LIBC=gnulibc1 # endif # else LIBC=gnulibc1 # endif #else #if defined(__INTEL_COMPILER) || defined(__PGI) LIBC=gnu #else LIBC=gnuaout #endif #endif #ifdef __dietlibc__ LIBC=dietlibc #endif EOF eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '/^LIBC/{s: ::g;p;}'`" test x"${LIBC}" != x && { echo "${UNAME_MACHINE}-pc-linux-${LIBC}" exit } test x"${TENTATIVE}" != x && { echo "${TENTATIVE}"; exit; } ;; i*86:DYNIX/ptx:4*:*) # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. # earlier versions are messed up and put the nodename in both # sysname and nodename. echo i386-sequent-sysv4 exit ;; i*86:UNIX_SV:4.2MP:2.*) # Unixware is an offshoot of SVR4, but it has its own version # number series starting with 2... # I am not positive that other SVR4 systems won't match this, # I just have to hope. -- rms. # Use sysv4.2uw... so that sysv4* matches it. echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} exit ;; i*86:OS/2:*:*) # If we were able to find `uname', then EMX Unix compatibility # is probably installed. echo ${UNAME_MACHINE}-pc-os2-emx exit ;; i*86:XTS-300:*:STOP) echo ${UNAME_MACHINE}-unknown-stop exit ;; i*86:atheos:*:*) echo ${UNAME_MACHINE}-unknown-atheos exit ;; i*86:syllable:*:*) echo ${UNAME_MACHINE}-pc-syllable exit ;; i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*) echo i386-unknown-lynxos${UNAME_RELEASE} exit ;; i*86:*DOS:*:*) echo ${UNAME_MACHINE}-pc-msdosdjgpp exit ;; i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} else echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} fi exit ;; i*86:*:5:[678]*) # UnixWare 7.x, OpenUNIX and OpenServer 6. case `/bin/uname -X | grep "^Machine"` in *486*) UNAME_MACHINE=i486 ;; *Pentium) UNAME_MACHINE=i586 ;; *Pent*|*Celeron) UNAME_MACHINE=i686 ;; esac echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} exit ;; i*86:*:3.2:*) if test -f /usr/options/cb.name; then UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ && UNAME_MACHINE=i586 (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ && UNAME_MACHINE=i686 (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ && UNAME_MACHINE=i686 echo ${UNAME_MACHINE}-pc-sco$UNAME_REL else echo ${UNAME_MACHINE}-pc-sysv32 fi exit ;; pc:*:*:*) # Left here for compatibility: # uname -m prints for DJGPP always 'pc', but it prints nothing about # the processor, so we play safe by assuming i386. echo i386-pc-msdosdjgpp exit ;; Intel:Mach:3*:*) echo i386-pc-mach3 exit ;; paragon:*:*:*) echo i860-intel-osf1 exit ;; i860:*:4.*:*) # i860-SVR4 if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 else # Add other i860-SVR4 vendors below as they are discovered. echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 fi exit ;; mini*:CTIX:SYS*5:*) # "miniframe" echo m68010-convergent-sysv exit ;; mc68k:UNIX:SYSTEM5:3.51m) echo m68k-convergent-sysv exit ;; M680?0:D-NIX:5.3:*) echo m68k-diab-dnix exit ;; M68*:*:R3V[5678]*:*) test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) OS_REL='' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4; exit; } ;; m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) echo m68k-unknown-lynxos${UNAME_RELEASE} exit ;; mc68030:UNIX_System_V:4.*:*) echo m68k-atari-sysv4 exit ;; TSUNAMI:LynxOS:2.*:*) echo sparc-unknown-lynxos${UNAME_RELEASE} exit ;; rs6000:LynxOS:2.*:*) echo rs6000-unknown-lynxos${UNAME_RELEASE} exit ;; PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*) echo powerpc-unknown-lynxos${UNAME_RELEASE} exit ;; SM[BE]S:UNIX_SV:*:*) echo mips-dde-sysv${UNAME_RELEASE} exit ;; RM*:ReliantUNIX-*:*:*) echo mips-sni-sysv4 exit ;; RM*:SINIX-*:*:*) echo mips-sni-sysv4 exit ;; *:SINIX-*:*:*) if uname -p 2>/dev/null >/dev/null ; then UNAME_MACHINE=`(uname -p) 2>/dev/null` echo ${UNAME_MACHINE}-sni-sysv4 else echo ns32k-sni-sysv fi exit ;; PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort # says echo i586-unisys-sysv4 exit ;; *:UNIX_System_V:4*:FTX*) # From Gerald Hewes . # How about differentiating between stratus architectures? -djm echo hppa1.1-stratus-sysv4 exit ;; *:*:*:FTX*) # From seanf@swdc.stratus.com. echo i860-stratus-sysv4 exit ;; i*86:VOS:*:*) # From Paul.Green@stratus.com. echo ${UNAME_MACHINE}-stratus-vos exit ;; *:VOS:*:*) # From Paul.Green@stratus.com. echo hppa1.1-stratus-vos exit ;; mc68*:A/UX:*:*) echo m68k-apple-aux${UNAME_RELEASE} exit ;; news*:NEWS-OS:6*:*) echo mips-sony-newsos6 exit ;; R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) if [ -d /usr/nec ]; then echo mips-nec-sysv${UNAME_RELEASE} else echo mips-unknown-sysv${UNAME_RELEASE} fi exit ;; BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. echo powerpc-be-beos exit ;; BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. echo powerpc-apple-beos exit ;; BePC:BeOS:*:*) # BeOS running on Intel PC compatible. echo i586-pc-beos exit ;; SX-4:SUPER-UX:*:*) echo sx4-nec-superux${UNAME_RELEASE} exit ;; SX-5:SUPER-UX:*:*) echo sx5-nec-superux${UNAME_RELEASE} exit ;; SX-6:SUPER-UX:*:*) echo sx6-nec-superux${UNAME_RELEASE} exit ;; Power*:Rhapsody:*:*) echo powerpc-apple-rhapsody${UNAME_RELEASE} exit ;; *:Rhapsody:*:*) echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} exit ;; *:Darwin:*:*) UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown case $UNAME_PROCESSOR in unknown) UNAME_PROCESSOR=powerpc ;; esac echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} exit ;; *:procnto*:*:* | *:QNX:[0123456789]*:*) UNAME_PROCESSOR=`uname -p` if test "$UNAME_PROCESSOR" = "x86"; then UNAME_PROCESSOR=i386 UNAME_MACHINE=pc fi echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} exit ;; *:QNX:*:4*) echo i386-pc-qnx exit ;; NSE-?:NONSTOP_KERNEL:*:*) echo nse-tandem-nsk${UNAME_RELEASE} exit ;; NSR-?:NONSTOP_KERNEL:*:*) echo nsr-tandem-nsk${UNAME_RELEASE} exit ;; *:NonStop-UX:*:*) echo mips-compaq-nonstopux exit ;; BS2000:POSIX*:*:*) echo bs2000-siemens-sysv exit ;; DS/*:UNIX_System_V:*:*) echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} exit ;; *:Plan9:*:*) # "uname -m" is not consistent, so use $cputype instead. 386 # is converted to i386 for consistency with other x86 # operating systems. if test "$cputype" = "386"; then UNAME_MACHINE=i386 else UNAME_MACHINE="$cputype" fi echo ${UNAME_MACHINE}-unknown-plan9 exit ;; *:TOPS-10:*:*) echo pdp10-unknown-tops10 exit ;; *:TENEX:*:*) echo pdp10-unknown-tenex exit ;; KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) echo pdp10-dec-tops20 exit ;; XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) echo pdp10-xkl-tops20 exit ;; *:TOPS-20:*:*) echo pdp10-unknown-tops20 exit ;; *:ITS:*:*) echo pdp10-unknown-its exit ;; SEI:*:*:SEIUX) echo mips-sei-seiux${UNAME_RELEASE} exit ;; *:DragonFly:*:*) echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` exit ;; *:*VMS:*:*) UNAME_MACHINE=`(uname -p) 2>/dev/null` case "${UNAME_MACHINE}" in A*) echo alpha-dec-vms ; exit ;; I*) echo ia64-dec-vms ; exit ;; V*) echo vax-dec-vms ; exit ;; esac ;; *:XENIX:*:SysV) echo i386-pc-xenix exit ;; i*86:skyos:*:*) echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' exit ;; i*86:rdos:*:*) echo ${UNAME_MACHINE}-pc-rdos exit ;; esac #echo '(No uname command or uname output not recognized.)' 1>&2 #echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 eval $set_cc_for_build cat >$dummy.c < # include #endif main () { #if defined (sony) #if defined (MIPSEB) /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, I don't know.... */ printf ("mips-sony-bsd\n"); exit (0); #else #include printf ("m68k-sony-newsos%s\n", #ifdef NEWSOS4 "4" #else "" #endif ); exit (0); #endif #endif #if defined (__arm) && defined (__acorn) && defined (__unix) printf ("arm-acorn-riscix\n"); exit (0); #endif #if defined (hp300) && !defined (hpux) printf ("m68k-hp-bsd\n"); exit (0); #endif #if defined (NeXT) #if !defined (__ARCHITECTURE__) #define __ARCHITECTURE__ "m68k" #endif int version; version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; if (version < 4) printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); else printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); exit (0); #endif #if defined (MULTIMAX) || defined (n16) #if defined (UMAXV) printf ("ns32k-encore-sysv\n"); exit (0); #else #if defined (CMU) printf ("ns32k-encore-mach\n"); exit (0); #else printf ("ns32k-encore-bsd\n"); exit (0); #endif #endif #endif #if defined (__386BSD__) printf ("i386-pc-bsd\n"); exit (0); #endif #if defined (sequent) #if defined (i386) printf ("i386-sequent-dynix\n"); exit (0); #endif #if defined (ns32000) printf ("ns32k-sequent-dynix\n"); exit (0); #endif #endif #if defined (_SEQUENT_) struct utsname un; uname(&un); if (strncmp(un.version, "V2", 2) == 0) { printf ("i386-sequent-ptx2\n"); exit (0); } if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ printf ("i386-sequent-ptx1\n"); exit (0); } printf ("i386-sequent-ptx\n"); exit (0); #endif #if defined (vax) # if !defined (ultrix) # include # if defined (BSD) # if BSD == 43 printf ("vax-dec-bsd4.3\n"); exit (0); # else # if BSD == 199006 printf ("vax-dec-bsd4.3reno\n"); exit (0); # else printf ("vax-dec-bsd\n"); exit (0); # endif # endif # else printf ("vax-dec-bsd\n"); exit (0); # endif # else printf ("vax-dec-ultrix\n"); exit (0); # endif #endif #if defined (alliant) && defined (i860) printf ("i860-alliant-bsd\n"); exit (0); #endif exit (1); } EOF $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && { echo "$SYSTEM_NAME"; exit; } # Apollos put the system type in the environment. test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } # Convex versions that predate uname can use getsysinfo(1) if [ -x /usr/convex/getsysinfo ] then case `getsysinfo -f cpu_type` in c1*) echo c1-convex-bsd exit ;; c2*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit ;; c34*) echo c34-convex-bsd exit ;; c38*) echo c38-convex-bsd exit ;; c4*) echo c4-convex-bsd exit ;; esac fi cat >&2 < in order to provide the needed information to handle your system. config.guess timestamp = $timestamp uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` /bin/uname -X = `(/bin/uname -X) 2>/dev/null` hostinfo = `(hostinfo) 2>/dev/null` /bin/universe = `(/bin/universe) 2>/dev/null` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` /bin/arch = `(/bin/arch) 2>/dev/null` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` UNAME_MACHINE = ${UNAME_MACHINE} UNAME_RELEASE = ${UNAME_RELEASE} UNAME_SYSTEM = ${UNAME_SYSTEM} UNAME_VERSION = ${UNAME_VERSION} EOF exit 1 # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: nagios-2.6/config.sub0000775000076500007650000007706010364217475014205 0ustar nagiosnagios#! /bin/sh # Configuration validation subroutine script. # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, # 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. timestamp='2006-01-02' # This file is (in principle) common to ALL GNU software. # The presence of a machine in this file suggests that SOME GNU software # can handle that machine. It does not imply ALL GNU software can. # # This file 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., 51 Franklin Street - Fifth Floor, Boston, MA # 02110-1301, USA. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Please send patches to . Submit a context # diff and a properly formatted ChangeLog entry. # # Configuration subroutine to validate and canonicalize a configuration type. # Supply the specified configuration type as an argument. # If it is invalid, we print an error message on stderr and exit with code 1. # Otherwise, we print the canonical config type on stdout and succeed. # This file is supposed to be the same for all GNU packages # and recognize all the CPU types, system types and aliases # that are meaningful with *any* GNU software. # Each package is responsible for reporting which valid configurations # it does not support. The user should be able to distinguish # a failure to support a valid configuration from a meaningless # configuration. # The goal of this file is to map all the various variations of a given # machine specification into a single specification in the form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM # or in some cases, the newer four-part form: # CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM # It is wrong to echo any other type of specification. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] CPU-MFR-OPSYS $0 [OPTION] ALIAS Canonicalize a configuration name. Operation modes: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.sub ($timestamp) Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" exit 1 ;; *local*) # First pass through any local machine types. echo $1 exit ;; * ) break ;; esac done case $# in 0) echo "$me: missing argument$help" >&2 exit 1;; 1) ;; *) echo "$me: too many arguments$help" >&2 exit 1;; esac # Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). # Here we must recognize all the valid KERNEL-OS combinations. maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` case $maybe_os in nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \ uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \ storm-chaos* | os2-emx* | rtmk-nova*) os=-$maybe_os basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` ;; *) basic_machine=`echo $1 | sed 's/-[^-]*$//'` if [ $basic_machine != $1 ] then os=`echo $1 | sed 's/.*-/-/'` else os=; fi ;; esac ### Let's recognize common machines as not being operating systems so ### that things like config.sub decstation-3100 work. We also ### recognize some manufacturers as not being operating systems, so we ### can provide default operating systems below. case $os in -sun*os*) # Prevent following clause from handling this invalid input. ;; -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ -apple | -axis | -knuth | -cray) os= basic_machine=$1 ;; -sim | -cisco | -oki | -wec | -winbond) os= basic_machine=$1 ;; -scout) ;; -wrs) os=-vxworks basic_machine=$1 ;; -chorusos*) os=-chorusos basic_machine=$1 ;; -chorusrdb) os=-chorusrdb basic_machine=$1 ;; -hiux*) os=-hiuxwe2 ;; -sco6) os=-sco5v6 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco5) os=-sco3.2v5 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco4) os=-sco3.2v4 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2.[4-9]*) os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2v[4-9]*) # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco5v6*) # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco*) os=-sco3.2v2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -udk*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -isc) os=-isc2.2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -clix*) basic_machine=clipper-intergraph ;; -isc*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -lynx*) os=-lynxos ;; -ptx*) basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` ;; -windowsnt*) os=`echo $os | sed -e 's/windowsnt/winnt/'` ;; -psos*) os=-psos ;; -mint | -mint[0-9]*) basic_machine=m68k-atari os=-mint ;; esac # Decode aliases for certain CPU-COMPANY combinations. case $basic_machine in # Recognize the basic CPU types without company name. # Some are omitted here because they have special meanings below. 1750a | 580 \ | a29k \ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ | am33_2.0 \ | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \ | bfin \ | c4x | clipper \ | d10v | d30v | dlx | dsp16xx \ | fr30 | frv \ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ | i370 | i860 | i960 | ia64 \ | ip2k | iq2000 \ | m32r | m32rle | m68000 | m68k | m88k | maxq | mb | microblaze | mcore \ | mips | mipsbe | mipseb | mipsel | mipsle \ | mips16 \ | mips64 | mips64el \ | mips64vr | mips64vrel \ | mips64orion | mips64orionel \ | mips64vr4100 | mips64vr4100el \ | mips64vr4300 | mips64vr4300el \ | mips64vr5000 | mips64vr5000el \ | mips64vr5900 | mips64vr5900el \ | mipsisa32 | mipsisa32el \ | mipsisa32r2 | mipsisa32r2el \ | mipsisa64 | mipsisa64el \ | mipsisa64r2 | mipsisa64r2el \ | mipsisa64sb1 | mipsisa64sb1el \ | mipsisa64sr71k | mipsisa64sr71kel \ | mipstx39 | mipstx39el \ | mn10200 | mn10300 \ | mt \ | msp430 \ | ns16k | ns32k \ | or32 \ | pdp10 | pdp11 | pj | pjl \ | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ | pyramid \ | sh | sh[1234] | sh[24]a | sh[23]e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \ | sh64 | sh64le \ | sparc | sparc64 | sparc64b | sparc86x | sparclet | sparclite \ | sparcv8 | sparcv9 | sparcv9b \ | strongarm \ | tahoe | thumb | tic4x | tic80 | tron \ | v850 | v850e \ | we32k \ | x86 | xscale | xscalee[bl] | xstormy16 | xtensa \ | z8k) basic_machine=$basic_machine-unknown ;; m32c) basic_machine=$basic_machine-unknown ;; m6811 | m68hc11 | m6812 | m68hc12) # Motorola 68HC11/12. basic_machine=$basic_machine-unknown os=-none ;; m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) ;; ms1) basic_machine=mt-unknown ;; # We use `pc' rather than `unknown' # because (1) that's what they normally are, and # (2) the word "unknown" tends to confuse beginning users. i*86 | x86_64) basic_machine=$basic_machine-pc ;; # Object if more than one company name word. *-*-*) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; # Recognize the basic CPU types with company name. 580-* \ | a29k-* \ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ | avr-* \ | bfin-* | bs2000-* \ | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \ | clipper-* | craynv-* | cydra-* \ | d10v-* | d30v-* | dlx-* \ | elxsi-* \ | f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \ | h8300-* | h8500-* \ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ | i*86-* | i860-* | i960-* | ia64-* \ | ip2k-* | iq2000-* \ | m32r-* | m32rle-* \ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ | m88110-* | m88k-* | maxq-* | mcore-* \ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ | mips16-* \ | mips64-* | mips64el-* \ | mips64vr-* | mips64vrel-* \ | mips64orion-* | mips64orionel-* \ | mips64vr4100-* | mips64vr4100el-* \ | mips64vr4300-* | mips64vr4300el-* \ | mips64vr5000-* | mips64vr5000el-* \ | mips64vr5900-* | mips64vr5900el-* \ | mipsisa32-* | mipsisa32el-* \ | mipsisa32r2-* | mipsisa32r2el-* \ | mipsisa64-* | mipsisa64el-* \ | mipsisa64r2-* | mipsisa64r2el-* \ | mipsisa64sb1-* | mipsisa64sb1el-* \ | mipsisa64sr71k-* | mipsisa64sr71kel-* \ | mipstx39-* | mipstx39el-* \ | mmix-* \ | mt-* \ | msp430-* \ | none-* | np1-* | ns16k-* | ns32k-* \ | orion-* \ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ | pyramid-* \ | romp-* | rs6000-* \ | sh-* | sh[1234]-* | sh[24]a-* | sh[23]e-* | sh[34]eb-* | shbe-* \ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ | sparc-* | sparc64-* | sparc64b-* | sparc86x-* | sparclet-* \ | sparclite-* \ | sparcv8-* | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \ | tahoe-* | thumb-* \ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ | tron-* \ | v850-* | v850e-* | vax-* \ | we32k-* \ | x86-* | x86_64-* | xps100-* | xscale-* | xscalee[bl]-* \ | xstormy16-* | xtensa-* \ | ymp-* \ | z8k-*) ;; m32c-*) ;; # Recognize the various machine names and aliases which stand # for a CPU type and a company and sometimes even an OS. 386bsd) basic_machine=i386-unknown os=-bsd ;; 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) basic_machine=m68000-att ;; 3b*) basic_machine=we32k-att ;; a29khif) basic_machine=a29k-amd os=-udi ;; abacus) basic_machine=abacus-unknown ;; adobe68k) basic_machine=m68010-adobe os=-scout ;; alliant | fx80) basic_machine=fx80-alliant ;; altos | altos3068) basic_machine=m68k-altos ;; am29k) basic_machine=a29k-none os=-bsd ;; amd64) basic_machine=x86_64-pc ;; amd64-*) basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; amdahl) basic_machine=580-amdahl os=-sysv ;; amiga | amiga-*) basic_machine=m68k-unknown ;; amigaos | amigados) basic_machine=m68k-unknown os=-amigaos ;; amigaunix | amix) basic_machine=m68k-unknown os=-sysv4 ;; apollo68) basic_machine=m68k-apollo os=-sysv ;; apollo68bsd) basic_machine=m68k-apollo os=-bsd ;; aux) basic_machine=m68k-apple os=-aux ;; balance) basic_machine=ns32k-sequent os=-dynix ;; c90) basic_machine=c90-cray os=-unicos ;; convex-c1) basic_machine=c1-convex os=-bsd ;; convex-c2) basic_machine=c2-convex os=-bsd ;; convex-c32) basic_machine=c32-convex os=-bsd ;; convex-c34) basic_machine=c34-convex os=-bsd ;; convex-c38) basic_machine=c38-convex os=-bsd ;; cray | j90) basic_machine=j90-cray os=-unicos ;; craynv) basic_machine=craynv-cray os=-unicosmp ;; cr16c) basic_machine=cr16c-unknown os=-elf ;; crds | unos) basic_machine=m68k-crds ;; crisv32 | crisv32-* | etraxfs*) basic_machine=crisv32-axis ;; cris | cris-* | etrax*) basic_machine=cris-axis ;; crx) basic_machine=crx-unknown os=-elf ;; da30 | da30-*) basic_machine=m68k-da30 ;; decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) basic_machine=mips-dec ;; decsystem10* | dec10*) basic_machine=pdp10-dec os=-tops10 ;; decsystem20* | dec20*) basic_machine=pdp10-dec os=-tops20 ;; delta | 3300 | motorola-3300 | motorola-delta \ | 3300-motorola | delta-motorola) basic_machine=m68k-motorola ;; delta88) basic_machine=m88k-motorola os=-sysv3 ;; djgpp) basic_machine=i586-pc os=-msdosdjgpp ;; dpx20 | dpx20-*) basic_machine=rs6000-bull os=-bosx ;; dpx2* | dpx2*-bull) basic_machine=m68k-bull os=-sysv3 ;; ebmon29k) basic_machine=a29k-amd os=-ebmon ;; elxsi) basic_machine=elxsi-elxsi os=-bsd ;; encore | umax | mmax) basic_machine=ns32k-encore ;; es1800 | OSE68k | ose68k | ose | OSE) basic_machine=m68k-ericsson os=-ose ;; fx2800) basic_machine=i860-alliant ;; genix) basic_machine=ns32k-ns ;; gmicro) basic_machine=tron-gmicro os=-sysv ;; go32) basic_machine=i386-pc os=-go32 ;; h3050r* | hiux*) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; h8300hms) basic_machine=h8300-hitachi os=-hms ;; h8300xray) basic_machine=h8300-hitachi os=-xray ;; h8500hms) basic_machine=h8500-hitachi os=-hms ;; harris) basic_machine=m88k-harris os=-sysv3 ;; hp300-*) basic_machine=m68k-hp ;; hp300bsd) basic_machine=m68k-hp os=-bsd ;; hp300hpux) basic_machine=m68k-hp os=-hpux ;; hp3k9[0-9][0-9] | hp9[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k2[0-9][0-9] | hp9k31[0-9]) basic_machine=m68000-hp ;; hp9k3[2-9][0-9]) basic_machine=m68k-hp ;; hp9k6[0-9][0-9] | hp6[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k7[0-79][0-9] | hp7[0-79][0-9]) basic_machine=hppa1.1-hp ;; hp9k78[0-9] | hp78[0-9]) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[0-9][13679] | hp8[0-9][13679]) basic_machine=hppa1.1-hp ;; hp9k8[0-9][0-9] | hp8[0-9][0-9]) basic_machine=hppa1.0-hp ;; hppa-next) os=-nextstep3 ;; hppaosf) basic_machine=hppa1.1-hp os=-osf ;; hppro) basic_machine=hppa1.1-hp os=-proelf ;; i370-ibm* | ibm*) basic_machine=i370-ibm ;; # I'm not sure what "Sysv32" means. Should this be sysv3.2? i*86v32) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv32 ;; i*86v4*) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv4 ;; i*86v) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv ;; i*86sol2) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-solaris2 ;; i386mach) basic_machine=i386-mach os=-mach ;; i386-vsta | vsta) basic_machine=i386-unknown os=-vsta ;; iris | iris4d) basic_machine=mips-sgi case $os in -irix*) ;; *) os=-irix4 ;; esac ;; isi68 | isi) basic_machine=m68k-isi os=-sysv ;; m88k-omron*) basic_machine=m88k-omron ;; magnum | m3230) basic_machine=mips-mips os=-sysv ;; merlin) basic_machine=ns32k-utek os=-sysv ;; mingw32) basic_machine=i386-pc os=-mingw32 ;; miniframe) basic_machine=m68000-convergent ;; *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) basic_machine=m68k-atari os=-mint ;; mips3*-*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` ;; mips3*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown ;; monitor) basic_machine=m68k-rom68k os=-coff ;; morphos) basic_machine=powerpc-unknown os=-morphos ;; msdos) basic_machine=i386-pc os=-msdos ;; ms1-*) basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` ;; mvs) basic_machine=i370-ibm os=-mvs ;; ncr3000) basic_machine=i486-ncr os=-sysv4 ;; netbsd386) basic_machine=i386-unknown os=-netbsd ;; netwinder) basic_machine=armv4l-rebel os=-linux ;; news | news700 | news800 | news900) basic_machine=m68k-sony os=-newsos ;; news1000) basic_machine=m68030-sony os=-newsos ;; news-3600 | risc-news) basic_machine=mips-sony os=-newsos ;; necv70) basic_machine=v70-nec os=-sysv ;; next | m*-next ) basic_machine=m68k-next case $os in -nextstep* ) ;; -ns2*) os=-nextstep2 ;; *) os=-nextstep3 ;; esac ;; nh3000) basic_machine=m68k-harris os=-cxux ;; nh[45]000) basic_machine=m88k-harris os=-cxux ;; nindy960) basic_machine=i960-intel os=-nindy ;; mon960) basic_machine=i960-intel os=-mon960 ;; nonstopux) basic_machine=mips-compaq os=-nonstopux ;; np1) basic_machine=np1-gould ;; nsr-tandem) basic_machine=nsr-tandem ;; op50n-* | op60c-*) basic_machine=hppa1.1-oki os=-proelf ;; openrisc | openrisc-*) basic_machine=or32-unknown ;; os400) basic_machine=powerpc-ibm os=-os400 ;; OSE68000 | ose68000) basic_machine=m68000-ericsson os=-ose ;; os68k) basic_machine=m68k-none os=-os68k ;; pa-hitachi) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; paragon) basic_machine=i860-intel os=-osf ;; pbd) basic_machine=sparc-tti ;; pbb) basic_machine=m68k-tti ;; pc532 | pc532-*) basic_machine=ns32k-pc532 ;; pc98) basic_machine=i386-pc ;; pc98-*) basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentium | p5 | k5 | k6 | nexgen | viac3) basic_machine=i586-pc ;; pentiumpro | p6 | 6x86 | athlon | athlon_*) basic_machine=i686-pc ;; pentiumii | pentium2 | pentiumiii | pentium3) basic_machine=i686-pc ;; pentium4) basic_machine=i786-pc ;; pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumpro-* | p6-* | 6x86-* | athlon-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentium4-*) basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pn) basic_machine=pn-gould ;; power) basic_machine=power-ibm ;; ppc) basic_machine=powerpc-unknown ;; ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppcle | powerpclittle | ppc-le | powerpc-little) basic_machine=powerpcle-unknown ;; ppcle-* | powerpclittle-*) basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64) basic_machine=powerpc64-unknown ;; ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64le | powerpc64little | ppc64-le | powerpc64-little) basic_machine=powerpc64le-unknown ;; ppc64le-* | powerpc64little-*) basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ps2) basic_machine=i386-ibm ;; pw32) basic_machine=i586-unknown os=-pw32 ;; rdos) basic_machine=i386-pc os=-rdos ;; rom68k) basic_machine=m68k-rom68k os=-coff ;; rm[46]00) basic_machine=mips-siemens ;; rtpc | rtpc-*) basic_machine=romp-ibm ;; s390 | s390-*) basic_machine=s390-ibm ;; s390x | s390x-*) basic_machine=s390x-ibm ;; sa29200) basic_machine=a29k-amd os=-udi ;; sb1) basic_machine=mipsisa64sb1-unknown ;; sb1el) basic_machine=mipsisa64sb1el-unknown ;; sei) basic_machine=mips-sei os=-seiux ;; sequent) basic_machine=i386-sequent ;; sh) basic_machine=sh-hitachi os=-hms ;; sh64) basic_machine=sh64-unknown ;; sparclite-wrs | simso-wrs) basic_machine=sparclite-wrs os=-vxworks ;; sps7) basic_machine=m68k-bull os=-sysv2 ;; spur) basic_machine=spur-unknown ;; st2000) basic_machine=m68k-tandem ;; stratus) basic_machine=i860-stratus os=-sysv4 ;; sun2) basic_machine=m68000-sun ;; sun2os3) basic_machine=m68000-sun os=-sunos3 ;; sun2os4) basic_machine=m68000-sun os=-sunos4 ;; sun3os3) basic_machine=m68k-sun os=-sunos3 ;; sun3os4) basic_machine=m68k-sun os=-sunos4 ;; sun4os3) basic_machine=sparc-sun os=-sunos3 ;; sun4os4) basic_machine=sparc-sun os=-sunos4 ;; sun4sol2) basic_machine=sparc-sun os=-solaris2 ;; sun3 | sun3-*) basic_machine=m68k-sun ;; sun4) basic_machine=sparc-sun ;; sun386 | sun386i | roadrunner) basic_machine=i386-sun ;; sv1) basic_machine=sv1-cray os=-unicos ;; symmetry) basic_machine=i386-sequent os=-dynix ;; t3e) basic_machine=alphaev5-cray os=-unicos ;; t90) basic_machine=t90-cray os=-unicos ;; tic54x | c54x*) basic_machine=tic54x-unknown os=-coff ;; tic55x | c55x*) basic_machine=tic55x-unknown os=-coff ;; tic6x | c6x*) basic_machine=tic6x-unknown os=-coff ;; tx39) basic_machine=mipstx39-unknown ;; tx39el) basic_machine=mipstx39el-unknown ;; toad1) basic_machine=pdp10-xkl os=-tops20 ;; tower | tower-32) basic_machine=m68k-ncr ;; tpf) basic_machine=s390x-ibm os=-tpf ;; udi29k) basic_machine=a29k-amd os=-udi ;; ultra3) basic_machine=a29k-nyu os=-sym1 ;; v810 | necv810) basic_machine=v810-nec os=-none ;; vaxv) basic_machine=vax-dec os=-sysv ;; vms) basic_machine=vax-dec os=-vms ;; vpp*|vx|vx-*) basic_machine=f301-fujitsu ;; vxworks960) basic_machine=i960-wrs os=-vxworks ;; vxworks68) basic_machine=m68k-wrs os=-vxworks ;; vxworks29k) basic_machine=a29k-wrs os=-vxworks ;; w65*) basic_machine=w65-wdc os=-none ;; w89k-*) basic_machine=hppa1.1-winbond os=-proelf ;; xbox) basic_machine=i686-pc os=-mingw32 ;; xps | xps100) basic_machine=xps100-honeywell ;; ymp) basic_machine=ymp-cray os=-unicos ;; z8k-*-coff) basic_machine=z8k-unknown os=-sim ;; none) basic_machine=none-none os=-none ;; # Here we handle the default manufacturer of certain CPU types. It is in # some cases the only manufacturer, in others, it is the most popular. w89k) basic_machine=hppa1.1-winbond ;; op50n) basic_machine=hppa1.1-oki ;; op60c) basic_machine=hppa1.1-oki ;; romp) basic_machine=romp-ibm ;; mmix) basic_machine=mmix-knuth ;; rs6000) basic_machine=rs6000-ibm ;; vax) basic_machine=vax-dec ;; pdp10) # there are many clones, so DEC is not a safe bet basic_machine=pdp10-unknown ;; pdp11) basic_machine=pdp11-dec ;; we32k) basic_machine=we32k-att ;; sh[1234] | sh[24]a | sh[34]eb | sh[1234]le | sh[23]ele) basic_machine=sh-unknown ;; sparc | sparcv8 | sparcv9 | sparcv9b) basic_machine=sparc-sun ;; cydra) basic_machine=cydra-cydrome ;; orion) basic_machine=orion-highlevel ;; orion105) basic_machine=clipper-highlevel ;; mac | mpw | mac-mpw) basic_machine=m68k-apple ;; pmac | pmac-mpw) basic_machine=powerpc-apple ;; *-unknown) # Make sure to match an already-canonicalized machine name. ;; *) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; esac # Here we canonicalize certain aliases for manufacturers. case $basic_machine in *-digital*) basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` ;; *-commodore*) basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` ;; *) ;; esac # Decode manufacturer-specific aliases for certain operating systems. if [ x"$os" != x"" ] then case $os in # First match some system type aliases # that might get confused with valid system types. # -solaris* is a basic system type, with this one exception. -solaris1 | -solaris1.*) os=`echo $os | sed -e 's|solaris1|sunos4|'` ;; -solaris) os=-solaris2 ;; -svr4*) os=-sysv4 ;; -unixware*) os=-sysv4.2uw ;; -gnu/linux*) os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` ;; # First accept the basic system types. # The portable systems comes first. # Each alternative MUST END IN A *, to match a version number. # -sysv* is not here because it comes later, after sysvr4. -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ | -aos* \ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ | -openbsd* | -solidbsd* \ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ | -chorusos* | -chorusrdb* \ | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \ | -uxpv* | -beos* | -mpeix* | -udk* \ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ | -skyos* | -haiku* | -rdos*) # Remember, each alternative MUST END IN *, to match a version number. ;; -qnx*) case $basic_machine in x86-* | i*86-*) ;; *) os=-nto$os ;; esac ;; -nto-qnx*) ;; -nto*) os=`echo $os | sed -e 's|nto|nto-qnx|'` ;; -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) ;; -mac*) os=`echo $os | sed -e 's|mac|macos|'` ;; -linux-dietlibc) os=-linux-dietlibc ;; -linux*) os=`echo $os | sed -e 's|linux|linux-gnu|'` ;; -sunos5*) os=`echo $os | sed -e 's|sunos5|solaris2|'` ;; -sunos6*) os=`echo $os | sed -e 's|sunos6|solaris3|'` ;; -opened*) os=-openedition ;; -os400*) os=-os400 ;; -wince*) os=-wince ;; -osfrose*) os=-osfrose ;; -osf*) os=-osf ;; -utek*) os=-bsd ;; -dynix*) os=-bsd ;; -acis*) os=-aos ;; -atheos*) os=-atheos ;; -syllable*) os=-syllable ;; -386bsd) os=-bsd ;; -ctix* | -uts*) os=-sysv ;; -nova*) os=-rtmk-nova ;; -ns2 ) os=-nextstep2 ;; -nsk*) os=-nsk ;; # Preserve the version number of sinix5. -sinix5.*) os=`echo $os | sed -e 's|sinix|sysv|'` ;; -sinix*) os=-sysv4 ;; -tpf*) os=-tpf ;; -triton*) os=-sysv3 ;; -oss*) os=-sysv3 ;; -svr4) os=-sysv4 ;; -svr3) os=-sysv3 ;; -sysvr4) os=-sysv4 ;; # This must come after -sysvr4. -sysv*) ;; -ose*) os=-ose ;; -es1800*) os=-ose ;; -xenix) os=-xenix ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) os=-mint ;; -aros*) os=-aros ;; -kaos*) os=-kaos ;; -zvmoe) os=-zvmoe ;; -none) ;; *) # Get rid of the `-' at the beginning of $os. os=`echo $os | sed 's/[^-]*-//'` echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 exit 1 ;; esac else # Here we handle the default operating systems that come with various machines. # The value should be what the vendor currently ships out the door with their # machine or put another way, the most popular os provided with the machine. # Note that if you're going to try to match "-MANUFACTURER" here (say, # "-sun"), then you have to tell the case statement up towards the top # that MANUFACTURER isn't an operating system. Otherwise, code above # will signal an error saying that MANUFACTURER isn't an operating # system, and we'll never get to this point. case $basic_machine in *-acorn) os=-riscix1.2 ;; arm*-rebel) os=-linux ;; arm*-semi) os=-aout ;; c4x-* | tic4x-*) os=-coff ;; # This must come before the *-dec entry. pdp10-*) os=-tops20 ;; pdp11-*) os=-none ;; *-dec | vax-*) os=-ultrix4.2 ;; m68*-apollo) os=-domain ;; i386-sun) os=-sunos4.0.2 ;; m68000-sun) os=-sunos3 # This also exists in the configure program, but was not the # default. # os=-sunos4 ;; m68*-cisco) os=-aout ;; mips*-cisco) os=-elf ;; mips*-*) os=-elf ;; or32-*) os=-coff ;; *-tti) # must be before sparc entry or we get the wrong os. os=-sysv3 ;; sparc-* | *-sun) os=-sunos4.1.1 ;; *-be) os=-beos ;; *-haiku) os=-haiku ;; *-ibm) os=-aix ;; *-knuth) os=-mmixware ;; *-wec) os=-proelf ;; *-winbond) os=-proelf ;; *-oki) os=-proelf ;; *-hp) os=-hpux ;; *-hitachi) os=-hiux ;; i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) os=-sysv ;; *-cbm) os=-amigaos ;; *-dg) os=-dgux ;; *-dolphin) os=-sysv3 ;; m68k-ccur) os=-rtu ;; m88k-omron*) os=-luna ;; *-next ) os=-nextstep ;; *-sequent) os=-ptx ;; *-crds) os=-unos ;; *-ns) os=-genix ;; i370-*) os=-mvs ;; *-next) os=-nextstep3 ;; *-gould) os=-sysv ;; *-highlevel) os=-bsd ;; *-encore) os=-bsd ;; *-sgi) os=-irix ;; *-siemens) os=-sysv4 ;; *-masscomp) os=-rtu ;; f30[01]-fujitsu | f700-fujitsu) os=-uxpv ;; *-rom68k) os=-coff ;; *-*bug) os=-coff ;; *-apple) os=-macos ;; *-atari*) os=-mint ;; *) os=-none ;; esac fi # Here we handle the case where we know the os, and the CPU type, but not the # manufacturer. We pick the logical manufacturer. vendor=unknown case $basic_machine in *-unknown) case $os in -riscix*) vendor=acorn ;; -sunos*) vendor=sun ;; -aix*) vendor=ibm ;; -beos*) vendor=be ;; -hpux*) vendor=hp ;; -mpeix*) vendor=hp ;; -hiux*) vendor=hitachi ;; -unos*) vendor=crds ;; -dgux*) vendor=dg ;; -luna*) vendor=omron ;; -genix*) vendor=ns ;; -mvs* | -opened*) vendor=ibm ;; -os400*) vendor=ibm ;; -ptx*) vendor=sequent ;; -tpf*) vendor=ibm ;; -vxsim* | -vxworks* | -windiss*) vendor=wrs ;; -aux*) vendor=apple ;; -hms*) vendor=hitachi ;; -mpw* | -macos*) vendor=apple ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) vendor=atari ;; -vos*) vendor=stratus ;; esac basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` ;; esac echo $basic_machine$os exit # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: nagios-2.6/configure0000775000076500007650000066255110532717360014131 0ustar nagiosnagios#! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.59. # # Copyright (C) 2003 Free Software Foundation, Inc. # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. ## --------------------- ## ## M4sh Initialization. ## ## --------------------- ## # Be Bourne compatible if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then set -o posix fi DUALCASE=1; export DUALCASE # for MKS sh # Support unset when possible. if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then as_unset=unset else as_unset=false fi # Work around bugs in pre-3.0 UWIN ksh. $as_unset ENV MAIL MAILPATH PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. for as_var in \ LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ LC_TELEPHONE LC_TIME do if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then eval $as_var=C; export $as_var else $as_unset $as_var fi done # Required to use basename. if expr a : '\(a\)' >/dev/null 2>&1; then as_expr=expr else as_expr=false fi if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi # Name of the executable. as_me=`$as_basename "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)$' \| \ . : '\(.\)' 2>/dev/null || echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } /^X\/\(\/\/\)$/{ s//\1/; q; } /^X\/\(\/\).*/{ s//\1/; q; } s/.*/./; q'` # PATH needs CR, and LINENO needs CR and PATH. # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then echo "#! /bin/sh" >conf$$.sh echo "exit 0" >>conf$$.sh chmod +x conf$$.sh if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then PATH_SEPARATOR=';' else PATH_SEPARATOR=: fi rm -f conf$$.sh fi as_lineno_1=$LINENO as_lineno_2=$LINENO as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` test "x$as_lineno_1" != "x$as_lineno_2" && test "x$as_lineno_3" = "x$as_lineno_2" || { # Find who we are. Look in the path if we contain no path at all # relative or not. case $0 in *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2 { (exit 1); exit 1; }; } fi case $CONFIG_SHELL in '') as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for as_base in sh bash ksh sh5; do case $as_dir in /*) if ("$as_dir/$as_base" -c ' as_lineno_1=$LINENO as_lineno_2=$LINENO as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` test "x$as_lineno_1" != "x$as_lineno_2" && test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; } $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; } CONFIG_SHELL=$as_dir/$as_base export CONFIG_SHELL exec "$CONFIG_SHELL" "$0" ${1+"$@"} fi;; esac done done ;; esac # Create $as_me.lineno as a copy of $as_myself, but with $LINENO # uniformly replaced by the line number. The first 'sed' inserts a # line-number line before each line; the second 'sed' does the real # work. The second script uses 'N' to pair each line-number line # with the numbered line, and appends trailing '-' during # substitution so that $LINENO is not a special case at line end. # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) sed '=' <$as_myself | sed ' N s,$,-, : loop s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, t loop s,-$,, s,^['$as_cr_digits']*\n,, ' >$as_me.lineno && chmod +x $as_me.lineno || { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 { (exit 1); exit 1; }; } # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensible to this). . ./$as_me.lineno # Exit status is that of the last command. exit } case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in *c*,-n*) ECHO_N= ECHO_C=' ' ECHO_T=' ' ;; *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; *) ECHO_N= ECHO_C='\c' ECHO_T= ;; esac if expr a : '\(a\)' >/dev/null 2>&1; then as_expr=expr else as_expr=false fi rm -f conf$$ conf$$.exe conf$$.file echo >conf$$.file if ln -s conf$$.file conf$$ 2>/dev/null; then # We could just check for DJGPP; but this test a) works b) is more generic # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). if test -f conf$$.exe; then # Don't use ln at all; we don't have any links as_ln_s='cp -p' else as_ln_s='ln -s' fi elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' fi rm -f conf$$ conf$$.exe conf$$.file if mkdir -p . 2>/dev/null; then as_mkdir_p=: else test -d ./-p && rmdir ./-p as_mkdir_p=false fi as_executable_p="test -f" # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" # IFS # We need space, tab and new line, in precisely that order. as_nl=' ' IFS=" $as_nl" # CDPATH. $as_unset CDPATH # Name of the host. # hostname on some systems (SVR3.2, Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` exec 6>&1 # # Initializations. # ac_default_prefix=/usr/local ac_config_libobj_dir=. cross_compiling=no subdirs= MFLAGS= MAKEFLAGS= SHELL=${CONFIG_SHELL-/bin/sh} # Maximum number of lines to put in a shell here document. # This variable seems obsolete. It should probably be removed, and # only ac_max_sed_lines should be used. : ${ac_max_here_lines=38} # Identity of this package. PACKAGE_NAME= PACKAGE_TARNAME= PACKAGE_VERSION= PACKAGE_STRING= PACKAGE_BUGREPORT= ac_unique_file="base/nagios.c" ac_default_prefix=/usr/local/nagios # Factoring default headers for most tests. ac_includes_default="\ #include #if HAVE_SYS_TYPES_H # include #endif #if HAVE_SYS_STAT_H # include #endif #if STDC_HEADERS # include # include #else # if HAVE_STDLIB_H # include # endif #endif #if HAVE_STRING_H # if !STDC_HEADERS && HAVE_MEMORY_H # include # endif # include #endif #if HAVE_STRINGS_H # include #endif #if HAVE_INTTYPES_H # include #else # if HAVE_STDINT_H # include # endif #endif #if HAVE_UNISTD_H # include #endif" ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA INSTALL build build_cpu build_vendor build_os host host_cpu host_vendor host_os CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT SET_MAKE STRIP CPP EGREP SOCKETLIBS THREADLIBS nagios_user nagios_grp INSTALL_OPTS command_user command_grp COMMAND_OPTS MAIL_PROG init_dir lockfile XSDC XSDH XCDC XCDH XRDC XRDH XODC XODH XPDC XPDH XDDC XDDH htmurl cgiurl BROKER_LDFLAGS BROKERLIBS MOD_CFLAGS MOD_LDFLAGS BROKER_O BROKER_H nagios_name nagiostats_name PATH_TO_TRACEROUTE PACKDIR VERSION SNPRINTF_O CGIEXTRAS GDLIBS PERLLIBS PERLDIR PERLXSI_O BASEEXTRALIBS INITDIR INSTALLPERLSTUFF PERL LIBOBJS LTLIBOBJS' ac_subst_files='' # Initialize some variables set by options. ac_init_help= ac_init_version=false # The variables have the same names as the options, with # dashes changed to underlines. cache_file=/dev/null exec_prefix=NONE no_create= no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= verbose= x_includes=NONE x_libraries=NONE # Installation directory options. # These are left unexpanded so users can "make install exec_prefix=/foo" # and all the variables that are supposed to be based on exec_prefix # by default will actually change. # Use braces instead of parens because sh, perl, etc. also accept them. bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datadir='${prefix}/share' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' libdir='${exec_prefix}/lib' includedir='${prefix}/include' oldincludedir='/usr/include' infodir='${prefix}/info' mandir='${prefix}/man' ac_prev= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval "$ac_prev=\$ac_option" ac_prev= continue fi ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'` # Accept the important Cygnus configure options, so we can diagnose typos. case $ac_option in -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir=$ac_optarg ;; -build | --build | --buil | --bui | --bu) ac_prev=build_alias ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build_alias=$ac_optarg ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file=$ac_optarg ;; --config-cache | -C) cache_file=config.cache ;; -datadir | --datadir | --datadi | --datad | --data | --dat | --da) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ | --da=*) datadir=$ac_optarg ;; -disable-* | --disable-*) ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid feature name: $ac_feature" >&2 { (exit 1); exit 1; }; } ac_feature=`echo $ac_feature | sed 's/-/_/g'` eval "enable_$ac_feature=no" ;; -enable-* | --enable-*) ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid feature name: $ac_feature" >&2 { (exit 1); exit 1; }; } ac_feature=`echo $ac_feature | sed 's/-/_/g'` case $ac_option in *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; *) ac_optarg=yes ;; esac eval "enable_$ac_feature='$ac_optarg'" ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix=$ac_optarg ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he | -h) ac_init_help=long ;; -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) ac_init_help=recursive ;; -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) ac_init_help=short ;; -host | --host | --hos | --ho) ac_prev=host_alias ;; -host=* | --host=* | --hos=* | --ho=*) host_alias=$ac_optarg ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir=$ac_optarg ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir=$ac_optarg ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir=$ac_optarg ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir=$ac_optarg ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst \ | --locals | --local | --loca | --loc | --lo) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* \ | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) localstatedir=$ac_optarg ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir=$ac_optarg ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c | -n) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir=$ac_optarg ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix=$ac_optarg ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix=$ac_optarg ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix=$ac_optarg ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name=$ac_optarg ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir=$ac_optarg ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir=$ac_optarg ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site=$ac_optarg ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir=$ac_optarg ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir=$ac_optarg ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target_alias ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target_alias=$ac_optarg ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers | -V) ac_init_version=: ;; -with-* | --with-*) ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid package name: $ac_package" >&2 { (exit 1); exit 1; }; } ac_package=`echo $ac_package| sed 's/-/_/g'` case $ac_option in *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; *) ac_optarg=yes ;; esac eval "with_$ac_package='$ac_optarg'" ;; -without-* | --without-*) ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid package name: $ac_package" >&2 { (exit 1); exit 1; }; } ac_package=`echo $ac_package | sed 's/-/_/g'` eval "with_$ac_package=no" ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes=$ac_optarg ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries=$ac_optarg ;; -*) { echo "$as_me: error: unrecognized option: $ac_option Try \`$0 --help' for more information." >&2 { (exit 1); exit 1; }; } ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid variable name: $ac_envvar" >&2 { (exit 1); exit 1; }; } ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` eval "$ac_envvar='$ac_optarg'" export $ac_envvar ;; *) # FIXME: should be removed in autoconf 3.0. echo "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && echo "$as_me: WARNING: invalid host type: $ac_option" >&2 : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} ;; esac done if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` { echo "$as_me: error: missing argument to $ac_option" >&2 { (exit 1); exit 1; }; } fi # Be sure to have absolute paths. for ac_var in exec_prefix prefix do eval ac_val=$`echo $ac_var` case $ac_val in [\\/$]* | ?:[\\/]* | NONE | '' ) ;; *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 { (exit 1); exit 1; }; };; esac done # Be sure to have absolute paths. for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \ localstatedir libdir includedir oldincludedir infodir mandir do eval ac_val=$`echo $ac_var` case $ac_val in [\\/$]* | ?:[\\/]* ) ;; *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 { (exit 1); exit 1; }; };; esac done # There might be people who depend on the old broken behavior: `$host' # used to hold the argument of --host etc. # FIXME: To remove some day. build=$build_alias host=$host_alias target=$target_alias # FIXME: To remove some day. if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. If a cross compiler is detected then cross compile mode will be used." >&2 elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi fi ac_tool_prefix= test -n "$host_alias" && ac_tool_prefix=$host_alias- test "$silent" = yes && exec 6>/dev/null # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then its parent. ac_confdir=`(dirname "$0") 2>/dev/null || $as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$0" : 'X\(//\)[^/]' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| \ . : '\(.\)' 2>/dev/null || echo X"$0" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } /^X\(\/\/\)[^/].*/{ s//\1/; q; } /^X\(\/\/\)$/{ s//\1/; q; } /^X\(\/\).*/{ s//\1/; q; } s/.*/./; q'` srcdir=$ac_confdir if test ! -r $srcdir/$ac_unique_file; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r $srcdir/$ac_unique_file; then if test "$ac_srcdir_defaulted" = yes; then { echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2 { (exit 1); exit 1; }; } else { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 { (exit 1); exit 1; }; } fi fi (cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null || { echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2 { (exit 1); exit 1; }; } srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'` ac_env_build_alias_set=${build_alias+set} ac_env_build_alias_value=$build_alias ac_cv_env_build_alias_set=${build_alias+set} ac_cv_env_build_alias_value=$build_alias ac_env_host_alias_set=${host_alias+set} ac_env_host_alias_value=$host_alias ac_cv_env_host_alias_set=${host_alias+set} ac_cv_env_host_alias_value=$host_alias ac_env_target_alias_set=${target_alias+set} ac_env_target_alias_value=$target_alias ac_cv_env_target_alias_set=${target_alias+set} ac_cv_env_target_alias_value=$target_alias ac_env_CC_set=${CC+set} ac_env_CC_value=$CC ac_cv_env_CC_set=${CC+set} ac_cv_env_CC_value=$CC ac_env_CFLAGS_set=${CFLAGS+set} ac_env_CFLAGS_value=$CFLAGS ac_cv_env_CFLAGS_set=${CFLAGS+set} ac_cv_env_CFLAGS_value=$CFLAGS ac_env_LDFLAGS_set=${LDFLAGS+set} ac_env_LDFLAGS_value=$LDFLAGS ac_cv_env_LDFLAGS_set=${LDFLAGS+set} ac_cv_env_LDFLAGS_value=$LDFLAGS ac_env_CPPFLAGS_set=${CPPFLAGS+set} ac_env_CPPFLAGS_value=$CPPFLAGS ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set} ac_cv_env_CPPFLAGS_value=$CPPFLAGS ac_env_CPP_set=${CPP+set} ac_env_CPP_value=$CPP ac_cv_env_CPP_set=${CPP+set} ac_cv_env_CPP_value=$CPP # # Report the --help message. # if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF \`configure' configures this package to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... To assign environment variables (e.g., CC, CFLAGS...), specify them as VAR=VALUE. See below for descriptions of some of the useful variables. Defaults for the options are specified in brackets. Configuration: -h, --help display this help and exit --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit -q, --quiet, --silent do not print \`checking...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for \`--cache-file=config.cache' -n, --no-create do not create output files --srcdir=DIR find the sources in DIR [configure dir or \`..'] _ACEOF cat <<_ACEOF Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [PREFIX] By default, \`make install' will install all the files in \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify an installation prefix other than \`$ac_default_prefix' using \`--prefix', for instance \`--prefix=\$HOME'. For better control, use the options below. Fine tuning of the installation directories: --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] --datadir=DIR read-only architecture-independent data [PREFIX/share] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] --infodir=DIR info documentation [PREFIX/info] --mandir=DIR man documentation [PREFIX/man] _ACEOF cat <<\_ACEOF System types: --build=BUILD configure for building on BUILD [guessed] --host=HOST cross-compile to build programs to run on HOST [BUILD] _ACEOF fi if test -n "$ac_init_help"; then cat <<\_ACEOF Optional Features: --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --disable-statusmap=disables compilation of statusmap CGI --disable-statuswrl=disables compilation of statuswrl (VRML) CGI --enable-DEBUG0 shows function entry and exit --enable-DEBUG1 shows general info messages --enable-DEBUG2 shows warning messages --enable-DEBUG3 shows scheduled events (service and host checks... etc) --enable-DEBUG4 shows service and host notifications --enable-DEBUG5 shows SQL queries --enable-DEBUGALL shows all debugging messages --enable-nanosleep enables use of nanosleep (instead sleep) in event timing --enable-event-broker enables integration of event broker routines --enable-embedded-perl will enable embedded Perl interpreter --enable-cygwin enables building under the CYGWIN environment Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --with-nagios-user= sets user name to run nagios --with-nagios-group= sets group name to run nagios --with-command-user= sets user name for command access --with-command-group= sets group name for command access --with-mail= sets path to equivalent program to mail --with-init-dir= sets directory to place init script into --with-lockfile= sets path and file name for lock file --with-gd-lib=DIR sets location of the gd library --with-gd-inc=DIR sets location of the gd include files --with-cgiurl= sets URL for cgi programs (do not use a trailing slash) --with-htmurl= sets URL for public html --with-perlcache turns on cacheing of internally compiled Perl scripts Some influential environment variables: CC C compiler command CFLAGS C compiler flags LDFLAGS linker flags, e.g. -L if you have libraries in a nonstandard directory CPPFLAGS C/C++ preprocessor flags, e.g. -I if you have headers in a nonstandard directory CPP C preprocessor Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. _ACEOF fi if test "$ac_init_help" = "recursive"; then # If there are subdirs, report their specific --help. ac_popdir=`pwd` for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue test -d $ac_dir || continue ac_builddir=. if test "$ac_dir" != .; then ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` # A "../" for each directory in $ac_dir_suffix. ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` else ac_dir_suffix= ac_top_builddir= fi case $srcdir in .) # No --srcdir option. We are building in place. ac_srcdir=. if test -z "$ac_top_builddir"; then ac_top_srcdir=. else ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` fi ;; [\\/]* | ?:[\\/]* ) # Absolute path. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ;; *) # Relative path. ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_builddir$srcdir ;; esac # Do not use `cd foo && pwd` to compute absolute paths, because # the directories may not exist. case `pwd` in .) ac_abs_builddir="$ac_dir";; *) case "$ac_dir" in .) ac_abs_builddir=`pwd`;; [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";; *) ac_abs_builddir=`pwd`/"$ac_dir";; esac;; esac case $ac_abs_builddir in .) ac_abs_top_builddir=${ac_top_builddir}.;; *) case ${ac_top_builddir}. in .) ac_abs_top_builddir=$ac_abs_builddir;; [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;; *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;; esac;; esac case $ac_abs_builddir in .) ac_abs_srcdir=$ac_srcdir;; *) case $ac_srcdir in .) ac_abs_srcdir=$ac_abs_builddir;; [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;; *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;; esac;; esac case $ac_abs_builddir in .) ac_abs_top_srcdir=$ac_top_srcdir;; *) case $ac_top_srcdir in .) ac_abs_top_srcdir=$ac_abs_builddir;; [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;; *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;; esac;; esac cd $ac_dir # Check for guested configure; otherwise get Cygnus style configure. if test -f $ac_srcdir/configure.gnu; then echo $SHELL $ac_srcdir/configure.gnu --help=recursive elif test -f $ac_srcdir/configure; then echo $SHELL $ac_srcdir/configure --help=recursive elif test -f $ac_srcdir/configure.ac || test -f $ac_srcdir/configure.in; then echo $ac_configure --help else echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 fi cd $ac_popdir done fi test -n "$ac_init_help" && exit 0 if $ac_init_version; then cat <<\_ACEOF Copyright (C) 2003 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF exit 0 fi exec 5>config.log cat >&5 <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by $as_me, which was generated by GNU Autoconf 2.59. Invocation command line was $ $0 $@ _ACEOF { cat <<_ASUNAME ## --------- ## ## Platform. ## ## --------- ## hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` /bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` /bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` hostinfo = `(hostinfo) 2>/dev/null || echo unknown` /bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` /bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` _ASUNAME as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. echo "PATH: $as_dir" done } >&5 cat >&5 <<_ACEOF ## ----------- ## ## Core tests. ## ## ----------- ## _ACEOF # Keep a trace of the command line. # Strip out --no-create and --no-recursion so they do not pile up. # Strip out --silent because we don't want to record it for future runs. # Also quote any args containing shell meta-characters. # Make two passes to allow for proper duplicate-argument suppression. ac_configure_args= ac_configure_args0= ac_configure_args1= ac_sep= ac_must_keep_next=false for ac_pass in 1 2 do for ac_arg do case $ac_arg in -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) continue ;; *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*) ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;; 2) ac_configure_args1="$ac_configure_args1 '$ac_arg'" if test $ac_must_keep_next = true; then ac_must_keep_next=false # Got value, back to normal. else case $ac_arg in *=* | --config-cache | -C | -disable-* | --disable-* \ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ | -with-* | --with-* | -without-* | --without-* | --x) case "$ac_configure_args0 " in "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; esac ;; -* ) ac_must_keep_next=true ;; esac fi ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'" # Get rid of the leading space. ac_sep=" " ;; esac done done $as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; } $as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; } # When interrupted or exit'd, cleanup temporary files, and complete # config.log. We remove comments because anyway the quotes in there # would cause problems or look ugly. # WARNING: Be sure not to use single quotes in there, as some shells, # such as our DU 5.0 friend, will then `close' the trap. trap 'exit_status=$? # Save into config.log some information that might help in debugging. { echo cat <<\_ASBOX ## ---------------- ## ## Cache variables. ## ## ---------------- ## _ASBOX echo # The following way of writing the cache mishandles newlines in values, { (set) 2>&1 | case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in *ac_space=\ *) sed -n \ "s/'"'"'/'"'"'\\\\'"'"''"'"'/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p" ;; *) sed -n \ "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" ;; esac; } echo cat <<\_ASBOX ## ----------------- ## ## Output variables. ## ## ----------------- ## _ASBOX echo for ac_var in $ac_subst_vars do eval ac_val=$`echo $ac_var` echo "$ac_var='"'"'$ac_val'"'"'" done | sort echo if test -n "$ac_subst_files"; then cat <<\_ASBOX ## ------------- ## ## Output files. ## ## ------------- ## _ASBOX echo for ac_var in $ac_subst_files do eval ac_val=$`echo $ac_var` echo "$ac_var='"'"'$ac_val'"'"'" done | sort echo fi if test -s confdefs.h; then cat <<\_ASBOX ## ----------- ## ## confdefs.h. ## ## ----------- ## _ASBOX echo sed "/^$/d" confdefs.h | sort echo fi test "$ac_signal" != 0 && echo "$as_me: caught signal $ac_signal" echo "$as_me: exit $exit_status" } >&5 rm -f core *.core && rm -rf conftest* confdefs* conf$$* $ac_clean_files && exit $exit_status ' 0 for ac_signal in 1 2 13 15; do trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal done ac_signal=0 # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -rf conftest* confdefs.h # AIX cpp loses on an empty file, so make sure it contains at least a newline. echo >confdefs.h # Predefined preprocessor variables. cat >>confdefs.h <<_ACEOF #define PACKAGE_NAME "$PACKAGE_NAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_TARNAME "$PACKAGE_TARNAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_VERSION "$PACKAGE_VERSION" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_STRING "$PACKAGE_STRING" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" _ACEOF # Let the site file select an alternate cache file if it wants to. # Prefer explicitly selected file to automatically selected ones. if test -z "$CONFIG_SITE"; then if test "x$prefix" != xNONE; then CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" else CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" fi fi for ac_site_file in $CONFIG_SITE; do if test -r "$ac_site_file"; then { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5 echo "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" fi done # Check that the precious variables saved in the cache have kept the same # value. ac_cache_corrupted=false for ac_var in `(set) 2>&1 | sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do eval ac_old_set=\$ac_cv_env_${ac_var}_set eval ac_new_set=\$ac_env_${ac_var}_set eval ac_old_val="\$ac_cv_env_${ac_var}_value" eval ac_new_val="\$ac_env_${ac_var}_value" case $ac_old_set,$ac_new_set in set,) { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5 echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_cache_corrupted=: ;; ,);; *) if test "x$ac_old_val" != "x$ac_new_val"; then { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5 echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} { echo "$as_me:$LINENO: former value: $ac_old_val" >&5 echo "$as_me: former value: $ac_old_val" >&2;} { echo "$as_me:$LINENO: current value: $ac_new_val" >&5 echo "$as_me: current value: $ac_new_val" >&2;} ac_cache_corrupted=: fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*) ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; *) ac_arg=$ac_var=$ac_new_val ;; esac case " $ac_configure_args " in *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. *) ac_configure_args="$ac_configure_args '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5 echo "$as_me: error: changes in the environment can compromise the build" >&2;} { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} { (exit 1); exit 1; }; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_config_headers="$ac_config_headers include/config.h include/snprintf.h include/nagios.h include/cgiutils.h" PKG_NAME=nagios PKG_VERSION="2.6" PKG_HOME_URL="http://www.nagios.org/" PKG_REL_DATE="11-27-2006" ac_aux_dir= for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do if test -f $ac_dir/install-sh; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install-sh -c" break elif test -f $ac_dir/install.sh; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install.sh -c" break elif test -f $ac_dir/shtool; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/shtool install -c" break fi done if test -z "$ac_aux_dir"; then { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&5 echo "$as_me: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&2;} { (exit 1); exit 1; }; } fi ac_config_guess="$SHELL $ac_aux_dir/config.guess" ac_config_sub="$SHELL $ac_aux_dir/config.sub" ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure. # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or # incompatible versions: # SysV /etc/install, /usr/sbin/install # SunOS /usr/etc/install # IRIX /sbin/install # AIX /bin/install # AmigaOS /C/install, which installs bootblocks on floppy discs # AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag # AFS /usr/afsws/bin/install, which mishandles nonexistent args # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # OS/2's system install, which has a completely different semantic # ./install, which can be erroneously created by make from ./install.sh. echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5 echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6 if test -z "$INSTALL"; then if test "${ac_cv_path_install+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. # Account for people who put trailing slashes in PATH elements. case $as_dir/ in ./ | .// | /cC/* | \ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \ /usr/ucb/* ) ;; *) # OSF1 and SCO ODT 3.0 have their own names for install. # Don't use installbsd from OSF since it installs stuff as root # by default. for ac_prog in ginstall scoinst install; do for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then if test $ac_prog = install && grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. : elif test $ac_prog = install && grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # program-specific install script used by HP pwplus--don't use. : else ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" break 3 fi fi done done ;; esac done fi if test "${ac_cv_path_install+set}" = set; then INSTALL=$ac_cv_path_install else # As a last resort, use the slow shell script. We don't cache a # path for INSTALL within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the path is relative. INSTALL=$ac_install_sh fi fi echo "$as_me:$LINENO: result: $INSTALL" >&5 echo "${ECHO_T}$INSTALL" >&6 # Use test -z because SunOS4 sh mishandles braces in ${var-val}. # It thinks the first close brace ends the variable substitution. test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' # Make sure we can run config.sub. $ac_config_sub sun4 >/dev/null 2>&1 || { { echo "$as_me:$LINENO: error: cannot run $ac_config_sub" >&5 echo "$as_me: error: cannot run $ac_config_sub" >&2;} { (exit 1); exit 1; }; } echo "$as_me:$LINENO: checking build system type" >&5 echo $ECHO_N "checking build system type... $ECHO_C" >&6 if test "${ac_cv_build+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_build_alias=$build_alias test -z "$ac_cv_build_alias" && ac_cv_build_alias=`$ac_config_guess` test -z "$ac_cv_build_alias" && { { echo "$as_me:$LINENO: error: cannot guess build type; you must specify one" >&5 echo "$as_me: error: cannot guess build type; you must specify one" >&2;} { (exit 1); exit 1; }; } ac_cv_build=`$ac_config_sub $ac_cv_build_alias` || { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_build_alias failed" >&5 echo "$as_me: error: $ac_config_sub $ac_cv_build_alias failed" >&2;} { (exit 1); exit 1; }; } fi echo "$as_me:$LINENO: result: $ac_cv_build" >&5 echo "${ECHO_T}$ac_cv_build" >&6 build=$ac_cv_build build_cpu=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` build_vendor=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` build_os=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` echo "$as_me:$LINENO: checking host system type" >&5 echo $ECHO_N "checking host system type... $ECHO_C" >&6 if test "${ac_cv_host+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_host_alias=$host_alias test -z "$ac_cv_host_alias" && ac_cv_host_alias=$ac_cv_build_alias ac_cv_host=`$ac_config_sub $ac_cv_host_alias` || { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_host_alias failed" >&5 echo "$as_me: error: $ac_config_sub $ac_cv_host_alias failed" >&2;} { (exit 1); exit 1; }; } fi echo "$as_me:$LINENO: result: $ac_cv_host" >&5 echo "${ECHO_T}$ac_cv_host" >&6 host=$ac_cv_host host_cpu=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` host_vendor=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` host_os=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}gcc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then echo "$as_me:$LINENO: result: $CC" >&5 echo "${ECHO_T}$CC" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_ac_ct_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="gcc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 echo "${ECHO_T}$ac_ct_CC" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi CC=$ac_ct_CC else CC="$ac_cv_prog_CC" fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}cc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then echo "$as_me:$LINENO: result: $CC" >&5 echo "${ECHO_T}$CC" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_ac_ct_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="cc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 echo "${ECHO_T}$ac_ct_CC" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi CC=$ac_ct_CC else CC="$ac_cv_prog_CC" fi fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else ac_prog_rejected=no as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# != 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" fi fi fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then echo "$as_me:$LINENO: result: $CC" >&5 echo "${ECHO_T}$CC" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then for ac_prog in cl do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then echo "$as_me:$LINENO: result: $CC" >&5 echo "${ECHO_T}$CC" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi test -n "$CC" && break done fi if test -z "$CC"; then ac_ct_CC=$CC for ac_prog in cl do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_prog_ac_ct_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 echo "${ECHO_T}$ac_ct_CC" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi test -n "$ac_ct_CC" && break done CC=$ac_ct_CC fi fi test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH See \`config.log' for more details." >&5 echo "$as_me: error: no acceptable C compiler found in \$PATH See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } # Provide some information about the compiler. echo "$as_me:$LINENO:" \ "checking for C compiler version" >&5 ac_compiler=`set X $ac_compile; echo $2` { (eval echo "$as_me:$LINENO: \"$ac_compiler --version &5\"") >&5 (eval $ac_compiler --version &5) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (eval echo "$as_me:$LINENO: \"$ac_compiler -v &5\"") >&5 (eval $ac_compiler -v &5) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (eval echo "$as_me:$LINENO: \"$ac_compiler -V &5\"") >&5 (eval $ac_compiler -V &5) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files a.out a.exe b.out" # Try to create an executable without -o first, disregard a.out. # It will help us diagnose broken compilers, and finding out an intuition # of exeext. echo "$as_me:$LINENO: checking for C compiler default output file name" >&5 echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6 ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5 (eval $ac_link_default) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then # Find the output, starting from the most likely. This scheme is # not robust to junk in `.', hence go to wildcards (a.*) only as a last # resort. # Be careful to initialize this variable, since it used to be cached. # Otherwise an old cache value of `no' led to `EXEEXT = no' in a Makefile. ac_cv_exeext= # b.out is created by i960 compilers. for ac_file in a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;; conftest.$ac_ext ) # This is the source file. ;; [ab].out ) # We found the default executable, but exeext='' is most # certainly right. break;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` # FIXME: I believe we export ac_cv_exeext for Libtool, # but it would be cool to find out if it's true. Does anybody # maintain Libtool? --akim. export ac_cv_exeext break;; * ) break;; esac done else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { echo "$as_me:$LINENO: error: C compiler cannot create executables See \`config.log' for more details." >&5 echo "$as_me: error: C compiler cannot create executables See \`config.log' for more details." >&2;} { (exit 77); exit 77; }; } fi ac_exeext=$ac_cv_exeext echo "$as_me:$LINENO: result: $ac_file" >&5 echo "${ECHO_T}$ac_file" >&6 # Check the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. echo "$as_me:$LINENO: checking whether the C compiler works" >&5 echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6 # FIXME: These cross compiler hacks should be removed for Autoconf 3.0 # If not cross compiling, check that we can run a simple program. if test "$cross_compiling" != yes; then if { ac_try='./$ac_file' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then cross_compiling=no else if test "$cross_compiling" = maybe; then cross_compiling=yes else { { echo "$as_me:$LINENO: error: cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details." >&5 echo "$as_me: error: cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi fi fi echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6 rm -f a.out a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save # Check the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. echo "$as_me:$LINENO: checking whether we are cross compiling" >&5 echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6 echo "$as_me:$LINENO: result: $cross_compiling" >&5 echo "${ECHO_T}$cross_compiling" >&6 echo "$as_me:$LINENO: checking for suffix of executables" >&5 echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6 if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then # If both `conftest.exe' and `conftest' are `present' (well, observable) # catch `conftest.exe'. For instance with Cygwin, `ls conftest' will # work properly (i.e., refer to `conftest.exe'), while it won't with # `rm'. for ac_file in conftest.exe conftest conftest.*; do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` export ac_cv_exeext break;; * ) break;; esac done else { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link See \`config.log' for more details." >&5 echo "$as_me: error: cannot compute suffix of executables: cannot compile and link See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi rm -f conftest$ac_cv_exeext echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5 echo "${ECHO_T}$ac_cv_exeext" >&6 rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext ac_exeext=$EXEEXT echo "$as_me:$LINENO: checking for suffix of object files" >&5 echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6 if test "${ac_cv_objext+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.o conftest.obj if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg ) ;; *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` break;; esac done else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile See \`config.log' for more details." >&5 echo "$as_me: error: cannot compute suffix of object files: cannot compile See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_objext" >&5 echo "${ECHO_T}$ac_cv_objext" >&6 OBJEXT=$ac_cv_objext ac_objext=$OBJEXT echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5 echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6 if test "${ac_cv_c_compiler_gnu+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_compiler_gnu=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_compiler_gnu=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5 echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6 GCC=`test $ac_compiler_gnu = yes && echo yes` ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS CFLAGS="-g" echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5 echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6 if test "${ac_cv_prog_cc_g+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_prog_cc_g=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_prog_cc_g=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 echo "${ECHO_T}$ac_cv_prog_cc_g" >&6 if test "$ac_test_CFLAGS" = set; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi echo "$as_me:$LINENO: checking for $CC option to accept ANSI C" >&5 echo $ECHO_N "checking for $CC option to accept ANSI C... $ECHO_C" >&6 if test "${ac_cv_prog_cc_stdc+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_prog_cc_stdc=no ac_save_CC=$CC cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include #include /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has function prototypes and stuff, but not '\xHH' hex character constants. These don't provoke an error unfortunately, instead are silently treated as 'x'. The following induces an error, until -std1 is added to get proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an array size at least. It's necessary to write '\x00'==0 to get something that's true only with -std1. */ int osf4_cc_array ['\x00' == 0 ? 1 : -1]; int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); int argc; char **argv; int main () { return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ; return 0; } _ACEOF # Don't try gcc -ansi; that turns off useful extensions and # breaks some systems' header files. # AIX -qlanglvl=ansi # Ultrix and OSF/1 -std1 # HP-UX 10.20 and later -Ae # HP-UX older versions -Aa -D_HPUX_SOURCE # SVR4 -Xc -D__EXTENSIONS__ for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_prog_cc_stdc=$ac_arg break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f conftest.err conftest.$ac_objext done rm -f conftest.$ac_ext conftest.$ac_objext CC=$ac_save_CC fi case "x$ac_cv_prog_cc_stdc" in x|xno) echo "$as_me:$LINENO: result: none needed" >&5 echo "${ECHO_T}none needed" >&6 ;; *) echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5 echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6 CC="$CC $ac_cv_prog_cc_stdc" ;; esac # Some people use a C++ compiler to compile C. Since we use `exit', # in C++ we need to declare it. In case someone uses the same compiler # for both compiling C and C++ we need to have the C++ compiler decide # the declaration of exit, since it's the most demanding environment. cat >conftest.$ac_ext <<_ACEOF #ifndef __cplusplus choke me #endif _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then for ac_declaration in \ '' \ 'extern "C" void std::exit (int) throw (); using std::exit;' \ 'extern "C" void std::exit (int); using std::exit;' \ 'extern "C" void exit (int) throw ();' \ 'extern "C" void exit (int);' \ 'void exit (int);' do cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_declaration #include int main () { exit (42); ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 continue fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_declaration int main () { exit (42); ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext done rm -f conftest* if test -n "$ac_declaration"; then echo '#ifdef __cplusplus' >>confdefs.h echo $ac_declaration >>confdefs.h echo '#endif' >>confdefs.h fi else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5 echo $ECHO_N "checking whether ${MAKE-make} sets \$(MAKE)... $ECHO_C" >&6 set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y,:./+-,___p_,'` if eval "test \"\${ac_cv_prog_make_${ac_make}_set+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.make <<\_ACEOF all: @echo 'ac_maketemp="$(MAKE)"' _ACEOF # GNU make sometimes prints "make[1]: Entering...", which would confuse us. eval `${MAKE-make} -f conftest.make 2>/dev/null | grep temp=` if test -n "$ac_maketemp"; then eval ac_cv_prog_make_${ac_make}_set=yes else eval ac_cv_prog_make_${ac_make}_set=no fi rm -f conftest.make fi if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6 SET_MAKE= else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 SET_MAKE="MAKE=${MAKE-make}" fi # Extract the first word of "strip", so it can be a program name with args. set dummy strip; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_path_STRIP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else case $STRIP in [\\/]* | ?:[\\/]*) ac_cv_path_STRIP="$STRIP" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_STRIP="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done test -z "$ac_cv_path_STRIP" && ac_cv_path_STRIP="true" ;; esac fi STRIP=$ac_cv_path_STRIP if test -n "$STRIP"; then echo "$as_me:$LINENO: result: $STRIP" >&5 echo "${ECHO_T}$STRIP" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5 echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6 # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then if test "${ac_cv_prog_CPP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else # Double quotes because CPP needs to be expanded for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" do ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Broken: fails on valid input. continue fi rm -f conftest.err conftest.$ac_ext # OK, works on sane cases. Now check whether non-existent headers # can be detected and how. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then # Broken: success on invalid input. continue else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.err conftest.$ac_ext if $ac_preproc_ok; then break fi done ac_cv_prog_CPP=$CPP fi CPP=$ac_cv_prog_CPP else ac_cv_prog_CPP=$CPP fi echo "$as_me:$LINENO: result: $CPP" >&5 echo "${ECHO_T}$CPP" >&6 ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Broken: fails on valid input. continue fi rm -f conftest.err conftest.$ac_ext # OK, works on sane cases. Now check whether non-existent headers # can be detected and how. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then # Broken: success on invalid input. continue else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details." >&5 echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu echo "$as_me:$LINENO: checking for egrep" >&5 echo $ECHO_N "checking for egrep... $ECHO_C" >&6 if test "${ac_cv_prog_egrep+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if echo a | (grep -E '(a|b)') >/dev/null 2>&1 then ac_cv_prog_egrep='grep -E' else ac_cv_prog_egrep='egrep' fi fi echo "$as_me:$LINENO: result: $ac_cv_prog_egrep" >&5 echo "${ECHO_T}$ac_cv_prog_egrep" >&6 EGREP=$ac_cv_prog_egrep echo "$as_me:$LINENO: checking for ANSI C header files" >&5 echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6 if test "${ac_cv_header_stdc+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_header_stdc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_header_stdc=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "memchr" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "free" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #if ((' ' & 0x0FF) == 0x020) # define ISLOWER(c) ('a' <= (c) && (c) <= 'z') # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #else # define ISLOWER(c) \ (('a' <= (c) && (c) <= 'i') \ || ('j' <= (c) && (c) <= 'r') \ || ('s' <= (c) && (c) <= 'z')) # define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) #endif #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2); exit (0); } _ACEOF rm -f conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then : else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) ac_cv_header_stdc=no fi rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi fi echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 echo "${ECHO_T}$ac_cv_header_stdc" >&6 if test $ac_cv_header_stdc = yes; then cat >>confdefs.h <<\_ACEOF #define STDC_HEADERS 1 _ACEOF fi echo "$as_me:$LINENO: checking whether time.h and sys/time.h may both be included" >&5 echo $ECHO_N "checking whether time.h and sys/time.h may both be included... $ECHO_C" >&6 if test "${ac_cv_header_time+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include int main () { if ((struct tm *) 0) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_header_time=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_header_time=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_header_time" >&5 echo "${ECHO_T}$ac_cv_header_time" >&6 if test $ac_cv_header_time = yes; then cat >>confdefs.h <<\_ACEOF #define TIME_WITH_SYS_TIME 1 _ACEOF fi echo "$as_me:$LINENO: checking for sys/wait.h that is POSIX.1 compatible" >&5 echo $ECHO_N "checking for sys/wait.h that is POSIX.1 compatible... $ECHO_C" >&6 if test "${ac_cv_header_sys_wait_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #ifndef WEXITSTATUS # define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8) #endif #ifndef WIFEXITED # define WIFEXITED(stat_val) (((stat_val) & 255) == 0) #endif int main () { int s; wait (&s); s = WIFEXITED (s) ? WEXITSTATUS (s) : 1; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_header_sys_wait_h=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_header_sys_wait_h=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_header_sys_wait_h" >&5 echo "${ECHO_T}$ac_cv_header_sys_wait_h" >&6 if test $ac_cv_header_sys_wait_h = yes; then cat >>confdefs.h <<\_ACEOF #define HAVE_SYS_WAIT_H 1 _ACEOF fi # On IRIX 5.3, sys/types and inttypes.h are conflicting. for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ inttypes.h stdint.h unistd.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 if eval "test \"\${$as_ac_Header+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then eval "$as_ac_Header=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_Header=no" fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_header in arpa/inet.h ctype.h dirent.h errno.h fcntl.h getopt.h grp.h limits.h math.h netdb.h netinet/in.h pthread.h pthreads.h pwd.h regex.h signal.h socket.h string.h strings.h sys/mman.h sys/types.h sys/time.h sys/resource.h sys/wait.h sys/socket.h sys/stat.h sys/timeb.h sys/un.h sys/ipc.h sys/msg.h sys/poll.h syslog.h uio.h unistd.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` if eval "test \"\${$as_ac_Header+set}\" = set"; then echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 if eval "test \"\${$as_ac_Header+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 else # Is the header compilable? echo "$as_me:$LINENO: checking $ac_header usability" >&5 echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6 # Is the header present? echo "$as_me:$LINENO: checking $ac_header presence" >&5 echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6 # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## ------------------------------------------ ## ## Report this to the AC_PACKAGE_NAME lists. ## ## ------------------------------------------ ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 if eval "test \"\${$as_ac_Header+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 fi if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done echo "$as_me:$LINENO: checking for an ANSI C-conforming const" >&5 echo $ECHO_N "checking for an ANSI C-conforming const... $ECHO_C" >&6 if test "${ac_cv_c_const+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { /* FIXME: Include the comments suggested by Paul. */ #ifndef __cplusplus /* Ultrix mips cc rejects this. */ typedef int charset[2]; const charset x; /* SunOS 4.1.1 cc rejects this. */ char const *const *ccp; char **p; /* NEC SVR4.0.2 mips cc rejects this. */ struct point {int x, y;}; static struct point const zero = {0,0}; /* AIX XL C 1.02.0.0 rejects this. It does not let you subtract one const X* pointer from another in an arm of an if-expression whose if-part is not a constant expression */ const char *g = "string"; ccp = &g + (g ? g-g : 0); /* HPUX 7.0 cc rejects these. */ ++ccp; p = (char**) ccp; ccp = (char const *const *) p; { /* SCO 3.2v4 cc rejects this. */ char *t; char const *s = 0 ? (char *) 0 : (char const *) 0; *t++ = 0; } { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ int x[] = {25, 17}; const int *foo = &x[0]; ++foo; } { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ typedef const int *iptr; iptr p = 0; ++p; } { /* AIX XL C 1.02.0.0 rejects this saying "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ struct s { int j; const int *ap[3]; }; struct s *b; b->j = 5; } { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ const int foo = 10; } #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_c_const=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_c_const=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_c_const" >&5 echo "${ECHO_T}$ac_cv_c_const" >&6 if test $ac_cv_c_const = no; then cat >>confdefs.h <<\_ACEOF #define const _ACEOF fi echo "$as_me:$LINENO: checking whether struct tm is in sys/time.h or time.h" >&5 echo $ECHO_N "checking whether struct tm is in sys/time.h or time.h... $ECHO_C" >&6 if test "${ac_cv_struct_tm+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include int main () { struct tm *tp; tp->tm_sec; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_struct_tm=time.h else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_struct_tm=sys/time.h fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_struct_tm" >&5 echo "${ECHO_T}$ac_cv_struct_tm" >&6 if test $ac_cv_struct_tm = sys/time.h; then cat >>confdefs.h <<\_ACEOF #define TM_IN_SYS_TIME 1 _ACEOF fi echo "$as_me:$LINENO: checking for struct tm.tm_zone" >&5 echo $ECHO_N "checking for struct tm.tm_zone... $ECHO_C" >&6 if test "${ac_cv_member_struct_tm_tm_zone+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include <$ac_cv_struct_tm> int main () { static struct tm ac_aggr; if (ac_aggr.tm_zone) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_member_struct_tm_tm_zone=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include <$ac_cv_struct_tm> int main () { static struct tm ac_aggr; if (sizeof ac_aggr.tm_zone) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_member_struct_tm_tm_zone=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_member_struct_tm_tm_zone=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_member_struct_tm_tm_zone" >&5 echo "${ECHO_T}$ac_cv_member_struct_tm_tm_zone" >&6 if test $ac_cv_member_struct_tm_tm_zone = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_STRUCT_TM_TM_ZONE 1 _ACEOF fi if test "$ac_cv_member_struct_tm_tm_zone" = yes; then cat >>confdefs.h <<\_ACEOF #define HAVE_TM_ZONE 1 _ACEOF else echo "$as_me:$LINENO: checking for tzname" >&5 echo $ECHO_N "checking for tzname... $ECHO_C" >&6 if test "${ac_cv_var_tzname+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #ifndef tzname /* For SGI. */ extern char *tzname[]; /* RS6000 and others reject char **tzname. */ #endif int main () { atoi(*tzname); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_var_tzname=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_var_tzname=no fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_var_tzname" >&5 echo "${ECHO_T}$ac_cv_var_tzname" >&6 if test $ac_cv_var_tzname = yes; then cat >>confdefs.h <<\_ACEOF #define HAVE_TZNAME 1 _ACEOF fi fi echo "$as_me:$LINENO: checking for mode_t" >&5 echo $ECHO_N "checking for mode_t... $ECHO_C" >&6 if test "${ac_cv_type_mode_t+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default int main () { if ((mode_t *) 0) return 0; if (sizeof (mode_t)) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_type_mode_t=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_type_mode_t=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_type_mode_t" >&5 echo "${ECHO_T}$ac_cv_type_mode_t" >&6 if test $ac_cv_type_mode_t = yes; then : else cat >>confdefs.h <<_ACEOF #define mode_t int _ACEOF fi echo "$as_me:$LINENO: checking for pid_t" >&5 echo $ECHO_N "checking for pid_t... $ECHO_C" >&6 if test "${ac_cv_type_pid_t+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default int main () { if ((pid_t *) 0) return 0; if (sizeof (pid_t)) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_type_pid_t=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_type_pid_t=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_type_pid_t" >&5 echo "${ECHO_T}$ac_cv_type_pid_t" >&6 if test $ac_cv_type_pid_t = yes; then : else cat >>confdefs.h <<_ACEOF #define pid_t int _ACEOF fi echo "$as_me:$LINENO: checking for size_t" >&5 echo $ECHO_N "checking for size_t... $ECHO_C" >&6 if test "${ac_cv_type_size_t+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default int main () { if ((size_t *) 0) return 0; if (sizeof (size_t)) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_type_size_t=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_type_size_t=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_type_size_t" >&5 echo "${ECHO_T}$ac_cv_type_size_t" >&6 if test $ac_cv_type_size_t = yes; then : else cat >>confdefs.h <<_ACEOF #define size_t unsigned _ACEOF fi echo "$as_me:$LINENO: checking return type of signal handlers" >&5 echo $ECHO_N "checking return type of signal handlers... $ECHO_C" >&6 if test "${ac_cv_type_signal+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #ifdef signal # undef signal #endif #ifdef __cplusplus extern "C" void (*signal (int, void (*)(int)))(int); #else void (*signal ()) (); #endif int main () { int i; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_type_signal=void else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_type_signal=int fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_type_signal" >&5 echo "${ECHO_T}$ac_cv_type_signal" >&6 cat >>confdefs.h <<_ACEOF #define RETSIGTYPE $ac_cv_type_signal _ACEOF echo "$as_me:$LINENO: checking for uid_t in sys/types.h" >&5 echo $ECHO_N "checking for uid_t in sys/types.h... $ECHO_C" >&6 if test "${ac_cv_type_uid_t+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "uid_t" >/dev/null 2>&1; then ac_cv_type_uid_t=yes else ac_cv_type_uid_t=no fi rm -f conftest* fi echo "$as_me:$LINENO: result: $ac_cv_type_uid_t" >&5 echo "${ECHO_T}$ac_cv_type_uid_t" >&6 if test $ac_cv_type_uid_t = no; then cat >>confdefs.h <<\_ACEOF #define uid_t int _ACEOF cat >>confdefs.h <<\_ACEOF #define gid_t int _ACEOF fi echo "$as_me:$LINENO: checking type of array argument to getgroups" >&5 echo $ECHO_N "checking type of array argument to getgroups... $ECHO_C" >&6 if test "${ac_cv_type_getgroups+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test "$cross_compiling" = yes; then ac_cv_type_getgroups=cross else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Thanks to Mike Rendell for this test. */ #include #define NGID 256 #undef MAX #define MAX(x, y) ((x) > (y) ? (x) : (y)) int main () { gid_t gidset[NGID]; int i, n; union { gid_t gval; long lval; } val; val.lval = -1; for (i = 0; i < NGID; i++) gidset[i] = val.gval; n = getgroups (sizeof (gidset) / MAX (sizeof (int), sizeof (gid_t)) - 1, gidset); /* Exit non-zero if getgroups seems to require an array of ints. This happens when gid_t is short but getgroups modifies an array of ints. */ exit ((n > 0 && gidset[n] != val.gval) ? 1 : 0); } _ACEOF rm -f conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_type_getgroups=gid_t else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) ac_cv_type_getgroups=int fi rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi if test $ac_cv_type_getgroups = cross; then cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "getgroups.*int.*gid_t" >/dev/null 2>&1; then ac_cv_type_getgroups=gid_t else ac_cv_type_getgroups=int fi rm -f conftest* fi fi echo "$as_me:$LINENO: result: $ac_cv_type_getgroups" >&5 echo "${ECHO_T}$ac_cv_type_getgroups" >&6 cat >>confdefs.h <<_ACEOF #define GETGROUPS_T $ac_cv_type_getgroups _ACEOF for ac_func in initgroups setenv strdup strstr strtoul unsetenv do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` echo "$as_me:$LINENO: checking for $ac_func" >&5 echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 if eval "test \"\${$as_ac_var+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define $ac_func to an innocuous variant, in case declares $ac_func. For example, HP-UX 11i declares gettimeofday. */ #define $ac_func innocuous_$ac_func /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $ac_func /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" { #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char $ac_func (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_$ac_func) || defined (__stub___$ac_func) choke me #else char (*f) () = $ac_func; #endif #ifdef __cplusplus } #endif int main () { return f != $ac_func; ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 if test `eval echo '${'$as_ac_var'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done echo "$as_me:$LINENO: checking for type of socket size" >&5 echo $ECHO_N "checking for type of socket size... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include int main () { int a = send(1, (const void *) 0, (size_t) 0, (int) 0); ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then cat >>confdefs.h <<\_ACEOF #define SOCKET_SIZE_TYPE size_t _ACEOF echo "$as_me:$LINENO: result: size_t" >&5 echo "${ECHO_T}size_t" >&6 else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 cat >>confdefs.h <<\_ACEOF #define SOCKET_SIZE_TYPE int _ACEOF echo "$as_me:$LINENO: result: int" >&5 echo "${ECHO_T}int" >&6 fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext THREADLIBS="" have_pthreads="no" echo "$as_me:$LINENO: checking for pthread_create in -lcma" >&5 echo $ECHO_N "checking for pthread_create in -lcma... $ECHO_C" >&6 if test "${ac_cv_lib_cma_pthread_create+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lcma $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char pthread_create (); int main () { pthread_create (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_cma_pthread_create=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_cma_pthread_create=no fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_lib_cma_pthread_create" >&5 echo "${ECHO_T}$ac_cv_lib_cma_pthread_create" >&6 if test $ac_cv_lib_cma_pthread_create = yes; then THREADLIBS="$THREADLIBS -lpthread" fi if test $ac_cv_lib_cma_pthread_create = yes; then have_pthreads="yes" fi echo "$as_me:$LINENO: checking for pthread_create in -lpthread" >&5 echo $ECHO_N "checking for pthread_create in -lpthread... $ECHO_C" >&6 if test "${ac_cv_lib_pthread_pthread_create+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lpthread $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char pthread_create (); int main () { pthread_create (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_pthread_pthread_create=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_pthread_pthread_create=no fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_lib_pthread_pthread_create" >&5 echo "${ECHO_T}$ac_cv_lib_pthread_pthread_create" >&6 if test $ac_cv_lib_pthread_pthread_create = yes; then THREADLIBS="$THREADLIBS -lpthread" fi if test $ac_cv_lib_pthread_pthread_create = yes; then have_pthreads="yes" else echo "$as_me:$LINENO: checking for pthread_mutex_init in -lpthread" >&5 echo $ECHO_N "checking for pthread_mutex_init in -lpthread... $ECHO_C" >&6 if test "${ac_cv_lib_pthread_pthread_mutex_init+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lpthread $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char pthread_mutex_init (); int main () { pthread_mutex_init (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_pthread_pthread_mutex_init=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_pthread_pthread_mutex_init=no fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_lib_pthread_pthread_mutex_init" >&5 echo "${ECHO_T}$ac_cv_lib_pthread_pthread_mutex_init" >&6 if test $ac_cv_lib_pthread_pthread_mutex_init = yes; then THREADLIBS="$THREADLIBS -lpthread" fi if test $ac_cv_lib_pthread_pthread_mutex_init = yes; then have_pthreads="yes" fi fi if test $have_pthreads = "no"; then echo "$as_me:$LINENO: checking for pthread_create in -lpthreads" >&5 echo $ECHO_N "checking for pthread_create in -lpthreads... $ECHO_C" >&6 if test "${ac_cv_lib_pthreads_pthread_create+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lpthreads $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char pthread_create (); int main () { pthread_create (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_pthreads_pthread_create=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_pthreads_pthread_create=no fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_lib_pthreads_pthread_create" >&5 echo "${ECHO_T}$ac_cv_lib_pthreads_pthread_create" >&6 if test $ac_cv_lib_pthreads_pthread_create = yes; then THREADLIBS="$THREADLIBS -lpthreads" fi if test $ac_cv_lib_pthreads_pthread_create = yes; then have_pthreads="yes" fi fi if test $have_pthreads = "no"; then echo "$as_me:$LINENO: checking for pthread_create in -llthread" >&5 echo $ECHO_N "checking for pthread_create in -llthread... $ECHO_C" >&6 if test "${ac_cv_lib_lthread_pthread_create+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-llthread -L/usr/local/lib $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char pthread_create (); int main () { pthread_create (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_lthread_pthread_create=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_lthread_pthread_create=no fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_lib_lthread_pthread_create" >&5 echo "${ECHO_T}$ac_cv_lib_lthread_pthread_create" >&6 if test $ac_cv_lib_lthread_pthread_create = yes; then CFLAGS="-D_THREAD_SAFE -I/usr/local/include/pthread/linuxthreads -I/usr/include $CFLAGS" THREADLIBS="-L/usr/local/lib -llthread -llgcc_r" else echo "$as_me:$LINENO: checking if we need -pthread for threads" >&5 echo $ECHO_N "checking if we need -pthread for threads... $ECHO_C" >&6 if test "${ac_ldflag_pthread+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_save_LDFLAGS="$LDFLAGS" LDFLAGS="-pthread $LDFLAGS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ char pthread_create(); int main () { pthread_create(); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then eval "ac_ldflag_pthread=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "ac_ldflag_pthread=no" fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext, THREADLIBS="$ac_save_LDFLAGS" fi if eval "test \"`echo $ac_ldflag_pthread`\" = yes"; then echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi fi fi echo "$as_me:$LINENO: checking for library containing nanosleep" >&5 echo $ECHO_N "checking for library containing nanosleep... $ECHO_C" >&6 if test "${ac_cv_search_nanosleep+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_func_search_save_LIBS=$LIBS ac_cv_search_nanosleep=no cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char nanosleep (); int main () { nanosleep (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_search_nanosleep="none required" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test "$ac_cv_search_nanosleep" = no; then for ac_lib in rt posix4; do LIBS="-l$ac_lib $ac_func_search_save_LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char nanosleep (); int main () { nanosleep (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_search_nanosleep="-l$ac_lib" break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext done fi LIBS=$ac_func_search_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_search_nanosleep" >&5 echo "${ECHO_T}$ac_cv_search_nanosleep" >&6 if test "$ac_cv_search_nanosleep" != no; then test "$ac_cv_search_nanosleep" = "none required" || LIBS="$ac_cv_search_nanosleep $LIBS" else echo "Error: nanosleep() needed for timing operations." exit 1 fi # Check whether --with-nagios_user or --without-nagios_user was given. if test "${with_nagios_user+set}" = set; then withval="$with_nagios_user" nagios_user=$withval else nagios_user=nagios fi; # Check whether --with-nagios_group or --without-nagios_group was given. if test "${with_nagios_group+set}" = set; then withval="$with_nagios_group" nagios_grp=$withval else nagios_grp=nagios fi; cat >>confdefs.h <<_ACEOF #define DEFAULT_NAGIOS_USER "$nagios_user" _ACEOF cat >>confdefs.h <<_ACEOF #define DEFAULT_NAGIOS_GROUP "$nagios_grp" _ACEOF INSTALL_OPTS="-o $nagios_user -g $nagios_grp" # Check whether --with-command_user or --without-command_user was given. if test "${with_command_user+set}" = set; then withval="$with_command_user" command_user=$withval else command_user=$nagios_user fi; # Check whether --with-command_group or --without-command_group was given. if test "${with_command_group+set}" = set; then withval="$with_command_group" command_grp=$withval else command_grp=$nagios_grp fi; COMMAND_OPTS="-o $command_user -g $command_grp" MAIL_PROG=no # Check whether --with-mail or --without-mail was given. if test "${with_mail+set}" = set; then withval="$with_mail" MAIL_PROG=$withval else MAIL_PROG=no fi; if test MAIL_PROG=no; then # Extract the first word of "mail", so it can be a program name with args. set dummy mail; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_path_MAIL_PROG+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else case $MAIL_PROG in [\\/]* | ?:[\\/]*) ac_cv_path_MAIL_PROG="$MAIL_PROG" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_MAIL_PROG="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done ;; esac fi MAIL_PROG=$ac_cv_path_MAIL_PROG if test -n "$MAIL_PROG"; then echo "$as_me:$LINENO: result: $MAIL_PROG" >&5 echo "${ECHO_T}$MAIL_PROG" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi fi init_dir=/etc/rc.d/init.d if test -d /etc/rc.d/init.d; then init_dir="/etc/rc.d/init.d" elif test -d /usr/local/etc/rc.d; then init_dir="/usr/local/etc/rc.d" elif test -d /etc/rc.d; then init_dir="/etc/rc.d" elif test -d /etc/init.d; then init_dir="/etc/init.d" elif test -d /sbin/init.d; then init_dir="/sbin/init.d" fi # Check whether --with-init_dir or --without-init_dir was given. if test "${with_init_dir+set}" = set; then withval="$with_init_dir" init_dir=$withval fi; echo "Init script directory: " $init_dir # Check whether --with-lockfile or --without-lockfile was given. if test "${with_lockfile+set}" = set; then withval="$with_lockfile" lockfile=$withval else lockfile=$localstatedir/nagios.lock fi; XSDTYPE=default XCDTYPE=default XRDTYPE=default XODTYPE=template XPDTYPE=default XDDTYPE=default XSDCOMMENT= XCDCOMMENT= XRDCOMMENT= XODCOMMENT= XPDCOMMENT= XDDCOMMENT= USE_MYSQL=no USE_PGSQL=no cat >>confdefs.h <<_ACEOF #define USE_XSDDEFAULT 1 _ACEOF XSDC="xsddefault.c" XSDH="xsddefault.h" XSDCOMMENT="Default (text file)" echo "We'll use default routines (in xdata/xsddefault.*) for status data I/O..." cat >>confdefs.h <<_ACEOF #define USE_XCDDEFAULT 1 _ACEOF XCDC="xcddefault.c" XCDH="xcddefault.h" XCDCOMMENT="Default (text file)" echo "We'll use default routines (in xdata/xcddefault.*) for comment data I/O..." cat >>confdefs.h <<_ACEOF #define USE_XRDDEFAULT 1 _ACEOF XRDC="xrddefault.c" XRDH="xrddefault.h" XRDCOMMENT="Default (text file)" echo "We'll use default routines (in xdata/xrddefault.*) for retention data I/O..." cat >>confdefs.h <<_ACEOF #define USE_XODTEMPLATE 1 _ACEOF XODC="xodtemplate.c" XODH="xodtemplate.h" XODCOMMENT="Template-based (text file)" echo "We'll use template-based routines (in xdata/xodtemplate.*) for object data I/O..." cat >>confdefs.h <<_ACEOF #define USE_XPDDEFAULT 1 _ACEOF XPDC="xpddefault.c" XPDH="xpddefault.h" XPDCOMMENT="Default (external commands)" echo "We'll use default routines (in xdata/xpddefault.*) for performance data I/O..." cat >>confdefs.h <<_ACEOF #define USE_XDDDEFAULT 1 _ACEOF XDDC="xdddefault.c" XDDH="xdddefault.h" XDDCOMMENT="Default (text file)" echo "We'll use default routines (in xdata/xdddefault.*) for scheduled downtime data I/O..." # Check whether --with-gd-lib or --without-gd-lib was given. if test "${with_gd_lib+set}" = set; then withval="$with_gd_lib" LDFLAGS="${LDFLAGS} -L${withval}" LD_RUN_PATH="${withval}${LD_RUN_PATH:+:}${LD_RUN_PATH}" fi; # Check whether --with-gd-inc or --without-gd-inc was given. if test "${with_gd_inc+set}" = set; then withval="$with_gd_inc" CFLAGS="${CFLAGS} -I${withval}" fi; TRYGD=yep TRYSTATUSMAP=yep # Check whether --enable-statusmap or --disable-statusmap was given. if test "${enable_statusmap+set}" = set; then enableval="$enable_statusmap" TRYSTATUSMAP=nope fi; TRYSTATUSWRL=yep # Check whether --enable-statuswrl or --disable-statuswrl was given. if test "${enable_statuswrl+set}" = set; then enableval="$enable_statuswrl" TRYSTATUSWRL=nope fi; if test x$TRYSTATUSWRL = xyep; then cat >>confdefs.h <<_ACEOF #define USE_STATUSWRL 1 _ACEOF CGIEXTRAS="$CGIEXTRAS statuswrl.cgi" fi if test x$TRYGD = xyep; then echo "$as_me:$LINENO: checking for main in -liconv" >&5 echo $ECHO_N "checking for main in -liconv... $ECHO_C" >&6 if test "${ac_cv_lib_iconv_main+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-liconv $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { main (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_iconv_main=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_iconv_main=no fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_lib_iconv_main" >&5 echo "${ECHO_T}$ac_cv_lib_iconv_main" >&6 if test $ac_cv_lib_iconv_main = yes; then ICONV=-liconv fi echo "$as_me:$LINENO: checking for gdImagePng in -lgd (order 1)" >&5 echo $ECHO_N "checking for gdImagePng in -lgd (order 1)... $ECHO_C" >&6 ac_lib_var=`echo gd'_'gdImagePng'_'1 | sed 'y%./+-%__p_%'` if eval "test \"\${ac_cv_lib_$ac_lib_var+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_save_LIBS="$LIBS" LIBS="-lgd -lttf -lpng -ljpeg -lz -lm $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char gdImagePng(); int main () { gdImagePng() ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then eval "ac_cv_lib_$ac_lib_var=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6 GDLIBFOUND=yep GDLIBS="-lgd -lttf -lpng -ljpeg -lz -lm" else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 : fi if test x$GDLIBFOUND = x; then echo "$as_me:$LINENO: checking for gdImagePng in -lgd (order 2)" >&5 echo $ECHO_N "checking for gdImagePng in -lgd (order 2)... $ECHO_C" >&6 ac_lib_var=`echo gd'_'gdImagePng'_'2 | sed 'y%./+-%__p_%'` if eval "test \"\${ac_cv_lib_$ac_lib_var+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_save_LIBS="$LIBS" LIBS="-lgd $ICONV -lpng -ljpeg -lz -lm $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char gdImagePng(); int main () { gdImagePng() ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then eval "ac_cv_lib_$ac_lib_var=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6 GDLIBFOUND=yep GDLIBS="-lgd $ICONV -lpng -ljpeg -lz -lm" else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 : fi fi if test x$GDLIBFOUND = x; then echo "$as_me:$LINENO: checking for gdImagePng in -lgd (order 3)" >&5 echo $ECHO_N "checking for gdImagePng in -lgd (order 3)... $ECHO_C" >&6 ac_lib_var=`echo gd'_'gdImagePng'_'3 | sed 'y%./+-%__p_%'` if eval "test \"\${ac_cv_lib_$ac_lib_var+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_save_LIBS="$LIBS" LIBS="-lgd $ICONV -lz -lm -lpng $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char gdImagePng(); int main () { gdImagePng() ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then eval "ac_cv_lib_$ac_lib_var=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6 GDLIBFOUND=yep GDLIBS="-lgd $ICONV -lz -lm -lpng" else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 : fi fi if test x$GDLIBFOUND = x; then echo "$as_me:$LINENO: checking for gdImagePng in -lgd (order 4)" >&5 echo $ECHO_N "checking for gdImagePng in -lgd (order 4)... $ECHO_C" >&6 ac_lib_var=`echo gd'_'gdImagePng'_'4 | sed 'y%./+-%__p_%'` if eval "test \"\${ac_cv_lib_$ac_lib_var+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_save_LIBS="$LIBS" LIBS="-lgd $ICONV -lpng -lz -lm $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char gdImagePng(); int main () { gdImagePng() ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then eval "ac_cv_lib_$ac_lib_var=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6 GDLIBFOUND=yep GDLIBS="-lgd $ICONV -lpng -lz -lm" else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 : fi fi if test x$GDLIBFOUND = x; then echo "" echo "" echo "*** GD, PNG, and/or JPEG libraries could not be located... *********" echo "" echo "Boutell's GD library is required to compile the statusmap, trends" echo "and histogram CGIs. Get it from http://www.boutell.com/gd/, compile" echo "it, and use the --with-gd-lib and --with-gd-inc arguments to specify" echo "the locations of the GD library and include files." echo "" echo "NOTE: In addition to the gd-devel library, you'll also need to make" echo " sure you have the png-devel and jpeg-devel libraries installed" echo " on your system." echo "" echo "NOTE: After you install the necessary libraries on your system:" echo " 1. Make sure /etc/ld.so.conf has an entry for the directory in" echo " which the GD, PNG, and JPEG libraries are installed." echo " 2. Run 'ldconfig' to update the run-time linker options." echo " 3. Run 'make clean' in the Nagios distribution to clean out" echo " any old references to your previous compile." echo " 4. Rerun the configure script." echo "" echo "NOTE: If you can't get the configure script to recognize the GD libs" echo " on your system, get over it and move on to other things. The" echo " CGIs that use the GD libs are just a small part of the entire" echo " Nagios package. Get everything else working first and then" echo " revisit the problem. Make sure to check the nagios-users" echo " mailing list archives for possible solutions to GD library" echo " problems when you resume your troubleshooting." echo "" echo "********************************************************************" echo "" echo "" else echo "GD library was found!" if test x$TRYSTATUSMAP = xyep; then cat >>confdefs.h <<_ACEOF #define USE_STATUSMAP 1 _ACEOF CGIEXTRAS="$CGIEXTRAS statusmap.cgi" fi cat >>confdefs.h <<_ACEOF #define USE_TRENDS 1 _ACEOF CGIEXTRAS="$CGIEXTRAS trends.cgi" cat >>confdefs.h <<_ACEOF #define USE_HISTOGRAM 1 _ACEOF CGIEXTRAS="$CGIEXTRAS histogram.cgi" fi fi # Check whether --with-cgiurl or --without-cgiurl was given. if test "${with_cgiurl+set}" = set; then withval="$with_cgiurl" cgiurl=$withval else cgiurl=/nagios/cgi-bin fi; # Check whether --with-htmurl or --without-htmurl was given. if test "${with_htmurl+set}" = set; then withval="$with_htmurl" htmurl=$withval else htmurl=/nagios fi; # Check whether --enable-DEBUG0 or --disable-DEBUG0 was given. if test "${enable_DEBUG0+set}" = set; then enableval="$enable_DEBUG0" cat >>confdefs.h <<_ACEOF #define DEBUG0 1 _ACEOF fi; # Check whether --enable-DEBUG1 or --disable-DEBUG1 was given. if test "${enable_DEBUG1+set}" = set; then enableval="$enable_DEBUG1" cat >>confdefs.h <<_ACEOF #define DEBUG1 1 _ACEOF fi; # Check whether --enable-DEBUG2 or --disable-DEBUG2 was given. if test "${enable_DEBUG2+set}" = set; then enableval="$enable_DEBUG2" cat >>confdefs.h <<_ACEOF #define DEBUG2 1 _ACEOF fi; # Check whether --enable-DEBUG3 or --disable-DEBUG3 was given. if test "${enable_DEBUG3+set}" = set; then enableval="$enable_DEBUG3" cat >>confdefs.h <<_ACEOF #define DEBUG3 1 _ACEOF fi; # Check whether --enable-DEBUG4 or --disable-DEBUG4 was given. if test "${enable_DEBUG4+set}" = set; then enableval="$enable_DEBUG4" cat >>confdefs.h <<_ACEOF #define DEBUG4 1 _ACEOF fi; # Check whether --enable-DEBUG5 or --disable-DEBUG5 was given. if test "${enable_DEBUG5+set}" = set; then enableval="$enable_DEBUG5" cat >>confdefs.h <<_ACEOF #define DEBUG5 1 _ACEOF fi; # Check whether --enable-DEBUGALL or --disable-DEBUGALL was given. if test "${enable_DEBUGALL+set}" = set; then enableval="$enable_DEBUGALL" cat >>confdefs.h <<_ACEOF #define DEBUG0 1 _ACEOF cat >>confdefs.h <<_ACEOF #define DEBUG1 1 _ACEOF cat >>confdefs.h <<_ACEOF #define DEBUG2 1 _ACEOF cat >>confdefs.h <<_ACEOF #define DEBUG3 1 _ACEOF cat >>confdefs.h <<_ACEOF #define DEBUG4 1 _ACEOF cat >>confdefs.h <<_ACEOF #define DEBUG5 1 _ACEOF fi; USE_NANOSLEEP=yes # Check whether --enable-nanosleep or --disable-nanosleep was given. if test "${enable_nanosleep+set}" = set; then enableval="$enable_nanosleep" USE_NANOSLEEP=$enableval else USE_NANOSLEEP=yes fi; if test x$USE_NANOSLEEP = xyes; then cat >>confdefs.h <<_ACEOF #define USE_NANOSLEEP 1 _ACEOF fi USE_EVENTBROKER=yes # Check whether --enable-event-broker or --disable-event-broker was given. if test "${enable_event_broker+set}" = set; then enableval="$enable_event_broker" USE_EVENTBROKER=$enableval else USE_EVENTBROKER=yes fi; BROKER_LDFLAGS="" BROKERLIBS=""; some_dl_found="no"; if test x$USE_EVENTBROKER = xyes; then if test "${ac_cv_header_ltdl_h+set}" = set; then echo "$as_me:$LINENO: checking for ltdl.h" >&5 echo $ECHO_N "checking for ltdl.h... $ECHO_C" >&6 if test "${ac_cv_header_ltdl_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi echo "$as_me:$LINENO: result: $ac_cv_header_ltdl_h" >&5 echo "${ECHO_T}$ac_cv_header_ltdl_h" >&6 else # Is the header compilable? echo "$as_me:$LINENO: checking ltdl.h usability" >&5 echo $ECHO_N "checking ltdl.h usability... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6 # Is the header present? echo "$as_me:$LINENO: checking ltdl.h presence" >&5 echo $ECHO_N "checking ltdl.h presence... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6 # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: ltdl.h: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: ltdl.h: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: ltdl.h: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: ltdl.h: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: ltdl.h: present but cannot be compiled" >&5 echo "$as_me: WARNING: ltdl.h: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: ltdl.h: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: ltdl.h: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: ltdl.h: see the Autoconf documentation" >&5 echo "$as_me: WARNING: ltdl.h: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: ltdl.h: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: ltdl.h: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: ltdl.h: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: ltdl.h: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: ltdl.h: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: ltdl.h: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## ------------------------------------------ ## ## Report this to the AC_PACKAGE_NAME lists. ## ## ------------------------------------------ ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac echo "$as_me:$LINENO: checking for ltdl.h" >&5 echo $ECHO_N "checking for ltdl.h... $ECHO_C" >&6 if test "${ac_cv_header_ltdl_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_header_ltdl_h=$ac_header_preproc fi echo "$as_me:$LINENO: result: $ac_cv_header_ltdl_h" >&5 echo "${ECHO_T}$ac_cv_header_ltdl_h" >&6 fi if test $ac_cv_header_ltdl_h = yes; then echo "$as_me:$LINENO: checking for lt_dlinit in -lltdl" >&5 echo $ECHO_N "checking for lt_dlinit in -lltdl... $ECHO_C" >&6 if test "${ac_cv_lib_ltdl_lt_dlinit+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lltdl $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char lt_dlinit (); int main () { lt_dlinit (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_ltdl_lt_dlinit=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_ltdl_lt_dlinit=no fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_lib_ltdl_lt_dlinit" >&5 echo "${ECHO_T}$ac_cv_lib_ltdl_lt_dlinit" >&6 if test $ac_cv_lib_ltdl_lt_dlinit = yes; then cat >>confdefs.h <<\_ACEOF #define HAVE_LTDL_H 1 _ACEOF some_dl_found="yes" BROKERLIBS="$BROKERLIBS -lltdl" fi fi if test "x$some_dl_found" != xyes; then if test "${ac_cv_header_dlfcn_h+set}" = set; then echo "$as_me:$LINENO: checking for dlfcn.h" >&5 echo $ECHO_N "checking for dlfcn.h... $ECHO_C" >&6 if test "${ac_cv_header_dlfcn_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi echo "$as_me:$LINENO: result: $ac_cv_header_dlfcn_h" >&5 echo "${ECHO_T}$ac_cv_header_dlfcn_h" >&6 else # Is the header compilable? echo "$as_me:$LINENO: checking dlfcn.h usability" >&5 echo $ECHO_N "checking dlfcn.h usability... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6 # Is the header present? echo "$as_me:$LINENO: checking dlfcn.h presence" >&5 echo $ECHO_N "checking dlfcn.h presence... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi else ac_cpp_err=yes fi if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6 # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: dlfcn.h: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: dlfcn.h: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: dlfcn.h: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: dlfcn.h: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: dlfcn.h: present but cannot be compiled" >&5 echo "$as_me: WARNING: dlfcn.h: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: dlfcn.h: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: dlfcn.h: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: dlfcn.h: see the Autoconf documentation" >&5 echo "$as_me: WARNING: dlfcn.h: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: dlfcn.h: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: dlfcn.h: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: dlfcn.h: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: dlfcn.h: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: dlfcn.h: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: dlfcn.h: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## ------------------------------------------ ## ## Report this to the AC_PACKAGE_NAME lists. ## ## ------------------------------------------ ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac echo "$as_me:$LINENO: checking for dlfcn.h" >&5 echo $ECHO_N "checking for dlfcn.h... $ECHO_C" >&6 if test "${ac_cv_header_dlfcn_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_header_dlfcn_h=$ac_header_preproc fi echo "$as_me:$LINENO: result: $ac_cv_header_dlfcn_h" >&5 echo "${ECHO_T}$ac_cv_header_dlfcn_h" >&6 fi if test $ac_cv_header_dlfcn_h = yes; then echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5 echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6 if test "${ac_cv_lib_dl_dlopen+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char dlopen (); int main () { dlopen (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_lib_dl_dlopen=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_dl_dlopen=no fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5 echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6 if test $ac_cv_lib_dl_dlopen = yes; then cat >>confdefs.h <<\_ACEOF #define HAVE_DLFCN_H 1 _ACEOF some_dl_found="yes" BROKERLIBS="$BROKERLIBS -ldl" fi fi fi # Check how to export functions from the broker executable, needed # when dynamically loaded drivers are loaded (so that they can find # broker functions). # OS'es with ELF executables using the GNU linker (Linux and recent *BSD, # in rare cases Solaris) typically need '-Wl,-export-dynamic' (i.e. pass # -export-dynamic to the linker - also known as -rdynamic and some other # variants); some sysVr4 system(s) instead need(s) '-Wl,-Bexport'. # AIX 4.x (perhaps only for x>=2) wants -Wl,-bexpall,-brtl and doesn't # reliably return an error for others, thus we separate it out. # Otherwise we assume that if the linker accepts the flag, it is needed. echo "$as_me:$LINENO: checking for extra flags needed to export symbols" >&5 echo $ECHO_N "checking for extra flags needed to export symbols... $ECHO_C" >&6 case $host_os in aix4*|aix5*) BROKER_LDFLAGS="$BROKER_LDFLAGS -Wl,-bexpall,-brtl" ;; bsdi*) BROKER_LDFLAGS="$BROKER_LDFLAGS -rdynamic" ;; *) save_ldflags="$LDFLAGS" LDFLAGS=-Wl,-export-dynamic cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then BROKER_LDFLAGS="$BROKER_LDFLAGS -Wl,-export-dynamic" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 LDFLAGS=-Wl,-Bexport cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then BROKER_LDFLAGS="$BROKER_LDFLAGS -Wl,-Bexport" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 echo "$as_me:$LINENO: result: none" >&5 echo "${ECHO_T}none" >&6 fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LDFLAGS="$save_ldflags" ;; esac test "x$BROKER_LDFLAGS" != x && echo "$as_me:$LINENO: result: $BROKER_LDFLAGS" >&5 echo "${ECHO_T}$BROKER_LDFLAGS" >&6 echo "$as_me:$LINENO: checking for linker flags for loadable modules" >&5 echo $ECHO_N "checking for linker flags for loadable modules... $ECHO_C" >&6 case $host_os in solaris2*|sysv4*) MOD_LDFLAGS="-G" ;; aix4*|aix5*) #MOD_LDFLAGS="-G -bnoentry -bexpall" MOD_LDFLAGS="-G -bM:SRE -bnoentry -bexpall" ;; freebsd2*) # Non-ELF GNU linker MOD_LDFLAGS="-Bshareable" ;; darwin*) # Mach-O linker, a shared lib and a loadable # object file is not the same thing. MOD_LDFLAGS="-bundle -flat_namespace -undefined suppress" MOD_CFLAGS="$MOD_CFLAGS -fno-common" ;; linux*) # assume GNU linker and ELF MOD_LDFLAGS="-shared" MOD_CFLAGS="-fPIC" ;; *) # assume GNU linker and ELF MOD_LDFLAGS="-shared" ;; esac echo "$as_me:$LINENO: result: $MOD_LDFLAGS" >&5 echo "${ECHO_T}$MOD_LDFLAGS" >&6 cat >>confdefs.h <<_ACEOF #define USE_EVENT_BROKER 1 _ACEOF BROKER_O="broker.o nebmods.o" BROKER_H="../include/broker.h ../include/nebmods.h ../include/nebmodules.h ../include/nebcallbacks.h ../include/neberrors.h" fi USEPERL=no; INSTALLPERLSTUFF=no; # Check whether --enable-embedded-perl or --disable-embedded-perl was given. if test "${enable_embedded_perl+set}" = set; then enableval="$enable_embedded_perl" cat >>confdefs.h <<_ACEOF #define EMBEDDEDPERL 1 _ACEOF PERLLIBS="`perl -MExtUtils::Embed -e ldopts`" PERLDIR="`perl -MConfig -e 'print $Config{installsitearch}'`" CFLAGS="${CFLAGS} `perl -MExtUtils::Embed -e ccopts`" USEPERL=yes INSTALLPERLSTUFF=yes; PERLXSI_O=perlxsi.o OBJS="${OBJS} ${PERLXSI_O}" echo "creating base/perlxsi.c" perl -MExtUtils::Embed -e xsinit -- -o base/perlxsi.c fi; PERLCACHE=no; # Check whether --with-perlcache or --without-perlcache was given. if test "${with_perlcache+set}" = set; then withval="$with_perlcache" cat >>confdefs.h <<\_ACEOF #define DO_CLEAN "0" _ACEOF PERLCACHE=yes; else cat >>confdefs.h <<\_ACEOF #define DO_CLEAN "1" _ACEOF PERLCACHE=no; fi; if test x$USEPERL = xyes; then echo "Embedded Perl interpreter will be compiled in..." if test x$PERLCACHE = xyes; then echo "Internally compiled Perl scripts will be cached..." else echo "Internally compiled Perl scripts will NOT be cached..." fi fi if test x$USEPERL = xyes; then if (perl -e 'use Config;exit -1 unless ($Config{'usethreads'});'); then echo "Using threaded perl" cat >>confdefs.h <<_ACEOF #define THREADEDPERL 1 _ACEOF fi fi nagios_name=nagios nagiostats_name=nagiostats # Check whether --enable-cygwin or --disable-cygwin was given. if test "${enable_cygwin+set}" = set; then enableval="$enable_cygwin" CFLAGS="${CFLAGS} -DCYGWIN" nagios_name=nagios.exe; nagiostats_name=nagiostats.exe; fi; # Extract the first word of "traceroute", so it can be a program name with args. set dummy traceroute; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_path_PATH_TO_TRACEROUTE+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else case $PATH_TO_TRACEROUTE in [\\/]* | ?:[\\/]*) ac_cv_path_PATH_TO_TRACEROUTE="$PATH_TO_TRACEROUTE" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_PATH_TO_TRACEROUTE="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done ;; esac fi PATH_TO_TRACEROUTE=$ac_cv_path_PATH_TO_TRACEROUTE if test -n "$PATH_TO_TRACEROUTE"; then echo "$as_me:$LINENO: result: $PATH_TO_TRACEROUTE" >&5 echo "${ECHO_T}$PATH_TO_TRACEROUTE" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi cat >>confdefs.h <<_ACEOF #define TRACEROUTE_COMMAND "$PATH_TO_TRACEROUTE" _ACEOF VERSION=$PKG_VERSION PACKDIR=`pwd`/pkg echo "$as_me:$LINENO: checking for snprintf" >&5 echo $ECHO_N "checking for snprintf... $ECHO_C" >&6 if test "${ac_cv_func_snprintf+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define snprintf to an innocuous variant, in case declares snprintf. For example, HP-UX 11i declares gettimeofday. */ #define snprintf innocuous_snprintf /* System header to define __stub macros and hopefully few prototypes, which can conflict with char snprintf (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef snprintf /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" { #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char snprintf (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_snprintf) || defined (__stub___snprintf) choke me #else char (*f) () = snprintf; #endif #ifdef __cplusplus } #endif int main () { return f != snprintf; ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest$ac_exeext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_func_snprintf=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_func_snprintf=no fi rm -f conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_func_snprintf" >&5 echo "${ECHO_T}$ac_cv_func_snprintf" >&6 if test $ac_cv_func_snprintf = yes; then cat >>confdefs.h <<\_ACEOF #define HAVE_SNPRINTF 1 _ACEOF else SNPRINTF_O=../common/snprintf.o fi echo "$as_me:$LINENO: checking for type va_list" >&5 echo $ECHO_N "checking for type va_list... $ECHO_C" >&6 cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef __STDC__ #include #include #include #else #include #include #include #endif int main () { va_list args; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6 else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 cat >>confdefs.h <<\_ACEOF #define NEED_VA_LIST 1 _ACEOF echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext # Extract the first word of "perl", so it can be a program name with args. set dummy perl; ac_word=$2 echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 if test "${ac_cv_path_PERL+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else case $PERL in [\\/]* | ?:[\\/]*) ac_cv_path_PERL="$PERL" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_PERL="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done ;; esac fi PERL=$ac_cv_path_PERL if test -n "$PERL"; then echo "$as_me:$LINENO: result: $PERL" >&5 echo "${ECHO_T}$PERL" >&6 else echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6 fi ac_config_files="$ac_config_files Makefile subst pkginfo base/Makefile common/Makefile contrib/Makefile cgi/Makefile html/Makefile module/Makefile include/Makefile xdata/Makefile daemon-init html/index.html html/side.html" test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' # VPATH may cause trouble with some makes, so we remove $(srcdir), # ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and # trailing colons and then remove the whole line if VPATH becomes empty # (actually we leave an empty line to preserve line numbers). if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=/{ s/:*\$(srcdir):*/:/; s/:*\${srcdir}:*/:/; s/:*@srcdir@:*/:/; s/^\([^=]*=[ ]*\):*/\1/; s/:*$//; s/^[^=]*=[ ]*$//; }' fi DEFS=-DHAVE_CONFIG_H ac_libobjs= ac_ltlibobjs= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_i=`echo "$ac_i" | sed 's/\$U\././;s/\.o$//;s/\.obj$//'` # 2. Add them. ac_libobjs="$ac_libobjs $ac_i\$U.$ac_objext" ac_ltlibobjs="$ac_ltlibobjs $ac_i"'$U.lo' done LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs : ${CONFIG_STATUS=./config.status} ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" { echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5 echo "$as_me: creating $CONFIG_STATUS" >&6;} cat >$CONFIG_STATUS <<_ACEOF #! $SHELL # Generated by $as_me. # Run this file to recreate the current configuration. # Compiler output produced by configure, useful for debugging # configure, is in config.log if it exists. debug=false ac_cs_recheck=false ac_cs_silent=false SHELL=\${CONFIG_SHELL-$SHELL} _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF ## --------------------- ## ## M4sh Initialization. ## ## --------------------- ## # Be Bourne compatible if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then set -o posix fi DUALCASE=1; export DUALCASE # for MKS sh # Support unset when possible. if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then as_unset=unset else as_unset=false fi # Work around bugs in pre-3.0 UWIN ksh. $as_unset ENV MAIL MAILPATH PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. for as_var in \ LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ LC_TELEPHONE LC_TIME do if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then eval $as_var=C; export $as_var else $as_unset $as_var fi done # Required to use basename. if expr a : '\(a\)' >/dev/null 2>&1; then as_expr=expr else as_expr=false fi if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi # Name of the executable. as_me=`$as_basename "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)$' \| \ . : '\(.\)' 2>/dev/null || echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } /^X\/\(\/\/\)$/{ s//\1/; q; } /^X\/\(\/\).*/{ s//\1/; q; } s/.*/./; q'` # PATH needs CR, and LINENO needs CR and PATH. # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then echo "#! /bin/sh" >conf$$.sh echo "exit 0" >>conf$$.sh chmod +x conf$$.sh if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then PATH_SEPARATOR=';' else PATH_SEPARATOR=: fi rm -f conf$$.sh fi as_lineno_1=$LINENO as_lineno_2=$LINENO as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` test "x$as_lineno_1" != "x$as_lineno_2" && test "x$as_lineno_3" = "x$as_lineno_2" || { # Find who we are. Look in the path if we contain no path at all # relative or not. case $0 in *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5 echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;} { (exit 1); exit 1; }; } fi case $CONFIG_SHELL in '') as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for as_base in sh bash ksh sh5; do case $as_dir in /*) if ("$as_dir/$as_base" -c ' as_lineno_1=$LINENO as_lineno_2=$LINENO as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` test "x$as_lineno_1" != "x$as_lineno_2" && test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; } $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; } CONFIG_SHELL=$as_dir/$as_base export CONFIG_SHELL exec "$CONFIG_SHELL" "$0" ${1+"$@"} fi;; esac done done ;; esac # Create $as_me.lineno as a copy of $as_myself, but with $LINENO # uniformly replaced by the line number. The first 'sed' inserts a # line-number line before each line; the second 'sed' does the real # work. The second script uses 'N' to pair each line-number line # with the numbered line, and appends trailing '-' during # substitution so that $LINENO is not a special case at line end. # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) sed '=' <$as_myself | sed ' N s,$,-, : loop s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, t loop s,-$,, s,^['$as_cr_digits']*\n,, ' >$as_me.lineno && chmod +x $as_me.lineno || { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5 echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;} { (exit 1); exit 1; }; } # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensible to this). . ./$as_me.lineno # Exit status is that of the last command. exit } case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in *c*,-n*) ECHO_N= ECHO_C=' ' ECHO_T=' ' ;; *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; *) ECHO_N= ECHO_C='\c' ECHO_T= ;; esac if expr a : '\(a\)' >/dev/null 2>&1; then as_expr=expr else as_expr=false fi rm -f conf$$ conf$$.exe conf$$.file echo >conf$$.file if ln -s conf$$.file conf$$ 2>/dev/null; then # We could just check for DJGPP; but this test a) works b) is more generic # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). if test -f conf$$.exe; then # Don't use ln at all; we don't have any links as_ln_s='cp -p' else as_ln_s='ln -s' fi elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' fi rm -f conf$$ conf$$.exe conf$$.file if mkdir -p . 2>/dev/null; then as_mkdir_p=: else test -d ./-p && rmdir ./-p as_mkdir_p=false fi as_executable_p="test -f" # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" # IFS # We need space, tab and new line, in precisely that order. as_nl=' ' IFS=" $as_nl" # CDPATH. $as_unset CDPATH exec 6>&1 # Open the log real soon, to keep \$[0] and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. Logging --version etc. is OK. exec 5>>config.log { echo sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX } >&5 cat >&5 <<_CSEOF This file was extended by $as_me, which was generated by GNU Autoconf 2.59. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS CONFIG_LINKS = $CONFIG_LINKS CONFIG_COMMANDS = $CONFIG_COMMANDS $ $0 $@ _CSEOF echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5 echo >&5 _ACEOF # Files that config.status was made for. if test -n "$ac_config_files"; then echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS fi if test -n "$ac_config_headers"; then echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS fi if test -n "$ac_config_links"; then echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS fi if test -n "$ac_config_commands"; then echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS fi cat >>$CONFIG_STATUS <<\_ACEOF ac_cs_usage="\ \`$as_me' instantiates files from templates according to the current configuration. Usage: $0 [OPTIONS] [FILE]... -h, --help print this help, then exit -V, --version print version number, then exit -q, --quiet do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions --file=FILE[:TEMPLATE] instantiate the configuration file FILE --header=FILE[:TEMPLATE] instantiate the configuration header FILE Configuration files: $config_files Configuration headers: $config_headers Report bugs to ." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF ac_cs_version="\\ config.status configured by $0, generated by GNU Autoconf 2.59, with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\" Copyright (C) 2003 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." srcdir=$srcdir INSTALL="$INSTALL" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF # If no file are specified by the user, then we need to provide default # value. By we need to know if files were specified by the user. ac_need_defaults=: while test $# != 0 do case $1 in --*=*) ac_option=`expr "x$1" : 'x\([^=]*\)='` ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'` ac_shift=: ;; -*) ac_option=$1 ac_optarg=$2 ac_shift=shift ;; *) # This is not an option, so the user has probably given explicit # arguments. ac_option=$1 ac_need_defaults=false;; esac case $ac_option in # Handling of the options. _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; --version | --vers* | -V ) echo "$ac_cs_version"; exit 0 ;; --he | --h) # Conflict between --help and --header { { echo "$as_me:$LINENO: error: ambiguous option: $1 Try \`$0 --help' for more information." >&5 echo "$as_me: error: ambiguous option: $1 Try \`$0 --help' for more information." >&2;} { (exit 1); exit 1; }; };; --help | --hel | -h ) echo "$ac_cs_usage"; exit 0 ;; --debug | --d* | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift CONFIG_FILES="$CONFIG_FILES $ac_optarg" ac_need_defaults=false;; --header | --heade | --head | --hea ) $ac_shift CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg" ac_need_defaults=false;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; # This is an error. -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1 Try \`$0 --help' for more information." >&5 echo "$as_me: error: unrecognized option: $1 Try \`$0 --help' for more information." >&2;} { (exit 1); exit 1; }; } ;; *) ac_config_targets="$ac_config_targets $1" ;; esac shift done ac_configure_extra_args= if $ac_cs_silent; then exec 6>/dev/null ac_configure_extra_args="$ac_configure_extra_args --silent" fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF if \$ac_cs_recheck; then echo "running $SHELL $0 " $ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6 exec $SHELL $0 $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion fi _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF for ac_config_target in $ac_config_targets do case "$ac_config_target" in # Handling of arguments. "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;; "subst" ) CONFIG_FILES="$CONFIG_FILES subst" ;; "pkginfo" ) CONFIG_FILES="$CONFIG_FILES pkginfo" ;; "base/Makefile" ) CONFIG_FILES="$CONFIG_FILES base/Makefile" ;; "common/Makefile" ) CONFIG_FILES="$CONFIG_FILES common/Makefile" ;; "contrib/Makefile" ) CONFIG_FILES="$CONFIG_FILES contrib/Makefile" ;; "cgi/Makefile" ) CONFIG_FILES="$CONFIG_FILES cgi/Makefile" ;; "html/Makefile" ) CONFIG_FILES="$CONFIG_FILES html/Makefile" ;; "module/Makefile" ) CONFIG_FILES="$CONFIG_FILES module/Makefile" ;; "include/Makefile" ) CONFIG_FILES="$CONFIG_FILES include/Makefile" ;; "xdata/Makefile" ) CONFIG_FILES="$CONFIG_FILES xdata/Makefile" ;; "daemon-init" ) CONFIG_FILES="$CONFIG_FILES daemon-init" ;; "html/index.html" ) CONFIG_FILES="$CONFIG_FILES html/index.html" ;; "html/side.html" ) CONFIG_FILES="$CONFIG_FILES html/side.html" ;; "include/config.h" ) CONFIG_HEADERS="$CONFIG_HEADERS include/config.h" ;; "include/snprintf.h" ) CONFIG_HEADERS="$CONFIG_HEADERS include/snprintf.h" ;; "include/nagios.h" ) CONFIG_HEADERS="$CONFIG_HEADERS include/nagios.h" ;; "include/cgiutils.h" ) CONFIG_HEADERS="$CONFIG_HEADERS include/cgiutils.h" ;; *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 echo "$as_me: error: invalid argument: $ac_config_target" >&2;} { (exit 1); exit 1; }; };; esac done # If the user did not use the arguments to specify the items to instantiate, # then the envvar interface is used. Set only those that are not. # We use the long form for the default assignment because of an extremely # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers fi # Have a temporary directory for convenience. Make it in the build tree # simply because there is no reason to put it here, and in addition, # creating and moving files from /tmp can sometimes cause problems. # Create a temporary directory, and hook for its removal unless debugging. $debug || { trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0 trap '{ (exit 1); exit 1; }' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d -q "./confstatXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" } || { tmp=./confstat$$-$RANDOM (umask 077 && mkdir $tmp) } || { echo "$me: cannot create a temporary directory in ." >&2 { (exit 1); exit 1; } } _ACEOF cat >>$CONFIG_STATUS <<_ACEOF # # CONFIG_FILES section. # # No need to generate the scripts if there are no CONFIG_FILES. # This happens for instance when ./config.status config.h if test -n "\$CONFIG_FILES"; then # Protect against being on the right side of a sed subst in config.status. sed 's/,@/@@/; s/@,/@@/; s/,;t t\$/@;t t/; /@;t t\$/s/[\\\\&,]/\\\\&/g; s/@@/,@/; s/@@/@,/; s/@;t t\$/,;t t/' >\$tmp/subs.sed <<\\CEOF s,@SHELL@,$SHELL,;t t s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t s,@exec_prefix@,$exec_prefix,;t t s,@prefix@,$prefix,;t t s,@program_transform_name@,$program_transform_name,;t t s,@bindir@,$bindir,;t t s,@sbindir@,$sbindir,;t t s,@libexecdir@,$libexecdir,;t t s,@datadir@,$datadir,;t t s,@sysconfdir@,$sysconfdir,;t t s,@sharedstatedir@,$sharedstatedir,;t t s,@localstatedir@,$localstatedir,;t t s,@libdir@,$libdir,;t t s,@includedir@,$includedir,;t t s,@oldincludedir@,$oldincludedir,;t t s,@infodir@,$infodir,;t t s,@mandir@,$mandir,;t t s,@build_alias@,$build_alias,;t t s,@host_alias@,$host_alias,;t t s,@target_alias@,$target_alias,;t t s,@DEFS@,$DEFS,;t t s,@ECHO_C@,$ECHO_C,;t t s,@ECHO_N@,$ECHO_N,;t t s,@ECHO_T@,$ECHO_T,;t t s,@LIBS@,$LIBS,;t t s,@INSTALL_PROGRAM@,$INSTALL_PROGRAM,;t t s,@INSTALL_SCRIPT@,$INSTALL_SCRIPT,;t t s,@INSTALL_DATA@,$INSTALL_DATA,;t t s,@INSTALL@,$INSTALL,;t t s,@build@,$build,;t t s,@build_cpu@,$build_cpu,;t t s,@build_vendor@,$build_vendor,;t t s,@build_os@,$build_os,;t t s,@host@,$host,;t t s,@host_cpu@,$host_cpu,;t t s,@host_vendor@,$host_vendor,;t t s,@host_os@,$host_os,;t t s,@CC@,$CC,;t t s,@CFLAGS@,$CFLAGS,;t t s,@LDFLAGS@,$LDFLAGS,;t t s,@CPPFLAGS@,$CPPFLAGS,;t t s,@ac_ct_CC@,$ac_ct_CC,;t t s,@EXEEXT@,$EXEEXT,;t t s,@OBJEXT@,$OBJEXT,;t t s,@SET_MAKE@,$SET_MAKE,;t t s,@STRIP@,$STRIP,;t t s,@CPP@,$CPP,;t t s,@EGREP@,$EGREP,;t t s,@SOCKETLIBS@,$SOCKETLIBS,;t t s,@THREADLIBS@,$THREADLIBS,;t t s,@nagios_user@,$nagios_user,;t t s,@nagios_grp@,$nagios_grp,;t t s,@INSTALL_OPTS@,$INSTALL_OPTS,;t t s,@command_user@,$command_user,;t t s,@command_grp@,$command_grp,;t t s,@COMMAND_OPTS@,$COMMAND_OPTS,;t t s,@MAIL_PROG@,$MAIL_PROG,;t t s,@init_dir@,$init_dir,;t t s,@lockfile@,$lockfile,;t t s,@XSDC@,$XSDC,;t t s,@XSDH@,$XSDH,;t t s,@XCDC@,$XCDC,;t t s,@XCDH@,$XCDH,;t t s,@XRDC@,$XRDC,;t t s,@XRDH@,$XRDH,;t t s,@XODC@,$XODC,;t t s,@XODH@,$XODH,;t t s,@XPDC@,$XPDC,;t t s,@XPDH@,$XPDH,;t t s,@XDDC@,$XDDC,;t t s,@XDDH@,$XDDH,;t t s,@htmurl@,$htmurl,;t t s,@cgiurl@,$cgiurl,;t t s,@BROKER_LDFLAGS@,$BROKER_LDFLAGS,;t t s,@BROKERLIBS@,$BROKERLIBS,;t t s,@MOD_CFLAGS@,$MOD_CFLAGS,;t t s,@MOD_LDFLAGS@,$MOD_LDFLAGS,;t t s,@BROKER_O@,$BROKER_O,;t t s,@BROKER_H@,$BROKER_H,;t t s,@nagios_name@,$nagios_name,;t t s,@nagiostats_name@,$nagiostats_name,;t t s,@PATH_TO_TRACEROUTE@,$PATH_TO_TRACEROUTE,;t t s,@PACKDIR@,$PACKDIR,;t t s,@VERSION@,$VERSION,;t t s,@SNPRINTF_O@,$SNPRINTF_O,;t t s,@CGIEXTRAS@,$CGIEXTRAS,;t t s,@GDLIBS@,$GDLIBS,;t t s,@PERLLIBS@,$PERLLIBS,;t t s,@PERLDIR@,$PERLDIR,;t t s,@PERLXSI_O@,$PERLXSI_O,;t t s,@BASEEXTRALIBS@,$BASEEXTRALIBS,;t t s,@INITDIR@,$INITDIR,;t t s,@INSTALLPERLSTUFF@,$INSTALLPERLSTUFF,;t t s,@PERL@,$PERL,;t t s,@LIBOBJS@,$LIBOBJS,;t t s,@LTLIBOBJS@,$LTLIBOBJS,;t t CEOF _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF # Split the substitutions into bite-sized pieces for seds with # small command number limits, like on Digital OSF/1 and HP-UX. ac_max_sed_lines=48 ac_sed_frag=1 # Number of current file. ac_beg=1 # First line for current file. ac_end=$ac_max_sed_lines # Line after last line for current file. ac_more_lines=: ac_sed_cmds= while $ac_more_lines; do if test $ac_beg -gt 1; then sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag else sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag fi if test ! -s $tmp/subs.frag; then ac_more_lines=false else # The purpose of the label and of the branching condition is to # speed up the sed processing (if there are no `@' at all, there # is no need to browse any of the substitutions). # These are the two extra sed commands mentioned above. (echo ':t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed if test -z "$ac_sed_cmds"; then ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed" else ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed" fi ac_sed_frag=`expr $ac_sed_frag + 1` ac_beg=$ac_end ac_end=`expr $ac_end + $ac_max_sed_lines` fi done if test -z "$ac_sed_cmds"; then ac_sed_cmds=cat fi fi # test -n "$CONFIG_FILES" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". case $ac_file in - | *:- | *:-:* ) # input from stdin cat >$tmp/stdin ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; * ) ac_file_in=$ac_file.in ;; esac # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories. ac_dir=`(dirname "$ac_file") 2>/dev/null || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| \ . : '\(.\)' 2>/dev/null || echo X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } /^X\(\/\/\)[^/].*/{ s//\1/; q; } /^X\(\/\/\)$/{ s//\1/; q; } /^X\(\/\).*/{ s//\1/; q; } s/.*/./; q'` { if $as_mkdir_p; then mkdir -p "$ac_dir" else as_dir="$ac_dir" as_dirs= while test ! -d "$as_dir"; do as_dirs="$as_dir $as_dirs" as_dir=`(dirname "$as_dir") 2>/dev/null || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| \ . : '\(.\)' 2>/dev/null || echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } /^X\(\/\/\)[^/].*/{ s//\1/; q; } /^X\(\/\/\)$/{ s//\1/; q; } /^X\(\/\).*/{ s//\1/; q; } s/.*/./; q'` done test ! -n "$as_dirs" || mkdir $as_dirs fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5 echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;} { (exit 1); exit 1; }; }; } ac_builddir=. if test "$ac_dir" != .; then ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` # A "../" for each directory in $ac_dir_suffix. ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` else ac_dir_suffix= ac_top_builddir= fi case $srcdir in .) # No --srcdir option. We are building in place. ac_srcdir=. if test -z "$ac_top_builddir"; then ac_top_srcdir=. else ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` fi ;; [\\/]* | ?:[\\/]* ) # Absolute path. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ;; *) # Relative path. ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_builddir$srcdir ;; esac # Do not use `cd foo && pwd` to compute absolute paths, because # the directories may not exist. case `pwd` in .) ac_abs_builddir="$ac_dir";; *) case "$ac_dir" in .) ac_abs_builddir=`pwd`;; [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";; *) ac_abs_builddir=`pwd`/"$ac_dir";; esac;; esac case $ac_abs_builddir in .) ac_abs_top_builddir=${ac_top_builddir}.;; *) case ${ac_top_builddir}. in .) ac_abs_top_builddir=$ac_abs_builddir;; [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;; *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;; esac;; esac case $ac_abs_builddir in .) ac_abs_srcdir=$ac_srcdir;; *) case $ac_srcdir in .) ac_abs_srcdir=$ac_abs_builddir;; [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;; *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;; esac;; esac case $ac_abs_builddir in .) ac_abs_top_srcdir=$ac_top_srcdir;; *) case $ac_top_srcdir in .) ac_abs_top_srcdir=$ac_abs_builddir;; [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;; *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;; esac;; esac case $INSTALL in [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; *) ac_INSTALL=$ac_top_builddir$INSTALL ;; esac if test x"$ac_file" != x-; then { echo "$as_me:$LINENO: creating $ac_file" >&5 echo "$as_me: creating $ac_file" >&6;} rm -f "$ac_file" fi # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ if test x"$ac_file" = x-; then configure_input= else configure_input="$ac_file. " fi configure_input=$configure_input"Generated from `echo $ac_file_in | sed 's,.*/,,'` by configure." # First look for the input files in the build tree, otherwise in the # src tree. ac_file_inputs=`IFS=: for f in $ac_file_in; do case $f in -) echo $tmp/stdin ;; [\\/$]*) # Absolute (can't be DOS-style, as IFS=:) test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 echo "$as_me: error: cannot find input file: $f" >&2;} { (exit 1); exit 1; }; } echo "$f";; *) # Relative if test -f "$f"; then # Build tree echo "$f" elif test -f "$srcdir/$f"; then # Source tree echo "$srcdir/$f" else # /dev/null tree { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 echo "$as_me: error: cannot find input file: $f" >&2;} { (exit 1); exit 1; }; } fi;; esac done` || { (exit 1); exit 1; } _ACEOF cat >>$CONFIG_STATUS <<_ACEOF sed "$ac_vpsub $extrasub _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b s,@configure_input@,$configure_input,;t t s,@srcdir@,$ac_srcdir,;t t s,@abs_srcdir@,$ac_abs_srcdir,;t t s,@top_srcdir@,$ac_top_srcdir,;t t s,@abs_top_srcdir@,$ac_abs_top_srcdir,;t t s,@builddir@,$ac_builddir,;t t s,@abs_builddir@,$ac_abs_builddir,;t t s,@top_builddir@,$ac_top_builddir,;t t s,@abs_top_builddir@,$ac_abs_top_builddir,;t t s,@INSTALL@,$ac_INSTALL,;t t " $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out rm -f $tmp/stdin if test x"$ac_file" != x-; then mv $tmp/out $ac_file else cat $tmp/out rm -f $tmp/out fi done _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF # # CONFIG_HEADER section. # # These sed commands are passed to sed as "A NAME B NAME C VALUE D", where # NAME is the cpp macro being defined and VALUE is the value it is being given. # # ac_d sets the value in "#define NAME VALUE" lines. ac_dA='s,^\([ ]*\)#\([ ]*define[ ][ ]*\)' ac_dB='[ ].*$,\1#\2' ac_dC=' ' ac_dD=',;t' # ac_u turns "#undef NAME" without trailing blanks into "#define NAME VALUE". ac_uA='s,^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' ac_uB='$,\1#\2define\3' ac_uC=' ' ac_uD=',;t' for ac_file in : $CONFIG_HEADERS; do test "x$ac_file" = x: && continue # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". case $ac_file in - | *:- | *:-:* ) # input from stdin cat >$tmp/stdin ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; * ) ac_file_in=$ac_file.in ;; esac test x"$ac_file" != x- && { echo "$as_me:$LINENO: creating $ac_file" >&5 echo "$as_me: creating $ac_file" >&6;} # First look for the input files in the build tree, otherwise in the # src tree. ac_file_inputs=`IFS=: for f in $ac_file_in; do case $f in -) echo $tmp/stdin ;; [\\/$]*) # Absolute (can't be DOS-style, as IFS=:) test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 echo "$as_me: error: cannot find input file: $f" >&2;} { (exit 1); exit 1; }; } # Do quote $f, to prevent DOS paths from being IFS'd. echo "$f";; *) # Relative if test -f "$f"; then # Build tree echo "$f" elif test -f "$srcdir/$f"; then # Source tree echo "$srcdir/$f" else # /dev/null tree { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 echo "$as_me: error: cannot find input file: $f" >&2;} { (exit 1); exit 1; }; } fi;; esac done` || { (exit 1); exit 1; } # Remove the trailing spaces. sed 's/[ ]*$//' $ac_file_inputs >$tmp/in _ACEOF # Transform confdefs.h into two sed scripts, `conftest.defines' and # `conftest.undefs', that substitutes the proper values into # config.h.in to produce config.h. The first handles `#define' # templates, and the second `#undef' templates. # And first: Protect against being on the right side of a sed subst in # config.status. Protect against being in an unquoted here document # in config.status. rm -f conftest.defines conftest.undefs # Using a here document instead of a string reduces the quoting nightmare. # Putting comments in sed scripts is not portable. # # `end' is used to avoid that the second main sed command (meant for # 0-ary CPP macros) applies to n-ary macro definitions. # See the Autoconf documentation for `clear'. cat >confdef2sed.sed <<\_ACEOF s/[\\&,]/\\&/g s,[\\$`],\\&,g t clear : clear s,^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*\)\(([^)]*)\)[ ]*\(.*\)$,${ac_dA}\1${ac_dB}\1\2${ac_dC}\3${ac_dD},gp t end s,^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)$,${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD},gp : end _ACEOF # If some macros were called several times there might be several times # the same #defines, which is useless. Nevertheless, we may not want to # sort them, since we want the *last* AC-DEFINE to be honored. uniq confdefs.h | sed -n -f confdef2sed.sed >conftest.defines sed 's/ac_d/ac_u/g' conftest.defines >conftest.undefs rm -f confdef2sed.sed # This sed command replaces #undef with comments. This is necessary, for # example, in the case of _POSIX_SOURCE, which is predefined and required # on some systems where configure will not decide to define it. cat >>conftest.undefs <<\_ACEOF s,^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*,/* & */, _ACEOF # Break up conftest.defines because some shells have a limit on the size # of here documents, and old seds have small limits too (100 cmds). echo ' # Handle all the #define templates only if necessary.' >>$CONFIG_STATUS echo ' if grep "^[ ]*#[ ]*define" $tmp/in >/dev/null; then' >>$CONFIG_STATUS echo ' # If there are no defines, we may have an empty if/fi' >>$CONFIG_STATUS echo ' :' >>$CONFIG_STATUS rm -f conftest.tail while grep . conftest.defines >/dev/null do # Write a limited-size here document to $tmp/defines.sed. echo ' cat >$tmp/defines.sed <>$CONFIG_STATUS # Speed up: don't consider the non `#define' lines. echo '/^[ ]*#[ ]*define/!b' >>$CONFIG_STATUS # Work around the forget-to-reset-the-flag bug. echo 't clr' >>$CONFIG_STATUS echo ': clr' >>$CONFIG_STATUS sed ${ac_max_here_lines}q conftest.defines >>$CONFIG_STATUS echo 'CEOF sed -f $tmp/defines.sed $tmp/in >$tmp/out rm -f $tmp/in mv $tmp/out $tmp/in ' >>$CONFIG_STATUS sed 1,${ac_max_here_lines}d conftest.defines >conftest.tail rm -f conftest.defines mv conftest.tail conftest.defines done rm -f conftest.defines echo ' fi # grep' >>$CONFIG_STATUS echo >>$CONFIG_STATUS # Break up conftest.undefs because some shells have a limit on the size # of here documents, and old seds have small limits too (100 cmds). echo ' # Handle all the #undef templates' >>$CONFIG_STATUS rm -f conftest.tail while grep . conftest.undefs >/dev/null do # Write a limited-size here document to $tmp/undefs.sed. echo ' cat >$tmp/undefs.sed <>$CONFIG_STATUS # Speed up: don't consider the non `#undef' echo '/^[ ]*#[ ]*undef/!b' >>$CONFIG_STATUS # Work around the forget-to-reset-the-flag bug. echo 't clr' >>$CONFIG_STATUS echo ': clr' >>$CONFIG_STATUS sed ${ac_max_here_lines}q conftest.undefs >>$CONFIG_STATUS echo 'CEOF sed -f $tmp/undefs.sed $tmp/in >$tmp/out rm -f $tmp/in mv $tmp/out $tmp/in ' >>$CONFIG_STATUS sed 1,${ac_max_here_lines}d conftest.undefs >conftest.tail rm -f conftest.undefs mv conftest.tail conftest.undefs done rm -f conftest.undefs cat >>$CONFIG_STATUS <<\_ACEOF # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ if test x"$ac_file" = x-; then echo "/* Generated by configure. */" >$tmp/config.h else echo "/* $ac_file. Generated by configure. */" >$tmp/config.h fi cat $tmp/in >>$tmp/config.h rm -f $tmp/in if test x"$ac_file" != x-; then if diff $ac_file $tmp/config.h >/dev/null 2>&1; then { echo "$as_me:$LINENO: $ac_file is unchanged" >&5 echo "$as_me: $ac_file is unchanged" >&6;} else ac_dir=`(dirname "$ac_file") 2>/dev/null || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| \ . : '\(.\)' 2>/dev/null || echo X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } /^X\(\/\/\)[^/].*/{ s//\1/; q; } /^X\(\/\/\)$/{ s//\1/; q; } /^X\(\/\).*/{ s//\1/; q; } s/.*/./; q'` { if $as_mkdir_p; then mkdir -p "$ac_dir" else as_dir="$ac_dir" as_dirs= while test ! -d "$as_dir"; do as_dirs="$as_dir $as_dirs" as_dir=`(dirname "$as_dir") 2>/dev/null || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| \ . : '\(.\)' 2>/dev/null || echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } /^X\(\/\/\)[^/].*/{ s//\1/; q; } /^X\(\/\/\)$/{ s//\1/; q; } /^X\(\/\).*/{ s//\1/; q; } s/.*/./; q'` done test ! -n "$as_dirs" || mkdir $as_dirs fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5 echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;} { (exit 1); exit 1; }; }; } rm -f $ac_file mv $tmp/config.h $ac_file fi else cat $tmp/config.h rm -f $tmp/config.h fi done _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF { (exit 0); exit 0; } _ACEOF chmod +x $CONFIG_STATUS ac_clean_files=$ac_clean_files_save # configure is writing to config.log, and then calls config.status. # config.status does its own redirection, appending to config.log. # Unfortunately, on DOS this fails, as config.log is still kept open # by configure, so config.status won't be able to write to it; its # output is simply discarded. So we exec the FD to /dev/null, # effectively closing config.log, so it can be properly (re)opened and # appended to by config.status. When coming back to configure, we # need to make the FD available again. if test "$no_create" != yes; then ac_cs_success=: ac_config_status_args= test "$silent" = yes && ac_config_status_args="$ac_config_status_args --quiet" exec 5>/dev/null $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false exec 5>>config.log # Use ||, not &&, to avoid exiting from the if with $? = 1, which # would make configure fail if this is the last instruction. $ac_cs_success || { (exit 1); exit 1; } fi perl subst include/locations.h perl subst include/nagios.h echo "" echo "Creating sample config files in sample-config/ ..." perl subst sample-config/nagios.cfg perl subst sample-config/cgi.cfg perl subst sample-config/resource.cfg perl subst sample-config/httpd.conf perl subst sample-config/template-object/localhost.cfg perl subst sample-config/template-object/commands.cfg echo "" echo "" echo "$as_me:$LINENO: result: *** Configuration summary for $PKG_NAME $PKG_VERSION $PKG_REL_DATE ***:" >&5 echo "${ECHO_T}*** Configuration summary for $PKG_NAME $PKG_VERSION $PKG_REL_DATE ***:" >&6 echo "" echo " General Options:" echo " -------------------------" echo "$as_me:$LINENO: result: Nagios executable: $nagios_name" >&5 echo "${ECHO_T} Nagios executable: $nagios_name" >&6 echo "$as_me:$LINENO: result: Nagios user/group: $nagios_user,$nagios_grp" >&5 echo "${ECHO_T} Nagios user/group: $nagios_user,$nagios_grp" >&6 echo "$as_me:$LINENO: result: Command user/group: $command_user,$command_grp" >&5 echo "${ECHO_T} Command user/group: $command_user,$command_grp" >&6 if test x$USEPERL = xyes; then if test x$PERLCACHE = xyes; then echo "$as_me:$LINENO: result: Embedded Perl: yes, with caching" >&5 echo "${ECHO_T} Embedded Perl: yes, with caching" >&6 else echo "$as_me:$LINENO: result: Embedded Perl: yes, without caching" >&5 echo "${ECHO_T} Embedded Perl: yes, without caching" >&6 fi else echo "$as_me:$LINENO: result: Embedded Perl: no" >&5 echo "${ECHO_T} Embedded Perl: no" >&6 fi if test x$USE_EVENTBROKER = xyes; then echo "$as_me:$LINENO: result: Event Broker: yes" >&5 echo "${ECHO_T} Event Broker: yes" >&6 else echo "$as_me:$LINENO: result: Event Broker: no" >&5 echo "${ECHO_T} Event Broker: no" >&6 fi echo "$as_me:$LINENO: result: Install \${prefix}: $prefix" >&5 echo "${ECHO_T} Install \${prefix}: $prefix" >&6 echo "$as_me:$LINENO: result: Lock file: $lockfile" >&5 echo "${ECHO_T} Lock file: $lockfile" >&6 echo "$as_me:$LINENO: result: Init directory: $init_dir" >&5 echo "${ECHO_T} Init directory: $init_dir" >&6 echo "$as_me:$LINENO: result: Host OS: $host_os" >&5 echo "${ECHO_T} Host OS: $host_os" >&6 echo "" echo " Web Interface Options:" echo " ------------------------" echo "$as_me:$LINENO: result: HTML URL: http://localhost$htmurl/" >&5 echo "${ECHO_T} HTML URL: http://localhost$htmurl/" >&6 echo "$as_me:$LINENO: result: CGI URL: http://localhost$cgiurl/" >&5 echo "${ECHO_T} CGI URL: http://localhost$cgiurl/" >&6 echo "$as_me:$LINENO: result: Traceroute (used by WAP): $PATH_TO_TRACEROUTE" >&5 echo "${ECHO_T} Traceroute (used by WAP): $PATH_TO_TRACEROUTE" >&6 echo "" echo "" echo "Review the options above for accuracy. If they look okay," echo "type 'make all' to compile the main program and CGIs." echo "" nagios-2.6/configure.in0000664000076500007650000005476210532717360014532 0ustar nagiosnagiosdnl Process this -*-m4-*- file with autoconf to produce a configure script. dnl Disable caching define([AC_CACHE_LOAD],) define([AC_CACHE_SAVE],) AC_INIT(base/nagios.c) AC_CONFIG_HEADER(include/config.h include/snprintf.h include/nagios.h include/cgiutils.h) AC_PREFIX_DEFAULT(/usr/local/nagios) PKG_NAME=nagios PKG_VERSION="2.6" PKG_HOME_URL="http://www.nagios.org/" PKG_REL_DATE="11-27-2006" dnl Figure out how to invoke "install" and what install options to use. AC_PROG_INSTALL AC_SUBST(INSTALL) dnl What OS are we running? AC_CANONICAL_HOST dnl Checks for programs. AC_PROG_CC AC_PROG_MAKE_SET AC_PATH_PROG([STRIP],[strip],[true]) dnl Checks for header files. AC_HEADER_STDC AC_HEADER_TIME AC_HEADER_SYS_WAIT AC_CHECK_HEADERS(arpa/inet.h ctype.h dirent.h errno.h fcntl.h getopt.h grp.h limits.h math.h netdb.h netinet/in.h pthread.h pthreads.h pwd.h regex.h signal.h socket.h string.h strings.h sys/mman.h sys/types.h sys/time.h sys/resource.h sys/wait.h sys/socket.h sys/stat.h sys/timeb.h sys/un.h sys/ipc.h sys/msg.h sys/poll.h syslog.h uio.h unistd.h) dnl Checks for typedefs, structures, and compiler characteristics. AC_C_CONST AC_STRUCT_TM AC_STRUCT_TIMEZONE AC_TYPE_MODE_T AC_TYPE_PID_T AC_TYPE_SIZE_T AC_TYPE_SIGNAL AC_TYPE_GETGROUPS dnl Checks for library functions. dnl AC_CHECK_LIB(nsl,main,SOCKETLIBS="$SOCKETLIBS -lnsl") dnl AC_CHECK_LIB(socket,socket,SOCKETLIBS="$SOCKETLIBS -lsocket") AC_SUBST(SOCKETLIBS) AC_CHECK_FUNCS(initgroups setenv strdup strstr strtoul unsetenv) AC_MSG_CHECKING(for type of socket size) AC_TRY_COMPILE([#include #include #include ], [int a = send(1, (const void *) 0, (size_t) 0, (int) 0);], [AC_DEFINE(SOCKET_SIZE_TYPE, size_t) AC_MSG_RESULT(size_t)], [AC_DEFINE(SOCKET_SIZE_TYPE, int) AC_MSG_RESULT(int)]) dnl Test for pthreads support - taken from ICU FreeBSD Port configure script THREADLIBS="" have_pthreads="no" dnl FreeBSD: Try ports/linuxthreads first - Mammad Zadeh dnl FreeBSD -pthread check - Jonathan McDowell AC_DEFUN(AC_PTHREAD_FREEBSD,[ AC_CHECK_LIB(lthread,pthread_create,[ CFLAGS="-D_THREAD_SAFE -I/usr/local/include/pthread/linuxthreads -I/usr/include $CFLAGS" THREADLIBS="-L/usr/local/lib -llthread -llgcc_r" ],[ AC_MSG_CHECKING([if we need -pthread for threads]) AC_CACHE_VAL(ac_ldflag_pthread,[ ac_save_LDFLAGS="$LDFLAGS" LDFLAGS="-pthread $LDFLAGS" AC_TRY_LINK([ char pthread_create(); ], pthread_create();, eval "ac_ldflag_pthread=yes", eval "ac_ldflag_pthread=no" ), THREADLIBS="$ac_save_LDFLAGS" ]) if eval "test \"`echo $ac_ldflag_pthread`\" = yes"; then AC_MSG_RESULT(yes) else AC_MSG_RESULT(no) fi ],-L/usr/local/lib) ]) dnl Test for HPUX cma threads first.. AC_CHECK_LIB(cma,pthread_create,THREADLIBS="$THREADLIBS -lpthread") if test $ac_cv_lib_cma_pthread_create = yes; then have_pthreads="yes" fi dnl special pthread handling dnl AIX uses pthreads instead of pthread, and HP/UX uses cma dnl FreeBSD users -pthread AC_CHECK_LIB(pthread,pthread_create,THREADLIBS="$THREADLIBS -lpthread") if test $ac_cv_lib_pthread_pthread_create = yes; then have_pthreads="yes" else dnl For HP 11 AC_CHECK_LIB(pthread,pthread_mutex_init,THREADLIBS="$THREADLIBS -lpthread") if test $ac_cv_lib_pthread_pthread_mutex_init = yes; then have_pthreads="yes" fi fi dnl AIX uses pthreads instead of pthread if test $have_pthreads = "no"; then AC_CHECK_LIB(pthreads,pthread_create,THREADLIBS="$THREADLIBS -lpthreads") if test $ac_cv_lib_pthreads_pthread_create = yes; then have_pthreads="yes" fi fi dnl all other thread tests fail, try BSD's -pthread if test $have_pthreads = "no"; then AC_PTHREAD_FREEBSD fi AC_SUBST(THREADLIBS) dnl Solaris needs rt or posix4 libraries for nanosleep() AC_SEARCH_LIBS(nanosleep,[rt posix4],,[ echo "Error: nanosleep() needed for timing operations." exit 1 ]) AC_ARG_WITH(nagios_user,--with-nagios-user= sets user name to run nagios,nagios_user=$withval,nagios_user=nagios) AC_ARG_WITH(nagios_group,--with-nagios-group= sets group name to run nagios,nagios_grp=$withval,nagios_grp=nagios) AC_SUBST(nagios_user) AC_SUBST(nagios_grp) AC_DEFINE_UNQUOTED(DEFAULT_NAGIOS_USER,"$nagios_user") AC_DEFINE_UNQUOTED(DEFAULT_NAGIOS_GROUP,"$nagios_grp") INSTALL_OPTS="-o $nagios_user -g $nagios_grp" AC_SUBST(INSTALL_OPTS) AC_ARG_WITH(command_user,--with-command-user= sets user name for command access,command_user=$withval,command_user=$nagios_user) AC_ARG_WITH(command_group,--with-command-group= sets group name for command access,command_grp=$withval,command_grp=$nagios_grp) AC_SUBST(command_user) AC_SUBST(command_grp) COMMAND_OPTS="-o $command_user -g $command_grp" AC_SUBST(COMMAND_OPTS) dnl Check for location of mail program MAIL_PROG=no AC_ARG_WITH(mail,--with-mail= sets path to equivalent program to mail,MAIL_PROG=$withval,MAIL_PROG=no) if test MAIL_PROG=no; then AC_PATH_PROG(MAIL_PROG,mail) fi AC_SUBST(MAIL_PROG) dnl Check for location of init scripts init_dir=/etc/rc.d/init.d if test -d /etc/rc.d/init.d; then init_dir="/etc/rc.d/init.d" elif test -d /usr/local/etc/rc.d; then init_dir="/usr/local/etc/rc.d" elif test -d /etc/rc.d; then init_dir="/etc/rc.d" elif test -d /etc/init.d; then init_dir="/etc/init.d" elif test -d /sbin/init.d; then init_dir="/sbin/init.d" fi dnl User can override init script location AC_ARG_WITH(init_dir,--with-init-dir= sets directory to place init script into,init_dir=$withval) AC_SUBST(init_dir) echo "Init script directory: " $init_dir AC_ARG_WITH(lockfile,--with-lockfile= sets path and file name for lock file,lockfile=$withval,lockfile=$localstatedir/nagios.lock) AC_SUBST(lockfile) dnl Default xdata routines... XSDTYPE=default XCDTYPE=default XRDTYPE=default XODTYPE=template XPDTYPE=default XDDTYPE=default XSDCOMMENT= XCDCOMMENT= XRDCOMMENT= XODCOMMENT= XPDCOMMENT= XDDCOMMENT= USE_MYSQL=no USE_PGSQL=no dnl Status data AC_DEFINE_UNQUOTED(USE_XSDDEFAULT) XSDC="xsddefault.c" XSDH="xsddefault.h" XSDCOMMENT="Default (text file)" echo "We'll use default routines (in xdata/xsddefault.*) for status data I/O..." AC_SUBST(XSDC) AC_SUBST(XSDH) dnl Comment data AC_DEFINE_UNQUOTED(USE_XCDDEFAULT) XCDC="xcddefault.c" XCDH="xcddefault.h" XCDCOMMENT="Default (text file)" echo "We'll use default routines (in xdata/xcddefault.*) for comment data I/O..." AC_SUBST(XCDC) AC_SUBST(XCDH) dnl Retention data AC_DEFINE_UNQUOTED(USE_XRDDEFAULT) XRDC="xrddefault.c" XRDH="xrddefault.h" XRDCOMMENT="Default (text file)" echo "We'll use default routines (in xdata/xrddefault.*) for retention data I/O..." AC_SUBST(XRDC) AC_SUBST(XRDH) dnl Object data AC_DEFINE_UNQUOTED(USE_XODTEMPLATE) XODC="xodtemplate.c" XODH="xodtemplate.h" XODCOMMENT="Template-based (text file)" echo "We'll use template-based routines (in xdata/xodtemplate.*) for object data I/O..." AC_SUBST(XODC) AC_SUBST(XODH) dnl Performance data AC_DEFINE_UNQUOTED(USE_XPDDEFAULT) XPDC="xpddefault.c" XPDH="xpddefault.h" XPDCOMMENT="Default (external commands)" echo "We'll use default routines (in xdata/xpddefault.*) for performance data I/O..." AC_SUBST(XPDC) AC_SUBST(XPDH) dnl Downtime data AC_DEFINE_UNQUOTED(USE_XDDDEFAULT) XDDC="xdddefault.c" XDDH="xdddefault.h" XDDCOMMENT="Default (text file)" echo "We'll use default routines (in xdata/xdddefault.*) for scheduled downtime data I/O..." AC_SUBST(XDDC) AC_SUBST(XDDH) dnl Option GD library and include paths AC_ARG_WITH(gd-lib,--with-gd-lib=DIR sets location of the gd library,[ LDFLAGS="${LDFLAGS} -L${withval}" LD_RUN_PATH="${withval}${LD_RUN_PATH:+:}${LD_RUN_PATH}" ]) AC_ARG_WITH(gd-inc,--with-gd-inc=DIR sets location of the gd include files,[ CFLAGS="${CFLAGS} -I${withval}" ]) TRYGD=yep dnl statusmap CGI enabled by default, unless users chooses not to use it TRYSTATUSMAP=yep AC_ARG_ENABLE(statusmap,--disable-statusmap=disables compilation of statusmap CGI,TRYSTATUSMAP=nope) dnl statuswrl CGI enabled by default, unless users chooses not to use it TRYSTATUSWRL=yep AC_ARG_ENABLE(statuswrl,--disable-statuswrl=disables compilation of statuswrl (VRML) CGI,TRYSTATUSWRL=nope) if test x$TRYSTATUSWRL = xyep; then AC_DEFINE_UNQUOTED(USE_STATUSWRL) CGIEXTRAS="$CGIEXTRAS statuswrl.cgi" fi dnl JMD_CHECK_LIB_ORDER(LIBRARY, FUNCTION, ORDER [, ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND dnl [, OTHER-LIBRARIES]]]) AC_DEFUN(JMD_CHECK_LIB_ORDER, [AC_MSG_CHECKING([for $2 in -l$1 (order $3)]) dnl Use a cache variable name containing both the library and function name, dnl because the test really is for library $1 defining function $2, not dnl just for library $1. Separate tests with the same $1 and different $2s dnl may have different results. ac_lib_var=`echo $1['_']$2['_']$3 | sed 'y%./+-%__p_%'` AC_CACHE_VAL(ac_cv_lib_$ac_lib_var, [ac_save_LIBS="$LIBS" LIBS="-l$1 $6 $LIBS" AC_TRY_LINK(dnl ifelse([AC_LANG], [FORTRAN77], , ifelse([$2], [main], , dnl Avoid conflicting decl of main. [/* Override any gcc2 internal prototype to avoid an error. */ ]ifelse([AC_LANG], CPLUSPLUS, [#ifdef __cplusplus extern "C" #endif ])dnl [/* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char $2(); ])), [$2()], eval "ac_cv_lib_$ac_lib_var=yes", eval "ac_cv_lib_$ac_lib_var=no") LIBS="$ac_save_LIBS" ])dnl if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then AC_MSG_RESULT(yes) ifelse([$4], , [changequote(, )dnl ac_tr_lib=HAVE_LIB`echo $1 | sed -e 's/[^a-zA-Z0-9_]/_/g' \ -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` changequote([, ])dnl AC_DEFINE_UNQUOTED($ac_tr_lib) LIBS="-l$1 $LIBS" ], [$4]) else AC_MSG_RESULT(no) ifelse([$5], , , [$5 ])dnl fi ]) dnl Should we try and detect the GD libs? if test x$TRYGD = xyep; then dnl libiconv is required on some systems - tack it on if found AC_CHECK_LIB(iconv,main,ICONV=-liconv,) dnl See if the GD lib is available and supports PNG images... dnl GD > 1.8.3 requires the TrueType library to be present as well, so test for that first... JMD_CHECK_LIB_ORDER(gd,gdImagePng,1,[ GDLIBFOUND=yep GDLIBS="-lgd -lttf -lpng -ljpeg -lz -lm" ],:,[-lttf -lpng -ljpeg -lz -lm]) dnl GD > 1.8.1 requires the jpeg library to be present as well, so test for that... if test x$GDLIBFOUND = x; then JMD_CHECK_LIB_ORDER(gd,gdImagePng,2,[ GDLIBFOUND=yep GDLIBS="-lgd $ICONV -lpng -ljpeg -lz -lm" ],:,[$ICONV -lpng -ljpeg -lz -lm]) fi dnl If we failed the first test, try without jpeg library if test x$GDLIBFOUND = x; then JMD_CHECK_LIB_ORDER(gd,gdImagePng,3,[ GDLIBFOUND=yep GDLIBS="-lgd $ICONV -lz -lm -lpng" ],:,[$ICONV -lz -lm -lpng]) fi dnl We failed again, so try a different library ordering (without jpeg libs) if test x$GDLIBFOUND = x; then JMD_CHECK_LIB_ORDER(gd,gdImagePng,4,[ GDLIBFOUND=yep GDLIBS="-lgd $ICONV -lpng -lz -lm" ],:,[$ICONV -lpng -lz -lm]) fi dnl Did we find the necessary GD libraries? if test x$GDLIBFOUND = x; then echo "" echo "" echo "*** GD, PNG, and/or JPEG libraries could not be located... *********" echo "" echo "Boutell's GD library is required to compile the statusmap, trends" echo "and histogram CGIs. Get it from http://www.boutell.com/gd/, compile" echo "it, and use the --with-gd-lib and --with-gd-inc arguments to specify" echo "the locations of the GD library and include files." echo "" echo "NOTE: In addition to the gd-devel library, you'll also need to make" echo " sure you have the png-devel and jpeg-devel libraries installed" echo " on your system." echo "" echo "NOTE: After you install the necessary libraries on your system:" echo " 1. Make sure /etc/ld.so.conf has an entry for the directory in" echo " which the GD, PNG, and JPEG libraries are installed." echo " 2. Run 'ldconfig' to update the run-time linker options." echo " 3. Run 'make clean' in the Nagios distribution to clean out" echo " any old references to your previous compile." echo " 4. Rerun the configure script." echo "" echo "NOTE: If you can't get the configure script to recognize the GD libs" echo " on your system, get over it and move on to other things. The" echo " CGIs that use the GD libs are just a small part of the entire" echo " Nagios package. Get everything else working first and then" echo " revisit the problem. Make sure to check the nagios-users" echo " mailing list archives for possible solutions to GD library" echo " problems when you resume your troubleshooting." echo "" echo "********************************************************************" echo "" echo "" dnl We found the GD lib! else echo "GD library was found!" if test x$TRYSTATUSMAP = xyep; then AC_DEFINE_UNQUOTED(USE_STATUSMAP) CGIEXTRAS="$CGIEXTRAS statusmap.cgi" fi dnl compile trends CGI AC_DEFINE_UNQUOTED(USE_TRENDS) CGIEXTRAS="$CGIEXTRAS trends.cgi" dnl compile histogram CGI AC_DEFINE_UNQUOTED(USE_HISTOGRAM) CGIEXTRAS="$CGIEXTRAS histogram.cgi" fi fi AC_ARG_WITH(cgiurl,--with-cgiurl= sets URL for cgi programs (do not use a trailing slash),cgiurl=$withval,cgiurl=/nagios/cgi-bin) AC_ARG_WITH(htmurl,--with-htmurl= sets URL for public html,htmurl=$withval,htmurl=/nagios) AC_SUBST(htmurl) AC_SUBST(cgiurl) AC_ARG_ENABLE(DEBUG0,--enable-DEBUG0 shows function entry and exit,AC_DEFINE_UNQUOTED(DEBUG0)) AC_ARG_ENABLE(DEBUG1,--enable-DEBUG1 shows general info messages,AC_DEFINE_UNQUOTED(DEBUG1)) AC_ARG_ENABLE(DEBUG2,--enable-DEBUG2 shows warning messages,AC_DEFINE_UNQUOTED(DEBUG2)) AC_ARG_ENABLE(DEBUG3,--enable-DEBUG3 shows scheduled events (service and host checks... etc),AC_DEFINE_UNQUOTED(DEBUG3)) AC_ARG_ENABLE(DEBUG4,--enable-DEBUG4 shows service and host notifications,AC_DEFINE_UNQUOTED(DEBUG4)) AC_ARG_ENABLE(DEBUG5,--enable-DEBUG5 shows SQL queries,AC_DEFINE_UNQUOTED(DEBUG5)) AC_ARG_ENABLE(DEBUGALL,--enable-DEBUGALL shows all debugging messages,[ AC_DEFINE_UNQUOTED(DEBUG0) AC_DEFINE_UNQUOTED(DEBUG1) AC_DEFINE_UNQUOTED(DEBUG2) AC_DEFINE_UNQUOTED(DEBUG3) AC_DEFINE_UNQUOTED(DEBUG4) AC_DEFINE_UNQUOTED(DEBUG5) ]) USE_NANOSLEEP=yes AC_ARG_ENABLE(nanosleep,--enable-nanosleep enables use of nanosleep (instead sleep) in event timing,USE_NANOSLEEP=$enableval,USE_NANOSLEEP=yes) if test x$USE_NANOSLEEP = xyes; then AC_DEFINE_UNQUOTED(USE_NANOSLEEP) fi USE_EVENTBROKER=yes AC_ARG_ENABLE(event-broker,--enable-event-broker enables integration of event broker routines,USE_EVENTBROKER=$enableval,USE_EVENTBROKER=yes) BROKER_LDFLAGS="" BROKERLIBS=""; some_dl_found="no"; if test x$USE_EVENTBROKER = xyes; then dnl Which loader library should we use? libtdl or dl? dnl Hopefully this will be portable and not give us headaches... AC_CHECK_HEADER(ltdl.h,[ AC_CHECK_LIB(ltdl,lt_dlinit,[ AC_DEFINE(HAVE_LTDL_H) some_dl_found="yes" BROKERLIBS="$BROKERLIBS -lltdl" ]) ]) if test "x$some_dl_found" != xyes; then AC_CHECK_HEADER(dlfcn.h,[ AC_CHECK_LIB(dl,dlopen,[ AC_DEFINE(HAVE_DLFCN_H) some_dl_found="yes" BROKERLIBS="$BROKERLIBS -ldl" ]) ]) fi dnl - Modified from www.erlang.org # Check how to export functions from the broker executable, needed # when dynamically loaded drivers are loaded (so that they can find # broker functions). # OS'es with ELF executables using the GNU linker (Linux and recent *BSD, # in rare cases Solaris) typically need '-Wl,-export-dynamic' (i.e. pass # -export-dynamic to the linker - also known as -rdynamic and some other # variants); some sysVr4 system(s) instead need(s) '-Wl,-Bexport'. # AIX 4.x (perhaps only for x>=2) wants -Wl,-bexpall,-brtl and doesn't # reliably return an error for others, thus we separate it out. # Otherwise we assume that if the linker accepts the flag, it is needed. AC_MSG_CHECKING(for extra flags needed to export symbols) case $host_os in aix4*|aix5*) BROKER_LDFLAGS="$BROKER_LDFLAGS -Wl,-bexpall,-brtl" ;; bsdi*) BROKER_LDFLAGS="$BROKER_LDFLAGS -rdynamic" ;; *) save_ldflags="$LDFLAGS" LDFLAGS=-Wl,-export-dynamic AC_TRY_LINK(,,[BROKER_LDFLAGS="$BROKER_LDFLAGS -Wl,-export-dynamic"], [ LDFLAGS=-Wl,-Bexport AC_TRY_LINK(,,[BROKER_LDFLAGS="$BROKER_LDFLAGS -Wl,-Bexport"], AC_MSG_RESULT(none))]) LDFLAGS="$save_ldflags" ;; esac AC_SUBST(BROKER_LDFLAGS) AC_SUBST(BROKERLIBS) test "x$BROKER_LDFLAGS" != x && AC_MSG_RESULT([$BROKER_LDFLAGS]) dnl - Modified version from www.erlang.org dnl - Some 12/15/05 mods made after reading http://xaxxon.slackworks.com/phuku/dl.html AC_MSG_CHECKING(for linker flags for loadable modules) case $host_os in solaris2*|sysv4*) MOD_LDFLAGS="-G" ;; aix4*|aix5*) #MOD_LDFLAGS="-G -bnoentry -bexpall" MOD_LDFLAGS="-G -bM:SRE -bnoentry -bexpall" ;; freebsd2*) # Non-ELF GNU linker MOD_LDFLAGS="-Bshareable" ;; darwin*) # Mach-O linker, a shared lib and a loadable # object file is not the same thing. MOD_LDFLAGS="-bundle -flat_namespace -undefined suppress" MOD_CFLAGS="$MOD_CFLAGS -fno-common" ;; linux*) # assume GNU linker and ELF MOD_LDFLAGS="-shared" MOD_CFLAGS="-fPIC" ;; *) # assume GNU linker and ELF MOD_LDFLAGS="-shared" ;; esac AC_MSG_RESULT([$MOD_LDFLAGS]) AC_SUBST(MOD_CFLAGS) AC_SUBST(MOD_LDFLAGS) AC_DEFINE_UNQUOTED(USE_EVENT_BROKER) BROKER_O="broker.o nebmods.o" AC_SUBST(BROKER_O) BROKER_H="../include/broker.h ../include/nebmods.h ../include/nebmodules.h ../include/nebcallbacks.h ../include/neberrors.h" AC_SUBST(BROKER_H) fi USEPERL=no; INSTALLPERLSTUFF=no; AC_ARG_ENABLE(embedded-perl,--enable-embedded-perl will enable embedded Perl interpreter,[ AC_DEFINE_UNQUOTED(EMBEDDEDPERL) PERLLIBS="`perl -MExtUtils::Embed -e ldopts`" PERLDIR="`perl -MConfig -e 'print $Config{installsitearch}'`" CFLAGS="${CFLAGS} `perl -MExtUtils::Embed -e ccopts`" USEPERL=yes INSTALLPERLSTUFF=yes; PERLXSI_O=perlxsi.o OBJS="${OBJS} ${PERLXSI_O}" echo "creating base/perlxsi.c" perl -MExtUtils::Embed -e xsinit -- -o base/perlxsi.c ]) PERLCACHE=no; AC_ARG_WITH(perlcache,--with-perlcache turns on cacheing of internally compiled Perl scripts,[ AC_DEFINE(DO_CLEAN,"0") PERLCACHE=yes; ] ,[ AC_DEFINE(DO_CLEAN,"1") PERLCACHE=no; ]) dnl Is embedded Perl being compiled in? if test x$USEPERL = xyes; then echo "Embedded Perl interpreter will be compiled in..." if test x$PERLCACHE = xyes; then echo "Internally compiled Perl scripts will be cached..." else echo "Internally compiled Perl scripts will NOT be cached..." fi fi dnl Test if we're using threaded Perl (patch by Chip Ach) if test x$USEPERL = xyes; then if (perl -e 'use Config;exit -1 unless ($Config{'usethreads'});'); then echo "Using threaded perl" AC_DEFINE_UNQUOTED(THREADEDPERL) fi fi dnl Option for compiling under CYGWIN nagios_name=nagios nagiostats_name=nagiostats AC_ARG_ENABLE(cygwin,--enable-cygwin enables building under the CYGWIN environment,[ CFLAGS="${CFLAGS} -DCYGWIN" nagios_name=nagios.exe; nagiostats_name=nagiostats.exe; ]) AC_SUBST(nagios_name) AC_SUBST(nagiostats_name) dnl Should predictive failure routines be compiled in? dnl AC_ARG_ENABLE(failure-prediction,--enable-failure-prediction will enable integration with failure prediction module (NOT HERE YET!),[ dnl AC_DEFINE_UNQUOTED(PREDICT_FAILURES) dnl BASEEXTRALIBS="$BASEEXTRALIBS \$(FDATALIBS)" dnl echo "Failure prediction routines (incomplete!) will be compiled in..." dnl ]) dnl Find traceroute AC_PATH_PROG(PATH_TO_TRACEROUTE,traceroute) AC_DEFINE_UNQUOTED(TRACEROUTE_COMMAND,"$PATH_TO_TRACEROUTE") dnl Package directory for Solaris pkgmk (and other OSs, eventually) dnl VERSION=`grep 1.0 include/common.h | cut -d ' ' -f 3 | sed 's/"//g'` VERSION=$PKG_VERSION PACKDIR=`pwd`/pkg AC_SUBST(PACKDIR) AC_SUBST(VERSION) AC_CHECK_FUNC(snprintf,AC_DEFINE(HAVE_SNPRINTF),SNPRINTF_O=../common/snprintf.o) AC_SUBST(SNPRINTF_O) AC_MSG_CHECKING(for type va_list) AC_TRY_COMPILE([#ifdef __STDC__ #include #include #include #else #include #include #include #endif], [va_list args;], [AC_MSG_RESULT(yes)], [AC_DEFINE(NEED_VA_LIST) AC_MSG_RESULT(no)]) AC_SUBST(CGIEXTRAS) AC_SUBST(GDLIBS) AC_SUBST(PERLLIBS) AC_SUBST(PERLDIR) AC_SUBST(PERLXSI_O) AC_SUBST(BASEEXTRALIBS) AC_SUBST(INITDIR) AC_SUBST(INSTALLPERLSTUFF) AC_PATH_PROG(PERL,perl) AC_OUTPUT(Makefile subst pkginfo base/Makefile common/Makefile contrib/Makefile cgi/Makefile html/Makefile module/Makefile include/Makefile xdata/Makefile daemon-init html/index.html html/side.html) perl subst include/locations.h perl subst include/nagios.h echo "" echo "Creating sample config files in sample-config/ ..." perl subst sample-config/nagios.cfg perl subst sample-config/cgi.cfg perl subst sample-config/resource.cfg perl subst sample-config/httpd.conf perl subst sample-config/template-object/localhost.cfg perl subst sample-config/template-object/commands.cfg dnl Review options echo "" echo "" AC_MSG_RESULT([*** Configuration summary for $PKG_NAME $PKG_VERSION $PKG_REL_DATE ***:]) echo "" echo " General Options:" echo " -------------------------" AC_MSG_RESULT([ Nagios executable: $nagios_name]) AC_MSG_RESULT([ Nagios user/group: $nagios_user,$nagios_grp]) AC_MSG_RESULT([ Command user/group: $command_user,$command_grp]) if test x$USEPERL = xyes; then if test x$PERLCACHE = xyes; then AC_MSG_RESULT([ Embedded Perl: yes, with caching]) else AC_MSG_RESULT([ Embedded Perl: yes, without caching]) fi else AC_MSG_RESULT([ Embedded Perl: no]) fi if test x$USE_EVENTBROKER = xyes; then AC_MSG_RESULT([ Event Broker: yes]) else AC_MSG_RESULT([ Event Broker: no]) fi AC_MSG_RESULT([ Install \${prefix}: $prefix]) AC_MSG_RESULT([ Lock file: $lockfile]) AC_MSG_RESULT([ Init directory: $init_dir]) AC_MSG_RESULT([ Host OS: $host_os]) echo "" echo " Web Interface Options:" echo " ------------------------" AC_MSG_RESULT([ HTML URL: http://localhost$htmurl/]) AC_MSG_RESULT([ CGI URL: http://localhost$cgiurl/]) AC_MSG_RESULT([ Traceroute (used by WAP): $PATH_TO_TRACEROUTE]) dnl echo "" dnl echo " External Data Routines:" dnl echo " ------------------------" dnl AC_MSG_RESULT([ Status data: $XSDCOMMENT]) dnl AC_MSG_RESULT([ Comment data: $XCDCOMMENT]) dnl AC_MSG_RESULT([ Downtime data: $XDDCOMMENT]) dnl AC_MSG_RESULT([ Peformance data: $XPDCOMMENT]) echo "" echo "" echo "Review the options above for accuracy. If they look okay," echo "type 'make all' to compile the main program and CGIs." echo "" nagios-2.6/daemon-init.in0000664000076500007650000001162110334752122014733 0ustar nagiosnagios#!/bin/sh # # chkconfig: 345 99 01 # description: Nagios network monitor # # File : nagios # # Author : Jorge Sanchez Aymar (jsanchez@lanchile.cl) # # Changelog : # # 1999-07-09 Karl DeBisschop # - setup for autoconf # - add reload function # 1999-08-06 Ethan Galstad # - Added configuration info for use with RedHat's chkconfig tool # per Fran Boon's suggestion # 1999-08-13 Jim Popovitch # - added variable for nagios/var directory # - cd into nagios/var directory before creating tmp files on startup # 1999-08-16 Ethan Galstad # - Added test for rc.d directory as suggested by Karl DeBisschop # 2000-07-23 Karl DeBisschop # - Clean out redhat macros and other dependencies # 2003-01-11 Ethan Galstad # - Updated su syntax (Gary Miller) # # Description: Starts and stops the Nagios monitor # used to provide network services status. # status_nagios () { if test ! -f $NagiosRunFile; then echo "No lock file found in $NagiosRunFile" return 1 fi NagiosPID=`head -n 1 $NagiosRunFile` if test -x $NagiosCGI/daemonchk.cgi; then if $NagiosCGI/daemonchk.cgi -l $NagiosRunFile; then return 0 else return 1 fi else if ps -p $NagiosPID; then return 0 else return 1 fi fi return 1 } killproc_nagios () { if test ! -f $NagiosRunFile; then echo "No lock file found in $NagiosRunFile" return 1 fi NagiosPID=`head -n 1 $NagiosRunFile` kill $2 $NagiosPID } # Source function library # Solaris doesn't have an rc.d directory, so do a test first if [ -f /etc/rc.d/init.d/functions ]; then . /etc/rc.d/init.d/functions elif [ -f /etc/init.d/functions ]; then . /etc/init.d/functions fi prefix=@prefix@ exec_prefix=@exec_prefix@ NagiosBin=@bindir@/nagios NagiosCfgFile=@sysconfdir@/nagios.cfg NagiosStatusFile=@localstatedir@/status.dat NagiosTempFile=@localstatedir@/nagios.tmp NagiosRetentionFile=@localstatedir@/retention.dat NagiosCommandFile=@localstatedir@/rw/nagios.cmd NagiosVarDir=@localstatedir@ NagiosRunFile=@lockfile@ NagiosLockDir=/var/lock/subsys NagiosLockFile=nagios NagiosCGIDir=@sbindir@ NagiosUser=@nagios_user@ NagiosGroup=@nagios_grp@ # Check that nagios exists. if [ ! -f $NagiosBin ]; then echo "Executable file $NagiosBin not found. Exiting." exit 1 fi # Check that nagios.cfg exists. if [ ! -f $NagiosCfgFile ]; then echo "Configuration file $NagiosCfgFile not found. Exiting." exit 1 fi # See how we were called. case "$1" in start) echo "Starting network monitor: nagios" $NagiosBin -v $NagiosCfgFile > /dev/null 2>&1; if [ $? -eq 0 ]; then su - $NagiosUser -c "touch $NagiosVarDir/nagios.log $NagiosRetentionFile" rm -f $NagiosCommandFile touch $NagiosRunFile chown $NagiosUser:$NagiosGroup $NagiosRunFile $NagiosBin -d $NagiosCfgFile if [ -d $NagiosLockDir ]; then touch $NagiosLockDir/$NagiosLockFile; fi #sleep 1 #status_nagios nagios exit 0 else echo "CONFIG ERROR! Start aborted. Check your Nagios configuration." exit 1 fi ;; stop) echo "Stopping network monitor: nagios" killproc_nagios nagios # now we have to wait for nagios to exit and remove its # own NagiosRunFile, otherwise a following "start" could # happen, and then the exiting nagios will remove the # new NagiosRunFile, allowing multiple nagios daemons # to (sooner or later) run - John Sellens echo -n 'Waiting for nagios to exit .' for i in 1 2 3 4 5 6 7 8 9 10 ; do if status_nagios > /dev/null; then echo -n ' .' sleep 1 else break fi done if status_nagios > /dev/null; then echo '' echo 'Warning - running nagios did not exit in time' else echo ' done.' fi rm -f $NagiosStatusFile $NagiosTempFile $NagiosRunFile $NagiosLockDir/$NagiosLockFile $NagiosCommandFile ;; status) status_nagios nagios ;; restart) printf "Running configuration check..." $NagiosBin -v $NagiosCfgFile > /dev/null 2>&1; if [ $? -eq 0 ]; then echo "done" $0 stop $0 start else #$NagiosBin -v $NagiosCfgFile echo " FAILED! Restart aborted. Check your Nagios configuration." exit 1 fi ;; reload|force-reload) printf "Running configuration check..." $NagiosBin -v $NagiosCfgFile > /dev/null 2>&1; if [ $? -eq 0 ]; then echo "done" if test ! -f $NagiosRunFile; then $0 start else NagiosPID=`head -n 1 $NagiosRunFile` if status_nagios > /dev/null; then printf "Reloading nagios configuration..." killproc_nagios nagios -HUP echo "done" else $0 stop $0 start fi fi else #$NagiosBin -v $NagiosCfgFile echo " FAILED! Reload aborted. Check your Nagios configuration." exit 1 fi ;; *) echo "Usage: nagios {start|stop|restart|reload|force-reload|status}" exit 1 ;; esac # End of this script nagios-2.6/functions0000775000076500007650000001556107436604416014157 0ustar nagiosnagios#!/bin/sh # # functions This file contains functions to be used by most or all # shell scripts in the /etc/init.d directory. # # Version: @(#) /etc/init.d/functions 1.01 26-Oct-1993 # # Author: Miquel van Smoorenburg, # Hacked by: Greg Galloway and Marc Ewing # Karl DeBisschop (19991018 for solaris) # # First set up a default search path. PATH=/opt/gnu/bin:/sbin:/usr/sbin:/bin:/usr/bin:/usr/X11R6/bin export PATH # Get a sane screen width [ -z "$COLUMNS" ] && COLUMNS=80 # Read in our configuration if [ -z "$BOOTUP" ]; then if [ -f /etc/sysconfig/init ]; then . /etc/sysconfig/init else # This all seem confusing? Look in /etc/sysconfig/init, # or in /usr/doc/initscripts-*/sysconfig.txt BOOTUP=color RES_COL=20 MOVE_TO_COL="printf \033[300C\033[%dD ${RES_COL}" SETCOLOR_SUCCESS='printf \033[1;%dm 32' SETCOLOR_FAILURE='printf \033[1;%dm 31' SETCOLOR_WARNING='printf \033[1;%dm 33' SETCOLOR_NORMAL='printf \033[0;%dm 39' LOGLEVEL=1 fi fi if [ "$BOOTUP" != "verbose" ]; then INITLOG_CMD="initlog -q -c" else INITLOG_CMD="initlog -q -c" fi #if which initlog | egrep "^no initlog" >/dev/null 2&1; then # INITLOG_CMD="" #fi #if which initlog | egrep "^no pidof" >/dev/null 2>&1; then # IN_INITLOG="not found" #else # IN_INITLOG= #fi # A function to start a program. daemon() { # Test syntax. gotbase= case $1 in '') echo '$0: Usage: daemon [+/-nicelevel] {program}' return 1;; --check) shift base=$1 gotbase="yes" shift nicelevel=0 ;; -*|+*) nicelevel=$1 shift;; *) nicelevel=0;; esac # Save basename. [ -z $gotbase ] && base=`basename $1` # See if it's already running. pid=`pidofproc $base` [ -n "$pid" ] && ps -p $pid >/dev/null 2>&1 && return # make sure it doesn't core dump anywhere; while this could mask # problems with the daemon, it also closes some security problems ulimit -c 0 # Echo daemon [ "$BOOTUP" = "verbose" ] && printf " $base" # And start it up. nice -n $nicelevel $INITLOG_CMD "$*" && success "$base startup" || failure "$base startup" } # A function to stop a program. killproc() { # Test syntax. if [ $# = 0 ]; then echo "Usage: killproc {program} [signal]" return 1 fi notset=0 # check for second arg to be kill level if [ "$2" != "" ] ; then killlevel=$2 else notset=1 killlevel="-9" fi # Save basename. base=`basename $1` # Find pid. pid=`pidofproc $base` # Kill it. if [ "$pid" != "" ] ; then [ $BOOTUP = "verbose" ] && printf "$base " if [ "$notset" = "1" ] ; then if ps -p $pid>/dev/null 2>&1; then # TERM first, then KILL if not dead kill -TERM $pid sleep 1 if ps -p $pid >/dev/null 2>&1 ; then sleep 1 if ps -p $pid >/dev/null 2>&1 ; then sleep 3 if ps -p $pid >/dev/null 2>&1 ; then kill -KILL $pid fi fi fi fi ps -p $pid >/dev/null 2>&1 && failure "$base shutdown" || success "$base shutdown" # use specified level only else if ps -p $pid >/dev/null 2>&1; then kill $killlevel $pid && success "$base $killlevel" || failure "$base $killlevel" fi fi else failure "$base shutdown" fi # Remove pid file if any. if [ "$notset" = "1" ]; then rm -f /var/run/$base.pid fi } # A function to find the pid of a program. pidofproc() { # Test syntax. if [ $# = 0 ] ; then echo "Usage: pidofproc {program}" return 1 fi # First try "/var/run/*.pid" files if [ -f /var/run/$1.pid ] ; then pid=`head -1 /var/run/$1.pid` if [ "$pid" != "" ] ; then echo $pid return 0 fi fi # Next try "pidof" # if which pidof | egrep -v "^no pidof" >/dev/null 2>&1; then # pid=`pidof $1` # if [ "$pid" != "" ] ; then # echo $pid # return 0 # fi # fi # Finally try to extract it from ps pid=`ps -eo pid,ppid,fname | egrep -v $$ | awk 'BEGIN { prog=ARGV[1]; ARGC=1 } { if ((prog == $3) || (("(" prog ")") == $3) || (("[" prog "]") == $3) || ((prog ":") == $3)) { print $1 ; exit 0 } }' $1` if [ "$pid" != "" ] ; then echo $pid return 0 fi return 2 } status() { # Test syntax. if [ $# = 0 ] ; then echo "Usage: status {program}" return 1 fi base=`basename $1` pid=`pidofproc $base` if [ "$pid" != "" ] ; then echo "$1 (pid $pid) is running..." return 0 fi # Next try "/var/run/*.pid" files if [ -f /var/run/$1.pid ] ; then pid=`head -1 /var/run/$1.pid` if [ "$pid" != "" ] ; then echo "$1 dead but pid file exists" return 1 fi fi # See if /var/lock/subsys/$1 exists if [ -f /var/lock/subsys/$1 ]; then echo "$1 dead but subsys locked" return 2 fi echo "$1 is stopped" return 3 } echo_success() { [ "$BOOTUP" = "color" ] && $MOVE_TO_COL printf "[ " [ "$BOOTUP" = "color" ] && $SETCOLOR_SUCCESS printf "OK" [ "$BOOTUP" = "color" ] && $SETCOLOR_NORMAL printf " ]" return 0 } echo_failure() { [ "$BOOTUP" = "color" ] && $MOVE_TO_COL printf "[" [ "$BOOTUP" = "color" ] && $SETCOLOR_FAILURE printf "FAILED" [ "$BOOTUP" = "color" ] && $SETCOLOR_NORMAL printf "]" return 1 } echo_passed() { [ "$BOOTUP" = "color" ] && $MOVE_TO_COL printf "[" [ "$BOOTUP" = "color" ] && $SETCOLOR_WARNING printf "PASSED" [ "$BOOTUP" = "color" ] && $SETCOLOR_NORMAL printf "]" return 1 } # Log that something succeeded success() { if [ -z "$IN_INITLOG" ]; then # initlog -n $0 -s "$1" -e 1 logger -t $0 "Success: $1" else logger -t $0 "Success: $1" # echo "-n $0 -s \"$1\" -e 1" >&21 fi [ "$BOOTUP" != "verbose" ] && echo_success return 0 } # Log that something failed failure() { rc=$? if [ -z "$IN_INITLOG" ]; then logger -t $0 "Failure: $1" # initlog -n $0 -s "$1" -e 2 else logger -t $0 "Failure: $1" # echo "-n $0 -s \"$1\" -e 2" >&21 fi [ "$BOOTUP" != "verbose" ] && echo_failure return $rc } # Log that something passed, but may have had errors. Useful for fsck passed() { rc=$? if [ -z "$IN_INITLOG" ]; then logger -t $0 "Success: $1" # initlog -n $0 -s "$1" -e 1 else logger -t $0 "Success: $1" # echo "-n $0 -s \"$1\" -e 1" >&21 fi [ "$BOOTUP" != "verbose" ] && echo_passed return $rc } # Run some action. Log its output. action() { STRING=$1 printf "$STRING " shift $INITLOG_CMD "$*" && success "$STRING" || failure "$STRING" rc=$? echo return $rc } # Confirm whether we really want to run this service confirm() { printf "Start service $1 (Y)es/(N)o/(C)ontinue? [Y] " read answer case $answer in y|Y|"") return 0 ;; c|C) return 2 ;; n|N) return 1 ;; *) confirm $1 return $? ;; esac } nagios-2.6/install-sh0000775000076500007650000001272107436604416014220 0ustar nagiosnagios#! /bin/sh # # install - install a program, script, or datafile # This comes from X11R5 (mit/util/scripts/install.sh). # # Copyright 1991 by the Massachusetts Institute of Technology # # Permission to use, copy, modify, distribute, and sell this software and its # documentation for any purpose is hereby granted without fee, provided that # the above copyright notice appear in all copies and that both that # copyright notice and this permission notice appear in supporting # documentation, and that the name of M.I.T. not be used in advertising or # publicity pertaining to distribution of the software without specific, # written prior permission. M.I.T. makes no representations about the # suitability of this software for any purpose. It is provided "as is" # without express or implied warranty. # # Calling this script install-sh is preferred over install.sh, to prevent # `make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written # from scratch. It can only install one file at a time, a restriction # shared with many OS's install programs. # set DOITPROG to echo to test this script # Don't use :- since 4.3BSD and earlier shells don't like it. doit="${DOITPROG-}" # put in absolute paths if you don't have them in your path; or use env. vars. mvprog="${MVPROG-mv}" cpprog="${CPPROG-cp}" chmodprog="${CHMODPROG-chmod}" chownprog="${CHOWNPROG-chown}" chgrpprog="${CHGRPPROG-chgrp}" stripprog="${STRIPPROG-strip}" rmprog="${RMPROG-rm}" mkdirprog="${MKDIRPROG-mkdir}" transformbasename="" transform_arg="" instcmd="$mvprog" chmodcmd="$chmodprog 0755" chowncmd="" chgrpcmd="" stripcmd="" rmcmd="$rmprog -f" mvcmd="$mvprog" src="" dst="" dir_arg="" while [ x"$1" != x ]; do case $1 in -c) instcmd="$cpprog" shift continue;; -d) dir_arg=true shift continue;; -m) chmodcmd="$chmodprog $2" shift shift continue;; -o) chowncmd="$chownprog $2" shift shift continue;; -g) chgrpcmd="$chgrpprog $2" shift shift continue;; -s) stripcmd="$stripprog" shift continue;; -t=*) transformarg=`echo $1 | sed 's/-t=//'` shift continue;; -b=*) transformbasename=`echo $1 | sed 's/-b=//'` shift continue;; *) if [ x"$src" = x ] then src=$1 else # this colon is to work around a 386BSD /bin/sh bug : dst=$1 fi shift continue;; esac done if [ x"$src" = x ] then echo "install: no input file specified" exit 1 else true fi if [ x"$dir_arg" != x ]; then dst=$src src="" if [ -d $dst ]; then instcmd=: else instcmd=mkdir fi else # Waiting for this to be detected by the "$instcmd $src $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if [ -f $src -o -d $src ] then true else echo "install: $src does not exist" exit 1 fi if [ x"$dst" = x ] then echo "install: no destination specified" exit 1 else true fi # If destination is a directory, append the input filename; if your system # does not like double slashes in filenames, you may need to add some logic if [ -d $dst ] then dst="$dst"/`basename $src` else true fi fi ## this sed command emulates the dirname command dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` # Make sure that the destination directory exists. # this part is taken from Noah Friedman's mkinstalldirs script # Skip lots of stat calls in the usual case. if [ ! -d "$dstdir" ]; then defaultIFS=' ' IFS="${IFS-${defaultIFS}}" oIFS="${IFS}" # Some sh's can't handle IFS=/ for some reason. IFS='%' set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` IFS="${oIFS}" pathcomp='' while [ $# -ne 0 ] ; do pathcomp="${pathcomp}${1}" shift if [ ! -d "${pathcomp}" ] ; then $mkdirprog "${pathcomp}" else true fi pathcomp="${pathcomp}/" done fi if [ x"$dir_arg" != x ] then $doit $instcmd $dst && if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi else # If we're going to rename the final executable, determine the name now. if [ x"$transformarg" = x ] then dstfile=`basename $dst` else dstfile=`basename $dst $transformbasename | sed $transformarg`$transformbasename fi # don't allow the sed command to completely eliminate the filename if [ x"$dstfile" = x ] then dstfile=`basename $dst` else true fi # Make a temp file name in the proper directory. dsttmp=$dstdir/#inst.$$# # Move or copy the file name to the temp name $doit $instcmd $src $dsttmp && trap "rm -f ${dsttmp}" 0 && # and set any options; do chmod last to preserve setuid bits # If any of these fail, we abort the whole thing. If we want to # ignore errors from any of these, just make sure not to ignore # errors from the above "$doit $instcmd $src $dsttmp" command. if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && # Now rename the file to the real destination. $doit $rmcmd -f $dstdir/$dstfile && $doit $mvcmd $dsttmp $dstdir/$dstfile fi && exit 0 nagios-2.6/make-tarball0000775000076500007650000000071507526113240014464 0ustar nagiosnagios#! /bin/sh if [ "x$1" = "x" ] then echo "Usage: $0 " exit 1 fi if test -e Makefile; then make distclean fi autoconf # Update version number and modification date in code ./update-version $1 PWDSAVE=`pwd` PACKAGE=nagios pushd .. if [ ! -d $PACKAGE-$1 ]; then ln -s `basename $PWDSAVE` $PACKAGE-$1 fi tar zhcvf $PACKAGE-$1.tar.gz --exclude RCS --exclude CVS --exclude build-* --exclude *~ --exclude .\#* $PACKAGE-$1 #rm $PACKAGE-$1 popd nagios-2.6/mkpackage0000775000076500007650000000146207436604416014065 0ustar nagiosnagios#! /bin/sh if [ "z$1" = "z" ] ; then echo You must specify an architecture to build for! exit 1 fi case "$1" in solaris) LD_RUN_PATH=/usr/lib:/usr/local/lib autoreconf PATH=.:..:$PATH configure --with-cgiurl=/nagios/cgi-bin \ --with-htmurl=/nagios \ --with-lockfile=/var/run/nagios.pid \ --with-nagios-user=nagios \ --with-nagios-grp=nagios \ --with-command-user=nagios \ --with-command-grp=www \ --prefix=/usr/local \ --exec-prefix=/usr/local/sbin \ --bindir=/usr/local/sbin \ --sbindir=/usr/local/lib/nagios/cgi \ --libexecdir=/usr/local/lib/nagios/plugins \ --datadir=/usr/local/share/nagios \ --sysconfdir=/etc/nagios \ --localstatedir=/var/log/nagios \ --with-mail=/usr/bin/mailx make pkgclean make all make pkgset ;; *) echo Platform $1 is not currently supported exit 1 ;; esac exit 0nagios-2.6/nagios.spec0000664000076500007650000003505110532717360014343 0ustar nagiosnagios%define name nagios %define version 2.6 %define release 1.fc4.test %define nsusr nagios %define nsgrp nagios %define cmdgrp nagiocmd %define wwwusr apache %define wwwgrp apache # Performance data handling method to use. By default we will use # the file-based one (as existed in NetSaint). # You can select the external command based method (the defaut for # Nagios) by specifying # --define 'PERF_EXTERNAL 1' # in the rpm command-line %{!?PERF_EXTERNAL: %define PERF_EXTERNAL 0} # Embedded Perl stuff, specify # --define 'EMBPERL 1' # in the rpm command-line to enable it %{!?EMBPERL: %define EMBPERL 0} # Macro that print mesages to syslog at package (un)install time %define nnmmsg logger -t %{name}/rpm Summary: Host/service/network monitoring program Name: %{name} Version: %{version} Release: %{release} License: GPL Group: Application/System Source0: %{name}-%{version}.tar.gz BuildRoot: %{_tmppath}/%{name}-buildroot Prefix: %{_prefix} Prefix: /etc/init.d Prefix: /etc/nagios Prefix: /var/log/nagios Prefix: /var/spool/nagios Requires: gd > 1.8, zlib, libpng, libjpeg, bash, grep PreReq: /usr/bin/logger, chkconfig, sh-utils, shadow-utils, sed, initscripts, fileutils, mktemp BuildRequires: gd-devel > 1.8, zlib-devel, libpng-devel, libjpeg-devel %description Nagios is a program that will monitor hosts and services on your network. It has the ability to email or page you when a problem arises and when a problem is resolved. Nagios is written in C and is designed to run under Linux (and some other *NIX variants) as a background process, intermittently running checks on various services that you specify. The actual service checks are performed by separate "plugin" programs which return the status of the checks to Nagios. The plugins are available at http://sourceforge.net/projects/nagiosplug This package provide core programs for nagios. The web interface, documentation, and development files are built as separate packages %package www Group: Application/System Summary: Provides the HTML and CGI files for the Nagios web interface. Requires: %{name} = %{version} Requires: webserver %description www Nagios is a program that will monitor hosts and services on your network. It has the ability to email or page you when a problem arises and when a problem is resolved. Nagios is written in C and is designed to run under Linux (and some other *NIX variants) as a background process, intermittently running checks on various services that you specify. Several CGI programs are included with Nagios in order to allow you to view the current service status, problem history, notification history, and log file via the web. This package provides the HTML and CGI files for the Nagios web interface. In addition, HTML documentation is included in this package %package devel Group: Application/System Summary: Provides include files that Nagios-related applications may compile against. Requires: %{name} = %{version} %description devel Nagios is a program that will monitor hosts and services on your network. It has the ability to email or page you when a problem arises and when a problem is resolved. Nagios is written in C and is designed to run under Linux (and some other *NIX variants) as a background process, intermittently running checks on various services that you specify. This package provides include files that Nagios-related applications may compile against. %prep %setup -q %pre # Create `nagios' user on the system if necessary if /usr/bin/id %{nsusr} > /dev/null 2>&1 ; then : # user already exists else /usr/sbin/useradd -r -d /var/log/nagios -s /bin/sh -c "%{nsusr}" %{nsusr} || \ %nnmmsg Unexpected error adding user "%{nsusr}". Aborting install process. fi # id cannot tell us if the group already exists # so just try to create it and assume it works /usr/sbin/groupadd %{cmdgrp} > /dev/null 2>&1 # if LSB standard /etc/init.d does not exist, # create it as a symlink to the first match we find if [ -d /etc/init.d -o -L /etc/init.d ]; then : # we're done elif [ -d /etc/rc.d/init.d ]; then ln -s /etc/rc.d/init.d /etc/init.d elif [ -d /usr/local/etc/rc.d ]; then ln -s /usr/local/etc/rc.d /etc/init.d elif [ -d /sbin/init.d ]; then ln -s /sbin/init.d /etc/init.d fi %preun if [ "$1" = 0 ]; then /sbin/service nagios stop > /dev/null 2>&1 /sbin/chkconfig --del nagios fi %postun if [ "$1" -ge "1" ]; then /sbin/service nagios condrestart >/dev/null 2>&1 || : fi # Delete nagios user and group # (if grep doesn't find a match, then it is NIS or LDAP served and cannot be deleted) if [ $1 = 0 ]; then /bin/grep '^%{nsusr}:' /etc/passwd > /dev/null 2>&1 && /usr/sbin/userdel %{nsusr} || %nnmmsg "User %{nsusr} could not be deleted." /bin/grep '^%{nsgrp}:' /etc/group > /dev/null 2>&1 && /usr/sbin/groupdel %{nsgrp} || %nnmmsg "Group %{nsgrp} could not be deleted." /bin/grep '^%{cmdgrp}:' /etc/group > /dev/null 2>&1 && /usr/sbin/groupdel %{cmdgrp} || %nnmmsg "Group %{cmdgrp} could not be deleted." fi %post www # If apache is installed, and we can find the apache user, set a shell var wwwusr=`awk '/^[ \t]*User[ \t]+[a-zA-Z0-9]+/ {print $2}' /etc/httpd/conf/*.conf` if [ "z" == "z$wwwusr" ]; then # otherwise, use the default wwwusr=%{wwwusr} fi # if apache user is not in cmdgrp, add it if /usr/bin/id -Gn $wwwusr 2>/dev/null | /bin/grep -q %{cmdgrp} > /dev/null 2>&1 ; then : # $wwwusr (default: apache) is already in nagiocmd group else # first find apache primary group pgrp=`/usr/bin/id -gn $wwwusr 2>/dev/null` # filter apache primary group from secondary groups sgrps=`/usr/bin/id -Gn $wwwusr 2>/dev/null | /bin/sed "s/^$pgrp //;s/ $pgrp //;s/^$pgrp$//;s/ /,/g;"` if [ "z" == "z$sgrps" ] ; then sgrps=%{nsgrp} else sgrps=$sgrps,%{cmdgrp} fi # modify apache user, adding it to cmdgrp /usr/sbin/usermod -G $sgrps $wwwusr >/dev/null 2>&1 %nnmmsg "User $wwwusr added to group %{cmdgrp} so sending commands to Nagios from the command CGI is possible." fi %preun www if [ $1 = 0 ]; then if test -f /etc/httpd/conf/httpd.conf; then TEMPFILE=`mktemp /etc/httpd/conf/httpd.conf.tmp.XXXXXX` if grep "^ *Include /etc/httpd/conf.d/nagios.conf" /etc/httpd/conf/httpd.conf > /dev/null; then grep -v "^ *Include /etc/httpd/conf.d/nagios.conf" /etc/httpd/conf/httpd.conf > $TEMPFILE mv $TEMPFILE /etc/httpd/conf/httpd.conf chmod 664 /etc/httpd/conf/httpd.conf /etc/rc.d/init.d/httpd restart fi fi fi %build export PATH=$PATH:/usr/sbin CFLAGS="$RPM_OPT_FLAGS" CXXFLAGS="$RPM_OPT_FLAGS" \ ./configure \ --with-init-dir=/etc/init.d \ --with-cgiurl=/nagios/cgi-bin \ --with-htmurl=/nagios \ --with-lockfile=/var/run/nagios.pid \ --with-nagios-user=%{nsusr} \ --with-nagios-group=%{nsgrp} \ --prefix=%{_prefix} \ --exec-prefix=%{_prefix}/sbin \ --bindir=%{_prefix}/sbin \ --sbindir=%{_prefix}/lib/nagios/cgi \ --libexecdir=%{_prefix}/lib/nagios/plugins \ --datadir=%{_prefix}/share/nagios \ --sysconfdir=/etc/nagios \ --localstatedir=/var/log/nagios \ %if ! %{PERF_EXTERNAL} --with-file-perfdata \ %endif %if %{EMBPERL} --enable-embedded-perl \ %endif --with-gd-lib=/usr/lib \ --with-gd-inc=/usr/include \ --with-template-objects \ --with-template-extinfo make all # make sample configs ###cd sample-config ###F=`mktemp temp.XXXXXX` ###sed -e 's=/var/log/nagios/rw/=/var/spool/nagios/=;s=@sysconfdir@/resource.cfg=@sysconfdir@/private/resource.cfg=' nagios.cfg > ${F} ###mv ${F} nagios.cfg ###cd .. # make daemonchk.cgi and event handlers cd contrib make cd eventhandlers for f in `find . -type f` ; do F=`mktemp temp.XXXXXX` sed "s=/usr/local/nagios/var/rw/=/var/spool/nagios/=; \ s=/usr/local/nagios/libexec/eventhandlers/=%{_prefix}/lib/nagios/plugins/eventhandlers=; \ s=/usr/local/nagios/test/var=/var/log/nagios=" ${f} > ${F} mv ${F} ${f} done cd ../.. %install [ "$RPM_BUILD_ROOT" != "/" ] && rm -rf $RPM_BUILD_ROOT install -d -m 0775 ${RPM_BUILD_ROOT}/var/spool/nagios install -d -m 0755 ${RPM_BUILD_ROOT}%{_prefix}/include/nagios install -d -m 0755 ${RPM_BUILD_ROOT}/etc/init.d install -d -m 0755 ${RPM_BUILD_ROOT}/etc/logrotate.d install -d -m 0755 ${RPM_BUILD_ROOT}/etc/httpd/conf.d install -d -m 0755 ${RPM_BUILD_ROOT}/etc/nagios ### install -d -m 0755 ${RPM_BUILD_ROOT}/etc/nagios/private make DESTDIR=${RPM_BUILD_ROOT} INSTALL_OPTS="" COMMAND_OPTS="" install make DESTDIR=${RPM_BUILD_ROOT} INSTALL_OPTS="" COMMAND_OPTS="" INIT_OPTS="" install-daemoninit # install templated configuration files cd sample-config for f in {nagios,cgi}.cfg ; do [ -f $f ] && install -c -m 664 $f ${RPM_BUILD_ROOT}/etc/nagios/${f} done ###mkdir -p ${RPM_BUILD_ROOT}/etc/nagios/private for f in resource.cfg ; do [ -f $f ] && install -c -m 664 $f ${RPM_BUILD_ROOT}/etc/nagios/${f} done cd template-object for f in {hosts,hostgroups,services,contacts,contactgroups,dependencies,escalations,timeperiods,checkcommands,misccommands,minimal}.cfg do [ -f $f ] && install -c -m 664 $f ${RPM_BUILD_ROOT}/etc/nagios/${f} done cd .. cd .. # install headers for development package install -m 0644 include/locations.h ${RPM_BUILD_ROOT}%{_prefix}/include/nagios # install httpd configuration in RH80-style httpd config subdir cp sample-config/httpd.conf ${RPM_BUILD_ROOT}/etc/httpd/conf.d/nagios.conf # install CGIs cd contrib make INSTALL=install DESTDIR=${RPM_BUILD_ROOT} INSTALL_OPTS="" COMMAND_OPTS="" CGIDIR=%{_libdir}/nagios/cgi install #mv ${RPM_BUILD_ROOT}%{_prefix}/lib/nagios/cgi/convertcfg ${RPM_BUILD_ROOT}%{_prefix}/lib/nagios/ #mv ${RPM_BUILD_ROOT}%{_prefix}/lib/nagios/cgi/mini_epn ${RPM_BUILD_ROOT}%{_prefix}/sbin/ cd .. # install event handlers cd contrib/eventhandlers install -d -m 0755 ${RPM_BUILD_ROOT}%{_prefix}/lib/nagios/eventhandlers for file in * ; do test -f $file && install -m 0755 $file ${RPM_BUILD_ROOT}%{_prefix}/lib/nagios/eventhandlers && rm -f $file done cd ../.. %clean rm -rf $RPM_BUILD_ROOT %files %defattr(755,root,root) /etc/init.d/nagios %{_prefix}/sbin/nagios %{_prefix}/sbin/nagiostats %if %{EMBPERL} %{_prefix}/sbin/p1.pl %endif %{_prefix}/sbin/mini_epn %{_prefix}/sbin/new_mini_epn %dir %{_prefix}/lib/nagios/eventhandlers %{_prefix}/lib/nagios/eventhandlers/* %{_sbindir}/convertcfg %dir /etc/nagios %defattr(644,root,root) %config(noreplace) /etc/nagios/*.cfg %defattr(750,root,%{nsgrp}) ###%dir /etc/nagios/private %defattr(640,root,%{nsgrp}) ### %config(noreplace) /etc/nagios/private/resource.cfg %defattr(755,%{nsusr},%{nsgrp}) %dir /var/log/nagios %dir /var/log/nagios/archives %defattr(2775,%{nsusr},%{nsgrp}) %dir /var/spool/nagios %doc Changelog INSTALLING LICENSE README UPGRADING %files www %defattr(755,root,root) %dir %{_prefix}/lib/nagios/cgi %{_libdir}/nagios/cgi/* %dir %{_prefix}/share/nagios %defattr(-,root,root) %{_prefix}/share/nagios/* %config(noreplace) /etc/httpd/conf.d/nagios.conf %files devel %defattr(-,root,root) %dir %{_prefix}/include/nagios %{_prefix}/include/nagios/locations.h %changelog * Tue Nov 22 2005 Andreas Kasenides - packaged %{_prefix}/sbin/new_mini_epn - moved resource.cfg in /etc/nagios * Thu Dec 30 2004 Rui Miguel Silva Seabra - FIX spec (wrong tag for License, and update to current state of compile) * Sat May 31 2003 Karl DeBisschop (1.1-1) - Merge with CVS for 1.1 release * Fri May 30 2003 Karl DeBisschop (1.0-4) - cmdgrp was not always getting created - patches for cmd.cgi and history.cgi * Sat May 24 2003 Karl DeBisschop (1.0-3) - patches for doco and PostgreSQL timestamp - make sure all files are packaged (otherwise, will not build on RH9) * Sat May 17 2003 Karl DeBisschop (1.0-2) - patch for file descriptor leak * Fri Oct 04 2002 Karl DeBisschop - merge many improvements from Ramiro Morales (macros for PERF_EXTERNAL and EMBPERL, cleanup pre/post scripts, nnmmsg logger macro, include eventhandlers, convertcfg, mini_epn) - use LSB-standard /etc/init.d/nagios startup location * Tue Aug 13 2002 Karl DeBisschop - INSTALL was renamed INSTALLING - p1.pl script included in package - web server restarted because Red Hat 7.3 init does not do 'reload' * Fri Jun 14 2002 Ethan Galstad (1.0a4) - Fixed spec file to work with Nagios * Wed Jan 17 2001 Karl DeBisschop (0.0.7a5-1) - switch from /usr/libexec to /usr/lib because linux FHS has no libexec - use global macro to set location of init script - fold htaccess.sample into contrib directory of tarball * Fri Nov 03 2000 Karl DeBisschop (0.0.6-1) - Rebuild with final sources * Wed Sep 06 2000 Karl DeBisschop (0.0.6b5-1) - Create separate cgi, html, and devel packages - Include commands.cfg * Sun Aug 27 2000 Karl DeBisschop (0.0.6b5-1) - beta 5 * Sun Jul 23 2000 Karl DeBisschop (0.0.6b3-2) - fixes for daemon-init, multi-OS RPM building * Wed Jul 12 2000 Karl DeBisschop (0.0.6b3-1) - beta 3 * Sun Jun 25 2000 Karl DeBisschop (0.0.6b2-3) - true beta2 sources * Sat Jun 24 2000 Karl DeBisschop (0.0.6b2-2) - cleanup spec, still using pre-beta2 sources * Sat Jun 24 2000 Karl DeBisschop (0.0.6b2-1) - mandrake merge using pre-beta2 sources (many thanks to Stefan van der Eijk ) * Wed Jun 14 2000 Karl DeBisschop (0.0.6b1-1) - add stylesheet diffs * Mon Jun 12 2000 Karl DeBisschop (0.0.6b1-1) - adapt for 0.0.6b1 * Mon Jun 05 2000 Karl DeBisschop (0.0.5-4) - add traceroute.cgi and htaccess.sample - move placement of docs (in files) to avoid group warnings - change www user and group to nobody and add warning * Mon Jun 05 2000 Karsten Weiss (0.0.5-3) - official group name - improved user detection * Tue Oct 19 1999 Mike McHenry (0.0.4-1) - Upgraded package from 0.0.4b4 to 0.0.4 * Mon Aug 16 1999 Mike McHenry - First RPM build (0.0.4b4) nagios-2.6/p1.pl0000664000076500007650000007522010410106436013055 0ustar nagiosnagios package Embed::Persistent; # p1.pl for Nagios 2.0 use strict ; use Text::ParseWords qw(parse_line) ; use constant LEAVE_MSG => 1 ; use constant CACHE_DUMP => 2 ; use constant PLUGIN_DUMP => 4 ; use constant DEBUG_LEVEL => 0 ; # use constant DEBUG_LEVEL => CACHE_DUMP ; # use constant DEBUG_LEVEL => LEAVE_MSG ; # use constant DEBUG_LEVEL => LEAVE_MSG | CACHE_DUMP ; # use constant DEBUG_LEVEL => LEAVE_MSG | CACHE_DUMP | PLUGIN_DUMP ; use constant DEBUG_LOG_PATH => '/usr/local/nagios/var/' ; # use constant DEBUG_LOG_PATH => './' ; use constant LEAVE_MSG_STREAM => DEBUG_LOG_PATH . 'epn_leave-msgs.log' ; use constant CACHE_DUMP_STREAM => DEBUG_LOG_PATH . 'epn_cache-dump.log' ; use constant PLUGIN_DUMP_STREAM => DEBUG_LOG_PATH . 'epn_plugin-dump.log' ; use constant NUMBER_OF_PERL_PLUGINS => 60 ; use constant Cache_Dump_Interval => 20 ; # Cache will be dumped every Cache_Dump_Interval plugin compilations (DEBUG_LEVEL & LEAVE_MSG) && do { open LH, '>> ' . LEAVE_MSG_STREAM or die "Can't open " . LEAVE_MSG_STREAM . ": $!" ; # Unbuffer LH since this will be written by child processes. select( (select(LH), $| = 1)[0] ) ; } ; (DEBUG_LEVEL & CACHE_DUMP) && do { (open CH, '>> ' . CACHE_DUMP_STREAM or die "Can't open " . CACHE_DUMP_STREAM . ": $!") ; select( (select(CH), $| = 1)[0] ) ; } ; (DEBUG_LEVEL & PLUGIN_DUMP) && (open PH, '>> ' . PLUGIN_DUMP_STREAM or die "Can't open " . PLUGIN_DUMP_STREAM . ": $!") ; require Data::Dumper if DEBUG_LEVEL & CACHE_DUMP ; my (%Cache, $Current_Run) ; keys %Cache = NUMBER_OF_PERL_PLUGINS ; # Offsets in %Cache{$filename} use constant MTIME => 0 ; use constant PLUGIN_ARGS => 1 ; use constant PLUGIN_ERROR => 2 ; use constant PLUGIN_HNDLR => 3 ; package main; use subs 'CORE::GLOBAL::exit'; sub CORE::GLOBAL::exit { die "ExitTrap: $_[0] (Redefine exit to trap plugin exit with eval BLOCK)" } package OutputTrap; # Methods for use by tied STDOUT in embedded PERL module. # Simply ties STDOUT to a scalar and caches values written to it. # NB No more than 256 characters per line are kept. sub TIEHANDLE { my ($class) = @_; my $me = ''; bless \$me, $class; } sub PRINT { my $self = shift; # $$self = substr(join('',@_), 0, 256) ; $$self .= substr(join('',@_), 0, 256) ; } sub PRINTF { my $self = shift; my $fmt = shift; # $$self = substr(sprintf($fmt,@_), 0, 256) ; $$self .= substr(sprintf($fmt,@_), 0, 256) ; } sub READLINE { my $self = shift; # Omit all lines after the first, per the nagios plugin guidelines $$self = (split /\n/, $$self)[0]; # Perl code other than plugins may print nothing; in this case return "(No output!)\n". return $$self ? substr($$self, 0, 256) : "(No output!)\n" ; } sub CLOSE { my $self = shift; undef $self ; } sub DESTROY { my $self = shift; undef $self; } package Embed::Persistent; sub valid_package_name { local $_ = shift ; s|([^A-Za-z0-9\/])|sprintf("_%2x",unpack("C",$1))|eg; # second pass only for words starting with a digit s|/(\d)|sprintf("/_%2x",unpack("C",$1))|eg; # Dress it up as a real package name s|/|::|g; return /^::/ ? "Embed$_" : "Embed::$_" ; } # Perl 5.005_03 only traps warnings for errors classed by perldiag # as Fatal (eg 'Global symbol """"%s"""" requires explicit package name'). # Therefore treat all warnings as fatal. sub throw_exception { die shift ; } sub eval_file { my ($filename, $delete, undef, $plugin_args) = @_ ; my $mtime = -M $filename ; my $ts = localtime(time()) if DEBUG_LEVEL ; if ( exists($Cache{$filename}) && $Cache{$filename}[MTIME] && $Cache{$filename}[MTIME] <= $mtime ) { # We have compiled this plugin before and # it has not changed on disk; nothing to do except # 1 parse the plugin arguments and cache them (to save # repeated parsing of the same args) - the same # plugin could be called with different args. # 2 return the error from a former compilation # if there was one. $Cache{$filename}[PLUGIN_ARGS]{$plugin_args} ||= [ parse_line('\s+', 0, $plugin_args) ] if $plugin_args ; if ( $Cache{$filename}[PLUGIN_ERROR] ) { print LH qq($ts eval_file: $filename failed compilation formerly and file has not changed; skipping compilation.\n) if DEBUG_LEVEL & LEAVE_MSG ; die qq(**ePN failed to compile $filename: "$Cache{$filename}[PLUGIN_ERROR]") ; } else { print LH qq($ts eval_file: $filename already successfully compiled and file has not changed; skipping compilation.\n) if DEBUG_LEVEL & LEAVE_MSG ; return $Cache{$filename}[PLUGIN_HNDLR] ; } } my $package = valid_package_name($filename) ; $Cache{$filename}[PLUGIN_ARGS]{$plugin_args} ||= [ parse_line('\s+', 0, $plugin_args) ] if $plugin_args ; local *FH; # die will be trapped by caller (checking ERRSV) open FH, $filename or die qq(**ePN failed to open "$filename": "$!") ; my $sub ; sysread FH, $sub, -s FH ; close FH; # Cater for scripts that have embedded EOF symbols (__END__) # XXXX # Doesn't make sense to me. # $sub =~ s/__END__/\;}\n__END__/; # Wrap the code into a subroutine inside our unique package # (using $_ here [to save a lexical] is not a good idea since # the definition of the package is visible to any other Perl # code that uses [non localised] $_). my $hndlr = <>> $sub # <<< END of PLUGIN >>> } EOSUB $Cache{$filename}[MTIME] = $mtime unless $delete ; # Suppress warning display. local $SIG{__WARN__} = \&throw_exception ; # Compile &$package::hndlr. Since non executable code is being eval'd # there is no need to protect lexicals in this scope. eval $hndlr; # $@ is set for any warning and error. # This guarantees that the plugin will not be run. if ($@) { # Report error line number wrt to original plugin text (7 lines added by eval_file). # Error text looks like # 'Use of uninitialized ..' at (eval 23) line 186, line 218 # The error line number is 'line 186' chomp($@) ; $@ =~ s/line (\d+)[\.,]/'line ' . ($1 - 7) . ','/e ; print LH qq($ts eval_file: syntax error in $filename: "$@".\n) if DEBUG_LEVEL & LEAVE_MSG ; if ( DEBUG_LEVEL & PLUGIN_DUMP ) { my $i = 1 ; $_ = $hndlr ; s/^/sprintf('%10d ', $i++)/meg ; # Will only get here once (when a faulty plugin is compiled). # Therefore only _faulty_ plugins are dumped once each time the text changes. print PH qq($ts eval_file: transformed plugin "$filename" to ==>\n$_\n) ; } $@ = substr($@, 0, 256) if length($@) > 256 ; $Cache{$filename}[PLUGIN_ERROR] = $@ ; # If the compilation fails, leave nothing behind that may affect subsequent # compilations. This will be trapped by caller (checking ERRSV). die qq(**ePN failed to compile $filename: "$@") ; } else { $Cache{$filename}[PLUGIN_ERROR] = '' ; } print LH qq($ts eval_file: successfully compiled "$filename $plugin_args".\n) if DEBUG_LEVEL & LEAVE_MSG ; print CH qq($ts eval_file: after $Current_Run compilations \%Cache =>\n), Data::Dumper->Dump([\%Cache], [qw(*Cache)]), "\n" if ( (DEBUG_LEVEL & CACHE_DUMP) && (++$Current_Run % Cache_Dump_Interval == 0) ) ; no strict 'refs' ; return $Cache{$filename}[PLUGIN_HNDLR] = *{ $package . '::hndlr' }{CODE} ; } sub run_package { my ($filename, undef, $plugin_hndlr_cr, $plugin_args) = @_; # Second parm (after $filename) _may_ be used to wallop stashes. my $res = 3 ; my $ts = localtime(time()) if DEBUG_LEVEL ; local $SIG{__WARN__} = \&throw_exception ; my $stdout = tie (*STDOUT, 'OutputTrap'); my @plugin_args = $plugin_args ? @{ $Cache{$filename}[PLUGIN_ARGS]{$plugin_args} } : () ; # If the plugin has args, they have been cached by eval_file. # ( cannot cache @plugin_args here because run_package() is # called by child processes so cannot update %Cache.) eval { $plugin_hndlr_cr->(@plugin_args) } ; if ($@) { # Error => normal plugin termination (exit) || run time error. $_ = $@ ; /^ExitTrap: (-?\d+)/ ? $res = $1 : # For normal plugin exit, $@ will always match /^ExitTrap: (-?\d+)/ /^ExitTrap: / ? $res = 0 : do { # Run time error/abnormal plugin termination. chomp ; # Report error line number wrt to original plugin text (7 lines added by eval_file). s/line (\d+)[\.,]/'line ' . ($1 - 7) . ','/e ; print STDOUT qq(**ePN $filename: "$_".\n) ; } ; ($@, $_) = ('', '') ; } # ! Error => Perl code is not a plugin (fell off the end; no exit) # !! (read any output from the tied file handle.) my $plugin_output = ; undef $stdout ; untie *STDOUT; print LH qq($ts run_package: "$filename $plugin_args" returning ($res, "$plugin_output").\n) if DEBUG_LEVEL & LEAVE_MSG ; return ($res, $plugin_output) ; } 1; =head1 NAME p1.pl - Perl program to provide Perl code persistence for the Nagios project (http://www.Nagios.Org). This program provides an API for calling Nagios Perl plugins from Nagios when it is built with embedded Perl support. The intent is to tradeoff memory usage (see BUGS) against repeated context switches to recompile Perl plugins. =head1 SYNOPSIS B /* 1 Initialise Perl - see perlembed - maintaining a persistent interpreter> */ /* 2 Push the arguments (char *args[]) of call_pv() onto the Perl stack */ /* 3 Compile the plugin - char *args[] is an array of pointers to strings required by p1.pl */ call_pv("Embed::Persistent::eval_file", G_SCALAR | G_EVAL) /* 4 if (SvTrue(ERRSV)) */ goto outahere ; /* 5 Pop the code reference to the Perl sub (corresp to the plugin) returned by Perl */ /* 6 Push the arguments (char *args[]) of call_pv() onto the Perl stack */ /* 7 Run the plugin */ call_pv("Embed::Persistent::run_package", G_ARRAY) /* 8 example arguments for call_ functions */ args = { "check_rcp", /* pointer to plugin file name */ "1", /* 1 to recompile plugins each time */ "", /* temporary file name - no longer used */ "-H sundev -C nfs" /* pointer to plugin argument string */ } B my ($plugin_file, $plugin_args) = split(/\s+/, $_, 2) ; my $plugin_hndlr_cr ; eval { # 'eval {}' simulates the G_EVAL flag to perl_call_argv('code', 'flags') # Otherwise, die in 'eval_file' will end the caller also. $plugin_hndlr_cr = Embed::Persistent::eval_file($plugin_file, 0, '', $plugin_args) ; } ; if ( $@) { print "plugin compilation failed.\n" ; } else { my ($rc, $output) = Embed::Persistent::run_package($plugin_file, 0, $plugin_hndlr_cr, $plugin_args) ; printf "embedded perl plugin return code and output was: %d & %s\n", $rc, $output) ; In the p1.pl text, 'use constant' statements set the log path and the log level. The log level flags determine the amount and type of messages logged in the log path. The default log level results in similar behaviour to former versions of p1.pl - log files will B be opened. If you want to enable logging =over 4 =item 1 Choose log options (see below) =item 2 Choose a log path =item 3 Edit p1.pl =back Set the values of (the 'use constant' statements) the log path, B, and set the B constant to one or more of the log options (B and friends ) or'ed together. The default is to log nothing and to use S</var/epn_stderr.log> as the log path. =head1 DESCRIPTION Nagios is a program to monitor service availability by scheduling 'plugins' - discrete programs that check a service (by for example simulating a users interaction with a web server using WWW::Mechanize) and output a line of text (the summary of the service state) for those responsible for the service, and exit with a coded value to relay the same information to Nagios. Each plugin is run in a new child process forked by Nagios. Plugins, like CGIs, can be coded in Perl. The persistence framework embeds a Perl interpreter in Nagios to =over 4 =item * reduce the time taken for the Perl compile and execute cycle. =item * eliminate the need for Nagios to fork a process (with popen) to run the Perl code. =item * eliminate reloading of frequently used modules. =back and all the good things mentioned in the B man page under 'Maintaining a persistent interpreter'. Plugin run-time and syntax errors, are returned to Nagios as the 'plugin output'. These messages appear in the Nagios log like S<**ePN 'check_test' Global symbol "$status" requires explicit package name at (eval 54) line 15.> Extra logging is given by setting DEBUG_LEVEL to include B B<1> opens an extra output stream in the path given by the value of DEBUG_LOG_PATH B<2> logs messages describing the success or otherwise of the plugin compilation and the result of the plugin run. An example of such messages are Fri Apr 22 11:54:21 2005 eval_file: successfully compiled "/usr/local/nagios/libexec/check_bass ". Fri Apr 22 11:54:21 2005 run_package: "/usr/local/nagios/libexec/check_bass " returning ("0", "BASS Transaction completed Ok. "). Fri Apr 22 11:55:02 2005 eval_file: successfully compiled "/usr/local/nagios/libexec/check_ad -D production.prod -S". Fri Apr 22 11:55:02 2005 run_package: "/usr/local/nagios/libexec/check_ad -D foo.dom -S" returning ("0", "Ok. Expected 2 domain controllers [foo1 foo2] for "foo.dom.prod" domain from "1.1.2.3" DNS, found 8 [foo1 foo2 ..] "). Fri Apr 22 11:55:19 2005 eval_file: successfully compiled "/usr/local/nagios/libexec/check_ldap adonis". Fri Apr 22 11:55:19 2005 run_package: "/usr/local/nagios/libexec/check_ldap adonis" returning ("0", "Ok. Schema query response DN: dc=ipaustralia,dc=gov,dc=au aci: (target="ldap:///dc=ipaustralia,dc=gov,dc=au")(targetattr!="userPassword")(targetfi "). Fri Apr 22 11:55:29 2005 eval_file: successfully compiled "/usr/local/nagios/libexec/check_scheduler -H aphrodite -p 7003". Fri Apr 22 11:55:30 2005 eval_file: successfully compiled "/usr/local/nagios/libexec/check_pams -H aphrodite -p 7003 -R". Fri Apr 22 11:55:29 2005 run_package: "/usr/local/nagios/libexec/check_scheduler -H aphrodite -p 7003" returning ("0", "Ok. COMSQ last ran 31 seconds ago. System: 0.02s Number of jobs waiting 0 "Detail" system sch_V2_6 14/01/2005 12:22:53 aimali Jobs: COMSQ/PollerManager Fri Apr 22 11:55:00, adhoc pause Fri Apr 22 09:00:00, PAMS/SchedExamDocCheck Thu Apr 21 23:00:00, CFX Cl" ). Fri Apr 22 11:55:30 2005 run_package: "/usr/local/nagios/libexec/check_pams -H aphrodite -p 7003 -R" returning ("0", "OK PAMS Worst: Test Time 2.61 Failure Ratio 0 [0:5] Statii: BASE OK Oracle (direct) OK COMS Processor OK CCS Name Search (direct) OK Correspondence Manager OK PAMS Tier OK CASEWORK OK Objective (direct) OK Customer Manager OK "). Fri Apr 22 11:55:45 2005 eval_file: successfully compiled "/usr/local/nagios/libexec/check_coms ". Fri Apr 22 11:55:45 2005 run_package: "/usr/local/nagios/libexec/check_coms " returning ("0", "COMS Ok. 11 successes 20 minutes ago. 55 minute deltas: (0 0 0 11 0 1 3 4 0 6) or graph ) .. after all the plugins are compiled, the 'successfully compiled mesages' are replaced by 'skipping compilation' Fri Apr 22 12:05:10 2005 eval_file: /usr/local/nagios/libexec/check_adds already successfully compiled and file has not changed; skipping compilation. Fri Apr 22 12:05:11 2005 eval_file: /usr/local/nagios/libexec/check_aub already successfully compiled and file has not changed; skipping compilation . Fri Apr 22 12:05:10 2005 run_package: "/usr/local/nagios/libexec/check_adds " returning ("0", "ADDS Transaction completed Ok. "). Fri Apr 22 12:05:13 2005 eval_file: /usr/local/nagios/libexec/check_eForm already successfully compiled and file has not changed; skipping compilation. Fri Apr 22 12:05:13 2005 run_package: "/usr/local/nagios/libexec/check_eForm " returning ("0", "eForm Transaction completed Ok. "). Fri Apr 22 12:05:15 2005 eval_file: /usr/local/nagios/libexec/check_cfx_log already successfully compiled and file has not changed; skipping compilation. Fri Apr 22 12:05:15 2005 run_package: "/usr/local/nagios/libexec/check_cfx_log -H faxgw1" returning ("0", "Ok. Last write of "//faxgw1/Faxloader$/cfxFaxLoaderClient.log" 0.0 minutes ago. File info (create, access, modify, write times): "Wed Mar 26 17:19:42 2003 Fri Apr 22 12:05:13 2005 Fri Apr 22 12:05:13 2005 Fri Apr 22 12:05:13 2005". "). Fri Apr 22 12:05:16 2005 eval_file: /usr/local/nagios/libexec/check_cfx_log already successfully compiled and file has not changed; skipping compilation. Fri Apr 22 12:05:16 2005 run_package: "/usr/local/nagios/libexec/check_cfx_log -H faxgw2" returning ("0", "Ok. Last write of "//faxgw2/Faxloader$/cfxFaxLoaderClient.log" 0.3 minutes ago. File info (create, access, modify, write times): "Wed Mar 26 17:27:24 2003 Fri Apr 22 12:04:55 2005 Fri Apr 22 12:04:55 2005 Fri Apr 22 12:04:55 2005". "). Fri Apr 22 12:05:17 2005 eval_file: /usr/local/nagios/libexec/check_apps_asearch already successfully compiled and file has not changed; skipping compilation. Fri Apr 22 12:05:18 2005 eval_file: /usr/local/nagios/libexec/check_aurioness already successfully compiled and file has not changed; skipping compi lation. Fri Apr 22 12:05:11 2005 run_package: "/usr/local/nagios/libexec/check_aub " returning ("0", "AU-B Transaction completed Ok. "). If you are lucky enough to have plugins with errors in them, Fri Apr 22 12:16:01 2005 run_package: "//usr/local/nagios/libexec/eventhandlers/restart_coldfusion OK SOFT" returning ("3", "**ePN "//usr/local/nagios/libexec/eventhandlers/restart_coldfusion": "Can't use string ("") as a subroutine ref while "strict refs" in use at /usr/local/nagios/bin/p1.pl line 291, line 218". B B<1> opens an extra output stream in the path given by the value of DEBUG_LOG_PATH. B<2> logs a listing of the text of any B plugin - as transformed by the persistence framework. Note that plugins that compile are B dumped. This option is only useful for investigating WTF a plugin that runs from the CLI does not run under Nagios with embedded Perl. Sat Apr 23 19:25:32 2005 eval_file: transformed plugin "check_dummy_plugin" to ==> 1 package Embed::check_5fdummy_5fplugin; 2 3 sub hndlr { 4 @ARGV = @_ ; 5 local $^W = 1 ; 6 7 # <<< START of PLUGIN (first line of plugin is line 8 in the text) >>> 8 #!/usr/bin/perl -w 9 10 use strict 11 # use strict ; 12 13 my @texts = split(/\n/, < 0 ? 2 : 0 ; 24 exit $rc ; 25 26 27 # <<< END of PLUGIN >>> 28 } This listing is logged each time the plugin source file modification time stamp is changed (when the file is compiled for the first time and then either by correcting a syntax error or touching the file). Note that the plugin text (lines 8 to 27 inclusive) has been transformed by the persistence framework as described below. B B<1> opens an extra output stream in the path given by the value of DEBUG_LOG_PATH. B<2> A dump of the %Cache data structure (showing the plugin file modification time, a hash keyed by the plugin argument string of arrays of parsed arguments (if non null), the last compilation error, and a code ref to the Perl subroutine corresponding the plugin (this is undef if the plugin failed to compile). Sat Apr 23 19:24:59 2005 eval_file: after 5 compilations %Cache => %Cache = ( '/usr/local/nagios/libexec/check_adds' => [ '100.230810185185', undef, '', sub { "DUMMY" } ], 'check_adds' => [ '3.96288194444444', undef, '', sub { "DUMMY" } ], 'check_atmoss' => [ '3.96288194444444', undef, '', sub { "DUMMY" } ], '/usr/local/nagios/libexec/check_pams' => [ '1.90859953703704', { '-R -I -H asterix -p 7003' => [ '-R', '-I', '-H', 'asterix', '-p', '7003' ] }, sub { "DUMMY" } ], 'check_dummy_plugin' => [ '3.96288194444444', undef, '', sub { "DUMMY" } ] ); .. This dump is produced periodically: each B<$Cache_Dump_Interval> plugin compilations the %Cache data structure is dumped. =head1 SUBROUTINES Unless otherwise stated, all subroutines take two (4) arguments :- =over 4 =item 1 plugin_filename - char * (called from C) or scalar (called from Perl): the path to the plugin. =item 2 DO_CLEAN - boolean: set if plugin is not to be cached. Defaults to 0. Setting this flag means that the plugin is compiled each time it is executed. Nagios B sets this flag when the Nagios is compiled with the configure setting --with-perlcache. =item 3 (SV *) code ref to the Perl subroutine corresponding to the plugin This argument is only used by run_package(); it is returned by eval_file(). =item 4 plugin arguments - char ** (called from C) or scalar (called from Perl); the plugin options and arguments =back =over 4 =item Embed::Persistent::eval_file( plugin_filename, DO_CLEAN, "", plugin_arguments ) E<10> Returns B a Perl code reference (an SV containing a hard reference to a subroutine) to the subroutine that has been produced and compiled by eval_file, B raises an exception (by calling die) and setting the value of B or B<$@> (if called from Perl). eval_file() transforms the plugin to a subroutine in a package, by compiling the string containing the transformed plugin, and caches the plugin file modification time (to avoid recompiling it), the parsed plugin arguments. and either the error trapped when the plugin is compiled or a code reference to the compiled subroutine representing the plugin. eval_file() caches these values in the cache named B<%Cache>. The plugin file name is the key to an array containing the values illustrated above. If the plugin file has not been modified, eval_file returns the cached plugin error B the code ref to the plugin subroutine. Otherwise, the plugin is compiled into a subroutine in a new package by =over 4 =item 1 creating a package name from the plugin file name (C) =item 2 turning off subroutine redefinition warnings (C) =item 3 overriding CORE::GLOBAL::exit from within package main (C) This allows the plugin to both call exit without taking down the persistence framework, and to return the exit code to the Nagios. =item 4 prepending the plugin text with code to let the plugin function as a subroutine. The plugin command line arguments are expected to be in @ARGV, so @ARGV is set to the subroutine arguments (@_). The new subroutine also sets the warning level to trap all warnings that may have been caused by by the transformation (the -w option to Perl in the text is no longer significant (because the shebang line is not fed to exec()). =item 5 writing the plugin as the subroutine named B in the new package. =item 6 returning either a code reference to the subroutine named hndlr in the package named in item 1, OR the compilation error trapped by eval 'string'. It is the callers responsibility to check either ERRSV (from C) or $@ (from Perl) and skip run_package() if these values are true. =back =item Embed::Persistent::run_package( plugin_filename, DO_CLEAN, (SV *) plugin_hndlr_cr, plugin_argument_string ) E<10> Returns (plugin_return_code, plugin_output) run_plugin() actually runs the plugins with the arguments contained in the (space separated string) 4th argument. =back =head1 DIFFERENCES FROM PERSISTENT.PL The example B takes no account of =over 4 =item * Capturing output from the Perl program being run This framework ties STDOUT to a scalar that stores the result of PRINT or PRINTF. =item * Running Perl programs in child processes This is the largest single difference between this framework and the example program persistent.pl. The example uses one subroutine (eval_file()) to compile and run the program. This is unsuitable for a process like Nagios that fork a new process to run a plugin. (It is unsuitable because were the child process to call eval_file() and then the update its copy of %Cache, other child processes would not get the updated %Cache, and would therefore recompile the plugin). Instead, eval_file() is split into two: eval_file() and run_package(). Eval_file is called by the Nagios parent process to compile the plugin and update %Cache. Child processes forked in base/checks.c have the same copy of %Cache and call run_plugin() to check the last compilation error (from %Cache) and run the plugin if the plugin was error free. =item * Dealing with Perl programs that call exit This framework redefines exit() to die emitting a string containing the plugin return code (the first argument of exit). Since the plugin is run by eval(), B<$@> contains this string from which the return code is extracted. =item * Providing command line arguments to the Perl program This framework sets @ARGV in the B subroutine to the remaining subroutine arguments. All of these clever ideas came from, AFAIK, Stephen Davies. =back =head1 BUGS =item * MEMORY LEAK This framework does nothing to prevent the memory leaks mentioned in B, relying on operator intervention. Probably the best way of doing so is by periodically scheduling =over 4 =item 1 A check of the memory used by the Nagios process (by running for example the standard Nagios plugin check_procs) =item 2 Restarting Nagios with the (supplied with Nagios) startup script (restart command). =back If you do periodically restart Nagios, make sure that =over 4 =item 1 plugins all set the PATH environment variable if they need other system binaries (otherwise, if the init script is excec'd by cron, the PATH will be reset and the plugins will fail - but only when reatsrted by cron). =item 2 that the group owning the Nagios command pipe is the same as the Nagios group (otherwise, the restarted Nagios will not be able to read from the command pipe). =back Nagios installations using the persistence framework B monitor the memory use of the Nagios process and stop/start it when the usage is exorbidant (eg, for a site with 400 services on 200 hosts and custom Perl plugins used for about 10% of the service checks, the Nagios process uses ~80 MB after 20-30 days runningi with Perl 5.005 [Memory usage is B greater with recent Perls]. It is usually stopped and started at this point). Note that a HUP signal is B sufficient to deallocate the Perl memory; the Nagios process must be stopped and started. In fact, since HUP causes Nagios to re-run the Perl interpreter initialisation code, memory use increases significantly. B; use the 'restart' argument of the Nagios supplied startup script. There are all sorts of suprising gotchas about the debug logging including =over 4 =item * No dump of good plugins. Only plugins that fail to compile (after transformation) are dumped. =item * Cache dump is periodic The Cache is only dumped after the user specified number of plugin B. If plugins are not compiled, you get no dump of the cache. =item * Debug level set at compile time Nagios must be restarted to change the debug level (use the examples if you have a troublesome plugin;l you may need a debug copy of Nagios) =item * Not all Cached fields visible Always compile one more plugin to ensure that all the fields in the cache are set. =back =head1 SEE ALSO =over 4 =item * perlembed (section on maintaining a persistent interpreter) =item * examples in the examples/ directory including both C and Perl drivers that run Nagios plugins using p1.pl. =back =head1 AUTHOR Originally by Stephen Davies. Now maintained by Stanley Hopcroft who retains responsibility for the 'bad bits'. =head1 COPYRIGHT Copyright (c) 2004 Stanley Hopcroft. All rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =cut nagios-2.6/pkginfo.in0000664000076500007650000000032207436604416014173 0ustar nagiosnagiosPKG="nagios" VERSION="@VERSION@" NAME="Nagios @VERSION@" CLASSES="none" CATEGORY="utility" VENDOR="www.nagios.org" EMAIL="nagios-users@lists.sourceforge.net" ISTATES="S s 1 2 3" RSTATES="S s 1 2 3" BASEDIR="/" nagios-2.6/subst.in0000775000076500007650000000214507436604416013706 0ustar nagiosnagios#!/usr/bin/perl -w my ${exec_prefix}; my ${prefix}; ${prefix}="@prefix@"; ${exec_prefix}="@exec_prefix@"; while ($f = shift @ARGV) { if (-x "/bin/mktemp") { $TEMP = `/bin/mktemp $f.$$.XXXXXX`; die 'Cannot make temporary file $TEMP' if($?); chomp $TEMP; } else { $XXXXXX = rand; $TEMP = "$f.$$.$XXXXXX"; } open(IN,"<$f.in"); open(OUT,">$TEMP") || die 'Cannot make temporary file $TEMP'; while () { s|\@nagios_user\@|@nagios_user@|g; s|\@nagios_grp\@|@nagios_grp@|g; s|\@lockfile\@|@lockfile@|g; s|\@libexecdir\@|@libexecdir@|g; # put all --with-vars before directories s|\@localstatedir\@|@localstatedir@|g; s|\@sysconfdir\@|@sysconfdir@|g; s|\@datadir\@|@datadir@|g; s|\@sbindir\@|@sbindir@|g; s|\@bindir\@|@bindir@|g; s|\@htmurl\@|@htmurl@|g; s|\@cgiurl\@|@cgiurl@|g; s|\@MAIL_PROG\@|@MAIL_PROG@|g; s|\@VERSION\@|@VERSION@|g; s|\$\{exec_prefix\}|@exec_prefix@|g; # must be next to last s|\$\{prefix\}|@prefix@|g; # must be last print OUT $_; } close IN; close OUT; if ((! -e $f) || (`diff $f $TEMP`)) { `mv $TEMP $f`; } else { unlink $TEMP; } } nagios-2.6/update-version0000775000076500007650000000452310532717360015102 0ustar nagiosnagios#!/bin/sh # Get date (two formats) if [ -n "$2" ]; then LONGDATE=`date -d "$2" "+%B %d, %Y"` SHORTDATE=`date -d "$2" "+%m-%d-%Y"` else LONGDATE=`date "+%B %d, %Y"` SHORTDATE=`date "+%m-%d-%Y"` fi # Current version number CURRENTVERSION=2.6 # Last date LASTDATE=11-27-2006 if [ "x$1" = "x" ] then echo "Usage: $0 [revision date]" echo "" echo "Run this script with the name of the new version (i.e \"2.0b1\") to" echo "update version number and modification date in files." echo "Use the \"newdate\" argument if you want to keep the current version" echo "number and just update the modification date." echo "" echo "Current version=$CURRENTVERSION" echo "Current Modification date=$LASTDATE" echo "" exit 1 fi newversion=$1 if [ "x$newversion" = "xnewdate" ] then newversion=$CURRENTVERSION fi # Update version number and release date in main HTML page perl -i -p -e "s/>Version .*Version $newversion.*<\//releaseDate\">$LONGDATE<\//;" html/main.html # Update version number and release date in common code perl -i -p -e "s/VERSION \".*\"/VERSION \"$newversion\"/;" include/common.h perl -i -p -e "s/MODIFICATION_DATE \".*\"/MODIFICATION_DATE \"$SHORTDATE\"/;" include/common.h # Update version number and release date in main code perl -i -p -e "s/Version: .*/Version: $newversion/;" base/nagios.c perl -i -p -e "s/Last Modified: [0-9].*/Last Modified: $SHORTDATE/;" base/nagios.c perl -i -p -e "s/Version: [0-9].*/Version: $newversion/;" base/nagiostats.c perl -i -p -e "s/Last Modified: [0-9].*/Last Modified: $SHORTDATE/;" base/nagiostats.c # Update version number and release date in configure script and configure.in perl -i -p -e "s/PKG_VERSION=.*/PKG_VERSION=\"$newversion\"/;" configure perl -i -p -e "s/PKG_REL_DATE=.*\"/PKG_REL_DATE=\"$SHORTDATE\"/;" configure perl -i -p -e "s/PKG_VERSION=.*/PKG_VERSION=\"$newversion\"/;" configure.in perl -i -p -e "s/PKG_REL_DATE=.*\"/PKG_REL_DATE=\"$SHORTDATE\"/;" configure.in # Update RPM spec file with version number perl -i -p -e "s/%define version .*/%define version $newversion/;" nagios.spec # Update this file with version number and last date perl -i -p -e "s/^CURRENTVERSION=.*/CURRENTVERSION=$newversion/;" update-version perl -i -p -e "s/^LASTDATE=.*/LASTDATE=$SHORTDATE/;" update-version nagios-2.6/common/0000775000076500007650000000000010532717565013502 5ustar nagiosnagiosnagios-2.6/common/Makefile.in0000664000076500007650000000104507645164371015551 0ustar nagiosnagios############################ # Makefile for Nagios # # Last Modified: 04-08-2003 ############################ # Source code directories SRC_BASE=../common SRC_CGI=../cgi CC=@CC@ CFLAGS=@CFLAGS@ @DEFS@ LDFLAGS=@LDFLAGS@ @LIBS@ prefix=@prefix@ exec_prefix=@exec_prefix@ LOGDIR=@localstatedir@ CFGDIR=@sysconfdir@ BINDIR=@bindir@ CGIDIR=@sbindir@ HTMLDIR=@datadir@ INSTALL=@INSTALL@ INSTALL_OPTS=@INSTALL_OPTS@ COMMAND_OPTS=@COMMAND_OPTS@ CP=@CP@ clean: rm -f core *.o rm -f *~ distclean: clean rm -f Makefile devclean: distclean install: nagios-2.6/common/comments.c0000664000076500007650000004732210512470706015472 0ustar nagiosnagios/***************************************************************************** * * COMMENTS.C - Comment functions for Nagios * * Copyright (c) 1999-2006 Ethan Galstad (nagios@nagios.org) * Last Modified: 10-09-2006 * * 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. * *****************************************************************************/ #include "../include/config.h" #include "../include/common.h" #include "../include/comments.h" #include "../include/objects.h" /***** IMPLEMENTATION-SPECIFIC INCLUDES *****/ #ifdef USE_XCDDEFAULT #include "../xdata/xcddefault.h" #endif #ifdef NSCORE #include "../include/nagios.h" #include "../include/broker.h" #endif #ifdef NSCGI #include "../include/cgiutils.h" #endif comment *comment_list=NULL; comment **comment_hashlist=NULL; #ifdef NSCORE /******************************************************************/ /**************** INITIALIZATION/CLEANUP FUNCTIONS ****************/ /******************************************************************/ /* initializes comment data */ int initialize_comment_data(char *config_file){ int result=OK; /**** IMPLEMENTATION-SPECIFIC CALLS ****/ #ifdef USE_XCDDEFAULT result=xcddefault_initialize_comment_data(config_file); #endif return result; } /* removes old/invalid comments */ int cleanup_comment_data(char *config_file){ int result=OK; /**** IMPLEMENTATION-SPECIFIC CALLS ****/ #ifdef USE_XCDDEFAULT result=xcddefault_cleanup_comment_data(config_file); #endif return result; } /******************************************************************/ /****************** COMMENT OUTPUT FUNCTIONS **********************/ /******************************************************************/ /* adds a new host or service comment */ int add_new_comment(int type, int entry_type, char *host_name, char *svc_description, time_t entry_time, char *author_name, char *comment_data, int persistent, int source, int expires, time_t expire_time, unsigned long *comment_id){ int result=OK; unsigned long new_comment_id=0L; if(type==HOST_COMMENT) result=add_new_host_comment(entry_type,host_name,entry_time,author_name,comment_data,persistent,source,expires,expire_time,&new_comment_id); else result=add_new_service_comment(entry_type,host_name,svc_description,entry_time,author_name,comment_data,persistent,source,expires,expire_time,&new_comment_id); /* add an event to expire comment data if necessary... */ if(expires==TRUE) schedule_new_event(EVENT_EXPIRE_COMMENT,FALSE,expire_time,FALSE,0,NULL,TRUE,(void *)new_comment_id,NULL); /* save comment id */ if(comment_id!=NULL) *comment_id=new_comment_id; return result; } /* adds a new host comment */ int add_new_host_comment(int entry_type, char *host_name, time_t entry_time, char *author_name, char *comment_data, int persistent, int source, int expires, time_t expire_time, unsigned long *comment_id){ int result=OK; unsigned long new_comment_id=0L; /**** IMPLEMENTATION-SPECIFIC CALLS ****/ #ifdef USE_XCDDEFAULT result=xcddefault_add_new_host_comment(entry_type,host_name,entry_time,author_name,comment_data,persistent,source,expires,expire_time,&new_comment_id); #endif /* save comment id */ if(comment_id!=NULL) *comment_id=new_comment_id; #ifdef USE_EVENT_BROKER /* send data to event broker */ broker_comment_data(NEBTYPE_COMMENT_ADD,NEBFLAG_NONE,NEBATTR_NONE,HOST_COMMENT,entry_type,host_name,NULL,entry_time,author_name,comment_data,persistent,source,expires,expire_time,new_comment_id,NULL); #endif return result; } /* adds a new service comment */ int add_new_service_comment(int entry_type, char *host_name, char *svc_description, time_t entry_time, char *author_name, char *comment_data, int persistent, int source, int expires, time_t expire_time, unsigned long *comment_id){ int result=OK; unsigned long new_comment_id=0L; /**** IMPLEMENTATION-SPECIFIC CALLS ****/ #ifdef USE_XCDDEFAULT result=xcddefault_add_new_service_comment(entry_type,host_name,svc_description,entry_time,author_name,comment_data,persistent,source,expires,expire_time,&new_comment_id); #endif /* save comment id */ if(comment_id!=NULL) *comment_id=new_comment_id; #ifdef USE_EVENT_BROKER /* send data to event broker */ broker_comment_data(NEBTYPE_COMMENT_ADD,NEBFLAG_NONE,NEBATTR_NONE,SERVICE_COMMENT,entry_type,host_name,svc_description,entry_time,author_name,comment_data,persistent,source,expires,expire_time,new_comment_id,NULL); #endif return result; } /******************************************************************/ /***************** COMMENT DELETION FUNCTIONS *********************/ /******************************************************************/ /* deletes a host or service comment */ int delete_comment(int type, unsigned long comment_id){ int result=OK; comment *this_comment=NULL; comment *last_comment=NULL; comment *next_comment=NULL; int hashslot=0; comment *this_hash=NULL; comment *last_hash=NULL; /* find the comment we should remove */ for(this_comment=comment_list,last_comment=comment_list;this_comment!=NULL;this_comment=next_comment){ next_comment=this_comment->next; /* we found the comment we should delete */ if(this_comment->comment_id==comment_id && this_comment->comment_type==type) break; last_comment=this_comment; } /* remove the comment from the list in memory */ if(this_comment!=NULL){ #ifdef USE_EVENT_BROKER /* send data to event broker */ broker_comment_data(NEBTYPE_COMMENT_DELETE,NEBFLAG_NONE,NEBATTR_NONE,type,this_comment->entry_type,this_comment->host_name,this_comment->service_description,this_comment->entry_time,this_comment->author,this_comment->comment_data,this_comment->persistent,this_comment->source,this_comment->expires,this_comment->expire_time,comment_id,NULL); #endif /* first remove from chained hash list */ hashslot=hashfunc1(this_comment->host_name,COMMENT_HASHSLOTS); last_hash=NULL; for(this_hash=comment_hashlist[hashslot];this_hash;this_hash=this_hash->nexthash){ if(this_hash==this_comment){ if(last_hash) last_hash->nexthash=this_hash->nexthash; else comment_hashlist[hashslot]=NULL; break; } last_hash=this_hash; } /* then removed from linked list */ if(comment_list==this_comment) comment_list=this_comment->next; else last_comment->next=next_comment; /* free memory */ free(this_comment->host_name); free(this_comment->service_description); free(this_comment->author); free(this_comment->comment_data); free(this_comment); result=OK; } else result=ERROR; /**** IMPLEMENTATION-SPECIFIC CALLS ****/ #ifdef USE_XCDDEFAULT if(type==HOST_COMMENT) result=xcddefault_delete_host_comment(comment_id); else result=xcddefault_delete_service_comment(comment_id); #endif return result; } /* deletes a host comment */ int delete_host_comment(unsigned long comment_id){ int result=OK; /* delete the comment from memory */ result=delete_comment(HOST_COMMENT,comment_id); return result; } /* deletes a service comment */ int delete_service_comment(unsigned long comment_id){ int result=OK; /* delete the comment from memory */ result=delete_comment(SERVICE_COMMENT,comment_id); return result; } /* deletes all comments for a particular host or service */ int delete_all_comments(int type, char *host_name, char *svc_description){ int result=OK; if(type==HOST_COMMENT) result=delete_all_host_comments(host_name); else result=delete_all_service_comments(host_name,svc_description); return result; } /* deletes all comments for a particular host */ int delete_all_host_comments(char *host_name){ int result=OK; comment *temp_comment=NULL; if(host_name==NULL) return ERROR; /* delete host comments from memory */ for(temp_comment=get_first_comment_by_host(host_name);temp_comment!=NULL;temp_comment=get_next_comment_by_host(host_name,temp_comment)){ if(temp_comment->comment_type==HOST_COMMENT) delete_comment(HOST_COMMENT,temp_comment->comment_id); } /**** IMPLEMENTATION-SPECIFIC CALLS ****/ #ifdef USE_XCDDEFAULT result=xcddefault_delete_all_host_comments(host_name); #endif return result; } /* deletes all comments for a particular service */ int delete_all_service_comments(char *host_name, char *svc_description){ int result=OK; comment *temp_comment=NULL; comment *next_comment=NULL; if(host_name==NULL || svc_description==NULL) return ERROR; /* delete service comments from memory */ for(temp_comment=comment_list;temp_comment!=NULL;temp_comment=next_comment){ next_comment=temp_comment->next; if(temp_comment->comment_type==SERVICE_COMMENT && !strcmp(temp_comment->host_name,host_name) && !strcmp(temp_comment->service_description,svc_description)) delete_comment(SERVICE_COMMENT,temp_comment->comment_id); } #ifdef REMOVED_032106 for(temp_comment=get_first_comment_by_host(host_name);temp_comment!=NULL;temp_comment=get_next_comment_by_host(host_name,temp_comment)){ if(temp_comment->comment_type==SERVICE_COMMENT && !strcmp(temp_comment->service_description,svc_description)) delete_comment(SERVICE_COMMENT,temp_comment->comment_id); } #endif /**** IMPLEMENTATION-SPECIFIC CALLS ****/ #ifdef USE_XCDDEFAULT result=xcddefault_delete_all_service_comments(host_name,svc_description); #endif return result; } /* checks for an expired comment (and removes it) */ int check_for_expired_comment(unsigned long comment_id){ comment *temp_comment=NULL; /* check all comments */ for(temp_comment=comment_list;temp_comment!=NULL;temp_comment=temp_comment->next){ /* delete the now expired comment */ if(temp_comment->comment_id==comment_id && temp_comment->expires==TRUE && temp_comment->expire_timecomment_type,comment_id); break; } } return OK; } #endif /******************************************************************/ /********************** INPUT FUNCTIONS ***************************/ /******************************************************************/ int read_comment_data(char *main_config_file){ int result=OK; /**** IMPLEMENTATION-SPECIFIC CALLS ****/ #ifdef USE_XCDDEFAULT result=xcddefault_read_comment_data(main_config_file); #endif return result; } /******************************************************************/ /****************** CHAINED HASH FUNCTIONS ************************/ /******************************************************************/ /* adds comment to hash list in memory */ int add_comment_to_hashlist(comment *new_comment){ comment *temp_comment=NULL; comment *lastpointer=NULL; int hashslot=0; /* initialize hash list */ if(comment_hashlist==NULL){ int i; comment_hashlist=(comment **)malloc(sizeof(comment *)*COMMENT_HASHSLOTS); if(comment_hashlist==NULL) return 0; for(i=0;ihost_name,COMMENT_HASHSLOTS); lastpointer=NULL; for(temp_comment=comment_hashlist[hashslot];temp_comment && compare_hashdata1(temp_comment->host_name,new_comment->host_name)<0;temp_comment=temp_comment->nexthash){ if(compare_hashdata1(temp_comment->host_name,new_comment->host_name)>=0) break; lastpointer=temp_comment; } /* multiples are allowed */ if(lastpointer) lastpointer->nexthash=new_comment; else comment_hashlist[hashslot]=new_comment; new_comment->nexthash=temp_comment; return 1; } /******************************************************************/ /******************** ADDITION FUNCTIONS **************************/ /******************************************************************/ /* adds a host comment to the list in memory */ int add_host_comment(int entry_type, char *host_name, time_t entry_time, char *author, char *comment_data, unsigned long comment_id, int persistent, int expires, time_t expire_time, int source){ int result=OK; result=add_comment(HOST_COMMENT,entry_type,host_name,NULL,entry_time,author,comment_data,comment_id,persistent,expires,expire_time,source); return result; } /* adds a service comment to the list in memory */ int add_service_comment(int entry_type, char *host_name, char *svc_description, time_t entry_time, char *author, char *comment_data, unsigned long comment_id, int persistent, int expires, time_t expire_time, int source){ int result=OK; result=add_comment(SERVICE_COMMENT,entry_type,host_name,svc_description,entry_time,author,comment_data,comment_id,persistent,expires,expire_time,source); return result; } /* adds a comment to the list in memory */ int add_comment(int comment_type, int entry_type, char *host_name, char *svc_description, time_t entry_time, char *author, char *comment_data, unsigned long comment_id, int persistent, int expires, time_t expire_time, int source){ comment *new_comment=NULL; comment *last_comment=NULL; comment *temp_comment=NULL; /* make sure we have the data we need */ if(host_name==NULL || author==NULL || comment_data==NULL || (comment_type==SERVICE_COMMENT && svc_description==NULL)) return ERROR; /* allocate memory for the comment */ new_comment=(comment *)malloc(sizeof(comment)); if(new_comment==NULL) return ERROR; new_comment->host_name=strdup(host_name); if(new_comment->host_name==NULL){ free(new_comment); return ERROR; } if(comment_type==SERVICE_COMMENT){ new_comment->service_description=strdup(svc_description); if(new_comment->service_description==NULL){ free(new_comment->host_name); free(new_comment); return ERROR; } } else new_comment->service_description=NULL; new_comment->author=strdup(author); if(new_comment->author==NULL){ if(new_comment->service_description!=NULL) free(new_comment->service_description); free(new_comment->host_name); free(new_comment); return ERROR; } new_comment->comment_data=strdup(comment_data); if(new_comment->comment_data==NULL){ free(new_comment->author); if(new_comment->service_description!=NULL) free(new_comment->service_description); free(new_comment->host_name); free(new_comment); return ERROR; } new_comment->comment_type=comment_type; new_comment->entry_type=entry_type; new_comment->source=source; new_comment->entry_time=entry_time; new_comment->comment_id=comment_id; new_comment->persistent=(persistent==TRUE)?TRUE:FALSE; new_comment->expires=(expires==TRUE)?TRUE:FALSE; new_comment->expire_time=expire_time; new_comment->next=NULL; new_comment->nexthash=NULL; /* add comment to hash list */ if(!add_comment_to_hashlist(new_comment)) return ERROR; /* add new comment to comment list, sorted by comment id */ last_comment=comment_list; for(temp_comment=comment_list;temp_comment!=NULL;temp_comment=temp_comment->next){ if(new_comment->comment_idcomment_id){ new_comment->next=temp_comment; if(temp_comment==comment_list) comment_list=new_comment; else last_comment->next=new_comment; break; } else last_comment=temp_comment; } if(comment_list==NULL){ new_comment->next=NULL; comment_list=new_comment; } else if(temp_comment==NULL){ new_comment->next=NULL; last_comment->next=new_comment; } #ifdef NSCORE #ifdef USE_EVENT_BROKER /* send data to event broker */ broker_comment_data(NEBTYPE_COMMENT_LOAD,NEBFLAG_NONE,NEBATTR_NONE,comment_type,entry_type,host_name,svc_description,entry_time,author,comment_data,persistent,source,expires,entry_time,comment_id,NULL); #endif #endif return OK; } /******************************************************************/ /********************* CLEANUP FUNCTIONS **************************/ /******************************************************************/ /* frees memory allocated for the comment data */ void free_comment_data(void){ comment *this_comment=NULL; comment *next_comment=NULL; /* free memory for the comment list */ for(this_comment=comment_list;this_comment!=NULL;this_comment=next_comment){ next_comment=this_comment->next; free(this_comment->host_name); free(this_comment->service_description); free(this_comment->author); free(this_comment->comment_data); free(this_comment); } /* free hash list and reset list pointer */ free(comment_hashlist); comment_hashlist=NULL; comment_list=NULL; return; } /******************************************************************/ /********************* UTILITY FUNCTIONS **************************/ /******************************************************************/ /* get the number of comments associated with a particular host */ int number_of_host_comments(char *host_name){ comment *temp_comment=NULL; int total_comments=0; if(host_name==NULL) return 0; for(temp_comment=get_first_comment_by_host(host_name);temp_comment!=NULL;temp_comment=get_next_comment_by_host(host_name,temp_comment)){ if(temp_comment->comment_type==HOST_COMMENT) total_comments++; } return total_comments; } /* get the number of comments associated with a particular service */ int number_of_service_comments(char *host_name, char *svc_description){ comment *temp_comment=NULL; int total_comments=0; if(host_name==NULL || svc_description==NULL) return 0; for(temp_comment=get_first_comment_by_host(host_name);temp_comment!=NULL;temp_comment=get_next_comment_by_host(host_name,temp_comment)){ if(temp_comment->comment_type==SERVICE_COMMENT && !strcmp(temp_comment->service_description,svc_description)) total_comments++; } return total_comments; } /******************************************************************/ /********************* TRAVERSAL FUNCTIONS ************************/ /******************************************************************/ comment *get_first_comment_by_host(char *host_name){ return get_next_comment_by_host(host_name,NULL); } comment *get_next_comment_by_host(char *host_name, comment *start){ comment *temp_comment; if(host_name==NULL || comment_hashlist==NULL) return NULL; if(start==NULL) temp_comment=comment_hashlist[hashfunc1(host_name,COMMENT_HASHSLOTS)]; else temp_comment=start->nexthash; for(;temp_comment && compare_hashdata1(temp_comment->host_name,host_name)<0;temp_comment=temp_comment->nexthash); if(temp_comment && compare_hashdata1(temp_comment->host_name,host_name)==0) return temp_comment; return NULL; } /******************************************************************/ /********************** SEARCH FUNCTIONS **************************/ /******************************************************************/ /* find a service comment by id */ comment *find_service_comment(unsigned long comment_id){ return find_comment(comment_id,SERVICE_COMMENT); } /* find a host comment by id */ comment *find_host_comment(unsigned long comment_id){ return find_comment(comment_id,HOST_COMMENT); } /* find a comment by id */ comment *find_comment(unsigned long comment_id, int comment_type){ comment *temp_comment=NULL; for(temp_comment=comment_list;temp_comment!=NULL;temp_comment=temp_comment->next){ if(temp_comment->comment_id==comment_id && temp_comment->comment_type==comment_type) return temp_comment; } return NULL; } nagios-2.6/common/downtime.c0000664000076500007650000007611110463767476015513 0ustar nagiosnagios/***************************************************************************** * * DOWNTIME.C - Scheduled downtime functions for Nagios * * Copyright (c) 2000-2005 Ethan Galstad (nagios@nagios.org) * Last Modified: 08-01-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. * *****************************************************************************/ #include "../include/config.h" #include "../include/common.h" #include "../include/comments.h" #include "../include/downtime.h" #include "../include/objects.h" #include "../include/statusdata.h" /***** IMPLEMENTATION-SPECIFIC INCLUDES *****/ #ifdef USE_XDDDEFAULT #include "../xdata/xdddefault.h" #endif #ifdef NSCORE #include "../include/nagios.h" #include "../include/broker.h" #endif #ifdef NSCGI #include "../include/cgiutils.h" #endif scheduled_downtime *scheduled_downtime_list=NULL; #ifdef NSCORE extern timed_event *event_list_high; #endif #ifdef NSCORE /******************************************************************/ /**************** INITIALIZATION/CLEANUP FUNCTIONS ****************/ /******************************************************************/ /* initializes scheduled downtime data */ int initialize_downtime_data(char *config_file){ int result; /**** IMPLEMENTATION-SPECIFIC CALLS ****/ #ifdef USE_XDDDEFAULT result=xdddefault_initialize_downtime_data(config_file); #endif return result; } /* cleans up scheduled downtime data */ int cleanup_downtime_data(char *config_file){ int result; /**** IMPLEMENTATION-SPECIFIC CALLS ****/ #ifdef USE_XDDDEFAULT result=xdddefault_cleanup_downtime_data(config_file); #endif /* free memory allocated to downtime data */ free_downtime_data(); return result; } /******************************************************************/ /********************** SCHEDULING FUNCTIONS **********************/ /******************************************************************/ /* schedules a host or service downtime */ int schedule_downtime(int type, char *host_name, char *service_description, time_t entry_time, char *author, char *comment_data, time_t start_time, time_t end_time, int fixed, unsigned long triggered_by, unsigned long duration, unsigned long *new_downtime_id){ unsigned long downtime_id; /* don't add old or invalid downtimes */ if(start_time>=end_time || end_time<=time(NULL)) return ERROR; /* add a new downtime entry */ add_new_downtime(type,host_name,service_description,entry_time,author,comment_data,start_time,end_time,fixed,triggered_by,duration,&downtime_id); /* register the scheduled downtime */ register_downtime(type,downtime_id); /* return downtime id */ if(new_downtime_id!=NULL) *new_downtime_id=downtime_id; return OK; } /* unschedules a host or service downtime */ int unschedule_downtime(int type,unsigned long downtime_id){ scheduled_downtime *temp_downtime; scheduled_downtime *event_downtime; host *hst=NULL; service *svc=NULL; timed_event *temp_event; char temp_buffer[MAX_INPUT_BUFFER]; #ifdef USE_EVENT_BROKER int attr; #endif /* find the downtime entry in the list in memory */ temp_downtime=find_downtime(type,downtime_id); if(temp_downtime==NULL) return ERROR; /* find the host or service associated with this downtime */ if(temp_downtime->type==HOST_DOWNTIME){ hst=find_host(temp_downtime->host_name); if(hst==NULL) return ERROR; } else{ svc=find_service(temp_downtime->host_name,temp_downtime->service_description); if(svc==NULL) return ERROR; } /* decrement pending flex downtime if necessary ... */ if(temp_downtime->fixed==FALSE && temp_downtime->incremented_pending_downtime==TRUE){ if(temp_downtime->type==HOST_DOWNTIME) hst->pending_flex_downtime--; else svc->pending_flex_downtime--; } /* decrement the downtime depth variable and update status data if necessary */ if(temp_downtime->is_in_effect==TRUE){ #ifdef USE_EVENT_BROKER /* send data to event broker */ attr=NEBATTR_DOWNTIME_STOP_CANCELLED; broker_downtime_data(NEBTYPE_DOWNTIME_STOP,NEBFLAG_NONE,attr,temp_downtime->type,temp_downtime->host_name,temp_downtime->service_description,temp_downtime->entry_time,temp_downtime->author,temp_downtime->comment,temp_downtime->start_time,temp_downtime->end_time,temp_downtime->fixed,temp_downtime->triggered_by,temp_downtime->duration,temp_downtime->downtime_id,NULL); #endif if(temp_downtime->type==HOST_DOWNTIME){ hst->scheduled_downtime_depth--; update_host_status(hst,FALSE); /* log a notice - this is parsed by the history CGI */ if(hst->scheduled_downtime_depth==0){ snprintf(temp_buffer,sizeof(temp_buffer),"HOST DOWNTIME ALERT: %s;CANCELLED; Scheduled downtime for host has been cancelled.\n",hst->name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_all_logs(temp_buffer,NSLOG_INFO_MESSAGE); } } else{ svc->scheduled_downtime_depth--; update_service_status(svc,FALSE); /* log a notice - this is parsed by the history CGI */ if(svc->scheduled_downtime_depth==0){ snprintf(temp_buffer,sizeof(temp_buffer),"SERVICE DOWNTIME ALERT: %s;%s;CANCELLED; Scheduled downtime for service has been cancelled.\n",svc->host_name,svc->description); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_all_logs(temp_buffer,NSLOG_INFO_MESSAGE); } } } /* remove scheduled entry from event queue */ for(temp_event=event_list_high;temp_event!=NULL;temp_event=temp_event->next){ if(temp_event->event_type!=EVENT_SCHEDULED_DOWNTIME) continue; event_downtime=(scheduled_downtime *)temp_event->event_data; if(event_downtime->type!=temp_downtime->type) continue; if(event_downtime->downtime_id==downtime_id) break; } if(temp_event!=NULL) remove_event(temp_event,&event_list_high); /* delete downtime entry */ if(temp_downtime->type==HOST_DOWNTIME) delete_host_downtime(downtime_id); else delete_service_downtime(downtime_id); /* unschedule all downtime entries that were triggered by this one */ for(temp_downtime=scheduled_downtime_list;temp_downtime!=NULL;temp_downtime=temp_downtime->next){ if(temp_downtime->triggered_by==downtime_id) unschedule_downtime(ANY_DOWNTIME,temp_downtime->downtime_id); } return OK; } /* registers scheduled downtime (schedules it, adds comments, etc.) */ int register_downtime(int type, unsigned long downtime_id){ char temp_buffer[MAX_INPUT_BUFFER]; char start_time_string[MAX_DATETIME_LENGTH]; char end_time_string[MAX_DATETIME_LENGTH]; scheduled_downtime *temp_downtime; host *hst=NULL; service *svc=NULL; char *type_string=""; int hours; int minutes; /* find the downtime entry in memory */ temp_downtime=find_downtime(type,downtime_id); if(temp_downtime==NULL) return ERROR; /* find the host or service associated with this downtime */ if(temp_downtime->type==HOST_DOWNTIME){ hst=find_host(temp_downtime->host_name); if(hst==NULL) return ERROR; } else{ svc=find_service(temp_downtime->host_name,temp_downtime->service_description); if(svc==NULL) return ERROR; } /* create the comment */ get_datetime_string(&(temp_downtime->start_time),start_time_string,MAX_DATETIME_LENGTH,SHORT_DATE_TIME); get_datetime_string(&(temp_downtime->end_time),end_time_string,MAX_DATETIME_LENGTH,SHORT_DATE_TIME); hours=temp_downtime->duration/3600; minutes=((temp_downtime->duration-(hours*3600))/60); if(temp_downtime->type==HOST_DOWNTIME) type_string="host"; else type_string="service"; if(temp_downtime->fixed==TRUE){ snprintf(temp_buffer,sizeof(temp_buffer)-1,"This %s has been scheduled for fixed downtime from %s to %s. Notifications for the %s will not be sent out during that time period.",type_string,start_time_string,end_time_string,type_string); } else{ snprintf(temp_buffer,sizeof(temp_buffer)-1,"This %s has been scheduled for flexible downtime starting between %s and %s and lasting for a period of %d hours and %d minutes. Notifications for the %s will not be sent out during that time period.",type_string,start_time_string,end_time_string,hours,minutes,type_string); } temp_buffer[sizeof(temp_buffer)-1]='\x0'; /* add a non-persistent comment to the host or service regarding the scheduled outage */ if(temp_downtime->type==SERVICE_DOWNTIME) add_new_comment(SERVICE_COMMENT,DOWNTIME_COMMENT,svc->host_name,svc->description,time(NULL),"(Nagios Process)",temp_buffer,0,COMMENTSOURCE_INTERNAL,FALSE,(time_t)0,&(temp_downtime->comment_id)); else add_new_comment(HOST_COMMENT,DOWNTIME_COMMENT,hst->name,NULL,time(NULL),"(Nagios Process)",temp_buffer,0,COMMENTSOURCE_INTERNAL,FALSE,(time_t)0,&(temp_downtime->comment_id)); /*** SCHEDULE DOWNTIME - FLEXIBLE (NON-FIXED) DOWNTIME IS HANDLED AT A LATER POINT ***/ /* only non-triggered downtime is scheduled... */ if(temp_downtime->triggered_by==0) schedule_new_event(EVENT_SCHEDULED_DOWNTIME,TRUE,temp_downtime->start_time,FALSE,0,NULL,FALSE,(void *)temp_downtime,NULL); return OK; } /* handles scheduled host or service downtime */ int handle_scheduled_downtime(scheduled_downtime *temp_downtime){ char buffer[MAX_INPUT_BUFFER]; scheduled_downtime *this_downtime; host *hst=NULL; service *svc=NULL; time_t event_time; #ifdef USE_EVENT_BROKER int attr; #endif #ifdef DEBUG0 printf("handle_scheduled_downtime() start\n"); #endif if(temp_downtime==NULL) return ERROR; /* find the host or service associated with this downtime */ if(temp_downtime->type==HOST_DOWNTIME){ hst=find_host(temp_downtime->host_name); if(hst==NULL) return ERROR; } else{ svc=find_service(temp_downtime->host_name,temp_downtime->service_description); if(svc==NULL) return ERROR; } /* if downtime if flexible and host/svc is in an ok state, don't do anything right now (wait for event handler to kill it off) */ /* start_flex_downtime variable is set to TRUE by event handler functions */ if(temp_downtime->fixed==FALSE){ /* we're not supposed to force a start of flex downtime... */ if(temp_downtime->start_flex_downtime==FALSE){ /* host is up or service is ok, so we don't really do anything right now */ if((temp_downtime->type==HOST_DOWNTIME && hst->current_state==HOST_UP) || (temp_downtime->type==SERVICE_DOWNTIME && svc->current_state==STATE_OK)){ /* increment pending flex downtime counter */ if(temp_downtime->type==HOST_DOWNTIME) hst->pending_flex_downtime++; else svc->pending_flex_downtime++; temp_downtime->incremented_pending_downtime=TRUE; /*** SINCE THE FLEX DOWNTIME MAY NEVER START, WE HAVE TO PROVIDE A WAY OF EXPIRING UNUSED DOWNTIME... ***/ schedule_new_event(EVENT_EXPIRE_DOWNTIME,TRUE,(temp_downtime->end_time+1),FALSE,0,NULL,FALSE,NULL,NULL); return OK; } } } /* have we come to the end of the scheduled downtime? */ if(temp_downtime->is_in_effect==TRUE){ #ifdef USE_EVENT_BROKER /* send data to event broker */ attr=NEBATTR_DOWNTIME_STOP_NORMAL; broker_downtime_data(NEBTYPE_DOWNTIME_STOP,NEBFLAG_NONE,attr,temp_downtime->type,temp_downtime->host_name,temp_downtime->service_description,temp_downtime->entry_time,temp_downtime->author,temp_downtime->comment,temp_downtime->start_time,temp_downtime->end_time,temp_downtime->fixed,temp_downtime->triggered_by,temp_downtime->duration,temp_downtime->downtime_id,NULL); #endif /* decrement the downtime depth variable */ if(temp_downtime->type==HOST_DOWNTIME) hst->scheduled_downtime_depth--; else svc->scheduled_downtime_depth--; if(temp_downtime->type==HOST_DOWNTIME && hst->scheduled_downtime_depth==0){ /* log a notice - this one is parsed by the history CGI */ snprintf(buffer,sizeof(buffer),"HOST DOWNTIME ALERT: %s;STOPPED; Host has exited from a period of scheduled downtime",hst->name); buffer[sizeof(buffer)-1]='\x0'; write_to_all_logs(buffer,NSLOG_INFO_MESSAGE); } else if(temp_downtime->type==SERVICE_DOWNTIME && svc->scheduled_downtime_depth==0){ /* log a notice - this one is parsed by the history CGI */ snprintf(buffer,sizeof(buffer),"SERVICE DOWNTIME ALERT: %s;%s;STOPPED; Service has exited from a period of scheduled downtime",svc->host_name,svc->description); buffer[sizeof(buffer)-1]='\x0'; write_to_all_logs(buffer,NSLOG_INFO_MESSAGE); } /* update the status data */ if(temp_downtime->type==HOST_DOWNTIME) update_host_status(hst,FALSE); else update_service_status(svc,FALSE); /* decrement pending flex downtime if necessary */ if(temp_downtime->fixed==FALSE && temp_downtime->incremented_pending_downtime==TRUE){ if(temp_downtime->type==HOST_DOWNTIME){ if(hst->pending_flex_downtime>0) hst->pending_flex_downtime--; } else{ if(svc->pending_flex_downtime>0) svc->pending_flex_downtime--; } } /* delete downtime entry from the log */ if(temp_downtime->type==HOST_DOWNTIME) delete_host_downtime(temp_downtime->downtime_id); else delete_service_downtime(temp_downtime->downtime_id); /* handle (stop) downtime that is triggered by this one */ for(this_downtime=scheduled_downtime_list;this_downtime!=NULL;this_downtime=this_downtime->next){ if(this_downtime->triggered_by==temp_downtime->downtime_id) handle_scheduled_downtime(this_downtime); } } /* else we are just starting the scheduled downtime */ else{ #ifdef USE_EVENT_BROKER /* send data to event broker */ broker_downtime_data(NEBTYPE_DOWNTIME_START,NEBFLAG_NONE,NEBATTR_NONE,temp_downtime->type,temp_downtime->host_name,temp_downtime->service_description,temp_downtime->entry_time,temp_downtime->author,temp_downtime->comment,temp_downtime->start_time,temp_downtime->end_time,temp_downtime->fixed,temp_downtime->triggered_by,temp_downtime->duration,temp_downtime->downtime_id,NULL); #endif if(temp_downtime->type==HOST_DOWNTIME && hst->scheduled_downtime_depth==0){ /* log a notice - this one is parsed by the history CGI */ snprintf(buffer,sizeof(buffer),"HOST DOWNTIME ALERT: %s;STARTED; Host has entered a period of scheduled downtime",hst->name); buffer[sizeof(buffer)-1]='\x0'; write_to_all_logs(buffer,NSLOG_INFO_MESSAGE); } else if(temp_downtime->type==SERVICE_DOWNTIME && svc->scheduled_downtime_depth==0){ /* log a notice - this one is parsed by the history CGI */ snprintf(buffer,sizeof(buffer),"SERVICE DOWNTIME ALERT: %s;%s;STARTED; Service has entered a period of scheduled downtime",svc->host_name,svc->description); buffer[sizeof(buffer)-1]='\x0'; write_to_all_logs(buffer,NSLOG_INFO_MESSAGE); } /* increment the downtime depth variable */ if(temp_downtime->type==HOST_DOWNTIME) hst->scheduled_downtime_depth++; else svc->scheduled_downtime_depth++; /* set the in effect flag */ temp_downtime->is_in_effect=TRUE; /* update the status data */ if(temp_downtime->type==HOST_DOWNTIME) update_host_status(hst,FALSE); else update_service_status(svc,FALSE); /* schedule an event */ if(temp_downtime->fixed==FALSE) event_time=(time_t)((unsigned long)time(NULL)+temp_downtime->duration); else event_time=temp_downtime->end_time; schedule_new_event(EVENT_SCHEDULED_DOWNTIME,TRUE,event_time,FALSE,0,NULL,FALSE,(void *)temp_downtime,NULL); /* handle (start) downtime that is triggered by this one */ for(this_downtime=scheduled_downtime_list;this_downtime!=NULL;this_downtime=this_downtime->next){ if(this_downtime->triggered_by==temp_downtime->downtime_id) handle_scheduled_downtime(this_downtime); } } #ifdef DEBUG0 printf("handle_scheduled_downtime() end\n"); #endif return OK; } /* checks for flexible (non-fixed) host downtime that should start now */ int check_pending_flex_host_downtime(host *hst){ scheduled_downtime *temp_downtime; time_t current_time; #ifdef DEBUG0 printf("check_pending_flex_host_downtime() start\n"); #endif if(hst==NULL) return ERROR; time(¤t_time); /* if host is currently up, nothing to do */ if(hst->current_state==HOST_UP) return OK; /* check all downtime entries */ for(temp_downtime=scheduled_downtime_list;temp_downtime!=NULL;temp_downtime=temp_downtime->next){ if(temp_downtime->type!=HOST_DOWNTIME) continue; if(temp_downtime->fixed==TRUE) continue; if(temp_downtime->is_in_effect==TRUE) continue; /* triggered downtime entries should be ignored here */ if(temp_downtime->triggered_by!=0) continue; /* this entry matches our host! */ if(find_host(temp_downtime->host_name)==hst){ /* if the time boundaries are okay, start this scheduled downtime */ if(temp_downtime->start_time<=current_time && current_time<=temp_downtime->end_time){ temp_downtime->start_flex_downtime=TRUE; handle_scheduled_downtime(temp_downtime); } } } #ifdef DEBUG0 printf("check_pending_flex_host_downtime() end\n"); #endif return OK; } /* checks for flexible (non-fixed) service downtime that should start now */ int check_pending_flex_service_downtime(service *svc){ scheduled_downtime *temp_downtime; time_t current_time; #ifdef DEBUG0 printf("check_pending_flex_service_downtime() start\n"); #endif if(svc==NULL) return ERROR; time(¤t_time); /* if service is currently ok, nothing to do */ if(svc->current_state==STATE_OK) return OK; /* check all downtime entries */ for(temp_downtime=scheduled_downtime_list;temp_downtime!=NULL;temp_downtime=temp_downtime->next){ if(temp_downtime->type!=SERVICE_DOWNTIME) continue; if(temp_downtime->fixed==TRUE) continue; if(temp_downtime->is_in_effect==TRUE) continue; /* triggered downtime entries should be ignored here */ if(temp_downtime->triggered_by!=0) continue; /* this entry matches our service! */ if(find_service(temp_downtime->host_name,temp_downtime->service_description)==svc){ /* if the time boundaries are okay, start this scheduled downtime */ if(temp_downtime->start_time<=current_time && current_time<=temp_downtime->end_time){ temp_downtime->start_flex_downtime=TRUE; handle_scheduled_downtime(temp_downtime); } } } #ifdef DEBUG0 printf("check_pending_flex_service_downtime() end\n"); #endif return OK; } /* checks for (and removes) expired downtime entries */ int check_for_expired_downtime(void){ scheduled_downtime *temp_downtime; scheduled_downtime *next_downtime; time_t current_time; #ifdef DEBUG0 printf("check_for_expired_downtime() start\n"); #endif time(¤t_time); /* check all downtime entries... */ for(temp_downtime=scheduled_downtime_list;temp_downtime!=NULL;temp_downtime=next_downtime){ next_downtime=temp_downtime->next; /* this entry should be removed */ if(temp_downtime->is_in_effect==FALSE && temp_downtime->end_timetype==HOST_DOWNTIME) delete_host_downtime(temp_downtime->downtime_id); else delete_service_downtime(temp_downtime->downtime_id); } } #ifdef DEBUG0 printf("check_for_expired_downtime() end\n"); #endif return OK; } /******************************************************************/ /************************* SAVE FUNCTIONS *************************/ /******************************************************************/ /* save a host or service downtime */ int add_new_downtime(int type, char *host_name, char *service_description, time_t entry_time, char *author, char *comment_data, time_t start_time, time_t end_time, int fixed, unsigned long triggered_by, unsigned long duration, unsigned long *downtime_id){ int result; if(type==HOST_DOWNTIME) result=add_new_host_downtime(host_name,entry_time,author,comment_data,start_time,end_time,fixed,triggered_by,duration,downtime_id); else result=add_new_service_downtime(host_name,service_description,entry_time,author,comment_data,start_time,end_time,fixed,triggered_by,duration,downtime_id); return result; } /* saves a host downtime entry */ int add_new_host_downtime(char *host_name, time_t entry_time, char *author, char *comment_data, time_t start_time, time_t end_time, int fixed, unsigned long triggered_by, unsigned long duration, unsigned long *downtime_id){ int result; unsigned long new_downtime_id; if(host_name==NULL) return ERROR; /**** IMPLEMENTATION-SPECIFIC CALLS ****/ #ifdef USE_XDDDEFAULT result=xdddefault_add_new_host_downtime(host_name,entry_time,author,comment_data,start_time,end_time,fixed,triggered_by,duration,&new_downtime_id); #endif /* save downtime id */ if(downtime_id!=NULL) *downtime_id=new_downtime_id; #ifdef USE_EVENT_BROKER /* send data to event broker */ broker_downtime_data(NEBTYPE_DOWNTIME_ADD,NEBFLAG_NONE,NEBATTR_NONE,HOST_DOWNTIME,host_name,NULL,entry_time,author,comment_data,start_time,end_time,fixed,triggered_by,duration,new_downtime_id,NULL); #endif return result; } /* saves a service downtime entry */ int add_new_service_downtime(char *host_name, char *service_description, time_t entry_time, char *author, char *comment_data, time_t start_time, time_t end_time, int fixed, unsigned long triggered_by, unsigned long duration, unsigned long *downtime_id){ int result; unsigned long new_downtime_id; if(host_name==NULL || service_description==NULL) return ERROR; /**** IMPLEMENTATION-SPECIFIC CALLS ****/ #ifdef USE_XDDDEFAULT result=xdddefault_add_new_service_downtime(host_name,service_description,entry_time,author,comment_data,start_time,end_time,fixed,triggered_by,duration,&new_downtime_id); #endif /* save downtime id */ if(downtime_id!=NULL) *downtime_id=new_downtime_id; #ifdef USE_EVENT_BROKER /* send data to event broker */ broker_downtime_data(NEBTYPE_DOWNTIME_ADD,NEBFLAG_NONE,NEBATTR_NONE,SERVICE_DOWNTIME,host_name,service_description,entry_time,author,comment_data,start_time,end_time,fixed,triggered_by,duration,new_downtime_id,NULL); #endif return result; } /******************************************************************/ /*********************** DELETION FUNCTIONS ***********************/ /******************************************************************/ /* deletes a scheduled host or service downtime entry from the list in memory */ int delete_downtime(int type,unsigned long downtime_id){ int result; scheduled_downtime *this_downtime=NULL; scheduled_downtime *last_downtime=NULL; scheduled_downtime *next_downtime=NULL; /* find the downtime we should remove */ for(this_downtime=scheduled_downtime_list,last_downtime=scheduled_downtime_list;this_downtime!=NULL;this_downtime=next_downtime){ next_downtime=this_downtime->next; /* we found the downtime we should delete */ if(this_downtime->downtime_id==downtime_id && this_downtime->type==type) break; last_downtime=this_downtime; } /* remove the downtime from the list in memory */ if(this_downtime!=NULL){ /* first remove the comment associated with this downtime */ if(this_downtime->type==HOST_DOWNTIME) delete_host_comment(this_downtime->comment_id); else delete_service_comment(this_downtime->comment_id); #ifdef USE_EVENT_BROKER /* send data to event broker */ broker_downtime_data(NEBTYPE_DOWNTIME_DELETE,NEBFLAG_NONE,NEBATTR_NONE,type,this_downtime->host_name,this_downtime->service_description,this_downtime->entry_time,this_downtime->author,this_downtime->comment,this_downtime->start_time,this_downtime->end_time,this_downtime->fixed,this_downtime->triggered_by,this_downtime->duration,downtime_id,NULL); #endif if(scheduled_downtime_list==this_downtime) scheduled_downtime_list=this_downtime->next; else last_downtime->next=next_downtime; /* free memory */ free(this_downtime->host_name); free(this_downtime->service_description); free(this_downtime->author); free(this_downtime->comment); free(this_downtime); result=OK; } else result=ERROR; return result; } /* deletes a scheduled host downtime entry */ int delete_host_downtime(unsigned long downtime_id){ int result; /* delete the downtime from memory */ delete_downtime(HOST_DOWNTIME,downtime_id); /**** IMPLEMENTATION-SPECIFIC CALLS ****/ #ifdef USE_XDDDEFAULT result=xdddefault_delete_host_downtime(downtime_id); #endif return result; } /* deletes a scheduled service downtime entry */ int delete_service_downtime(unsigned long downtime_id){ int result; /* delete the downtime from memory */ delete_downtime(SERVICE_DOWNTIME,downtime_id); /**** IMPLEMENTATION-SPECIFIC CALLS ****/ #ifdef USE_XDDDEFAULT result=xdddefault_delete_service_downtime(downtime_id); #endif return result; } #endif #ifdef NSCGI /******************************************************************/ /************************ INPUT FUNCTIONS *************************/ /******************************************************************/ /* reads all downtime data */ int read_downtime_data(char *main_config_file){ int result; /**** IMPLEMENTATION-SPECIFIC CALLS ****/ #ifdef USE_XDDDEFAULT result=xdddefault_read_downtime_data(main_config_file); #endif return result; } #endif /******************************************************************/ /******************** ADDITION FUNCTIONS **************************/ /******************************************************************/ /* adds a host downtime entry to the list in memory */ int add_host_downtime(char *host_name, time_t entry_time, char *author, char *comment_data, time_t start_time, time_t end_time, int fixed, unsigned long triggered_by, unsigned long duration, unsigned long downtime_id){ int result; result=add_downtime(HOST_DOWNTIME,host_name,NULL,entry_time,author,comment_data,start_time,end_time,fixed,triggered_by,duration,downtime_id); return result; } /* adds a service downtime entry to the list in memory */ int add_service_downtime(char *host_name, char *svc_description, time_t entry_time, char *author, char *comment_data, time_t start_time, time_t end_time, int fixed, unsigned long triggered_by, unsigned long duration, unsigned long downtime_id){ int result; result=add_downtime(SERVICE_DOWNTIME,host_name,svc_description,entry_time,author,comment_data,start_time,end_time,fixed,triggered_by,duration,downtime_id); return result; } /* adds a host or service downtime entry to the list in memory */ int add_downtime(int downtime_type, char *host_name, char *svc_description, time_t entry_time, char *author, char *comment_data, time_t start_time, time_t end_time, int fixed, unsigned long triggered_by, unsigned long duration, unsigned long downtime_id){ scheduled_downtime *new_downtime=NULL; scheduled_downtime *last_downtime=NULL; scheduled_downtime *temp_downtime=NULL; /* don't add triggered downtimes that don't have a valid parent */ if(triggered_by>0 && find_downtime(ANY_DOWNTIME,triggered_by)==NULL) return ERROR; /* allocate memory for the downtime */ new_downtime=(scheduled_downtime *)malloc(sizeof(scheduled_downtime)); if(new_downtime==NULL) return ERROR; new_downtime->host_name=strdup(host_name); if(new_downtime->host_name==NULL){ free(new_downtime); return ERROR; } if(downtime_type==SERVICE_DOWNTIME){ new_downtime->service_description=strdup(svc_description); if(new_downtime->service_description==NULL){ free(new_downtime->host_name); free(new_downtime); return ERROR; } } else new_downtime->service_description=NULL; if(author==NULL) new_downtime->author=NULL; else new_downtime->author=strdup(author); if(comment_data==NULL) new_downtime->comment=NULL; else new_downtime->comment=strdup(comment_data); new_downtime->type=downtime_type; new_downtime->entry_time=entry_time; new_downtime->start_time=start_time; new_downtime->end_time=end_time; new_downtime->fixed=(fixed>0)?TRUE:FALSE; new_downtime->triggered_by=triggered_by; new_downtime->duration=duration; new_downtime->downtime_id=downtime_id; #ifdef NSCORE new_downtime->comment_id=0; new_downtime->is_in_effect=FALSE; new_downtime->start_flex_downtime=FALSE; new_downtime->incremented_pending_downtime=FALSE; #endif /* add new downtime to downtime list, sorted by start time */ last_downtime=scheduled_downtime_list; for(temp_downtime=scheduled_downtime_list;temp_downtime!=NULL;temp_downtime=temp_downtime->next){ if(new_downtime->start_timestart_time){ new_downtime->next=temp_downtime; if(temp_downtime==scheduled_downtime_list) scheduled_downtime_list=new_downtime; else last_downtime->next=new_downtime; break; } else last_downtime=temp_downtime; } if(scheduled_downtime_list==NULL){ new_downtime->next=NULL; scheduled_downtime_list=new_downtime; } else if(temp_downtime==NULL){ new_downtime->next=NULL; last_downtime->next=new_downtime; } #ifdef NSCORE #ifdef USE_EVENT_BROKER /* send data to event broker */ broker_downtime_data(NEBTYPE_DOWNTIME_LOAD,NEBFLAG_NONE,NEBATTR_NONE,downtime_type,host_name,svc_description,entry_time,author,comment_data,start_time,end_time,fixed,triggered_by,duration,downtime_id,NULL); #endif #endif return OK; } /******************************************************************/ /************************ SEARCH FUNCTIONS ************************/ /******************************************************************/ /* finds a specific downtime entry */ scheduled_downtime *find_downtime(int type, unsigned long downtime_id){ scheduled_downtime *temp_downtime; for(temp_downtime=scheduled_downtime_list;temp_downtime!=NULL;temp_downtime=temp_downtime->next){ if(type!=ANY_DOWNTIME && temp_downtime->type!=type) continue; if(temp_downtime->downtime_id==downtime_id) return temp_downtime; } return NULL; } /* finds a specific host downtime entry */ scheduled_downtime *find_host_downtime(unsigned long downtime_id){ return find_downtime(HOST_DOWNTIME,downtime_id); } /* finds a specific service downtime entry */ scheduled_downtime *find_service_downtime(unsigned long downtime_id){ return find_downtime(SERVICE_DOWNTIME,downtime_id); } /******************************************************************/ /********************* CLEANUP FUNCTIONS **************************/ /******************************************************************/ /* frees memory allocated for the scheduled downtime data */ void free_downtime_data(void){ scheduled_downtime *this_downtime; scheduled_downtime *next_downtime; /* free memory for the scheduled_downtime list */ for(this_downtime=scheduled_downtime_list;this_downtime!=NULL;this_downtime=next_downtime){ next_downtime=this_downtime->next; free(this_downtime->host_name); free(this_downtime->service_description); free(this_downtime->author); free(this_downtime->comment); free(this_downtime); } /* reset list pointer */ scheduled_downtime_list=NULL; return; } nagios-2.6/common/objects.c0000664000076500007650000063123410377720771015310 0ustar nagiosnagios/***************************************************************************** * * OBJECTS.C - Object addition and search functions for Nagios * * Copyright (c) 1999-2006 Ethan Galstad (nagios@nagios.org) * Last Modified: 02-24-2006 * * 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. * *****************************************************************************/ #include "../include/config.h" #include "../include/common.h" #include "../include/objects.h" #ifdef NSCORE #include "../include/nagios.h" #endif #ifdef NSCGI #include "../include/cgiutils.h" #endif /**** IMPLEMENTATION-SPECIFIC HEADER FILES ****/ #ifdef USE_XODTEMPLATE /* template-based routines */ #include "../xdata/xodtemplate.h" #endif host *host_list=NULL,*host_list_tail=NULL; service *service_list=NULL,*service_list_tail=NULL; contact *contact_list=NULL,*contact_list_tail=NULL; contactgroup *contactgroup_list=NULL,*contactgroup_list_tail=NULL; hostgroup *hostgroup_list=NULL,*hostgroup_list_tail=NULL; servicegroup *servicegroup_list=NULL,*servicegroup_list_tail=NULL; command *command_list=NULL,*command_list_tail=NULL; timeperiod *timeperiod_list=NULL,*timeperiod_list_tail=NULL; serviceescalation *serviceescalation_list=NULL,*serviceescalation_list_tail=NULL; servicedependency *servicedependency_list=NULL,*servicedependency_list_tail=NULL; hostdependency *hostdependency_list=NULL,*hostdependency_list_tail=NULL; hostescalation *hostescalation_list=NULL,*hostescalation_list_tail=NULL; hostextinfo *hostextinfo_list=NULL,*hostextinfo_list_tail=NULL; serviceextinfo *serviceextinfo_list=NULL,*serviceextinfo_list_tail=NULL; host **host_hashlist=NULL; service **service_hashlist=NULL; command **command_hashlist=NULL; timeperiod **timeperiod_hashlist=NULL; contact **contact_hashlist=NULL; contactgroup **contactgroup_hashlist=NULL; hostgroup **hostgroup_hashlist=NULL; servicegroup **servicegroup_hashlist=NULL; hostextinfo **hostextinfo_hashlist=NULL; serviceextinfo **serviceextinfo_hashlist=NULL; hostdependency **hostdependency_hashlist=NULL; servicedependency **servicedependency_hashlist=NULL; hostescalation **hostescalation_hashlist=NULL; serviceescalation **serviceescalation_hashlist=NULL; #ifdef NSCORE int __nagios_object_structure_version=CURRENT_OBJECT_STRUCTURE_VERSION; #endif /******************************************************************/ /******* TOP-LEVEL HOST CONFIGURATION DATA INPUT FUNCTION *********/ /******************************************************************/ /* read all host configuration data from external source */ int read_object_config_data(char *main_config_file,int options,int cache){ int result=OK; #ifdef DEBUG0 printf("read_object_config_data() start\n"); #endif /********* IMPLEMENTATION-SPECIFIC INPUT FUNCTION ********/ #ifdef USE_XODTEMPLATE /* read in data from all text host config files (template-based) */ result=xodtemplate_read_config_data(main_config_file,options,cache); if(result!=OK) return ERROR; #endif #ifdef DEBUG0 printf("read_object_config_data() end\n"); #endif return result; } /******************************************************************/ /****************** CHAINED HASH FUNCTIONS ************************/ /******************************************************************/ /* adds host to hash list in memory */ int add_host_to_hashlist(host *new_host){ host *temp_host, *lastpointer; int hashslot; #ifdef NSCORE char temp_buffer[MAX_INPUT_BUFFER]; #endif /* initialize hash list */ if(host_hashlist==NULL){ int i; host_hashlist=(host **)malloc(sizeof(host *)*HOST_HASHSLOTS); if(host_hashlist==NULL) return 0; for(i=0;iname,HOST_HASHSLOTS); lastpointer=NULL; for(temp_host=host_hashlist[hashslot];temp_host && compare_hashdata1(temp_host->name,new_host->name)<0;temp_host=temp_host->nexthash) lastpointer=temp_host; if(!temp_host || (compare_hashdata1(temp_host->name,new_host->name)!=0)){ if(lastpointer) lastpointer->nexthash=new_host; else host_hashlist[hashslot]=new_host; new_host->nexthash=temp_host; return 1; } /* else already exists */ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not add duplicate host '%s'.\n",new_host->name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return 0; } int add_service_to_hashlist(service *new_service){ service *temp_service, *lastpointer; int hashslot; #ifdef NSCORE char temp_buffer[MAX_INPUT_BUFFER]; #endif /* initialize hash list */ if(service_hashlist==NULL){ int i; service_hashlist=(service **)malloc(sizeof(service *)*SERVICE_HASHSLOTS); if(service_hashlist==NULL) return 0; for(i=0;i< SERVICE_HASHSLOTS;i++) service_hashlist[i]=NULL; } if(!new_service) return 0; hashslot=hashfunc2(new_service->host_name,new_service->description,SERVICE_HASHSLOTS); lastpointer=NULL; for(temp_service=service_hashlist[hashslot];temp_service && compare_hashdata2(temp_service->host_name,temp_service->description,new_service->host_name,new_service->description)<0;temp_service=temp_service->nexthash) lastpointer=temp_service; if(!temp_service || (compare_hashdata2(temp_service->host_name,temp_service->description,new_service->host_name,new_service->description)!=0)){ if(lastpointer) lastpointer->nexthash=new_service; else service_hashlist[hashslot]=new_service; new_service->nexthash=temp_service; return 1; } /* else already exists */ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not add duplicate service '%s' on host '%s'.\n",new_service->description,new_service->host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return 0; } int add_command_to_hashlist(command *new_command){ command *temp_command, *lastpointer; int hashslot; #ifdef NSCORE char temp_buffer[MAX_INPUT_BUFFER]; #endif /* initialize hash list */ if(command_hashlist==NULL){ int i; command_hashlist=(command **)malloc(sizeof(command *)*COMMAND_HASHSLOTS); if(command_hashlist==NULL) return 0; for(i=0;iname,COMMAND_HASHSLOTS); lastpointer=NULL; for(temp_command=command_hashlist[hashslot];temp_command && compare_hashdata1(temp_command->name,new_command->name)<0;temp_command=temp_command->nexthash) lastpointer=temp_command; if(!temp_command || (compare_hashdata1(temp_command->name,new_command->name)!=0)){ if(lastpointer) lastpointer->nexthash=new_command; else command_hashlist[hashslot]=new_command; new_command->nexthash=temp_command; return 1; } /* else already exists */ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not add duplicate command '%s'.\n",new_command->name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return 0; } int add_timeperiod_to_hashlist(timeperiod *new_timeperiod){ timeperiod *temp_timeperiod, *lastpointer; int hashslot; #ifdef NSCORE char temp_buffer[MAX_INPUT_BUFFER]; #endif /* initialize hash list */ if(timeperiod_hashlist==NULL){ int i; timeperiod_hashlist=(timeperiod **)malloc(sizeof(timeperiod *)*TIMEPERIOD_HASHSLOTS); if(timeperiod_hashlist==NULL) return 0; for(i=0;iname,TIMEPERIOD_HASHSLOTS); lastpointer=NULL; for(temp_timeperiod=timeperiod_hashlist[hashslot];temp_timeperiod && compare_hashdata1(temp_timeperiod->name,new_timeperiod->name)<0;temp_timeperiod=temp_timeperiod->nexthash) lastpointer=temp_timeperiod; if(!temp_timeperiod || (compare_hashdata1(temp_timeperiod->name,new_timeperiod->name)!=0)){ if(lastpointer) lastpointer->nexthash=new_timeperiod; else timeperiod_hashlist[hashslot]=new_timeperiod; new_timeperiod->nexthash=temp_timeperiod; return 1; } /* else already exists */ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not add duplicate timeperiod '%s'.\n",new_timeperiod->name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return 0; } int add_contact_to_hashlist(contact *new_contact){ contact *temp_contact, *lastpointer; int hashslot; #ifdef NSCORE char temp_buffer[MAX_INPUT_BUFFER]; #endif /* initialize hash list */ if(contact_hashlist==NULL){ int i; contact_hashlist=(contact **)malloc(sizeof(contact *)*CONTACT_HASHSLOTS); if(contact_hashlist==NULL) return 0; for(i=0;iname,CONTACT_HASHSLOTS); lastpointer=NULL; for(temp_contact=contact_hashlist[hashslot];temp_contact && compare_hashdata1(temp_contact->name,new_contact->name)<0;temp_contact=temp_contact->nexthash) lastpointer=temp_contact; if(!temp_contact || (compare_hashdata1(temp_contact->name,new_contact->name)!=0)){ if(lastpointer) lastpointer->nexthash=new_contact; else contact_hashlist[hashslot]=new_contact; new_contact->nexthash=temp_contact; return 1; } /* else already exists */ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not add duplicate contact '%s'.\n",new_contact->name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return 0; } int add_contactgroup_to_hashlist(contactgroup *new_contactgroup){ contactgroup *temp_contactgroup, *lastpointer; int hashslot; #ifdef NSCORE char temp_buffer[MAX_INPUT_BUFFER]; #endif /* initialize hash list */ if(contactgroup_hashlist==NULL){ int i; contactgroup_hashlist=(contactgroup **)malloc(sizeof(contactgroup *)*CONTACTGROUP_HASHSLOTS); if(contactgroup_hashlist==NULL) return 0; for(i=0;igroup_name,CONTACTGROUP_HASHSLOTS); lastpointer=NULL; for(temp_contactgroup=contactgroup_hashlist[hashslot];temp_contactgroup && compare_hashdata1(temp_contactgroup->group_name,new_contactgroup->group_name)<0;temp_contactgroup=temp_contactgroup->nexthash) lastpointer=temp_contactgroup; if(!temp_contactgroup || (compare_hashdata1(temp_contactgroup->group_name,new_contactgroup->group_name)!=0)){ if(lastpointer) lastpointer->nexthash=new_contactgroup; else contactgroup_hashlist[hashslot]=new_contactgroup; new_contactgroup->nexthash=temp_contactgroup; return 1; } /* else already exists */ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not add duplicate contactgroup '%s'.\n",new_contactgroup->group_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return 0; } int add_hostgroup_to_hashlist(hostgroup *new_hostgroup){ hostgroup *temp_hostgroup, *lastpointer; int hashslot; #ifdef NSCORE char temp_buffer[MAX_INPUT_BUFFER]; #endif /* initialize hash list */ if(hostgroup_hashlist==NULL){ int i; hostgroup_hashlist=(hostgroup **)malloc(sizeof(hostgroup *)*HOSTGROUP_HASHSLOTS); if(hostgroup_hashlist==NULL) return 0; for(i=0;igroup_name,HOSTGROUP_HASHSLOTS); lastpointer=NULL; for(temp_hostgroup=hostgroup_hashlist[hashslot];temp_hostgroup && compare_hashdata1(temp_hostgroup->group_name,new_hostgroup->group_name)<0;temp_hostgroup=temp_hostgroup->nexthash) lastpointer=temp_hostgroup; if(!temp_hostgroup || (compare_hashdata1(temp_hostgroup->group_name,new_hostgroup->group_name)!=0)){ if(lastpointer) lastpointer->nexthash=new_hostgroup; else hostgroup_hashlist[hashslot]=new_hostgroup; new_hostgroup->nexthash=temp_hostgroup; return 1; } /* else already exists */ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not add duplicate hostgroup '%s'.\n",new_hostgroup->group_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return 0; } int add_servicegroup_to_hashlist(servicegroup *new_servicegroup){ servicegroup *temp_servicegroup, *lastpointer; int hashslot; #ifdef NSCORE char temp_buffer[MAX_INPUT_BUFFER]; #endif /* initialize hash list */ if(servicegroup_hashlist==NULL){ int i; servicegroup_hashlist=(servicegroup **)malloc(sizeof(servicegroup *)*SERVICEGROUP_HASHSLOTS); if(servicegroup_hashlist==NULL) return 0; for(i=0;igroup_name,SERVICEGROUP_HASHSLOTS); lastpointer=NULL; for(temp_servicegroup=servicegroup_hashlist[hashslot];temp_servicegroup && compare_hashdata1(temp_servicegroup->group_name,new_servicegroup->group_name)<0;temp_servicegroup=temp_servicegroup->nexthash) lastpointer=temp_servicegroup; if(!temp_servicegroup || (compare_hashdata1(temp_servicegroup->group_name,new_servicegroup->group_name)!=0)){ if(lastpointer) lastpointer->nexthash=new_servicegroup; else servicegroup_hashlist[hashslot]=new_servicegroup; new_servicegroup->nexthash=temp_servicegroup; return 1; } /* else already exists */ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not add duplicate servicegroup '%s'.\n",new_servicegroup->group_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return 0; } /* adds hostextinfo to hash list in memory */ int add_hostextinfo_to_hashlist(hostextinfo *new_hostextinfo){ hostextinfo *temp_hostextinfo, *lastpointer; int hashslot; #ifdef NSCORE char temp_buffer[MAX_INPUT_BUFFER]; #endif /* initialize hash list */ if(hostextinfo_hashlist==NULL){ int i; hostextinfo_hashlist=(hostextinfo **)malloc(sizeof(hostextinfo *)*HOSTEXTINFO_HASHSLOTS); if(hostextinfo_hashlist==NULL) return 0; for(i=0;ihost_name,HOSTEXTINFO_HASHSLOTS); lastpointer=NULL; for(temp_hostextinfo=hostextinfo_hashlist[hashslot];temp_hostextinfo && compare_hashdata1(temp_hostextinfo->host_name,new_hostextinfo->host_name)<0;temp_hostextinfo=temp_hostextinfo->nexthash) lastpointer=temp_hostextinfo; if(!temp_hostextinfo || (compare_hashdata1(temp_hostextinfo->host_name,new_hostextinfo->host_name)!=0)){ if(lastpointer) lastpointer->nexthash=new_hostextinfo; else hostextinfo_hashlist[hashslot]=new_hostextinfo; new_hostextinfo->nexthash=temp_hostextinfo; return 1; } /* else already exists */ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not add duplicate hostextinfo entry for host '%s'.\n",new_hostextinfo->host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return 0; } int add_serviceextinfo_to_hashlist(serviceextinfo *new_serviceextinfo){ serviceextinfo *temp_serviceextinfo, *lastpointer; int hashslot; #ifdef NSCORE char temp_buffer[MAX_INPUT_BUFFER]; #endif /* initialize hash list */ if(serviceextinfo_hashlist==NULL){ int i; serviceextinfo_hashlist=(serviceextinfo **)malloc(sizeof(serviceextinfo *)*SERVICEEXTINFO_HASHSLOTS); if(serviceextinfo_hashlist==NULL) return 0; for(i=0;i< SERVICEEXTINFO_HASHSLOTS;i++) serviceextinfo_hashlist[i]=NULL; } if(!new_serviceextinfo) return 0; hashslot=hashfunc2(new_serviceextinfo->host_name,new_serviceextinfo->description,SERVICEEXTINFO_HASHSLOTS); lastpointer=NULL; for(temp_serviceextinfo=serviceextinfo_hashlist[hashslot];temp_serviceextinfo && compare_hashdata2(temp_serviceextinfo->host_name,temp_serviceextinfo->description,new_serviceextinfo->host_name,new_serviceextinfo->description)<0;temp_serviceextinfo=temp_serviceextinfo->nexthash) lastpointer=temp_serviceextinfo; if(!temp_serviceextinfo || (compare_hashdata2(temp_serviceextinfo->host_name,temp_serviceextinfo->description,new_serviceextinfo->host_name,new_serviceextinfo->description)!=0)){ if(lastpointer) lastpointer->nexthash=new_serviceextinfo; else serviceextinfo_hashlist[hashslot]=new_serviceextinfo; new_serviceextinfo->nexthash=temp_serviceextinfo; return 1; } /* else already exists */ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not add duplicate serviceextinfo entry for service '%s' on host '%s'.\n",new_serviceextinfo->description,new_serviceextinfo->host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return 0; } /* adds hostdependency to hash list in memory */ int add_hostdependency_to_hashlist(hostdependency *new_hostdependency){ hostdependency *temp_hostdependency, *lastpointer; int hashslot; /* initialize hash list */ if(hostdependency_hashlist==NULL){ int i; hostdependency_hashlist=(hostdependency **)malloc(sizeof(hostdependency *)*HOSTDEPENDENCY_HASHSLOTS); if(hostdependency_hashlist==NULL) return 0; for(i=0;idependent_host_name,HOSTDEPENDENCY_HASHSLOTS); lastpointer=NULL; for(temp_hostdependency=hostdependency_hashlist[hashslot];temp_hostdependency && compare_hashdata1(temp_hostdependency->dependent_host_name,new_hostdependency->dependent_host_name)<0;temp_hostdependency=temp_hostdependency->nexthash) lastpointer=temp_hostdependency; /* duplicates are allowed */ if(lastpointer) lastpointer->nexthash=new_hostdependency; else hostdependency_hashlist[hashslot]=new_hostdependency; new_hostdependency->nexthash=temp_hostdependency; return 1; } int add_servicedependency_to_hashlist(servicedependency *new_servicedependency){ servicedependency *temp_servicedependency, *lastpointer; int hashslot; /* initialize hash list */ if(servicedependency_hashlist==NULL){ int i; servicedependency_hashlist=(servicedependency **)malloc(sizeof(servicedependency *)*SERVICEDEPENDENCY_HASHSLOTS); if(servicedependency_hashlist==NULL) return 0; for(i=0;i< SERVICEDEPENDENCY_HASHSLOTS;i++) servicedependency_hashlist[i]=NULL; } if(!new_servicedependency) return 0; hashslot=hashfunc2(new_servicedependency->dependent_host_name,new_servicedependency->dependent_service_description,SERVICEDEPENDENCY_HASHSLOTS); lastpointer=NULL; for(temp_servicedependency=servicedependency_hashlist[hashslot];temp_servicedependency && compare_hashdata2(temp_servicedependency->dependent_host_name,temp_servicedependency->dependent_service_description,new_servicedependency->dependent_host_name,new_servicedependency->dependent_service_description)<0;temp_servicedependency=temp_servicedependency->nexthash) lastpointer=temp_servicedependency; /* duplicates are allowed */ if(lastpointer) lastpointer->nexthash=new_servicedependency; else servicedependency_hashlist[hashslot]=new_servicedependency; new_servicedependency->nexthash=temp_servicedependency; return 1; } /* adds hostescalation to hash list in memory */ int add_hostescalation_to_hashlist(hostescalation *new_hostescalation){ hostescalation *temp_hostescalation, *lastpointer; int hashslot; /* initialize hash list */ if(hostescalation_hashlist==NULL){ int i; hostescalation_hashlist=(hostescalation **)malloc(sizeof(hostescalation *)*HOSTESCALATION_HASHSLOTS); if(hostescalation_hashlist==NULL) return 0; for(i=0;ihost_name,HOSTESCALATION_HASHSLOTS); lastpointer=NULL; for(temp_hostescalation=hostescalation_hashlist[hashslot];temp_hostescalation && compare_hashdata1(temp_hostescalation->host_name,new_hostescalation->host_name)<0;temp_hostescalation=temp_hostescalation->nexthash) lastpointer=temp_hostescalation; /* duplicates are allowed */ if(lastpointer) lastpointer->nexthash=new_hostescalation; else hostescalation_hashlist[hashslot]=new_hostescalation; new_hostescalation->nexthash=temp_hostescalation; return 1; } int add_serviceescalation_to_hashlist(serviceescalation *new_serviceescalation){ serviceescalation *temp_serviceescalation, *lastpointer; int hashslot; /* initialize hash list */ if(serviceescalation_hashlist==NULL){ int i; serviceescalation_hashlist=(serviceescalation **)malloc(sizeof(serviceescalation *)*SERVICEESCALATION_HASHSLOTS); if(serviceescalation_hashlist==NULL) return 0; for(i=0;i< SERVICEESCALATION_HASHSLOTS;i++) serviceescalation_hashlist[i]=NULL; } if(!new_serviceescalation) return 0; hashslot=hashfunc2(new_serviceescalation->host_name,new_serviceescalation->description,SERVICEESCALATION_HASHSLOTS); lastpointer=NULL; for(temp_serviceescalation=serviceescalation_hashlist[hashslot];temp_serviceescalation && compare_hashdata2(temp_serviceescalation->host_name,temp_serviceescalation->description,new_serviceescalation->host_name,new_serviceescalation->description)<0;temp_serviceescalation=temp_serviceescalation->nexthash) lastpointer=temp_serviceescalation; /* duplicates are allowed */ if(lastpointer) lastpointer->nexthash=new_serviceescalation; else serviceescalation_hashlist[hashslot]=new_serviceescalation; new_serviceescalation->nexthash=temp_serviceescalation; return 1; } /******************************************************************/ /**************** OBJECT ADDITION FUNCTIONS ***********************/ /******************************************************************/ /* add a new timeperiod to the list in memory */ timeperiod *add_timeperiod(char *name,char *alias){ timeperiod *new_timeperiod; timeperiod *temp_timeperiod; int day=0; #ifdef NSCORE char temp_buffer[MAX_INPUT_BUFFER]; #endif #ifdef DEBUG0 printf("add_timeperiod() start\n"); #endif /* make sure we have the data we need */ if(name==NULL || alias==NULL) return NULL; strip(name); strip(alias); if(!strcmp(name,"") || !strcmp(alias,"")){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Name or alias for timeperiod is NULL\n"); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } /* make sure there isn't a timeperiod by this name added already */ temp_timeperiod=find_timeperiod(name); if(temp_timeperiod!=NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Timeperiod '%s' has already been defined\n",name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } /* allocate memory for the new timeperiod */ new_timeperiod=malloc(sizeof(timeperiod)); if(new_timeperiod==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not allocate memory for timeperiod '%s'\n",name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } new_timeperiod->name=(char *)malloc(strlen(name)+1); if(new_timeperiod->name==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not allocate memory for timeperiod '%s' name\n",name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif free(new_timeperiod); return NULL; } new_timeperiod->alias=(char *)malloc(strlen(alias)+1); if(new_timeperiod->alias==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not allocate memory for timeperiod '%s' alias\n",name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif free(new_timeperiod->name); free(new_timeperiod); return NULL; } strcpy(new_timeperiod->name,name); strcpy(new_timeperiod->alias,alias); /* initialize the time ranges for each day in the time period to NULL */ for(day=0;day<7;day++) new_timeperiod->days[day]=NULL; new_timeperiod->next=NULL; new_timeperiod->nexthash=NULL; /* add new timeperiod to timeperiod chained hash list */ if(!add_timeperiod_to_hashlist(new_timeperiod)){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not allocate memory for timeperiod list to add timeperiod '%s'\n",name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif free(new_timeperiod->alias); free(new_timeperiod->name); free(new_timeperiod); return NULL; } #ifdef NSCORE /* timeperiods are sorted alphabetically for daemon, so add new items to tail of list */ if(timeperiod_list==NULL){ timeperiod_list=new_timeperiod; timeperiod_list_tail=timeperiod_list; } else{ timeperiod_list_tail->next=new_timeperiod; timeperiod_list_tail=new_timeperiod; } #else /* timeperiods are sorted in reverse for CGIs, so add new items to head of list */ new_timeperiod->next=timeperiod_list; timeperiod_list=new_timeperiod; #endif #ifdef DEBUG1 printf("\tName: %s\n",new_timeperiod->name); printf("\tAlias: %s\n",new_timeperiod->alias); #endif #ifdef DEBUG0 printf("add_timeperiod() end\n"); #endif return new_timeperiod; } /* add a new timerange to a timeperiod */ timerange *add_timerange_to_timeperiod(timeperiod *period, int day, unsigned long start_time, unsigned long end_time){ timerange *new_timerange; #ifdef NSCORE char temp_buffer[MAX_INPUT_BUFFER]; #endif #ifdef DEBUG0 printf("add_timerange_to_timeperiod() start\n"); #endif /* make sure we have the data we need */ if(period==NULL) return NULL; if(day<0 || day>6){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Day %d is not valid for timeperiod '%s'\n",day,period->name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } if(start_time<0 || start_time>86400){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Start time %lu on day %d is not valid for timeperiod '%s'\n",start_time,day,period->name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } if(end_time<0 || end_time>86400){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: End time %lu on day %d is not value for timeperiod '%s'\n",end_time,day,period->name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } /* allocate memory for the new time range */ new_timerange=malloc(sizeof(timerange)); if(new_timerange==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not allocate memory for day %d timerange in timeperiod '%s'\n",day,period->name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } new_timerange->range_start=start_time; new_timerange->range_end=end_time; /* add the new time range to the head of the range list for this day */ new_timerange->next=period->days[day]; period->days[day]=new_timerange; #ifdef DEBUG0 printf("add_timerange_to_timeperiod() end\n"); #endif return new_timerange; } /* add a new host definition */ host *add_host(char *name, char *alias, char *address, char *check_period, int check_interval, int max_attempts, int notify_up, int notify_down, int notify_unreachable, int notify_flapping, int notification_interval, char *notification_period, int notifications_enabled, char *check_command, int checks_enabled, int accept_passive_checks, char *event_handler, int event_handler_enabled, int flap_detection_enabled, double low_flap_threshold, double high_flap_threshold, int stalk_up, int stalk_down, int stalk_unreachable, int process_perfdata, int failure_prediction_enabled, char *failure_prediction_options, int check_freshness, int freshness_threshold, int retain_status_information, int retain_nonstatus_information, int obsess_over_host){ host *temp_host; host *new_host; #ifdef NSCORE char temp_buffer[MAX_INPUT_BUFFER]; int x; #endif #ifdef DEBUG0 printf("add_host() start\n"); #endif /* make sure we have the data we need */ if(name==NULL || alias==NULL || address==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Host name, alias, or address is NULL\n"); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } strip(name); strip(alias); strip(address); strip(check_command); strip(event_handler); strip(notification_period); if(!strcmp(name,"") || !strcmp(alias,"") || !strcmp(address,"")){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Host name, alias, or address is NULL\n"); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } /* make sure there isn't a host by this name already added */ temp_host=find_host(name); if(temp_host!=NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Host '%s' has already been defined\n",name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } /* make sure the name isn't too long */ if(strlen(name)>MAX_HOSTNAME_LENGTH-1){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Host name '%s' exceeds maximum length of %d characters\n",name,MAX_HOSTNAME_LENGTH-1); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } if(max_attempts<=0){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Invalid max_check_attempts value for host '%s'\n",name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } if(check_interval<0){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Invalid check_interval value for host '%s'\n",name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } if(notification_interval<0){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Invalid notification_interval value for host '%s'\n",name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } if(notify_up<0 || notify_up>1){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Invalid notify_up value for host '%s'\n",name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } if(notify_down<0 || notify_down>1){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Invalid notify_down value for host '%s'\n",name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } if(notify_unreachable<0 || notify_unreachable>1){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Invalid notify_unreachable value for host '%s'\n",name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } if(notify_flapping<0 || notify_flapping>1){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Invalid notify_flappingvalue for host '%s'\n",name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } if(checks_enabled<0 || checks_enabled>1){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Invalid checks_enabled value for host '%s'\n",name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } if(accept_passive_checks<0 || accept_passive_checks>1){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Invalid accept_passive_checks value for host '%s'\n",name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } if(notifications_enabled<0 || notifications_enabled>1){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Invalid notifications_enabled value for host '%s'\n",name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } if(event_handler_enabled<0 || event_handler_enabled>1){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Invalid event_handler_enabled value for host '%s'\n",name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } if(flap_detection_enabled<0 || flap_detection_enabled>1){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Invalid flap_detection_enabled value for host '%s'\n",name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } if(stalk_up<0 || stalk_up>1){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Invalid stalk_up value for host '%s'\n",name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } if(stalk_down<0 || stalk_down>1){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Invalid stalk_warning value for host '%s'\n",name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } if(stalk_unreachable<0 || stalk_unreachable>1){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Invalid stalk_unknown value for host '%s'\n",name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } if(process_perfdata<0 || process_perfdata>1){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Invalid process_perfdata value for host '%s'\n",name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } if(failure_prediction_enabled<0 || failure_prediction_enabled>1){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Invalid failure_prediction_enabled value for host '%s'\n",name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } if(check_freshness<0 || check_freshness>1){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Invalid check_freshness value for host '%s'\n",name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } if(freshness_threshold<0){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Invalid freshness_threshold value for host '%s'\n",name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } if(obsess_over_host<0 || obsess_over_host>1){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Invalid obsess_over_host value for host '%s'\n",name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } if(retain_status_information<0 || retain_status_information>1){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Invalid retain_status_information value for host '%s'\n",name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } if(retain_nonstatus_information<0 || retain_nonstatus_information>1){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Invalid retain_nonstatus_information value for host '%s'\n",name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } /* allocate memory for a new host */ new_host=(host *)malloc(sizeof(host)); if(new_host==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not allocate memory for host '%s'\n",name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } new_host->name=strdup(name); if(new_host->name==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not allocate memory for host '%s' name\n",name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif free(new_host); return NULL; } new_host->alias=strdup(alias); if(new_host->alias==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not allocate memory for host '%s' alias\n",name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif free(new_host->name); free(new_host); return NULL; } new_host->address=strdup(address); if(new_host->address==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not allocate memory for host '%s' address\n",name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif free(new_host->alias); free(new_host->name); free(new_host); return NULL; } if(check_period!=NULL && strcmp(check_period,"")){ new_host->check_period=strdup(check_period); if(new_host->check_period==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not allocate memory for host '%s' check period\n",name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif free(new_host->address); free(new_host->alias); free(new_host->name); free(new_host); return NULL; } } else new_host->check_period=NULL; if(notification_period!=NULL && strcmp(notification_period,"")){ new_host->notification_period=strdup(notification_period); if(new_host->notification_period==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not allocate memory for host '%s' notification period\n",name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif free(new_host->check_period); free(new_host->address); free(new_host->alias); free(new_host->name); free(new_host); return NULL; } } else new_host->notification_period=NULL; if(check_command!=NULL && strcmp(check_command,"")){ new_host->host_check_command=strdup(check_command); if(new_host->host_check_command==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not allocate memory for host '%s' check command\n",name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif if(new_host->notification_period!=NULL) free(new_host->notification_period); free(new_host->check_period); free(new_host->address); free(new_host->alias); free(new_host->name); free(new_host); return NULL; } } else new_host->host_check_command=NULL; if(event_handler!=NULL && strcmp(event_handler,"")){ new_host->event_handler=strdup(event_handler); if(new_host->event_handler==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not allocate memory for host '%s' event handler\n",name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif if(new_host->host_check_command!=NULL) free(new_host->host_check_command); if(new_host->notification_period!=NULL) free(new_host->notification_period); free(new_host->check_period); free(new_host->address); free(new_host->alias); free(new_host->name); free(new_host); return NULL; } } else new_host->event_handler=NULL; if(failure_prediction_options!=NULL && strcmp(failure_prediction_options,"")){ new_host->failure_prediction_options=strdup(failure_prediction_options); if(new_host->failure_prediction_options==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not allocate memory for host '%s' failure prediction options\n",name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif if(new_host->event_handler!=NULL) free(new_host->event_handler); if(new_host->host_check_command!=NULL) free(new_host->host_check_command); if(new_host->notification_period!=NULL) free(new_host->notification_period); free(new_host->check_period); free(new_host->address); free(new_host->alias); free(new_host->name); free(new_host); return NULL; } } else new_host->failure_prediction_options=NULL; new_host->parent_hosts=NULL; new_host->max_attempts=max_attempts; new_host->contact_groups=NULL; new_host->check_interval=check_interval; new_host->notification_interval=notification_interval; new_host->notify_on_recovery=(notify_up>0)?TRUE:FALSE; new_host->notify_on_down=(notify_down>0)?TRUE:FALSE; new_host->notify_on_unreachable=(notify_unreachable>0)?TRUE:FALSE; new_host->notify_on_flapping=(notify_flapping>0)?TRUE:FALSE; new_host->flap_detection_enabled=(flap_detection_enabled>0)?TRUE:FALSE; new_host->low_flap_threshold=low_flap_threshold; new_host->high_flap_threshold=high_flap_threshold; new_host->stalk_on_up=(stalk_up>0)?TRUE:FALSE; new_host->stalk_on_down=(stalk_down>0)?TRUE:FALSE; new_host->stalk_on_unreachable=(stalk_unreachable>0)?TRUE:FALSE; new_host->process_performance_data=(process_perfdata>0)?TRUE:FALSE; new_host->check_freshness=(check_freshness>0)?TRUE:FALSE; new_host->freshness_threshold=freshness_threshold; new_host->accept_passive_host_checks=(accept_passive_checks>0)?TRUE:FALSE; new_host->event_handler_enabled=(event_handler_enabled>0)?TRUE:FALSE; new_host->failure_prediction_enabled=(failure_prediction_enabled>0)?TRUE:FALSE; new_host->obsess_over_host=(obsess_over_host>0)?TRUE:FALSE; new_host->retain_status_information=(retain_status_information>0)?TRUE:FALSE; new_host->retain_nonstatus_information=(retain_nonstatus_information>0)?TRUE:FALSE; #ifdef NSCORE new_host->current_state=HOST_UP; new_host->last_state=HOST_UP; new_host->last_hard_state=HOST_UP; new_host->check_type=HOST_CHECK_ACTIVE; new_host->last_host_notification=(time_t)0; new_host->next_host_notification=(time_t)0; new_host->next_check=(time_t)0; new_host->should_be_scheduled=TRUE; new_host->last_check=(time_t)0; new_host->current_attempt=1; new_host->state_type=HARD_STATE; new_host->execution_time=0.0; new_host->latency=0.0; new_host->last_state_change=(time_t)0; new_host->last_hard_state_change=(time_t)0; new_host->last_time_up=(time_t)0; new_host->last_time_down=(time_t)0; new_host->last_time_unreachable=(time_t)0; new_host->has_been_checked=FALSE; new_host->is_being_freshened=FALSE; new_host->problem_has_been_acknowledged=FALSE; new_host->acknowledgement_type=ACKNOWLEDGEMENT_NONE; new_host->notified_on_down=FALSE; new_host->notified_on_unreachable=FALSE; new_host->current_notification_number=0; new_host->no_more_notifications=FALSE; new_host->check_flapping_recovery_notification=FALSE; new_host->checks_enabled=(checks_enabled>0)?TRUE:FALSE; new_host->notifications_enabled=(notifications_enabled>0)?TRUE:FALSE; new_host->scheduled_downtime_depth=0; new_host->check_options=CHECK_OPTION_NONE; new_host->pending_flex_downtime=0; for(x=0;xstate_history[x]=STATE_OK; new_host->state_history_index=0; new_host->last_state_history_update=(time_t)0; new_host->is_flapping=FALSE; new_host->flapping_comment_id=0; new_host->percent_state_change=0.0; new_host->total_services=0; new_host->total_service_check_interval=0L; new_host->modified_attributes=MODATTR_NONE; new_host->circular_path_checked=FALSE; new_host->contains_circular_path=FALSE; /* allocate new plugin output buffer */ new_host->plugin_output=(char *)malloc(MAX_PLUGINOUTPUT_LENGTH); if(new_host->plugin_output==NULL){ snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not allocate memory for host '%s' plugin output buffer\n",name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); if(new_host->failure_prediction_options!=NULL) free(new_host->failure_prediction_options); if(new_host->event_handler!=NULL) free(new_host->event_handler); if(new_host->host_check_command!=NULL) free(new_host->host_check_command); if(new_host->notification_period!=NULL) free(new_host->notification_period); free(new_host->address); free(new_host->alias); free(new_host->name); free(new_host); return NULL; } strcpy(new_host->plugin_output,""); /* allocate new performance data buffer */ new_host->perf_data=(char *)malloc(MAX_PLUGINOUTPUT_LENGTH); if(new_host->perf_data==NULL){ snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not allocate memory for host '%s' performance data buffer\n",name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); if(new_host->failure_prediction_options!=NULL) free(new_host->failure_prediction_options); if(new_host->event_handler!=NULL) free(new_host->event_handler); if(new_host->host_check_command!=NULL) free(new_host->host_check_command); if(new_host->notification_period!=NULL) free(new_host->notification_period); free(new_host->address); free(new_host->alias); free(new_host->name); free(new_host->plugin_output); free(new_host); return NULL; } strcpy(new_host->perf_data,""); #endif new_host->next=NULL; new_host->nexthash=NULL; /* add new host to host chained hash list */ if(!add_host_to_hashlist(new_host)){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not allocate memory for host list to add host '%s'\n",name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); free(new_host->plugin_output); if(new_host->perf_data) free(new_host->perf_data); #endif if(new_host->failure_prediction_options!=NULL) free(new_host->failure_prediction_options); if(new_host->event_handler!=NULL) free(new_host->event_handler); if(new_host->host_check_command!=NULL) free(new_host->host_check_command); if(new_host->notification_period!=NULL) free(new_host->notification_period); free(new_host->address); free(new_host->alias); free(new_host->name); free(new_host); return NULL; } #ifdef NSCORE /* hosts are sorted alphabetically for daemon, so add new items to tail of list */ if(host_list==NULL){ host_list=new_host; host_list_tail=host_list; } else{ host_list_tail->next=new_host; host_list_tail=new_host; } #else /* hosts are sorted in reverse for CGIs, so add new items to head of list */ new_host->next=host_list; host_list=new_host; #endif #ifdef DEBUG1 printf("\tHost Name: %s\n",new_host->name); printf("\tHost Alias: %s\n",new_host->alias); printf("\tHost Address: %s\n",new_host->address); printf("\tHost Check Command: %s\n",new_host->host_check_command); printf("\tMax. Check Attempts: %d\n",new_host->max_attempts); printf("\tHost Event Handler: %s\n",(new_host->event_handler==NULL)?"N/A":new_host->event_handler); printf("\tNotify On Down: %s\n",(new_host->notify_on_down==1)?"yes":"no"); printf("\tNotify On Unreachable: %s\n",(new_host->notify_on_unreachable==1)?"yes":"no"); printf("\tNotify On Recovery: %s\n",(new_host->notify_on_recovery==1)?"yes":"no"); printf("\tNotification Interval: %d\n",new_host->notification_interval); printf("\tNotification Time Period: %s\n",(new_host->notification_period==NULL)?"N/A":new_host->notification_period); #endif #ifdef DEBUG0 printf("add_host() end\n"); #endif return new_host; } hostsmember *add_parent_host_to_host(host *hst,char *host_name){ hostsmember *new_hostsmember; #ifdef NSCORE char temp_buffer[MAX_INPUT_BUFFER]; #endif #ifdef DEBUG0 printf("add_parent_host_to_host() start\n"); #endif /* make sure we have the data we need */ if(hst==NULL || host_name==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Host is NULL or parent host name is NULL\n"); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } strip(host_name); if(!strcmp(host_name,"")){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Host '%s' parent host name is NULL\n",hst->name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } /* a host cannot be a parent/child of itself */ if(!strcmp(host_name,hst->name)){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Host '%s' cannot be a child/parent of itself\n",hst->name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } /* allocate memory */ new_hostsmember=(hostsmember *)malloc(sizeof(hostsmember)); if(new_hostsmember==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not allocate memory for host '%s' parent host (%s)\n",hst->name,host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } new_hostsmember->host_name=strdup(host_name); if(new_hostsmember->host_name==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not allocate memory for host '%s' parent host (%s) name\n",hst->name,host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif free(new_hostsmember); return NULL; } /* add the parent host entry to the host definition */ new_hostsmember->next=hst->parent_hosts; hst->parent_hosts=new_hostsmember; #ifdef DEBUG0 printf("add_parent_host_to_host() end\n"); #endif return new_hostsmember; } /* add a new contactgroup to a host */ contactgroupsmember *add_contactgroup_to_host(host *hst, char *group_name){ contactgroupsmember *new_contactgroupsmember; #ifdef NSCORE char temp_buffer[MAX_INPUT_BUFFER]; #endif #ifdef DEBUG0 printf("add_contactgroup_to_host() start\n"); #endif /* make sure we have the data we need */ if(hst==NULL || group_name==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Host or contactgroup member is NULL\n"); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } strip(group_name); if(!strcmp(group_name,"")){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Host '%s' contactgroup member is NULL\n",hst->name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } /* allocate memory for a new member */ new_contactgroupsmember=malloc(sizeof(contactgroupsmember)); if(new_contactgroupsmember==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not allocate memory for host '%s' contactgroup member '%s'\n",hst->name,group_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } new_contactgroupsmember->group_name=strdup(group_name); if(new_contactgroupsmember->group_name==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not allocate memory for host '%s' contactgroup member '%s' name\n",hst->name,group_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif free(new_contactgroupsmember); return NULL; } /* add the new member to the head of the member list */ new_contactgroupsmember->next=hst->contact_groups; hst->contact_groups=new_contactgroupsmember;; #ifdef DEBUG0 printf("add_host_to_host() end\n"); #endif return new_contactgroupsmember; } /* add a new host group to the list in memory */ hostgroup *add_hostgroup(char *name,char *alias){ hostgroup *temp_hostgroup; hostgroup *new_hostgroup; #ifdef NSCORE char temp_buffer[MAX_INPUT_BUFFER]; #endif #ifdef DEBUG0 printf("add_hostgroup() start\n"); #endif /* make sure we have the data we need */ if(name==NULL || alias==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Hostgroup name and/or alias is NULL\n"); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } strip(name); strip(alias); if(!strcmp(name,"") || !strcmp(alias,"")){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Hostgroup name and/or alias is NULL\n"); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } /* make sure a hostgroup by this name hasn't been added already */ temp_hostgroup=find_hostgroup(name); if(temp_hostgroup!=NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Hostgroup '%s' has already been defined\n",name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } /* allocate memory */ new_hostgroup=(hostgroup *)malloc(sizeof(hostgroup)); if(new_hostgroup==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not allocate memory for hostgroup '%s'\n",name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } new_hostgroup->group_name=strdup(name); if(new_hostgroup->group_name==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not allocate memory for hostgroup '%s' name\n",name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif free(new_hostgroup); return NULL; } new_hostgroup->alias=strdup(alias); if(new_hostgroup->alias==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not allocate memory for hostgroup '%s' alias\n",name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif free(new_hostgroup->group_name); free(new_hostgroup); return NULL; } new_hostgroup->members=NULL; new_hostgroup->next=NULL; new_hostgroup->nexthash=NULL; /* add new hostgroup to hostgroup chained hash list */ if(!add_hostgroup_to_hashlist(new_hostgroup)){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not allocate memory for hostgroup list to add hostgroup '%s'\n",name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif free(new_hostgroup->group_name); free(new_hostgroup->alias); free(new_hostgroup); return NULL; } #ifdef NSCORE /* hostgroups are sorted alphabetically for daemon, so add new items to tail of list */ if(hostgroup_list==NULL){ hostgroup_list=new_hostgroup; hostgroup_list_tail=hostgroup_list; } else{ hostgroup_list_tail->next=new_hostgroup; hostgroup_list_tail=new_hostgroup; } #else /* hostgroups are sorted in reverse for CGIs, so add new items to head of list */ new_hostgroup->next=hostgroup_list; hostgroup_list=new_hostgroup; #endif #ifdef DEBUG1 printf("\tGroup name: %s\n",new_hostgroup->group_name); printf("\tAlias: %s\n",new_hostgroup->alias); #endif #ifdef DEBUG0 printf("add_hostgroup() end\n"); #endif return new_hostgroup; } /* add a new host to a host group */ hostgroupmember *add_host_to_hostgroup(hostgroup *temp_hostgroup, char *host_name){ hostgroupmember *new_member; hostgroupmember *last_member; hostgroupmember *temp_member; #ifdef NSCORE char temp_buffer[MAX_INPUT_BUFFER]; #endif #ifdef DEBUG0 printf("add_host_to_hostgroup() start\n"); #endif /* make sure we have the data we need */ if(temp_hostgroup==NULL || host_name==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Hostgroup or group member is NULL\n"); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } strip(host_name); if(!strcmp(host_name,"")){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Hostgroup member is NULL\n"); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } /* allocate memory for a new member */ new_member=malloc(sizeof(hostgroupmember)); if(new_member==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not allocate memory for hostgroup '%s' member '%s'\n",temp_hostgroup->group_name,host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } new_member->host_name=strdup(host_name); if(new_member->host_name==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not allocate memory for hostgroup '%s' member '%s' name\n",temp_hostgroup->group_name,host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif free(new_member); return NULL; } /* add the new member to the member list, sorted by host name */ last_member=temp_hostgroup->members; for(temp_member=temp_hostgroup->members;temp_member!=NULL;temp_member=temp_member->next){ if(strcmp(new_member->host_name,temp_member->host_name)<0){ new_member->next=temp_member; if(temp_member==temp_hostgroup->members) temp_hostgroup->members=new_member; else last_member->next=new_member; break; } else last_member=temp_member; } if(temp_hostgroup->members==NULL){ new_member->next=NULL; temp_hostgroup->members=new_member; } else if(temp_member==NULL){ new_member->next=NULL; last_member->next=new_member; } #ifdef DEBUG0 printf("add_host_to_hostgroup() end\n"); #endif return new_member; } /* add a new service group to the list in memory */ servicegroup *add_servicegroup(char *name,char *alias){ servicegroup *temp_servicegroup; servicegroup *new_servicegroup; #ifdef NSCORE char temp_buffer[MAX_INPUT_BUFFER]; #endif #ifdef DEBUG0 printf("add_servicegroup() start\n"); #endif /* make sure we have the data we need */ if(name==NULL || alias==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Servicegroup name and/or alias is NULL\n"); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } strip(name); strip(alias); if(!strcmp(name,"") || !strcmp(alias,"")){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Servicegroup name and/or alias is NULL\n"); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } /* make sure a servicegroup by this name hasn't been added already */ temp_servicegroup=find_servicegroup(name); if(temp_servicegroup!=NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Servicegroup '%s' has already been defined\n",name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } /* allocate memory */ new_servicegroup=(servicegroup *)malloc(sizeof(servicegroup)); if(new_servicegroup==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not allocate memory for servicegroup '%s'\n",name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } new_servicegroup->group_name=strdup(name); if(new_servicegroup->group_name==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not allocate memory for servicegroup '%s' name\n",name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif free(new_servicegroup); return NULL; } new_servicegroup->alias=strdup(alias); if(new_servicegroup->alias==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not allocate memory for servicegroup '%s' alias\n",name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif free(new_servicegroup->group_name); free(new_servicegroup); return NULL; } new_servicegroup->members=NULL; new_servicegroup->next=NULL; new_servicegroup->nexthash=NULL; /* add new servicegroup to servicegroup chained hash list */ if(!add_servicegroup_to_hashlist(new_servicegroup)){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not allocate memory for servicegroup list to add servicegroup '%s'\n",name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif free(new_servicegroup->group_name); free(new_servicegroup->alias); free(new_servicegroup); return NULL; } #ifdef NSCORE /* servicegroups are sorted alphabetically for daemon, so add new items to tail of list */ if(servicegroup_list==NULL){ servicegroup_list=new_servicegroup; servicegroup_list_tail=servicegroup_list; } else{ servicegroup_list_tail->next=new_servicegroup; servicegroup_list_tail=new_servicegroup; } #else /* servicegroups are sorted in reverse for CGIs, so add new items to head of list */ new_servicegroup->next=servicegroup_list; servicegroup_list=new_servicegroup; #endif #ifdef DEBUG1 printf("\tGroup name: %s\n",new_servicegroup->group_name); printf("\tAlias: %s\n",new_servicegroup->alias); #endif #ifdef DEBUG0 printf("add_servicegroup() end\n"); #endif return new_servicegroup; } /* add a new service to a service group */ servicegroupmember *add_service_to_servicegroup(servicegroup *temp_servicegroup, char *host_name, char *svc_description){ servicegroupmember *new_member; servicegroupmember *last_member; servicegroupmember *temp_member; #ifdef NSCORE char temp_buffer[MAX_INPUT_BUFFER]; #endif #ifdef DEBUG0 printf("add_service_to_servicegroup() start\n"); #endif /* make sure we have the data we need */ if(temp_servicegroup==NULL || host_name==NULL || svc_description==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Servicegroup or group member is NULL\n"); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } strip(host_name); strip(svc_description); if(!strcmp(host_name,"") || !strcmp(svc_description,"")){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Servicegroup member is NULL\n"); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } /* allocate memory for a new member */ new_member=malloc(sizeof(servicegroupmember)); if(new_member==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not allocate memory for servicegroup '%s' member (service '%s' on host '%s')\n",temp_servicegroup->group_name,host_name,svc_description); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } new_member->host_name=strdup(host_name); if(new_member->host_name==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not allocate memory for servicegroup '%s' member (service '%s' on host '%s') name\n",temp_servicegroup->group_name,host_name,svc_description); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif free(new_member); return NULL; } new_member->service_description=strdup(svc_description); if(new_member->service_description==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not allocate memory for servicegroup '%s' member (service '%s' on host '%s') name\n",temp_servicegroup->group_name,host_name,svc_description); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif free(new_member->host_name); free(new_member); return NULL; } /* add new member to member list, sorted by host name then service description */ last_member=temp_servicegroup->members; for(temp_member=temp_servicegroup->members;temp_member!=NULL;temp_member=temp_member->next){ if(strcmp(new_member->host_name,temp_member->host_name)<0){ new_member->next=temp_member; if(temp_member==temp_servicegroup->members) temp_servicegroup->members=new_member; else last_member->next=new_member; break; } else if(strcmp(new_member->host_name,temp_member->host_name)==0 && strcmp(new_member->service_description,temp_member->service_description)<0){ new_member->next=temp_member; if(temp_member==temp_servicegroup->members) temp_servicegroup->members=new_member; else last_member->next=new_member; break; } else last_member=temp_member; } if(temp_servicegroup->members==NULL){ new_member->next=NULL; temp_servicegroup->members=new_member; } else if(temp_member==NULL){ new_member->next=NULL; last_member->next=new_member; } #ifdef DEBUG0 printf("add_service_to_servicegroup() end\n"); #endif return new_member; } /* add a new contact to the list in memory */ contact *add_contact(char *name,char *alias, char *email, char *pager, char **addresses, char *svc_notification_period, char *host_notification_period,int notify_service_ok,int notify_service_critical,int notify_service_warning, int notify_service_unknown, int notify_service_flapping, int notify_host_up, int notify_host_down, int notify_host_unreachable, int notify_host_flapping){ contact *temp_contact; contact *new_contact; int x; #ifdef NSCORE char temp_buffer[MAX_INPUT_BUFFER]; #endif #ifdef DEBUG0 printf("add_contact() start\n"); #endif /* make sure we have the data we need */ if(name==NULL || alias==NULL || (email==NULL && pager==NULL)){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Contact name, alias, or email address and pager number are NULL\n"); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } strip(name); strip(alias); strip(email); strip(pager); strip(svc_notification_period); strip(host_notification_period); if(!strcmp(name,"") || !strcmp(alias,"")){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Contact name or alias is NULL\n"); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } if((email==NULL || !strcmp(email,"")) && (pager==NULL || !strcmp(pager,""))){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Contact email address and pager number are both NULL\n"); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } /* make sure there isn't a contact by this name already added */ temp_contact=find_contact(name); if(temp_contact!=NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Contact '%s' has already been defined\n",name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } if(notify_service_ok<0 || notify_service_ok>1){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Invalid notify_service_ok value for contact '%s'\n",name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } if(notify_service_critical<0 || notify_service_critical>1){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Invalid notify_service_critical value for contact '%s'\n",name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } if(notify_service_warning<0 || notify_service_warning>1){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Invalid notify_service_warning value for contact '%s'\n",name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } if(notify_service_unknown<0 || notify_service_unknown>1){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Invalid notify_service_unknown value for contact '%s'\n",name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } if(notify_service_flapping<0 || notify_service_flapping>1){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Invalid notify_service_flapping value for contact '%s'\n",name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } if(notify_host_up<0 || notify_host_up>1){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Invalid notify_host_up value for contact '%s'\n",name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } if(notify_host_down<0 || notify_host_down>1){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Invalid notify_host_down value for contact '%s'\n",name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } if(notify_host_unreachable<0 || notify_host_unreachable>1){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Invalid notify_host_unreachable value for contact '%s'\n",name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } if(notify_host_flapping<0 || notify_host_flapping>1){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Invalid notify_host_flapping value for contact '%s'\n",name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } /* allocate memory for a new contact */ new_contact=(contact *)malloc(sizeof(contact)); if(new_contact==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not allocate memory for contact '%s'\n",name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } new_contact->name=strdup(name); if(new_contact->name==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not allocate memory for contact '%s' name\n",name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif free(new_contact); return NULL; } new_contact->alias=strdup(alias); if(new_contact->alias==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not allocate memory for contact '%s' alias\n",name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif free(new_contact->name); free(new_contact); return NULL; } if(email!=NULL && strcmp(email,"")){ new_contact->email=strdup(email); if(new_contact->email==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not allocate memory for contact '%s' email address\n",name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif free(new_contact->name); free(new_contact->alias); free(new_contact); return NULL; } } else new_contact->email=NULL; if(pager!=NULL && strcmp(pager,"")){ new_contact->pager=strdup(pager); if(new_contact->pager==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not allocate memory for contact '%s' pager number\n",name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif free(new_contact->name); free(new_contact->alias); if(new_contact->email!=NULL) free(new_contact->email); free(new_contact); return NULL; } } else new_contact->pager=NULL; if(svc_notification_period!=NULL && strcmp(svc_notification_period,"")){ new_contact->service_notification_period=strdup(svc_notification_period); if(new_contact->service_notification_period==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not allocate memory for contact '%s' service notification period\n",name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif free(new_contact->name); free(new_contact->alias); if(new_contact->email!=NULL) free(new_contact->email); if(new_contact->pager!=NULL) free(new_contact->pager); free(new_contact); return NULL; } } else new_contact->service_notification_period=NULL; if(host_notification_period!=NULL && strcmp(host_notification_period,"")){ new_contact->host_notification_period=strdup(host_notification_period); if(new_contact->host_notification_period==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not allocate memory for contact '%s' host notification period\n",name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif free(new_contact->name); free(new_contact->alias); if(new_contact->email!=NULL) free(new_contact->email); if(new_contact->pager!=NULL) free(new_contact->pager); if(new_contact->service_notification_period!=NULL) free(new_contact->service_notification_period); free(new_contact); return NULL; } } else new_contact->host_notification_period=NULL; for(x=0;xaddress[x]=NULL; if(addresses[x]!=NULL){ strip(addresses[x]); new_contact->address[x]=strdup(addresses[x]); if(new_contact->address[x]==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not allocate memory for contact '%s' address #%d\n",name,x); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif free(new_contact->name); free(new_contact->alias); free(new_contact->email); free(new_contact->pager); free(new_contact->service_notification_period); free(new_contact->host_notification_period); free(new_contact); return NULL; } } } new_contact->host_notification_commands=NULL; new_contact->service_notification_commands=NULL; new_contact->notify_on_service_recovery=(notify_service_ok>0)?TRUE:FALSE; new_contact->notify_on_service_critical=(notify_service_critical>0)?TRUE:FALSE; new_contact->notify_on_service_warning=(notify_service_warning>0)?TRUE:FALSE; new_contact->notify_on_service_unknown=(notify_service_unknown>0)?TRUE:FALSE; new_contact->notify_on_service_flapping=(notify_service_flapping>0)?TRUE:FALSE; new_contact->notify_on_host_recovery=(notify_host_up>0)?TRUE:FALSE; new_contact->notify_on_host_down=(notify_host_down>0)?TRUE:FALSE; new_contact->notify_on_host_unreachable=(notify_host_unreachable>0)?TRUE:FALSE; new_contact->notify_on_host_flapping=(notify_host_flapping>0)?TRUE:FALSE; new_contact->next=NULL; new_contact->nexthash=NULL; /* add new contact to contact chained hash list */ if(!add_contact_to_hashlist(new_contact)){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not allocate memory for contact list to add contact '%s'\n",name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif for(x=0;xaddress[x]); free(new_contact->name); free(new_contact->alias); free(new_contact->email); free(new_contact->pager); free(new_contact->service_notification_period); free(new_contact->host_notification_period); free(new_contact); return NULL; } #ifdef NSCORE /* contacts are sorted alphabetically for daemon, so add new items to tail of list */ if(contact_list==NULL){ contact_list=new_contact; contact_list_tail=contact_list; } else{ contact_list_tail->next=new_contact; contact_list_tail=new_contact; } #else /* contacts are sorted in reverse for CGIs, so add new items to head of list */ new_contact->next=contact_list; contact_list=new_contact; #endif #ifdef DEBUG1 printf("\tContact Name: %s\n",new_contact->name); printf("\tContact Alias: %s\n",new_contact->alias); printf("\tContact Email Address: %s\n",(new_contact->email==NULL)?"":new_contact->email); printf("\tContact Pager Address/Number: %s\n",(new_contact->pager==NULL)?"":new_contact->pager); printf("\tSvc Notification Time Period: %s\n",new_contact->service_notification_period); printf("\tHost Notification Time Period: %s\n",new_contact->host_notification_period); #endif #ifdef DEBUG0 printf("add_contact() end\n"); #endif return new_contact; } /* adds a host notification command to a contact definition */ commandsmember *add_host_notification_command_to_contact(contact *cntct,char *command_name){ commandsmember *new_commandsmember; #ifdef NSCORE char temp_buffer[MAX_INPUT_BUFFER]; #endif #ifdef DEBUG0 printf("add_host_notification_command_to_contact() start\n"); #endif /* make sure we have the data we need */ if(cntct==NULL || command_name==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Contact or host notification command is NULL\n"); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } strip(command_name); if(!strcmp(command_name,"")){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Contact '%s' host notification command is NULL\n",cntct->name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } /* allocate memory */ new_commandsmember=malloc(sizeof(commandsmember)); if(new_commandsmember==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not allocate memory for contact '%s' host notification command '%s'\n",cntct->name,command_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } new_commandsmember->command=strdup(command_name); if(new_commandsmember->command==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not allocate memory for contact '%s' host notification command '%s' name\n",cntct->name,command_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif free(new_commandsmember); return NULL; } /* add the notification command */ new_commandsmember->next=cntct->host_notification_commands; cntct->host_notification_commands=new_commandsmember; #ifdef DEBUG0 printf("add_host_notification_command_to_contact() end\n"); #endif return new_commandsmember; } /* adds a service notification command to a contact definition */ commandsmember *add_service_notification_command_to_contact(contact *cntct,char *command_name){ commandsmember *new_commandsmember; #ifdef NSCORE char temp_buffer[MAX_INPUT_BUFFER]; #endif #ifdef DEBUG0 printf("add_service_notification_command_to_contact() start\n"); #endif /* make sure we have the data we need */ if(cntct==NULL || command_name==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Contact or service notification command is NULL\n"); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } strip(command_name); if(!strcmp(command_name,"")){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Contact '%s' service notification command is NULL\n",cntct->name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } /* allocate memory */ new_commandsmember=malloc(sizeof(commandsmember)); if(new_commandsmember==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not allocate memory for contact '%s' service notification command '%s'\n",cntct->name,command_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } new_commandsmember->command=strdup(command_name); if(new_commandsmember->command==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not allocate memory for contact '%s' service notification command '%s' name\n",cntct->name,command_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif free(new_commandsmember); return NULL; } /* add the notification command */ new_commandsmember->next=cntct->service_notification_commands; cntct->service_notification_commands=new_commandsmember; #ifdef DEBUG0 printf("add_service_notification_command_to_contact() end\n"); #endif return new_commandsmember; } /* add a new contact group to the list in memory */ contactgroup *add_contactgroup(char *name,char *alias){ contactgroup *temp_contactgroup; contactgroup *new_contactgroup; #ifdef NSCORE char temp_buffer[MAX_INPUT_BUFFER]; #endif #ifdef DEBUG0 printf("add_contactgroup() start\n"); #endif /* make sure we have the data we need */ if(name==NULL || alias==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Contactgroup name or alias is NULL\n"); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } strip(name); strip(alias); if(!strcmp(name,"") || !strcmp(alias,"")){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Contactgroup name or alias is NULL\n"); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } /* make sure there isn't a contactgroup by this name added already */ temp_contactgroup=find_contactgroup(name); if(temp_contactgroup!=NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Contactgroup '%s' has already been defined\n",name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } /* allocate memory for a new contactgroup entry */ new_contactgroup=malloc(sizeof(contactgroup)); if(new_contactgroup==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not allocate memory for contactgroup '%s'\n",name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } new_contactgroup->group_name=strdup(name); if(new_contactgroup->group_name==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not allocate memory for contactgroup '%s' name\n",name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif free(new_contactgroup); return NULL; } new_contactgroup->alias=strdup(alias); if(new_contactgroup->alias==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not allocate memory for contactgroup '%s' alias\n",name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif free(new_contactgroup->group_name); free(new_contactgroup); return NULL; } new_contactgroup->members=NULL; new_contactgroup->next=NULL; new_contactgroup->nexthash=NULL; /* add new contactgroup to contactgroup chained hash list */ if(!add_contactgroup_to_hashlist(new_contactgroup)){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not allocate memory for contactgroup list to add contactgroup '%s'\n",name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif free(new_contactgroup->alias); free(new_contactgroup->group_name); free(new_contactgroup); return NULL; } #ifdef NSCORE /* contactgroups are sorted alphabetically for daemon, so add new items to tail of list */ if(contactgroup_list==NULL){ contactgroup_list=new_contactgroup; contactgroup_list_tail=contactgroup_list; } else{ contactgroup_list_tail->next=new_contactgroup; contactgroup_list_tail=new_contactgroup; } #else /* contactgroups are sorted in reverse for CGIs, so add new items to head of list */ new_contactgroup->next=contactgroup_list; contactgroup_list=new_contactgroup; #endif #ifdef DEBUG1 printf("\tGroup name: %s\n",new_contactgroup->group_name); printf("\tAlias: %s\n",new_contactgroup->alias); #endif #ifdef DEBUG0 printf("add_contactgroup() end\n"); #endif return new_contactgroup; } /* add a new member to a contact group */ contactgroupmember *add_contact_to_contactgroup(contactgroup *grp,char *contact_name){ contactgroupmember *new_contactgroupmember; #ifdef NSCORE char temp_buffer[MAX_INPUT_BUFFER]; #endif #ifdef DEBUG0 printf("add_contact_to_contactgroup() start\n"); #endif /* make sure we have the data we need */ if(grp==NULL || contact_name==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Contactgroup or contact name is NULL\n"); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } strip(contact_name); if(!strcmp(contact_name,"")){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Contactgroup '%s' contact name is NULL\n",grp->group_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } /* allocate memory for a new member */ new_contactgroupmember=malloc(sizeof(contactgroupmember)); if(new_contactgroupmember==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not allocate memory for contactgroup '%s' contact '%s'\n",grp->group_name,contact_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } new_contactgroupmember->contact_name=strdup(contact_name); if(new_contactgroupmember->contact_name==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not allocate memory for contactgroup '%s' contact '%s' name\n",grp->group_name,contact_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif free(new_contactgroupmember); return NULL; } /* add the new member to the head of the member list */ new_contactgroupmember->next=grp->members; grp->members=new_contactgroupmember; #ifdef DEBUG0 printf("add_contact_to_contactgroup() end\n"); #endif return new_contactgroupmember; } /* add a new service to the list in memory */ service *add_service(char *host_name, char *description, char *check_period, int max_attempts, int parallelize, int accept_passive_checks, int check_interval, int retry_interval, int notification_interval, char *notification_period, int notify_recovery, int notify_unknown, int notify_warning, int notify_critical, int notify_flapping, int notifications_enabled, int is_volatile, char *event_handler, int event_handler_enabled, char *check_command, int checks_enabled, int flap_detection_enabled, double low_flap_threshold, double high_flap_threshold, int stalk_ok, int stalk_warning, int stalk_unknown, int stalk_critical, int process_perfdata, int failure_prediction_enabled, char *failure_prediction_options, int check_freshness, int freshness_threshold, int retain_status_information, int retain_nonstatus_information, int obsess_over_service){ service *temp_service; service *new_service; #ifdef NSCORE char temp_buffer[MAX_INPUT_BUFFER]; int x; #endif #ifdef DEBUG0 printf("add_service() start\n"); #endif /* make sure we have everything we need */ if(host_name==NULL || description==NULL || check_command==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Service description, host name, or check command is NULL\n"); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } strip(host_name); strip(description); strip(check_command); strip(event_handler); strip(notification_period); strip(check_period); if(!strcmp(host_name,"") || !strcmp(description,"") || !strcmp(check_command,"")){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Service description, host name, or check command is NULL\n"); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } /* make sure the host name isn't too long */ if(strlen(host_name)>MAX_HOSTNAME_LENGTH-1){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Host name '%s' for service '%s' exceeds maximum length of %d characters\n",host_name,description,MAX_HOSTNAME_LENGTH-1); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } /* make sure there isn't a service by this name added already */ temp_service=find_service(host_name,description); if(temp_service!=NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Service '%s' on host '%s' has already been defined\n",description,host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } /* make sure the service description isn't too long */ if(strlen(description)>MAX_SERVICEDESC_LENGTH-1){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Name of service '%s' on host '%s' exceeds maximum length of %d characters\n",description,host_name,MAX_SERVICEDESC_LENGTH-1); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } if(parallelize<0 || parallelize>1){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Invalid parallelize value for service '%s' on host '%s'\n",description,host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } if(accept_passive_checks<0 || accept_passive_checks>1){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Invalid accept_passive_checks value for service '%s' on host '%s'\n",description,host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } if(event_handler_enabled<0 || event_handler_enabled>1){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Invalid event_handler_enabled value for service '%s' on host '%s'\n",description,host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } if(checks_enabled<0 || checks_enabled>1){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Invalid checks_enabled value for service '%s' on host '%s'\n",description,host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } if(notifications_enabled<0 || notifications_enabled>1){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Invalid notifications_enabled value for service '%s' on host '%s'\n",description,host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } if(max_attempts<=0 || check_interval<0 || retry_interval<=0 || notification_interval<0){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Invalid max_attempts, check_interval, retry_interval, or notification_interval value for service '%s' on host '%s'\n",description,host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } if(notify_recovery<0 || notify_recovery>1){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Invalid notify_recovery value for service '%s' on host '%s'\n",description,host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } if(notify_critical<0 || notify_critical>1){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Invalid notify_critical value for service '%s' on host '%s'\n",description,host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } if(notify_flapping<0 || notify_flapping>1){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Invalid notify_flapping value '%d' for service '%s' on host '%s'\n",notify_flapping,description,host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } if(notify_recovery<0 || notify_recovery>1){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Invalid notify_recovery value for service '%s' on host '%s'\n",description,host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } if(is_volatile<0 || is_volatile>1){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Invalid is_volatile value for service '%s' on host '%s'\n",description,host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } if(flap_detection_enabled<0 || flap_detection_enabled>1){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Invalid flap_detection_enabled value for service '%s' on host '%s'\n",description,host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } if(stalk_ok<0 || stalk_ok>1){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Invalid stalk_ok value for service '%s' on host '%s'\n",description,host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } if(stalk_warning<0 || stalk_warning>1){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Invalid stalk_warning value for service '%s' on host '%s'\n",description,host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } if(stalk_unknown<0 || stalk_unknown>1){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Invalid stalk_unknown value for service '%s' on host '%s'\n",description,host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } if(stalk_critical<0 || stalk_critical>1){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Invalid stalk_critical value for service '%s' on host '%s'\n",description,host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } if(process_perfdata<0 || process_perfdata>1){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Invalid process_perfdata value for service '%s' on host '%s'\n",description,host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } if(failure_prediction_enabled<0 || failure_prediction_enabled>1){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Invalid failure_prediction_enabled value for service '%s' on host '%s'\n",description,host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } if(check_freshness<0 || check_freshness>1){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Invalid check_freshness value for service '%s' on host '%s'\n",description,host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } if(freshness_threshold<0){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Invalid freshness_threshold value for service '%s' on host '%s'\n",description,host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } if(retain_status_information<0 || retain_status_information>1){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Invalid retain_status_information value for service '%s' on host '%s'\n",description,host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } if(retain_nonstatus_information<0 || retain_nonstatus_information>1){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Invalid retain_nonstatus_information value for service '%s' on host '%s'\n",description,host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } if(obsess_over_service<0 || obsess_over_service>1){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Invalid obsess_over_service value for service '%s' on host '%s'\n",description,host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } /* allocate memory */ new_service=(service *)malloc(sizeof(service)); if(new_service==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not allocate memory for service '%s' on host '%s'\n",description,host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } new_service->host_name=strdup(host_name); if(new_service->host_name==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not allocate memory for service '%s' on host '%s' name\n",description,host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif free(new_service); return NULL; } new_service->description=strdup(description); if(new_service->description==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not allocate memory for service '%s' on host '%s' description\n",description,host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif free(new_service->host_name); free(new_service); return NULL; } new_service->service_check_command=strdup(check_command); if(new_service->service_check_command==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not allocate memory for service '%s' on host '%s' check command\n",description,host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif free(new_service->description); free(new_service->host_name); free(new_service); return NULL; } if(event_handler!=NULL && strcmp(event_handler,"")){ new_service->event_handler=strdup(event_handler); if(new_service->event_handler==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not allocate memory for service '%s' on host '%s' event handler\n",description,host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif free(new_service->service_check_command); free(new_service->description); free(new_service->host_name); free(new_service); return NULL; } } else new_service->event_handler=NULL; if(notification_period!=NULL && strcmp(notification_period,"")){ new_service->notification_period=strdup(notification_period); if(new_service->notification_period==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not allocate memory for service '%s' on host '%s' notification period\n",description,host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif if(new_service->event_handler!=NULL) free(new_service->event_handler); free(new_service->service_check_command); free(new_service->description); free(new_service->host_name); free(new_service); return NULL; } } else new_service->notification_period=NULL; if(check_period!=NULL && strcmp(check_period,"")){ new_service->check_period=strdup(check_period); if(new_service->check_period==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not allocate memory for service '%s' on host '%s' check period\n",description,host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif if(new_service->notification_period!=NULL) free(new_service->notification_period); if(new_service->event_handler!=NULL) free(new_service->event_handler); free(new_service->service_check_command); free(new_service->description); free(new_service->host_name); free(new_service); return NULL; } } else new_service->check_period=NULL; if(failure_prediction_options!=NULL && strcmp(failure_prediction_options,"")){ new_service->failure_prediction_options=strdup(failure_prediction_options); if(new_service->failure_prediction_options==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not allocate memory for service '%s' on host '%s' failure prediction options\n",description,host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif if(new_service->check_period!=NULL) free(new_service->check_period); if(new_service->notification_period!=NULL) free(new_service->notification_period); if(new_service->event_handler!=NULL) free(new_service->event_handler); free(new_service->service_check_command); free(new_service->description); free(new_service->host_name); free(new_service); return NULL; } } else new_service->failure_prediction_options=NULL; new_service->contact_groups=NULL; new_service->check_interval=check_interval; new_service->retry_interval=retry_interval; new_service->max_attempts=max_attempts; new_service->parallelize=(parallelize>0)?TRUE:FALSE; new_service->notification_interval=notification_interval; new_service->notify_on_unknown=(notify_unknown>0)?TRUE:FALSE; new_service->notify_on_warning=(notify_warning>0)?TRUE:FALSE; new_service->notify_on_critical=(notify_critical>0)?TRUE:FALSE; new_service->notify_on_recovery=(notify_recovery>0)?TRUE:FALSE; new_service->notify_on_flapping=(notify_flapping>0)?TRUE:FALSE; new_service->is_volatile=(is_volatile>0)?TRUE:FALSE; new_service->flap_detection_enabled=(flap_detection_enabled>0)?TRUE:FALSE; new_service->low_flap_threshold=low_flap_threshold; new_service->high_flap_threshold=high_flap_threshold; new_service->stalk_on_ok=(stalk_ok>0)?TRUE:FALSE; new_service->stalk_on_warning=(stalk_warning>0)?TRUE:FALSE; new_service->stalk_on_unknown=(stalk_unknown>0)?TRUE:FALSE; new_service->stalk_on_critical=(stalk_critical>0)?TRUE:FALSE; new_service->process_performance_data=(process_perfdata>0)?TRUE:FALSE; new_service->check_freshness=(check_freshness>0)?TRUE:FALSE; new_service->freshness_threshold=freshness_threshold; new_service->accept_passive_service_checks=(accept_passive_checks>0)?TRUE:FALSE; new_service->event_handler_enabled=(event_handler_enabled>0)?TRUE:FALSE; new_service->checks_enabled=(checks_enabled>0)?TRUE:FALSE; new_service->retain_status_information=(retain_status_information>0)?TRUE:FALSE; new_service->retain_nonstatus_information=(retain_nonstatus_information>0)?TRUE:FALSE; new_service->notifications_enabled=(notifications_enabled>0)?TRUE:FALSE; new_service->obsess_over_service=(obsess_over_service>0)?TRUE:FALSE; new_service->failure_prediction_enabled=(failure_prediction_enabled>0)?TRUE:FALSE; #ifdef NSCORE new_service->problem_has_been_acknowledged=FALSE; new_service->acknowledgement_type=ACKNOWLEDGEMENT_NONE; new_service->check_type=SERVICE_CHECK_ACTIVE; new_service->current_attempt=1; new_service->current_state=STATE_OK; new_service->last_state=STATE_OK; new_service->last_hard_state=STATE_OK; /* initial state type changed from SOFT_STATE on 6/17/03 - shouldn't this have been HARD_STATE all along? */ new_service->state_type=HARD_STATE; new_service->host_problem_at_last_check=FALSE; #ifdef REMOVED_041403 new_service->no_recovery_notification=FALSE; #endif new_service->check_flapping_recovery_notification=FALSE; new_service->next_check=(time_t)0; new_service->should_be_scheduled=TRUE; new_service->last_check=(time_t)0; new_service->last_notification=(time_t)0; new_service->next_notification=(time_t)0; new_service->no_more_notifications=FALSE; new_service->last_state_change=(time_t)0; new_service->last_hard_state_change=(time_t)0; new_service->last_time_ok=(time_t)0; new_service->last_time_warning=(time_t)0; new_service->last_time_unknown=(time_t)0; new_service->last_time_critical=(time_t)0; new_service->has_been_checked=FALSE; new_service->is_being_freshened=FALSE; new_service->notified_on_unknown=FALSE; new_service->notified_on_warning=FALSE; new_service->notified_on_critical=FALSE; new_service->current_notification_number=0; new_service->latency=0.0; new_service->execution_time=0.0; new_service->is_executing=FALSE; new_service->check_options=CHECK_OPTION_NONE; new_service->scheduled_downtime_depth=0; new_service->pending_flex_downtime=0; for(x=0;xstate_history[x]=STATE_OK; new_service->state_history_index=0; new_service->is_flapping=FALSE; new_service->flapping_comment_id=0; new_service->percent_state_change=0.0; new_service->modified_attributes=MODATTR_NONE; /* allocate new plugin output buffer */ new_service->plugin_output=(char *)malloc(MAX_PLUGINOUTPUT_LENGTH); if(new_service->plugin_output==NULL){ snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not allocate memory for service '%s' on host '%s' plugin output buffer\n",description,host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); if(new_service->failure_prediction_options!=NULL) free(new_service->failure_prediction_options); if(new_service->notification_period!=NULL) free(new_service->notification_period); if(new_service->event_handler!=NULL) free(new_service->event_handler); free(new_service->service_check_command); free(new_service->description); free(new_service->host_name); free(new_service); return NULL; } strcpy(new_service->plugin_output,"(Service assumed to be ok)"); /* allocate new performance data buffer */ new_service->perf_data=(char *)malloc(MAX_PLUGINOUTPUT_LENGTH); if(new_service->perf_data==NULL){ snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not allocate memory for service '%s' on host '%s' performance data buffer\n",description,host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); if(new_service->failure_prediction_options!=NULL) free(new_service->failure_prediction_options); if(new_service->notification_period!=NULL) free(new_service->notification_period); if(new_service->event_handler!=NULL) free(new_service->event_handler); free(new_service->service_check_command); free(new_service->description); free(new_service->host_name); free(new_service->plugin_output); free(new_service); return NULL; } strcpy(new_service->perf_data,""); #endif new_service->next=NULL; new_service->nexthash=NULL; /* add new service to service chained hash list */ if(!add_service_to_hashlist(new_service)){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not allocate memory for service list to add new service '%s' on host '%s'\n",description,host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); if(new_service->perf_data!=NULL) free(new_service->perf_data); if(new_service->plugin_output) free(new_service->plugin_output); #endif if(new_service->failure_prediction_options!=NULL) free(new_service->failure_prediction_options); if(new_service->notification_period!=NULL) free(new_service->notification_period); if(new_service->event_handler!=NULL) free(new_service->event_handler); if(new_service->service_check_command) free(new_service->service_check_command); if(new_service->description) free(new_service->description); if(new_service->host_name) free(new_service->host_name); free(new_service); return NULL; } #ifdef NSCORE /* services are sorted alphabetically for daemon, so add new items to tail of list */ if(service_list==NULL){ service_list=new_service; service_list_tail=service_list; } else{ service_list_tail->next=new_service; service_list_tail=new_service; } #else /* services are sorted in reverse for CGIs, so add new items to head of list */ new_service->next=service_list; service_list=new_service; #endif #ifdef DEBUG1 printf("\tHost: %s\n",new_service->host_name); printf("\tDescription: %s\n",new_service->description); printf("\tCommand: %s\n",new_service->service_check_command); printf("\tCheck Interval: %d\n",new_service->check_interval); printf("\tRetry Interval: %d\n",new_service->retry_interval); printf("\tMax attempts: %d\n",new_service->max_attempts); printf("\tNotification Interval: %d\n",new_service->notification_interval); printf("\tNotification Time Period: %s\n",new_service->notification_period); printf("\tNotify On Warning: %s\n",(new_service->notify_on_warning==1)?"yes":"no"); printf("\tNotify On Critical: %s\n",(new_service->notify_on_critical==1)?"yes":"no"); printf("\tNotify On Recovery: %s\n",(new_service->notify_on_recovery==1)?"yes":"no"); printf("\tEvent Handler: %s\n",(new_service->event_handler==NULL)?"N/A":new_service->event_handler); #endif #ifdef DEBUG0 printf("add_service() end\n"); #endif return new_service; } /* adds a contact group to a service */ contactgroupsmember *add_contactgroup_to_service(service *svc,char *group_name){ contactgroupsmember *new_contactgroupsmember; #ifdef NSCORE char temp_buffer[MAX_INPUT_BUFFER]; #endif #ifdef DEBUG0 printf("add_contactgroup_to_service() start\n"); #endif /* bail out if we weren't given the data we need */ if(svc==NULL || group_name==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Service or contactgroup name is NULL\n"); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } strip(group_name); if(!strcmp(group_name,"")){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Contactgroup name is NULL\n"); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } /* allocate memory for the contactgroups member */ new_contactgroupsmember=malloc(sizeof(contactgroupsmember)); if(new_contactgroupsmember==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not allocate memory for contact group '%s' for service '%s' on host '%s'\n",group_name,svc->description,svc->host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } new_contactgroupsmember->group_name=strdup(group_name); if(new_contactgroupsmember->group_name==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not allocate memory for contact group '%s' name for service '%s' on host '%s'\n",group_name,svc->description,svc->host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif free(new_contactgroupsmember); return NULL; } /* add this contactgroup to the service */ new_contactgroupsmember->next=svc->contact_groups; svc->contact_groups=new_contactgroupsmember; #ifdef DEBUG0 printf("add_contactgroup_to_service() end\n"); #endif return new_contactgroupsmember; } /* add a new command to the list in memory */ command *add_command(char *name,char *value){ command *new_command; command *temp_command; #ifdef NSCORE char temp_buffer[MAX_INPUT_BUFFER]; #endif #ifdef DEBUG0 printf("add_command() start\n"); #endif /* make sure we have the data we need */ if(name==NULL || value==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Command name of command line is NULL\n"); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } strip(name); strip(value); if(!strcmp(name,"") || !strcmp(value,"")){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Command name of command line is NULL\n"); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } /* make sure there isn't a command by this name added already */ temp_command=find_command(name); if(temp_command!=NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Command '%s' has already been defined\n",name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } /* allocate memory for the new command */ new_command=(command *)malloc(sizeof(command)); if(new_command==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not allocate memory for command '%s'\n",name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } new_command->name=strdup(name); if(new_command->name==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not allocate memory for command '%s' name\n",name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif free(new_command); return NULL; } new_command->command_line=strdup(value); if(new_command->command_line==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not allocate memory for command '%s' alias\n",name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif free(new_command->name); free(new_command); return NULL; } new_command->next=NULL; new_command->nexthash=NULL; /* add new command to command chained hash list */ if(!add_command_to_hashlist(new_command)){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not allocate memory for command list to add command '%s'\n",name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif free(new_command->name); free(new_command); return NULL; } #ifdef NSCORE /* commands are sorted alphabetically for daemon, so add new items to tail of list */ if(command_list==NULL){ command_list=new_command; command_list_tail=command_list; } else { command_list_tail->next=new_command; command_list_tail=new_command; } #else /* commands are sorted in reverse for CGIs, so add new items to head of list */ new_command->next=command_list; command_list=new_command; #endif #ifdef DEBUG1 printf("\tName: %s\n",new_command->name); printf("\tCommand Line: %s\n",new_command->command_line); #endif #ifdef DEBUG0 printf("add_command() end\n"); #endif return new_command; } /* add a new service escalation to the list in memory */ serviceescalation *add_serviceescalation(char *host_name,char *description,int first_notification,int last_notification, int notification_interval, char *escalation_period, int escalate_on_warning, int escalate_on_unknown, int escalate_on_critical, int escalate_on_recovery){ serviceescalation *new_serviceescalation; #ifdef NSCORE char temp_buffer[MAX_INPUT_BUFFER]; #endif #ifdef DEBUG0 printf("add_serviceescalation() start\n"); #endif /* make sure we have the data we need */ if(host_name==NULL || description==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Service escalation host name or description is NULL\n"); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } strip(host_name); strip(description); if(!strcmp(host_name,"") || !strcmp(description,"")){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Service escalation host name or description is NULL\n"); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } /* check options */ if(escalate_on_warning<0 || escalate_on_warning>1 || escalate_on_unknown<0 || escalate_on_unknown>1 || escalate_on_critical<0 || escalate_on_critical>1 || escalate_on_recovery<0 || escalate_on_recovery>1){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Invalid escalation options in service '%s' on host '%s' escalation\n",description,host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } /* allocate memory for a new service escalation entry */ new_serviceescalation=malloc(sizeof(serviceescalation)); if(new_serviceescalation==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not allocate memory for service '%s' on host '%s' escalation\n",description,host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } new_serviceescalation->host_name=strdup(host_name); if(new_serviceescalation->host_name==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not allocate memory for service '%s' on host '%s' escalation host name\n",description,host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif free(new_serviceescalation); return NULL; } new_serviceescalation->description=strdup(description); if(new_serviceescalation->description==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not allocate memory for service '%s' on host '%s' escalation description\n",description,host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif free(new_serviceescalation->host_name); free(new_serviceescalation); return NULL; } if(escalation_period==NULL) new_serviceescalation->escalation_period=NULL; else{ new_serviceescalation->escalation_period=strdup(escalation_period); if(new_serviceescalation->escalation_period==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not allocate memory for service '%s' on host '%s' escalation period\n",description,host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif free(new_serviceescalation->host_name); free(new_serviceescalation->description); free(new_serviceescalation); return NULL; } } new_serviceescalation->first_notification=first_notification; new_serviceescalation->last_notification=last_notification; new_serviceescalation->notification_interval=(notification_interval<=0)?0:notification_interval; new_serviceescalation->escalate_on_recovery=(escalate_on_recovery>0)?TRUE:FALSE; new_serviceescalation->escalate_on_warning=(escalate_on_warning>0)?TRUE:FALSE; new_serviceescalation->escalate_on_unknown=(escalate_on_unknown>0)?TRUE:FALSE; new_serviceescalation->escalate_on_critical=(escalate_on_critical>0)?TRUE:FALSE; new_serviceescalation->contact_groups=NULL; new_serviceescalation->next=NULL; new_serviceescalation->nexthash=NULL; /* add new serviceescalation to serviceescalation chained hash list */ if(!add_serviceescalation_to_hashlist(new_serviceescalation)){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not allocate memory for serviceescalation list to add escalation for service '%s' on host '%s'\n",description,host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif free(new_serviceescalation->host_name); free(new_serviceescalation->description); free(new_serviceescalation->escalation_period); free(new_serviceescalation); return NULL; } #ifdef NSCORE /* service escalations are sorted alphabetically for daemon, so add new items to tail of list */ if(serviceescalation_list==NULL){ serviceescalation_list=new_serviceescalation; serviceescalation_list_tail=serviceescalation_list; } else{ serviceescalation_list_tail->next=new_serviceescalation; serviceescalation_list_tail=new_serviceescalation; } #else /* service escalations are sorted in reverse for CGIs, so add new items to head of list */ new_serviceescalation->next=serviceescalation_list; serviceescalation_list=new_serviceescalation; #endif #ifdef DEBUG1 printf("\tHost name: %s\n",new_serviceescalation->host_name); printf("\tSvc description: %s\n",new_serviceescalation->description); printf("\tFirst notification: %d\n",new_serviceescalation->first_notification); printf("\tLast notification: %d\n",new_serviceescalation->last_notification); printf("\tNotification Interval: %d\n",new_serviceescalation->notification_interval); #endif #ifdef DEBUG0 printf("add_serviceescalation() end\n"); #endif return new_serviceescalation; } /* adds a contact group to a service escalation */ contactgroupsmember *add_contactgroup_to_serviceescalation(serviceescalation *se,char *group_name){ contactgroupsmember *new_contactgroupsmember; #ifdef NSCORE char temp_buffer[MAX_INPUT_BUFFER]; #endif #ifdef DEBUG0 printf("add_contactgroup_to_serviceescalation() start\n"); #endif /* bail out if we weren't given the data we need */ if(se==NULL || group_name==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Service escalation or contactgroup name is NULL\n"); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } strip(group_name); if(!strcmp(group_name,"")){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Contactgroup name is NULL\n"); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } /* allocate memory for the contactgroups member */ new_contactgroupsmember=(contactgroupsmember *)malloc(sizeof(contactgroupsmember)); if(new_contactgroupsmember==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not allocate memory for contact group '%s' for service '%s' on host '%s' escalation\n",group_name,se->description,se->host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } new_contactgroupsmember->group_name=strdup(group_name); if(new_contactgroupsmember->group_name==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not allocate memory for contact group '%s' name for service '%s' on host '%s' escalation\n",group_name,se->description,se->host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif free(new_contactgroupsmember); return NULL; } /* add this contactgroup to the service escalation */ new_contactgroupsmember->next=se->contact_groups; se->contact_groups=new_contactgroupsmember; #ifdef DEBUG0 printf("add_contactgroup_to_serviceescalation() end\n"); #endif return new_contactgroupsmember; } /* adds a service dependency definition */ servicedependency *add_service_dependency(char *dependent_host_name, char *dependent_service_description, char *host_name, char *service_description, int dependency_type, int inherits_parent, int fail_on_ok, int fail_on_warning, int fail_on_unknown, int fail_on_critical, int fail_on_pending){ servicedependency *new_servicedependency; #ifdef NSCORE char temp_buffer[MAX_INPUT_BUFFER]; #endif #ifdef DEBUG0 printf("add_service_dependency() start\n"); #endif /* make sure we have what we need */ if(dependent_host_name==NULL || dependent_service_description==NULL || host_name==NULL || service_description==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: NULL service description/host name in service dependency definition\n"); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } strip(dependent_host_name); strip(dependent_service_description); strip(host_name); strip(service_description); if(!strcmp(dependent_host_name,"") || !strcmp(dependent_service_description,"") || !strcmp(host_name,"") || !strcmp(service_description,"")){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: NULL service description/host name in service dependency definition\n"); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } if(fail_on_ok<0 || fail_on_ok>1){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Invalid fail_on_ok value for service '%s' on host '%s' dependency definition\n",dependent_service_description,dependent_host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } if(fail_on_warning<0 || fail_on_warning>1){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Invalid fail_on_warning value for service '%s' on host '%s' dependency definition\n",dependent_service_description,dependent_host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } if(fail_on_unknown<0 || fail_on_unknown>1){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Invalid fail_on_unknown value for service '%s' on host '%s' dependency definition\n",dependent_service_description,dependent_host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } if(fail_on_critical<0 || fail_on_critical>1){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Invalid fail_on_critical value for service '%s' on host '%s' dependency definition\n",dependent_service_description,dependent_host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } if(fail_on_pending<0 || fail_on_pending>1){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Invalid fail_on_pending value for service '%s' on host '%s' dependency definition\n",dependent_service_description,dependent_host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } if(inherits_parent<0 || inherits_parent>1){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Invalid inherits_parent value for service '%s' on host '%s' dependency definition\n",dependent_service_description,dependent_host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } /* allocate memory for a new service dependency entry */ new_servicedependency=(servicedependency *)malloc(sizeof(servicedependency)); if(new_servicedependency==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not allocate memory for service '%s' on host '%s' dependency\n",dependent_service_description,dependent_host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } new_servicedependency->dependent_host_name=strdup(dependent_host_name); if(new_servicedependency->dependent_host_name==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not allocate memory for service '%s' on host '%s' dependency\n",dependent_service_description,dependent_host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif free(new_servicedependency); return NULL; } new_servicedependency->dependent_service_description=strdup(dependent_service_description); if(new_servicedependency->dependent_service_description==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not allocate memory for service '%s' on host '%s' dependency\n",dependent_service_description,dependent_host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif free(new_servicedependency); free(new_servicedependency->dependent_host_name); return NULL; } new_servicedependency->host_name=strdup(host_name); if(new_servicedependency->host_name==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not allocate memory for service '%s' on host '%s' dependency\n",dependent_service_description,dependent_host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif free(new_servicedependency); free(new_servicedependency->dependent_host_name); free(new_servicedependency->dependent_service_description); return NULL; } new_servicedependency->service_description=strdup(service_description); if(new_servicedependency->service_description==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not allocate memory for service '%s' on host '%s' dependency\n",dependent_service_description,dependent_host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif free(new_servicedependency); free(new_servicedependency->dependent_host_name); free(new_servicedependency->dependent_service_description); free(new_servicedependency->host_name); return NULL; } new_servicedependency->dependency_type=(dependency_type==EXECUTION_DEPENDENCY)?EXECUTION_DEPENDENCY:NOTIFICATION_DEPENDENCY; new_servicedependency->inherits_parent=(inherits_parent>0)?TRUE:FALSE; new_servicedependency->fail_on_ok=(fail_on_ok==1)?TRUE:FALSE; new_servicedependency->fail_on_warning=(fail_on_warning==1)?TRUE:FALSE; new_servicedependency->fail_on_unknown=(fail_on_unknown==1)?TRUE:FALSE; new_servicedependency->fail_on_critical=(fail_on_critical==1)?TRUE:FALSE; new_servicedependency->fail_on_pending=(fail_on_pending==1)?TRUE:FALSE; #ifdef NSCORE new_servicedependency->circular_path_checked=FALSE; new_servicedependency->contains_circular_path=FALSE; #endif new_servicedependency->next=NULL; new_servicedependency->nexthash=NULL; /* add new servicedependency to servicedependency chained hash list */ if(!add_servicedependency_to_hashlist(new_servicedependency)){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not allocate memory for servicedependency list to add dependency for service '%s' on host '%s'\n",dependent_service_description,dependent_host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif free(new_servicedependency->host_name); free(new_servicedependency->service_description); free(new_servicedependency->dependent_host_name); free(new_servicedependency->dependent_service_description); free(new_servicedependency); return NULL; } #ifdef NSCORE /* service dependencies are sorted alphabetically for daemon, so add new items to tail of list */ if(servicedependency_list==NULL){ servicedependency_list=new_servicedependency; servicedependency_list_tail=servicedependency_list; } else{ servicedependency_list_tail->next=new_servicedependency; servicedependency_list_tail=new_servicedependency; } #else /* service dependencies are sorted in reverse for CGIs, so add new items to head of list */ new_servicedependency->next=servicedependency_list; servicedependency_list=new_servicedependency; #endif #ifdef DEBUG0 printf("add_service_dependency() end\n"); #endif return new_servicedependency; } /* adds a host dependency definition */ hostdependency *add_host_dependency(char *dependent_host_name, char *host_name, int dependency_type, int inherits_parent, int fail_on_up, int fail_on_down, int fail_on_unreachable, int fail_on_pending){ hostdependency *new_hostdependency; #ifdef NSCORE char temp_buffer[MAX_INPUT_BUFFER]; #endif #ifdef DEBUG0 printf("add_host_dependency() start\n"); #endif /* make sure we have what we need */ if(dependent_host_name==NULL || host_name==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: NULL host name in host dependency definition\n"); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } strip(dependent_host_name); strip(host_name); if(!strcmp(dependent_host_name,"") || !strcmp(host_name,"")){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: NULL host name in host dependency definition\n"); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } if(fail_on_up<0 || fail_on_up>1){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Invalid fail_on_up value for host '%s' dependency definition\n",dependent_host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } if(fail_on_down<0 || fail_on_down>1){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Invalid fail_on_down value for host '%s' dependency definition\n",dependent_host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } if(fail_on_unreachable<0 || fail_on_unreachable>1){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Invalid fail_on_unreachable value for host '%s' dependency definition\n",dependent_host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } if(fail_on_pending<0 || fail_on_pending>1){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Invalid fail_on_pending value for host '%s' dependency definition\n",dependent_host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } /* allocate memory for a new host dependency entry */ new_hostdependency=(hostdependency *)malloc(sizeof(hostdependency)); if(new_hostdependency==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not allocate memory for host '%s' dependency\n",dependent_host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } new_hostdependency->dependent_host_name=strdup(dependent_host_name); if(new_hostdependency->dependent_host_name==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not allocate memory for host '%s' dependency\n",dependent_host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif free(new_hostdependency); return NULL; } new_hostdependency->host_name=strdup(host_name); if(new_hostdependency->host_name==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not allocate memory for host '%s' dependency\n",dependent_host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif free(new_hostdependency); free(new_hostdependency->dependent_host_name); return NULL; } new_hostdependency->dependency_type=(dependency_type==EXECUTION_DEPENDENCY)?EXECUTION_DEPENDENCY:NOTIFICATION_DEPENDENCY; new_hostdependency->inherits_parent=(inherits_parent>0)?TRUE:FALSE; new_hostdependency->fail_on_up=(fail_on_up==1)?TRUE:FALSE; new_hostdependency->fail_on_down=(fail_on_down==1)?TRUE:FALSE; new_hostdependency->fail_on_unreachable=(fail_on_unreachable==1)?TRUE:FALSE; new_hostdependency->fail_on_pending=(fail_on_pending==1)?TRUE:FALSE; #ifdef NSCORE new_hostdependency->circular_path_checked=FALSE; new_hostdependency->contains_circular_path=FALSE; #endif new_hostdependency->next=NULL; new_hostdependency->nexthash=NULL; /* add new hostdependency to hostdependency chained hash list */ if(!add_hostdependency_to_hashlist(new_hostdependency)){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not allocate memory for hostdependency list to add dependency for host '%s'\n",dependent_host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif free(new_hostdependency->host_name); free(new_hostdependency->dependent_host_name); free(new_hostdependency); return NULL; } #ifdef NSCORE /* host dependencies are sorted alphabetically for daemon, so add new items to tail of list */ if(hostdependency_list==NULL){ hostdependency_list=new_hostdependency; hostdependency_list_tail=hostdependency_list; } else { hostdependency_list_tail->next=new_hostdependency; hostdependency_list_tail=new_hostdependency; } #else /* host dependencies are sorted in reverse for CGIs, so add new items to head of list */ new_hostdependency->next=hostdependency_list; hostdependency_list=new_hostdependency; #endif #ifdef DEBUG0 printf("add_host_dependency() end\n"); #endif return new_hostdependency; } /* add a new host escalation to the list in memory */ hostescalation *add_hostescalation(char *host_name,int first_notification,int last_notification, int notification_interval, char *escalation_period, int escalate_on_down, int escalate_on_unreachable, int escalate_on_recovery){ hostescalation *new_hostescalation; #ifdef NSCORE char temp_buffer[MAX_INPUT_BUFFER]; #endif #ifdef DEBUG0 printf("add_hostescalation() start\n"); #endif /* make sure we have the data we need */ if(host_name==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Host escalation host name is NULL\n"); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } strip(host_name); if(!strcmp(host_name,"")){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Host escalation host name is NULL\n"); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } /* check options */ if(escalate_on_down<0 || escalate_on_down>1 || escalate_on_unreachable<0 || escalate_on_unreachable>1 || escalate_on_recovery<0 || escalate_on_recovery>1){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Invalid escalation options in host '%s' escalation\n",host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } /* allocate memory for a new host escalation entry */ new_hostescalation=malloc(sizeof(hostescalation)); if(new_hostescalation==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not allocate memory for host '%s' escalation\n",host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } new_hostescalation->host_name=strdup(host_name); if(new_hostescalation->host_name==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not allocate memory for host '%s' escalation host name\n",host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif free(new_hostescalation); return NULL; } if(escalation_period==NULL) new_hostescalation->escalation_period=NULL; else{ new_hostescalation->escalation_period=strdup(escalation_period); if(new_hostescalation->escalation_period==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not allocate memory for host '%s' escalation period\n",host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif free(new_hostescalation->host_name); free(new_hostescalation); return NULL; } } new_hostescalation->first_notification=first_notification; new_hostescalation->last_notification=last_notification; new_hostescalation->notification_interval=(notification_interval<=0)?0:notification_interval; new_hostescalation->escalate_on_recovery=(escalate_on_recovery>0)?TRUE:FALSE; new_hostescalation->escalate_on_down=(escalate_on_down>0)?TRUE:FALSE; new_hostescalation->escalate_on_unreachable=(escalate_on_unreachable>0)?TRUE:FALSE; new_hostescalation->contact_groups=NULL; new_hostescalation->next=NULL; new_hostescalation->nexthash=NULL; /* add new hostescalation to hostescalation chained hash list */ if(!add_hostescalation_to_hashlist(new_hostescalation)){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not allocate memory for hostescalation list to add escalation for host '%s'\n",host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif free(new_hostescalation->host_name); free(new_hostescalation->escalation_period); free(new_hostescalation); return NULL; } #ifdef NSCORE /* host escalations are sorted alphabetically for daemon, so add new items to tail of list */ if(hostescalation_list==NULL){ hostescalation_list=new_hostescalation; hostescalation_list_tail=hostescalation_list; } else{ hostescalation_list_tail->next=new_hostescalation; hostescalation_list_tail=new_hostescalation; } #else /* host escalations are sorted in reverse for CGIs, so add new items to head of list */ new_hostescalation->next=hostescalation_list; hostescalation_list=new_hostescalation; #endif #ifdef DEBUG1 printf("\tHost name: %s\n",new_hostescalation->host_name); printf("\tFirst notification: %d\n",new_hostescalation->first_notification); printf("\tLast notification: %d\n",new_hostescalation->last_notification); printf("\tNotification Interval: %d\n",new_hostescalation->notification_interval); #endif #ifdef DEBUG0 printf("add_hostescalation() end\n"); #endif return new_hostescalation; } /* adds a contact group to a host escalation */ contactgroupsmember *add_contactgroup_to_hostescalation(hostescalation *he,char *group_name){ contactgroupsmember *new_contactgroupsmember; #ifdef NSCORE char temp_buffer[MAX_INPUT_BUFFER]; #endif #ifdef DEBUG0 printf("add_contactgroup_to_hostescalation() start\n"); #endif /* bail out if we weren't given the data we need */ if(he==NULL || group_name==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Host escalation or contactgroup name is NULL\n"); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } strip(group_name); if(!strcmp(group_name,"")){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Contactgroup name is NULL\n"); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } /* allocate memory for the contactgroups member */ new_contactgroupsmember=(contactgroupsmember *)malloc(sizeof(contactgroupsmember)); if(new_contactgroupsmember==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not allocate memory for contact group '%s' for host '%s' escalation\n",group_name,he->host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } new_contactgroupsmember->group_name=strdup(group_name); if(new_contactgroupsmember->group_name==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not allocate memory for contact group '%s' name for host '%s' escalation\n",group_name,he->host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif free(new_contactgroupsmember); return NULL; } /* add this contactgroup to the host escalation */ new_contactgroupsmember->next=he->contact_groups; he->contact_groups=new_contactgroupsmember; #ifdef DEBUG0 printf("add_contactgroup_to_hostescalation() end\n"); #endif return new_contactgroupsmember; } /* adds an extended host info structure to the list in memory */ hostextinfo * add_hostextinfo(char *host_name, char *notes, char *notes_url, char *action_url, char *icon_image, char *vrml_image, char *statusmap_image, char *icon_image_alt, int x_2d, int y_2d, double x_3d, double y_3d, double z_3d, int have_2d_coords, int have_3d_coords){ hostextinfo *new_hostextinfo; #ifdef NSCORE char temp_buffer[MAX_INPUT_BUFFER]; #endif #ifdef DEBUG0 printf("add_hostextinfo() start\n"); #endif /* make sure we have what we need */ if(host_name==NULL || !strcmp(host_name,"")){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Host name is NULL\n"); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } /* allocate memory for a new data structure */ new_hostextinfo=(hostextinfo *)malloc(sizeof(hostextinfo)); if(new_hostextinfo==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not allocate memory for host '%s' extended info.\n",host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } new_hostextinfo->host_name=strdup(host_name); if(new_hostextinfo->host_name==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not allocate memory for host '%s' extended info.\n",host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif free(new_hostextinfo); return NULL; } if(notes==NULL || !strcmp(notes,"")) new_hostextinfo->notes=NULL; else{ new_hostextinfo->notes=strdup(notes); if(new_hostextinfo->notes==NULL){ free(new_hostextinfo->host_name); free(new_hostextinfo); #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not allocate memory for host '%s' extended info.\n",host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } } if(notes_url==NULL || !strcmp(notes_url,"")) new_hostextinfo->notes_url=NULL; else{ new_hostextinfo->notes_url=strdup(notes_url); if(new_hostextinfo->notes_url==NULL){ free(new_hostextinfo->notes); free(new_hostextinfo->host_name); free(new_hostextinfo); #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not allocate memory for host '%s' extended info.\n",host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } } if(action_url==NULL || !strcmp(action_url,"")) new_hostextinfo->action_url=NULL; else{ new_hostextinfo->action_url=strdup(action_url); if(new_hostextinfo->action_url==NULL){ free(new_hostextinfo->notes_url); free(new_hostextinfo->notes); free(new_hostextinfo->host_name); free(new_hostextinfo); #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not allocate memory for host '%s' extended info.\n",host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } } if(icon_image==NULL || !strcmp(icon_image,"")) new_hostextinfo->icon_image=NULL; else{ new_hostextinfo->icon_image=strdup(icon_image); if(new_hostextinfo->icon_image==NULL){ free(new_hostextinfo->action_url); free(new_hostextinfo->notes_url); free(new_hostextinfo->notes); free(new_hostextinfo->host_name); free(new_hostextinfo); #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not allocate memory for host '%s' extended info.\n",host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } } if(vrml_image==NULL || !strcmp(vrml_image,"")) new_hostextinfo->vrml_image=NULL; else{ new_hostextinfo->vrml_image=strdup(vrml_image); if(new_hostextinfo->vrml_image==NULL){ free(new_hostextinfo->icon_image); free(new_hostextinfo->action_url); free(new_hostextinfo->notes_url); free(new_hostextinfo->notes); free(new_hostextinfo->host_name); free(new_hostextinfo); #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not allocate memory for host '%s' extended info.\n",host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } } if(statusmap_image==NULL || !strcmp(statusmap_image,"")) new_hostextinfo->statusmap_image=NULL; else{ new_hostextinfo->statusmap_image=strdup(statusmap_image); if(new_hostextinfo->statusmap_image==NULL){ free(new_hostextinfo->vrml_image); free(new_hostextinfo->icon_image); free(new_hostextinfo->action_url); free(new_hostextinfo->notes_url); free(new_hostextinfo->notes); free(new_hostextinfo->host_name); free(new_hostextinfo); #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not allocate memory for host '%s' extended info.\n",host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } } if(icon_image_alt==NULL || !strcmp(icon_image_alt,"")) new_hostextinfo->icon_image_alt=NULL; else{ new_hostextinfo->icon_image_alt=strdup(icon_image_alt); if(new_hostextinfo->icon_image_alt==NULL){ free(new_hostextinfo->statusmap_image); free(new_hostextinfo->vrml_image); free(new_hostextinfo->icon_image); free(new_hostextinfo->action_url); free(new_hostextinfo->notes_url); free(new_hostextinfo->notes); free(new_hostextinfo->host_name); free(new_hostextinfo); #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not allocate memory for host '%s' extended info.\n",host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } } /* 2-D coordinates */ new_hostextinfo->x_2d=x_2d; new_hostextinfo->y_2d=y_2d; new_hostextinfo->have_2d_coords=have_2d_coords; /* 3-D coordinates */ new_hostextinfo->x_3d=x_3d; new_hostextinfo->y_3d=y_3d; new_hostextinfo->z_3d=z_3d; new_hostextinfo->have_3d_coords=have_3d_coords; /* default is to not draw this item */ new_hostextinfo->should_be_drawn=FALSE; new_hostextinfo->next=NULL; new_hostextinfo->nexthash=NULL; /* add new hostextinfo to hostextinfo chained hash list */ if(!add_hostextinfo_to_hashlist(new_hostextinfo)){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not allocate memory for hostextinfo list to add extended info for host '%s'.\n",host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif free(new_hostextinfo->statusmap_image); free(new_hostextinfo->vrml_image); free(new_hostextinfo->icon_image); free(new_hostextinfo->icon_image_alt); free(new_hostextinfo->action_url); free(new_hostextinfo->notes_url); free(new_hostextinfo->notes); free(new_hostextinfo->host_name); free(new_hostextinfo); return NULL; } #ifdef NSCORE /* hostextinfo entries are sorted alphabetically for daemon, so add new items to tail of list */ if(hostextinfo_list==NULL){ hostextinfo_list=new_hostextinfo; hostextinfo_list_tail=hostextinfo_list; } else{ hostextinfo_list_tail->next=new_hostextinfo; hostextinfo_list_tail=new_hostextinfo; } #else /* hostextinfo entries are sorted in reverse for CGIs, so add new items to head of list */ new_hostextinfo->next=hostextinfo_list; hostextinfo_list=new_hostextinfo; #endif #ifdef DEBUG0 printf("add_hostextinfo() end\n"); #endif return new_hostextinfo; } /* adds an extended service info structure to the list in memory */ serviceextinfo * add_serviceextinfo(char *host_name, char *description, char *notes, char *notes_url, char *action_url, char *icon_image, char *icon_image_alt){ serviceextinfo *new_serviceextinfo; #ifdef NSCORE char temp_buffer[MAX_INPUT_BUFFER]; #endif #ifdef DEBUG0 printf("add_serviceextinfo() start\n"); #endif /* make sure we have what we need */ if((host_name==NULL || !strcmp(host_name,"")) || (description==NULL || !strcmp(description,""))){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Host name or service description is NULL\n"); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } /* allocate memory for a new data structure */ new_serviceextinfo=(serviceextinfo *)malloc(sizeof(serviceextinfo)); if(new_serviceextinfo==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not allocate memory for service '%s' on host '%s' extended info.\n",description,host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } new_serviceextinfo->host_name=strdup(host_name); if(new_serviceextinfo->host_name==NULL){ free(new_serviceextinfo); #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not allocate memory for service '%s' on host '%s' extended info.\n",description,host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } new_serviceextinfo->description=strdup(description); if(new_serviceextinfo->description==NULL){ free(new_serviceextinfo->host_name); free(new_serviceextinfo); #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not allocate memory for service '%s' on host '%s' extended info.\n",description,host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } if(notes==NULL || !strcmp(notes,"")) new_serviceextinfo->notes=NULL; else{ new_serviceextinfo->notes=strdup(notes); if(new_serviceextinfo->notes==NULL){ free(new_serviceextinfo->description); free(new_serviceextinfo->host_name); free(new_serviceextinfo); #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not allocate memory for service '%s' on host '%s' extended info.\n",description,host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } } if(notes_url==NULL || !strcmp(notes_url,"")) new_serviceextinfo->notes_url=NULL; else{ new_serviceextinfo->notes_url=strdup(notes_url); if(new_serviceextinfo->notes_url==NULL){ free(new_serviceextinfo->notes); free(new_serviceextinfo->description); free(new_serviceextinfo->host_name); free(new_serviceextinfo); #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not allocate memory for service '%s' on host '%s' extended info.\n",description,host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } } if(action_url==NULL || !strcmp(action_url,"")) new_serviceextinfo->action_url=NULL; else{ new_serviceextinfo->action_url=strdup(action_url); if(new_serviceextinfo->action_url==NULL){ free(new_serviceextinfo->notes_url); free(new_serviceextinfo->notes); free(new_serviceextinfo->description); free(new_serviceextinfo->host_name); free(new_serviceextinfo); #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not allocate memory for service '%s' on host '%s' extended info.\n",description,host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } } if(icon_image==NULL || !strcmp(icon_image,"")) new_serviceextinfo->icon_image=NULL; else{ new_serviceextinfo->icon_image=strdup(icon_image); if(new_serviceextinfo->icon_image==NULL){ free(new_serviceextinfo->notes); free(new_serviceextinfo->notes_url); free(new_serviceextinfo->action_url); free(new_serviceextinfo->description); free(new_serviceextinfo->host_name); free(new_serviceextinfo); #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not allocate memory for service '%s' on host '%s' extended info.\n",description,host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } } if(icon_image_alt==NULL || !strcmp(icon_image_alt,"")) new_serviceextinfo->icon_image_alt=NULL; else{ new_serviceextinfo->icon_image_alt=strdup(icon_image_alt); if(new_serviceextinfo->icon_image_alt==NULL){ free(new_serviceextinfo->icon_image); free(new_serviceextinfo->notes); free(new_serviceextinfo->notes_url); free(new_serviceextinfo->action_url); free(new_serviceextinfo->description); free(new_serviceextinfo->host_name); free(new_serviceextinfo); #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not allocate memory for service '%s' on host '%s' extended info.\n",description,host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return NULL; } } new_serviceextinfo->next=NULL; new_serviceextinfo->nexthash=NULL; /* add new serviceextinfo to serviceextinfo chained hash list */ if(!add_serviceextinfo_to_hashlist(new_serviceextinfo)){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not allocate memory for serviceextinfo list to add extended info for service '%s' on host '%s'.\n",description,host_name); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif free(new_serviceextinfo->icon_image); free(new_serviceextinfo->icon_image_alt); free(new_serviceextinfo->notes_url); free(new_serviceextinfo->notes); free(new_serviceextinfo->action_url); free(new_serviceextinfo->description); free(new_serviceextinfo->host_name); free(new_serviceextinfo); return NULL; } #ifdef NSCORE /* serviceextinfo entries are sorted alphabetically for daemon, so add new items to tail of list */ if(serviceextinfo_list==NULL){ serviceextinfo_list=new_serviceextinfo; serviceextinfo_list_tail=serviceextinfo_list; } else{ serviceextinfo_list_tail->next=new_serviceextinfo; serviceextinfo_list_tail=new_serviceextinfo; } #else /* serviceextinfo entries are sorted in reverse for CGIs, so add new items to head of list */ new_serviceextinfo->next=serviceextinfo_list; serviceextinfo_list=new_serviceextinfo; #endif #ifdef DEBUG0 printf("add_serviceextinfo() end\n"); #endif return new_serviceextinfo; } /******************************************************************/ /******************** OBJECT SEARCH FUNCTIONS *********************/ /******************************************************************/ /* given a timeperiod name and a starting point, find a timeperiod from the list in memory */ timeperiod * find_timeperiod(char *name){ timeperiod *temp_timeperiod; #ifdef DEBUG0 printf("find_timeperiod() start\n"); #endif if(name==NULL || timeperiod_hashlist==NULL) return NULL; for(temp_timeperiod=timeperiod_hashlist[hashfunc1(name,TIMEPERIOD_HASHSLOTS)];temp_timeperiod && compare_hashdata1(temp_timeperiod->name,name)<0;temp_timeperiod=temp_timeperiod->nexthash); if(temp_timeperiod && (compare_hashdata1(temp_timeperiod->name,name)==0)) return temp_timeperiod; #ifdef DEBUG0 printf("find_timeperiod() end\n"); #endif /* we couldn't find a matching timeperiod */ return NULL; } /* given a host name, find it in the list in memory */ host * find_host(char *name){ host *temp_host; #ifdef DEBUG0 printf("find_host() start\n"); #endif if(name==NULL || host_hashlist==NULL) return NULL; for(temp_host=host_hashlist[hashfunc1(name,HOST_HASHSLOTS)];temp_host && compare_hashdata1(temp_host->name,name)<0;temp_host=temp_host->nexthash); if(temp_host && (compare_hashdata1(temp_host->name,name)==0)) return temp_host; #ifdef DEBUG0 printf("find_host() end\n"); #endif /* Couldn't find matching host */ return NULL; } /* find a hostgroup from the list in memory */ hostgroup * find_hostgroup(char *name){ hostgroup *temp_hostgroup; #ifdef DEBUG0 printf("find_hostgroup() start\n"); #endif if(name==NULL || hostgroup_hashlist==NULL) return NULL; for(temp_hostgroup=hostgroup_hashlist[hashfunc1(name,HOSTGROUP_HASHSLOTS)];temp_hostgroup && compare_hashdata1(temp_hostgroup->group_name,name)<0;temp_hostgroup=temp_hostgroup->nexthash); if(temp_hostgroup && (compare_hashdata1(temp_hostgroup->group_name,name)==0)) return temp_hostgroup; #ifdef DEBUG0 printf("find_hostgroup() end\n"); #endif /* we couldn't find a matching hostgroup */ return NULL; } #ifdef REMOVED_061803 /* find a member of a host group */ hostgroupmember * find_hostgroupmember(char *name,hostgroup *grp){ hostgroupmember *temp_member; #ifdef DEBUG0 printf("find_hostgroupmember() start\n"); #endif if(name==NULL || grp==NULL) return NULL; temp_member=grp->members; while(temp_member!=NULL){ /* we found a match */ if(!strcmp(temp_member->host_name,name)) return temp_member; temp_member=temp_member->next; } #ifdef DEBUG0 printf("find_hostgroupmember() end\n"); #endif /* we couldn't find a matching member */ return NULL; } #endif /* find a servicegroup from the list in memory */ servicegroup * find_servicegroup(char *name){ servicegroup *temp_servicegroup; #ifdef DEBUG0 printf("find_servicegroup() start\n"); #endif if(name==NULL || servicegroup_hashlist==NULL) return NULL; for(temp_servicegroup=servicegroup_hashlist[hashfunc1(name,SERVICEGROUP_HASHSLOTS)];temp_servicegroup && compare_hashdata1(temp_servicegroup->group_name,name)<0;temp_servicegroup=temp_servicegroup->nexthash); if(temp_servicegroup && (compare_hashdata1(temp_servicegroup->group_name,name)==0)) return temp_servicegroup; #ifdef DEBUG0 printf("find_servicegroup() end\n"); #endif /* we couldn't find a matching servicegroup */ return NULL; } #ifdef REMOVED_0618003 /* find a member of a service group */ servicegroupmember * find_servicegroupmember(char *host_name,char *svc_description,servicegroup *grp){ servicegroupmember *temp_member; #ifdef DEBUG0 printf("find_servicegroupmember() start\n"); #endif if(host_name==NULL || svc_description==NULL || grp==NULL) return NULL; temp_member=grp->members; while(temp_member!=NULL){ /* we found a match */ if(!strcmp(temp_member->host_name,host_name) && !strcmp(temp_member->service_description,svc_description)) return temp_member; temp_member=temp_member->next; } #ifdef DEBUG0 printf("find_servicegroupmember() end\n"); #endif /* we couldn't find a matching member */ return NULL; } #endif /* find a contact from the list in memory */ contact * find_contact(char *name){ contact *temp_contact; #ifdef DEBUG0 printf("find_contact() start\n"); #endif if(name==NULL || contact_hashlist==NULL) return NULL; for(temp_contact=contact_hashlist[hashfunc1(name,CONTACT_HASHSLOTS)];temp_contact && compare_hashdata1(temp_contact->name,name)<0;temp_contact=temp_contact->nexthash); if(temp_contact && (compare_hashdata1(temp_contact->name,name)==0)) return temp_contact; #ifdef DEBUG0 printf("find_contact() end\n"); #endif /* we couldn't find a matching contact */ return NULL; } /* find a contact group from the list in memory */ contactgroup * find_contactgroup(char *name){ contactgroup *temp_contactgroup; #ifdef DEBUG0 printf("find_contactgroup() start\n"); #endif if(name==NULL || contactgroup_hashlist==NULL) return NULL; for(temp_contactgroup=contactgroup_hashlist[hashfunc1(name,CONTACTGROUP_HASHSLOTS)];temp_contactgroup && compare_hashdata1(temp_contactgroup->group_name,name)<0;temp_contactgroup=temp_contactgroup->nexthash); if(temp_contactgroup && (compare_hashdata1(temp_contactgroup->group_name,name)==0)) return temp_contactgroup; #ifdef DEBUG0 printf("find_contactgroup() end\n"); #endif /* we couldn't find a matching contactgroup */ return NULL; } /* find the corresponding member of a contact group */ contactgroupmember * find_contactgroupmember(char *name,contactgroup *grp){ contactgroupmember *temp_member; #ifdef DEBUG0 printf("find_contactgroupmember() start\n"); #endif if(name==NULL || grp==NULL) return NULL; temp_member=grp->members; while(temp_member!=NULL){ /* we found a match */ if(!strcmp(temp_member->contact_name,name)) return temp_member; temp_member=temp_member->next; } #ifdef DEBUG0 printf("find_contactgroupmember() end\n"); #endif /* we couldn't find a matching member */ return NULL; } /* given a command name, find a command from the list in memory */ command * find_command(char *name){ command *temp_command; #ifdef DEBUG0 printf("find_command() start\n"); #endif if(name==NULL || command_hashlist==NULL) return NULL; for(temp_command=command_hashlist[hashfunc1(name,COMMAND_HASHSLOTS)];temp_command && compare_hashdata1(temp_command->name,name)<0;temp_command=temp_command->nexthash); if(temp_command && (compare_hashdata1(temp_command->name,name)==0)) return temp_command; #ifdef DEBUG0 printf("find_command() end\n"); #endif /* we couldn't find a matching command */ return NULL; } /* given a host/service name, find the service in the list in memory */ service * find_service(char *host_name,char *svc_desc){ service *temp_service; #ifdef DEBUG0 printf("find_service() start\n"); #endif if(host_name==NULL || svc_desc==NULL || service_hashlist==NULL) return NULL; for(temp_service=service_hashlist[hashfunc2(host_name,svc_desc,SERVICE_HASHSLOTS)];temp_service && compare_hashdata2(temp_service->host_name,temp_service->description,host_name,svc_desc)<0;temp_service=temp_service->nexthash); if(temp_service && (compare_hashdata2(temp_service->host_name,temp_service->description,host_name,svc_desc)==0)) return temp_service; #ifdef DEBUG0 printf("find_service() end\n"); #endif /* we couldn't find a matching service */ return NULL; } /* find the extended information for a given host */ hostextinfo * find_hostextinfo(char *host_name){ hostextinfo *temp_hostextinfo; #ifdef DEBUG0 printf("find_hostextinfo() start\n"); #endif if(host_name==NULL || hostextinfo_hashlist==NULL) return NULL; for(temp_hostextinfo=hostextinfo_hashlist[hashfunc1(host_name,HOSTEXTINFO_HASHSLOTS)];temp_hostextinfo && compare_hashdata1(temp_hostextinfo->host_name,host_name)<0;temp_hostextinfo=temp_hostextinfo->nexthash); if(temp_hostextinfo && (compare_hashdata1(temp_hostextinfo->host_name,host_name)==0)) return temp_hostextinfo; #ifdef DEBUG0 printf("find_hostextinfo() end\n"); #endif /* we couldn't find a matching extended host info object */ return NULL; } /* find the extended information for a given service */ serviceextinfo * find_serviceextinfo(char *host_name, char *description){ serviceextinfo *temp_serviceextinfo; #ifdef DEBUG0 printf("find_serviceextinfo() start\n"); #endif if(host_name==NULL || description==NULL || serviceextinfo_hashlist==NULL) return NULL; for(temp_serviceextinfo=serviceextinfo_hashlist[hashfunc2(host_name,description,SERVICEEXTINFO_HASHSLOTS)];temp_serviceextinfo && compare_hashdata2(temp_serviceextinfo->host_name,temp_serviceextinfo->description,host_name,description)<0;temp_serviceextinfo=temp_serviceextinfo->nexthash); if(temp_serviceextinfo && (compare_hashdata2(temp_serviceextinfo->host_name,temp_serviceextinfo->description,host_name,description)==0)) return temp_serviceextinfo; #ifdef DEBUG0 printf("find_serviceextinfo() end\n"); #endif /* we couldn't find a matching extended service info object */ return NULL; } /******************************************************************/ /******************* OBJECT TRAVERSAL FUNCTIONS *******************/ /******************************************************************/ hostescalation *get_first_hostescalation_by_host(char *host_name){ return get_next_hostescalation_by_host(host_name,NULL); } hostescalation *get_next_hostescalation_by_host(char *host_name, hostescalation *start){ hostescalation *temp_hostescalation; if(host_name==NULL || hostescalation_hashlist==NULL) return NULL; if(start==NULL) temp_hostescalation=hostescalation_hashlist[hashfunc1(host_name,HOSTESCALATION_HASHSLOTS)]; else temp_hostescalation=start->nexthash; for(;temp_hostescalation && compare_hashdata1(temp_hostescalation->host_name,host_name)<0;temp_hostescalation=temp_hostescalation->nexthash); if(temp_hostescalation && compare_hashdata1(temp_hostescalation->host_name,host_name)==0) return temp_hostescalation; return NULL; } serviceescalation *get_first_serviceescalation_by_service(char *host_name, char *svc_description){ return get_next_serviceescalation_by_service(host_name,svc_description,NULL); } serviceescalation *get_next_serviceescalation_by_service(char *host_name, char *svc_description, serviceescalation *start){ serviceescalation *temp_serviceescalation; if(host_name==NULL || svc_description==NULL || serviceescalation_hashlist==NULL) return NULL; if(start==NULL) temp_serviceescalation=serviceescalation_hashlist[hashfunc2(host_name,svc_description,SERVICEESCALATION_HASHSLOTS)]; else temp_serviceescalation=start->nexthash; for(;temp_serviceescalation && compare_hashdata2(temp_serviceescalation->host_name,temp_serviceescalation->description,host_name,svc_description)<0;temp_serviceescalation=temp_serviceescalation->nexthash); if(temp_serviceescalation && compare_hashdata2(temp_serviceescalation->host_name,temp_serviceescalation->description,host_name,svc_description)==0) return temp_serviceescalation; return NULL; } hostdependency *get_first_hostdependency_by_dependent_host(char *host_name){ return get_next_hostdependency_by_dependent_host(host_name,NULL); } hostdependency *get_next_hostdependency_by_dependent_host(char *host_name, hostdependency *start){ hostdependency *temp_hostdependency; if(host_name==NULL || hostdependency_hashlist==NULL) return NULL; if(start==NULL) temp_hostdependency=hostdependency_hashlist[hashfunc1(host_name,HOSTDEPENDENCY_HASHSLOTS)]; else temp_hostdependency=start->nexthash; for(;temp_hostdependency && compare_hashdata1(temp_hostdependency->dependent_host_name,host_name)<0;temp_hostdependency=temp_hostdependency->nexthash); if(temp_hostdependency && compare_hashdata1(temp_hostdependency->dependent_host_name,host_name)==0) return temp_hostdependency; return NULL; } servicedependency *get_first_servicedependency_by_dependent_service(char *host_name, char *svc_description){ return get_next_servicedependency_by_dependent_service(host_name,svc_description,NULL); } servicedependency *get_next_servicedependency_by_dependent_service(char *host_name, char *svc_description, servicedependency *start){ servicedependency *temp_servicedependency; if(host_name==NULL || svc_description==NULL || servicedependency_hashlist==NULL) return NULL; if(start==NULL) temp_servicedependency=servicedependency_hashlist[hashfunc2(host_name,svc_description,SERVICEDEPENDENCY_HASHSLOTS)]; else temp_servicedependency=start->nexthash; for(;temp_servicedependency && compare_hashdata2(temp_servicedependency->dependent_host_name,temp_servicedependency->dependent_service_description,host_name,svc_description)<0;temp_servicedependency=temp_servicedependency->nexthash); if(temp_servicedependency && compare_hashdata2(temp_servicedependency->dependent_host_name,temp_servicedependency->dependent_service_description,host_name,svc_description)==0) return temp_servicedependency; return NULL; } /******************************************************************/ /********************* OBJECT QUERY FUNCTIONS *********************/ /******************************************************************/ /* determines whether or not a specific host is an immediate child of another host */ int is_host_immediate_child_of_host(host *parent_host,host *child_host){ hostsmember *temp_hostsmember=NULL; if(child_host==NULL) return FALSE; if(parent_host==NULL){ if(child_host->parent_hosts==NULL) return TRUE; } else{ for(temp_hostsmember=child_host->parent_hosts;temp_hostsmember!=NULL;temp_hostsmember=temp_hostsmember->next){ if(!strcmp(temp_hostsmember->host_name,parent_host->name)) return TRUE; } } return FALSE; } /* determines whether or not a specific host is an immediate child (and the primary child) of another host */ int is_host_primary_immediate_child_of_host(host *parent_host, host *child_host){ hostsmember *temp_hostsmember; if(is_host_immediate_child_of_host(parent_host,child_host)==FALSE) return FALSE; if(parent_host==NULL) return TRUE; if(child_host==NULL) return FALSE; if(child_host->parent_hosts==NULL) return TRUE; for(temp_hostsmember=child_host->parent_hosts;temp_hostsmember->next!=NULL;temp_hostsmember=temp_hostsmember->next); if(!strcmp(temp_hostsmember->host_name,parent_host->name)) return TRUE; return FALSE; } /* determines whether or not a specific host is an immediate parent of another host */ int is_host_immediate_parent_of_host(host *child_host,host *parent_host){ if(is_host_immediate_child_of_host(parent_host,child_host)==TRUE) return TRUE; return FALSE; } /* returns a count of the immediate children for a given host */ int number_of_immediate_child_hosts(host *hst){ int children=0; host *temp_host; for(temp_host=host_list;temp_host!=NULL;temp_host=temp_host->next){ if(is_host_immediate_child_of_host(hst,temp_host)==TRUE) children++; } return children; } /* returns a count of the total children for a given host */ int number_of_total_child_hosts(host *hst){ int children=0; host *temp_host; for(temp_host=host_list;temp_host!=NULL;temp_host=temp_host->next){ if(is_host_immediate_child_of_host(hst,temp_host)==TRUE) children+=number_of_total_child_hosts(temp_host)+1; } return children; } /* get the number of immediate parent hosts for a given host */ int number_of_immediate_parent_hosts(host *hst){ int parents=0; host *temp_host; for(temp_host=host_list;temp_host!=NULL;temp_host=temp_host->next){ if(is_host_immediate_parent_of_host(hst,temp_host)==TRUE){ parents++; break; } } return parents; } /* get the total number of parent hosts for a given host */ int number_of_total_parent_hosts(host *hst){ int parents=0; host *temp_host; for(temp_host=host_list;temp_host!=NULL;temp_host=temp_host->next){ if(is_host_immediate_parent_of_host(hst,temp_host)==TRUE){ parents+=number_of_total_parent_hosts(temp_host)+1; break; } } return parents; } /* tests whether a host is a member of a particular hostgroup */ int is_host_member_of_hostgroup(hostgroup *group, host *hst){ hostgroupmember *temp_hostgroupmember; if(group==NULL || hst==NULL) return FALSE; for(temp_hostgroupmember=group->members;temp_hostgroupmember!=NULL;temp_hostgroupmember=temp_hostgroupmember->next){ if(!strcmp(temp_hostgroupmember->host_name,hst->name)) return TRUE; } return FALSE; } /* tests whether a host is a member of a particular servicegroup */ int is_host_member_of_servicegroup(servicegroup *group, host *hst){ servicegroupmember *temp_servicegroupmember; if(group==NULL || hst==NULL) return FALSE; for(temp_servicegroupmember=group->members;temp_servicegroupmember!=NULL;temp_servicegroupmember=temp_servicegroupmember->next){ if(!strcmp(temp_servicegroupmember->host_name,hst->name)) return TRUE; } return FALSE; } /* tests whether a service is a member of a particular servicegroup */ int is_service_member_of_servicegroup(servicegroup *group, service *svc){ servicegroupmember *temp_servicegroupmember; if(group==NULL || svc==NULL) return FALSE; for(temp_servicegroupmember=group->members;temp_servicegroupmember!=NULL;temp_servicegroupmember=temp_servicegroupmember->next){ if(!strcmp(temp_servicegroupmember->host_name,svc->host_name) && !strcmp(temp_servicegroupmember->service_description,svc->description)) return TRUE; } return FALSE; } /* tests whether a contact is a member of a particular contactgroup */ int is_contact_member_of_contactgroup(contactgroup *group, contact *cntct){ contactgroupmember *temp_contactgroupmember; if(group==NULL || cntct==NULL) return FALSE; /* search all contacts in this contact group */ for(temp_contactgroupmember=group->members;temp_contactgroupmember!=NULL;temp_contactgroupmember=temp_contactgroupmember->next){ /* we found the contact! */ if(!strcmp(temp_contactgroupmember->contact_name,cntct->name)) return TRUE; } return FALSE; } /* tests whether a contact is a member of a particular hostgroup - used only by the CGIs */ int is_contact_for_hostgroup(hostgroup *group, contact *cntct){ hostgroupmember *temp_hostgroupmember; host *temp_host; if(group==NULL || cntct==NULL) return FALSE; for(temp_hostgroupmember=group->members;temp_hostgroupmember!=NULL;temp_hostgroupmember=temp_hostgroupmember->next){ temp_host=find_host(temp_hostgroupmember->host_name); if(temp_host==NULL) continue; if(is_contact_for_host(temp_host,cntct)==TRUE) return TRUE; } return FALSE; } /* tests whether a contact is a member of a particular servicegroup - used only by the CGIs */ int is_contact_for_servicegroup(servicegroup *group, contact *cntct){ servicegroupmember *temp_servicegroupmember; service *temp_service; if(group==NULL || cntct==NULL) return FALSE; for(temp_servicegroupmember=group->members;temp_servicegroupmember!=NULL;temp_servicegroupmember=temp_servicegroupmember->next){ temp_service=find_service(temp_servicegroupmember->host_name,temp_servicegroupmember->service_description); if(temp_service==NULL) continue; if(is_contact_for_service(temp_service,cntct)==TRUE) return TRUE; } return FALSE; } /* tests whether a contact is a contact for a particular host */ int is_contact_for_host(host *hst, contact *cntct){ contactgroupsmember *temp_contactgroupsmember; contactgroup *temp_contactgroup; if(hst==NULL || cntct==NULL){ return FALSE; } /* search all contact groups of this host */ for(temp_contactgroupsmember=hst->contact_groups;temp_contactgroupsmember!=NULL;temp_contactgroupsmember=temp_contactgroupsmember->next){ /* find the contact group */ temp_contactgroup=find_contactgroup(temp_contactgroupsmember->group_name); if(temp_contactgroup==NULL) continue; if(is_contact_member_of_contactgroup(temp_contactgroup,cntct)==TRUE) return TRUE; } return FALSE; } /* tests whether or not a contact is an escalated contact for a particular host */ int is_escalated_contact_for_host(host *hst, contact *cntct){ contactgroupsmember *temp_contactgroupsmember; contactgroup *temp_contactgroup; hostescalation *temp_hostescalation; /* search all host escalations */ for(temp_hostescalation=get_first_hostescalation_by_host(hst->name);temp_hostescalation!=NULL;temp_hostescalation=get_next_hostescalation_by_host(hst->name,temp_hostescalation)){ /* search all the contact groups in this escalation... */ for(temp_contactgroupsmember=temp_hostescalation->contact_groups;temp_contactgroupsmember!=NULL;temp_contactgroupsmember=temp_contactgroupsmember->next){ /* find the contact group */ temp_contactgroup=find_contactgroup(temp_contactgroupsmember->group_name); if(temp_contactgroup==NULL) continue; /* see if the contact is a member of this contact group */ if(is_contact_member_of_contactgroup(temp_contactgroup,cntct)==TRUE) return TRUE; } } return FALSE; } /* tests whether a contact is a contact for a particular service */ int is_contact_for_service(service *svc, contact *cntct){ contactgroupsmember *temp_contactgroupsmember; contactgroup *temp_contactgroup; if(svc==NULL || cntct==NULL) return FALSE; /* search all contact groups of this service */ for(temp_contactgroupsmember=svc->contact_groups;temp_contactgroupsmember!=NULL;temp_contactgroupsmember=temp_contactgroupsmember->next){ /* find the contact group */ temp_contactgroup=find_contactgroup(temp_contactgroupsmember->group_name); if(temp_contactgroup==NULL) continue; if(is_contact_member_of_contactgroup(temp_contactgroup,cntct)==TRUE) return TRUE; } return FALSE; } /* tests whether or not a contact is an escalated contact for a particular service */ int is_escalated_contact_for_service(service *svc, contact *cntct){ serviceescalation *temp_serviceescalation; contactgroupsmember *temp_contactgroupsmember; contactgroup *temp_contactgroup; /* search all the service escalations */ for(temp_serviceescalation=get_first_serviceescalation_by_service(svc->host_name,svc->description);temp_serviceescalation!=NULL;temp_serviceescalation=get_next_serviceescalation_by_service(svc->host_name,svc->description,temp_serviceescalation)){ /* search all the contact groups in this escalation... */ for(temp_contactgroupsmember=temp_serviceescalation->contact_groups;temp_contactgroupsmember!=NULL;temp_contactgroupsmember=temp_contactgroupsmember->next){ /* find the contact group */ temp_contactgroup=find_contactgroup(temp_contactgroupsmember->group_name); if(temp_contactgroup==NULL) continue; /* see if the contact is a member of this contact group */ if(is_contact_member_of_contactgroup(temp_contactgroup,cntct)==TRUE) return TRUE; } } return FALSE; } #ifdef NSCORE /* checks to see if there exists a circular parent/child path for a host */ int check_for_circular_path(host *root_hst, host *hst){ host *temp_host; /* don't go into a loop, don't bother checking anymore if we know this host already has a loop */ if(root_hst->contains_circular_path==TRUE) return TRUE; /* host has already been checked - there is a path somewhere, but it may not be for this particular host... */ /* this should speed up detection for some loops */ if(hst->circular_path_checked==TRUE) return FALSE; /* set the check flag so we don't get into an infinite loop */ hst->circular_path_checked=TRUE; /* check this hosts' parents to see if a circular path exists */ if(is_host_immediate_parent_of_host(root_hst,hst)==TRUE){ root_hst->contains_circular_path=TRUE; hst->contains_circular_path=TRUE; return TRUE; } /* check all immediate children for a circular path */ for(temp_host=host_list;temp_host!=NULL;temp_host=temp_host->next){ if(is_host_immediate_child_of_host(hst,temp_host)==TRUE) if(check_for_circular_path(root_hst,temp_host)==TRUE) return TRUE; } return FALSE; } /* checks to see if there exists a circular dependency for a service */ int check_for_circular_servicedependency(servicedependency *root_dep, servicedependency *dep, int dependency_type){ servicedependency *temp_sd; if(root_dep==NULL || dep==NULL) return FALSE; /* this is not the proper dependency type */ if(root_dep->dependency_type!=dependency_type || dep->dependency_type!=dependency_type) return FALSE; /* don't go into a loop, don't bother checking anymore if we know this dependency already has a loop */ if(root_dep->contains_circular_path==TRUE) return TRUE; /* dependency has already been checked - there is a path somewhere, but it may not be for this particular dep... */ /* this should speed up detection for some loops */ if(dep->circular_path_checked==TRUE) return FALSE; /* set the check flag so we don't get into an infinite loop */ dep->circular_path_checked=TRUE; /* is this service dependent on the root service? */ if(dep!=root_dep){ if(!strcmp(root_dep->dependent_host_name,dep->host_name) && !strcmp(root_dep->dependent_service_description,dep->service_description)){ root_dep->contains_circular_path=TRUE; dep->contains_circular_path=TRUE; return TRUE; } } /* notification dependencies are ok at this point as long as they don't inherit */ if(dependency_type==NOTIFICATION_DEPENDENCY && dep->inherits_parent==FALSE) return FALSE; /* check all parent dependencies */ for(temp_sd=servicedependency_list;temp_sd!=NULL;temp_sd=temp_sd->next){ /* only check parent dependencies */ if(strcmp(dep->host_name,temp_sd->dependent_host_name) || strcmp(dep->service_description,temp_sd->dependent_service_description)) continue; if(check_for_circular_servicedependency(root_dep,temp_sd,dependency_type)==TRUE) return TRUE; } return FALSE; } /* checks to see if there exists a circular dependency for a host */ int check_for_circular_hostdependency(hostdependency *root_dep, hostdependency *dep, int dependency_type){ hostdependency *temp_hd; if(root_dep==NULL || dep==NULL) return FALSE; /* this is not the proper dependency type */ if(root_dep->dependency_type!=dependency_type || dep->dependency_type!=dependency_type) return FALSE; /* don't go into a loop, don't bother checking anymore if we know this dependency already has a loop */ if(root_dep->contains_circular_path==TRUE) return TRUE; /* dependency has already been checked - there is a path somewhere, but it may not be for this particular dep... */ /* this should speed up detection for some loops */ if(dep->circular_path_checked==TRUE) return FALSE; /* set the check flag so we don't get into an infinite loop */ dep->circular_path_checked=TRUE; /* is this host dependent on the root host? */ if(dep!=root_dep){ if(!strcmp(root_dep->dependent_host_name,dep->host_name)){ root_dep->contains_circular_path=TRUE; dep->contains_circular_path=TRUE; return TRUE; } } /* notification dependencies are ok at this point as long as they don't inherit */ if(dependency_type==NOTIFICATION_DEPENDENCY && dep->inherits_parent==FALSE) return FALSE; /* check all parent dependencies */ for(temp_hd=hostdependency_list;temp_hd!=NULL;temp_hd=temp_hd->next){ /* only check parent dependencies */ if(strcmp(dep->host_name,temp_hd->dependent_host_name)) continue; if(check_for_circular_hostdependency(root_dep,temp_hd,dependency_type)==TRUE) return TRUE; } return FALSE; } #endif /******************************************************************/ /******************* OBJECT DELETION FUNCTIONS ********************/ /******************************************************************/ /* free all allocated memory for objects */ int free_object_data(void){ timeperiod *this_timeperiod=NULL; timeperiod *next_timeperiod=NULL; timerange *this_timerange=NULL; timerange *next_timerange=NULL; host *this_host=NULL; host *next_host=NULL; hostsmember *this_hostsmember=NULL; hostsmember *next_hostsmember=NULL; hostgroup *this_hostgroup=NULL; hostgroup *next_hostgroup=NULL; hostgroupmember *this_hostgroupmember=NULL; hostgroupmember *next_hostgroupmember=NULL; servicegroup *this_servicegroup=NULL; servicegroup *next_servicegroup=NULL; servicegroupmember *this_servicegroupmember=NULL; servicegroupmember *next_servicegroupmember=NULL; contact *this_contact=NULL; contact *next_contact=NULL; contactgroup *this_contactgroup=NULL; contactgroup *next_contactgroup=NULL; contactgroupmember *this_contactgroupmember=NULL; contactgroupmember *next_contactgroupmember=NULL; contactgroupsmember *this_contactgroupsmember=NULL; contactgroupsmember *next_contactgroupsmember=NULL; service *this_service=NULL; service *next_service=NULL; command *this_command=NULL; command *next_command=NULL; commandsmember *this_commandsmember=NULL; commandsmember *next_commandsmember=NULL; serviceescalation *this_serviceescalation=NULL; serviceescalation *next_serviceescalation=NULL; servicedependency *this_servicedependency=NULL; servicedependency *next_servicedependency=NULL; hostdependency *this_hostdependency=NULL; hostdependency *next_hostdependency=NULL; hostescalation *this_hostescalation=NULL; hostescalation *next_hostescalation=NULL; int day; int i; #ifdef DEBUG0 printf("free_object_data() start\n"); #endif /* free memory for the timeperiod list */ this_timeperiod=timeperiod_list; while(this_timeperiod!=NULL){ /* free the time ranges contained in this timeperiod */ for(day=0;day<7;day++){ for(this_timerange=this_timeperiod->days[day];this_timerange!=NULL;this_timerange=next_timerange){ next_timerange=this_timerange->next; free(this_timerange); } } next_timeperiod=this_timeperiod->next; free(this_timeperiod->name); free(this_timeperiod->alias); free(this_timeperiod); this_timeperiod=next_timeperiod; } /* free hashlist and reset pointers */ free(timeperiod_hashlist); timeperiod_hashlist=NULL; timeperiod_list=NULL; #ifdef DEBUG1 printf("\ttimeperiod_list freed\n"); #endif /* free memory for the host list */ this_host=host_list; while(this_host!=NULL){ next_host=this_host->next; /* free memory for parent hosts */ this_hostsmember=this_host->parent_hosts; while(this_hostsmember!=NULL){ next_hostsmember=this_hostsmember->next; free(this_hostsmember->host_name); free(this_hostsmember); this_hostsmember=next_hostsmember; } /* free memory for contact groups */ this_contactgroupsmember=this_host->contact_groups; while(this_contactgroupsmember!=NULL){ next_contactgroupsmember=this_contactgroupsmember->next; free(this_contactgroupsmember->group_name); free(this_contactgroupsmember); this_contactgroupsmember=next_contactgroupsmember; } free(this_host->name); free(this_host->alias); free(this_host->address); #ifdef NSCORE free(this_host->plugin_output); free(this_host->perf_data); #endif free(this_host->check_period); free(this_host->host_check_command); free(this_host->event_handler); free(this_host->failure_prediction_options); free(this_host->notification_period); free(this_host); this_host=next_host; } /* free hashlist and reset pointers */ free(host_hashlist); host_hashlist=NULL; host_list=NULL; #ifdef DEBUG1 printf("\thost_list freed\n"); #endif /* free memory for the host group list */ this_hostgroup=hostgroup_list; while(this_hostgroup!=NULL){ /* free memory for the group members */ this_hostgroupmember=this_hostgroup->members; while(this_hostgroupmember!=NULL){ next_hostgroupmember=this_hostgroupmember->next; free(this_hostgroupmember->host_name); free(this_hostgroupmember); this_hostgroupmember=next_hostgroupmember; } next_hostgroup=this_hostgroup->next; free(this_hostgroup->group_name); free(this_hostgroup->alias); free(this_hostgroup); this_hostgroup=next_hostgroup; } /* free hashlist and reset pointers */ free(hostgroup_hashlist); hostgroup_hashlist=NULL; hostgroup_list=NULL; #ifdef DEBUG1 printf("\thostgroup_list freed\n"); #endif /* free memory for the service group list */ this_servicegroup=servicegroup_list; while(this_servicegroup!=NULL){ /* free memory for the group members */ this_servicegroupmember=this_servicegroup->members; while(this_servicegroupmember!=NULL){ next_servicegroupmember=this_servicegroupmember->next; free(this_servicegroupmember->host_name); free(this_servicegroupmember->service_description); free(this_servicegroupmember); this_servicegroupmember=next_servicegroupmember; } next_servicegroup=this_servicegroup->next; free(this_servicegroup->group_name); free(this_servicegroup->alias); free(this_servicegroup); this_servicegroup=next_servicegroup; } /* free hashlist and reset pointers */ free(servicegroup_hashlist); servicegroup_hashlist=NULL; servicegroup_list=NULL; #ifdef DEBUG1 printf("\tservicegroup_list freed\n"); #endif /* free memory for the contact list */ this_contact=contact_list; while(this_contact!=NULL){ /* free memory for the host notification commands */ this_commandsmember=this_contact->host_notification_commands; while(this_commandsmember!=NULL){ next_commandsmember=this_commandsmember->next; if(this_commandsmember->command!=NULL) free(this_commandsmember->command); free(this_commandsmember); this_commandsmember=next_commandsmember; } /* free memory for the service notification commands */ this_commandsmember=this_contact->service_notification_commands; while(this_commandsmember!=NULL){ next_commandsmember=this_commandsmember->next; if(this_commandsmember->command!=NULL) free(this_commandsmember->command); free(this_commandsmember); this_commandsmember=next_commandsmember; } next_contact=this_contact->next; free(this_contact->name); free(this_contact->alias); free(this_contact->email); free(this_contact->pager); for(i=0;iaddress[i]); free(this_contact->host_notification_period); free(this_contact->service_notification_period); free(this_contact); this_contact=next_contact; } /* free hashlist and reset pointers */ free(contact_hashlist); contact_hashlist=NULL; contact_list=NULL; #ifdef DEBUG1 printf("\tcontact_list freed\n"); #endif /* free memory for the contact group list */ this_contactgroup=contactgroup_list; while(this_contactgroup!=NULL){ /* free memory for the group members */ this_contactgroupmember=this_contactgroup->members; while(this_contactgroupmember!=NULL){ next_contactgroupmember=this_contactgroupmember->next; free(this_contactgroupmember->contact_name); free(this_contactgroupmember); this_contactgroupmember=next_contactgroupmember; } next_contactgroup=this_contactgroup->next; free(this_contactgroup->group_name); free(this_contactgroup->alias); free(this_contactgroup); this_contactgroup=next_contactgroup; } /* free hashlist and reset pointers */ free(contactgroup_hashlist); contactgroup_hashlist=NULL; contactgroup_list=NULL; #ifdef DEBUG1 printf("\tcontactgroup_list freed\n"); #endif /* free memory for the service list */ this_service=service_list; while(this_service!=NULL){ next_service=this_service->next; /* free memory for contact groups */ this_contactgroupsmember=this_service->contact_groups; while(this_contactgroupsmember!=NULL){ next_contactgroupsmember=this_contactgroupsmember->next; free(this_contactgroupsmember->group_name); free(this_contactgroupsmember); this_contactgroupsmember=next_contactgroupsmember; } free(this_service->host_name); free(this_service->description); free(this_service->service_check_command); #ifdef NSCORE free(this_service->plugin_output); free(this_service->perf_data); #endif free(this_service->notification_period); free(this_service->check_period); free(this_service->event_handler); free(this_service->failure_prediction_options); free(this_service); this_service=next_service; } /* free hashlist and reset pointers */ free(service_hashlist); service_hashlist=NULL; service_list=NULL; #ifdef DEBUG1 printf("\tservice_list freed\n"); #endif /* free memory for the command list */ this_command=command_list; while(this_command!=NULL){ next_command=this_command->next; free(this_command->name); free(this_command->command_line); free(this_command); this_command=next_command; } /* free hashlist and reset pointers */ free(command_hashlist); command_hashlist=NULL; command_list=NULL; #ifdef DEBUG1 printf("\tcommand_list freed\n"); #endif /* free memory for the service escalation list */ this_serviceescalation=serviceescalation_list; while(this_serviceescalation!=NULL){ /* free memory for the contact group members */ this_contactgroupsmember=this_serviceescalation->contact_groups; while(this_contactgroupsmember!=NULL){ next_contactgroupsmember=this_contactgroupsmember->next; free(this_contactgroupsmember->group_name); free(this_contactgroupsmember); this_contactgroupsmember=next_contactgroupsmember; } next_serviceescalation=this_serviceescalation->next; free(this_serviceescalation->host_name); free(this_serviceescalation->description); free(this_serviceescalation->escalation_period); free(this_serviceescalation); this_serviceescalation=next_serviceescalation; } /* free hashlist and reset pointers */ free(serviceescalation_hashlist); serviceescalation_hashlist=NULL; serviceescalation_list=NULL; #ifdef DEBUG1 printf("\tserviceescalation_list freed\n"); #endif /* free memory for the service dependency list */ this_servicedependency=servicedependency_list; while(this_servicedependency!=NULL){ next_servicedependency=this_servicedependency->next; free(this_servicedependency->dependent_host_name); free(this_servicedependency->dependent_service_description); free(this_servicedependency->host_name); free(this_servicedependency->service_description); free(this_servicedependency); this_servicedependency=next_servicedependency; } /* free hashlist and reset pointers */ free(servicedependency_hashlist); servicedependency_hashlist=NULL; servicedependency_list=NULL; #ifdef DEBUG1 printf("\tservicedependency_list freed\n"); #endif /* free memory for the host dependency list */ this_hostdependency=hostdependency_list; while(this_hostdependency!=NULL){ next_hostdependency=this_hostdependency->next; free(this_hostdependency->dependent_host_name); free(this_hostdependency->host_name); free(this_hostdependency); this_hostdependency=next_hostdependency; } /* free hashlist and reset pointers */ free(hostdependency_hashlist); hostdependency_hashlist=NULL; hostdependency_list=NULL; #ifdef DEBUG1 printf("\thostdependency_list freed\n"); #endif /* free memory for the host escalation list */ this_hostescalation=hostescalation_list; while(this_hostescalation!=NULL){ /* free memory for the contact group members */ this_contactgroupsmember=this_hostescalation->contact_groups; while(this_contactgroupsmember!=NULL){ next_contactgroupsmember=this_contactgroupsmember->next; free(this_contactgroupsmember->group_name); free(this_contactgroupsmember); this_contactgroupsmember=next_contactgroupsmember; } next_hostescalation=this_hostescalation->next; free(this_hostescalation->host_name); free(this_hostescalation->escalation_period); free(this_hostescalation); this_hostescalation=next_hostescalation; } /* free hashlist and reset pointers */ free(hostescalation_hashlist); hostescalation_hashlist=NULL; hostescalation_list=NULL; /* free extended info data */ free_extended_data(); #ifdef DEBUG1 printf("\thostescalation_list freed\n"); #endif #ifdef DEBUG0 printf("free_object_data() end\n"); #endif return OK; } /* free all allocated memory for extended info objects */ int free_extended_data(void){ hostextinfo *this_hostextinfo=NULL; hostextinfo *next_hostextinfo=NULL; serviceextinfo *this_serviceextinfo=NULL; serviceextinfo *next_serviceextinfo=NULL; #ifdef DEBUG0 printf("free_extended_data() start\n"); #endif /* free memory for the extended host info list */ for(this_hostextinfo=hostextinfo_list;this_hostextinfo!=NULL;this_hostextinfo=next_hostextinfo){ next_hostextinfo=this_hostextinfo->next; free(this_hostextinfo->host_name); free(this_hostextinfo->notes); free(this_hostextinfo->notes_url); free(this_hostextinfo->action_url); free(this_hostextinfo->icon_image); free(this_hostextinfo->vrml_image); free(this_hostextinfo->statusmap_image); free(this_hostextinfo->icon_image_alt); free(this_hostextinfo); } #ifdef DEBUG1 printf("\thostextinfo_list freed\n"); #endif /* free hashlist and reset pointers */ free(hostextinfo_hashlist); hostextinfo_hashlist=NULL; hostextinfo_list=NULL; /* free memory for the extended service info list */ for(this_serviceextinfo=serviceextinfo_list;this_serviceextinfo!=NULL;this_serviceextinfo=next_serviceextinfo){ next_serviceextinfo=this_serviceextinfo->next; free(this_serviceextinfo->host_name); free(this_serviceextinfo->description); free(this_serviceextinfo->notes); free(this_serviceextinfo->notes_url); free(this_serviceextinfo->action_url); free(this_serviceextinfo->icon_image); free(this_serviceextinfo->icon_image_alt); free(this_serviceextinfo); } #ifdef DEBUG1 printf("\tserviceextinfo_list freed\n"); #endif /* free hashlist and reset pointers */ free(serviceextinfo_hashlist); serviceextinfo_hashlist=NULL; serviceextinfo_list=NULL; #ifdef DEBUG0 printf("free_extended_data() end\n"); #endif return OK; } nagios-2.6/common/snprintf.c0000664000076500007650000005401507532266735015522 0ustar nagiosnagios/* * Copyright Patrick Powell 1995 * This code is based on code written by Patrick Powell (papowell@astart.com) * It may be used for any purpose as long as this notice remains intact * on all source code distributions */ /************************************************************** * Original: * Patrick Powell Tue Apr 11 09:48:21 PDT 1995 * A bombproof version of doprnt (dopr) included. * Sigh. This sort of thing is always nasty do deal with. Note that * the version here does not include floating point... * * snprintf() is used instead of sprintf() as it does limit checks * for string length. This covers a nasty loophole. * * The other functions are there to prevent NULL pointers from * causing nast effects. * * More Recently: * Brandon Long 9/15/96 for mutt 0.43 * This was ugly. It is still ugly. I opted out of floating point * numbers, but the formatter understands just about everything * from the normal C string format, at least as far as I can tell from * the Solaris 2.5 printf(3S) man page. * * Brandon Long 10/22/97 for mutt 0.87.1 * Ok, added some minimal floating point support, which means this * probably requires libm on most operating systems. Don't yet * support the exponent (e,E) and sigfig (g,G). Also, fmtint() * was pretty badly broken, it just wasn't being exercised in ways * which showed it, so that's been fixed. Also, formated the code * to mutt conventions, and removed dead code left over from the * original. Also, there is now a builtin-test, just compile with: * gcc -DTEST_SNPRINTF -o snprintf snprintf.c -lm * and run snprintf for results. * * Thomas Roessler 01/27/98 for mutt 0.89i * The PGP code was using unsigned hexadecimal formats. * Unfortunately, unsigned formats simply didn't work. * * Michael Elkins 03/05/98 for mutt 0.90.8 * The original code assumed that both snprintf() and vsnprintf() were * missing. Some systems only have snprintf() but not vsnprintf(), so * the code is now broken down under HAVE_SNPRINTF and HAVE_VSNPRINTF. * * Andrew Tridgell (tridge@samba.org) Oct 1998 * fixed handling of %.0f * added test for HAVE_LONG_DOUBLE * * tridge@samba.org, idra@samba.org, April 2001 * got rid of fcvt code (twas buggy and made testing harder) * added C99 semantics * **************************************************************/ #ifndef NO_CONFIG_H /* for some tests */ #include "config.h" #else #define NULL 0 #endif #ifdef TEST_SNPRINTF /* need math library headers for testing */ #include #endif #ifdef HAVE_STRING_H #include #endif #ifdef HAVE_STRINGS_H #include #endif #ifdef HAVE_CTYPE_H #include #endif #include #include #ifdef HAVE_STDLIB_H #include #endif #if defined(HAVE_SNPRINTF) && defined(HAVE_VSNPRINTF) && defined(HAVE_C99_VSNPRINTF) /* only include stdio.h if we are not re-defining snprintf or vsnprintf */ #include /* make the compiler happy with an empty file */ void dummy_snprintf(void) {} #else #ifdef HAVE_LONG_DOUBLE #define LDOUBLE long double #else #define LDOUBLE double #endif #ifdef HAVE_LONG_LONG #define LLONG long long #else #define LLONG long #endif /* free memory if the pointer is valid and zero the pointer */ #ifndef SAFE_FREE #define SAFE_FREE(x) do { if ((x) != NULL) {free((x)); (x)=NULL;} } while(0) #endif #ifndef VA_COPY #ifdef HAVE_VA_COPY #define VA_COPY(dest, src) __va_copy(dest, src) #else #define VA_COPY(dest, src) (dest) = (src) #endif #endif static size_t dopr(char *buffer, size_t maxlen, const char *format, va_list args_in); static void fmtstr(char *buffer, size_t *currlen, size_t maxlen, char *value, int flags, int min, int max); static void fmtint(char *buffer, size_t *currlen, size_t maxlen, long value, int base, int min, int max, int flags); static void fmtfp(char *buffer, size_t *currlen, size_t maxlen, LDOUBLE fvalue, int min, int max, int flags); static void dopr_outch(char *buffer, size_t *currlen, size_t maxlen, char c); /* * dopr(): poor man's version of doprintf */ /* format read states */ #define DP_S_DEFAULT 0 #define DP_S_FLAGS 1 #define DP_S_MIN 2 #define DP_S_DOT 3 #define DP_S_MAX 4 #define DP_S_MOD 5 #define DP_S_CONV 6 #define DP_S_DONE 7 /* format flags - Bits */ #define DP_F_MINUS (1 << 0) #define DP_F_PLUS (1 << 1) #define DP_F_SPACE (1 << 2) #define DP_F_NUM (1 << 3) #define DP_F_ZERO (1 << 4) #define DP_F_UP (1 << 5) #define DP_F_UNSIGNED (1 << 6) /* Conversion Flags */ #define DP_C_SHORT 1 #define DP_C_LONG 2 #define DP_C_LDOUBLE 3 #define DP_C_LLONG 4 #define char_to_int(p) ((p)- '0') #ifndef MAX #define MAX(p,q) (((p) >= (q)) ? (p) : (q)) #endif static size_t dopr(char *buffer, size_t maxlen, const char *format, va_list args_in) { char ch; LLONG value; LDOUBLE fvalue; char *strvalue; int min; int max; int state; int flags; int cflags; size_t currlen; va_list args; VA_COPY(args, args_in); state = DP_S_DEFAULT; currlen = flags = cflags = min = 0; max = -1; ch = *format++; while (state != DP_S_DONE) { if (ch == '\0') state = DP_S_DONE; switch(state) { case DP_S_DEFAULT: if (ch == '%') state = DP_S_FLAGS; else dopr_outch (buffer, &currlen, maxlen, ch); ch = *format++; break; case DP_S_FLAGS: switch (ch) { case '-': flags |= DP_F_MINUS; ch = *format++; break; case '+': flags |= DP_F_PLUS; ch = *format++; break; case ' ': flags |= DP_F_SPACE; ch = *format++; break; case '#': flags |= DP_F_NUM; ch = *format++; break; case '0': flags |= DP_F_ZERO; ch = *format++; break; default: state = DP_S_MIN; break; } break; case DP_S_MIN: if (isdigit((unsigned char)ch)) { min = 10*min + char_to_int (ch); ch = *format++; } else if (ch == '*') { min = va_arg (args, int); ch = *format++; state = DP_S_DOT; } else { state = DP_S_DOT; } break; case DP_S_DOT: if (ch == '.') { state = DP_S_MAX; ch = *format++; } else { state = DP_S_MOD; } break; case DP_S_MAX: if (isdigit((unsigned char)ch)) { if (max < 0) max = 0; max = 10*max + char_to_int (ch); ch = *format++; } else if (ch == '*') { max = va_arg (args, int); ch = *format++; state = DP_S_MOD; } else { state = DP_S_MOD; } break; case DP_S_MOD: switch (ch) { case 'h': cflags = DP_C_SHORT; ch = *format++; break; case 'l': cflags = DP_C_LONG; ch = *format++; if (ch == 'l') { /* It's a long long */ cflags = DP_C_LLONG; ch = *format++; } break; case 'L': cflags = DP_C_LDOUBLE; ch = *format++; break; default: break; } state = DP_S_CONV; break; case DP_S_CONV: switch (ch) { case 'd': case 'i': if (cflags == DP_C_SHORT) value = va_arg (args, int); else if (cflags == DP_C_LONG) value = va_arg (args, long int); else if (cflags == DP_C_LLONG) value = va_arg (args, LLONG); else value = va_arg (args, int); fmtint (buffer, &currlen, maxlen, value, 10, min, max, flags); break; case 'o': flags |= DP_F_UNSIGNED; if (cflags == DP_C_SHORT) value = va_arg (args, unsigned int); else if (cflags == DP_C_LONG) value = (long)va_arg (args, unsigned long int); else if (cflags == DP_C_LLONG) value = (long)va_arg (args, unsigned LLONG); else value = (long)va_arg (args, unsigned int); fmtint (buffer, &currlen, maxlen, value, 8, min, max, flags); break; case 'u': flags |= DP_F_UNSIGNED; if (cflags == DP_C_SHORT) value = va_arg (args, unsigned int); else if (cflags == DP_C_LONG) value = (long)va_arg (args, unsigned long int); else if (cflags == DP_C_LLONG) value = (LLONG)va_arg (args, unsigned LLONG); else value = (long)va_arg (args, unsigned int); fmtint (buffer, &currlen, maxlen, value, 10, min, max, flags); break; case 'X': flags |= DP_F_UP; case 'x': flags |= DP_F_UNSIGNED; if (cflags == DP_C_SHORT) value = va_arg (args, unsigned int); else if (cflags == DP_C_LONG) value = (long)va_arg (args, unsigned long int); else if (cflags == DP_C_LLONG) value = (LLONG)va_arg (args, unsigned LLONG); else value = (long)va_arg (args, unsigned int); fmtint (buffer, &currlen, maxlen, value, 16, min, max, flags); break; case 'f': if (cflags == DP_C_LDOUBLE) fvalue = va_arg (args, LDOUBLE); else fvalue = va_arg (args, double); /* um, floating point? */ fmtfp (buffer, &currlen, maxlen, fvalue, min, max, flags); break; case 'E': flags |= DP_F_UP; case 'e': if (cflags == DP_C_LDOUBLE) fvalue = va_arg (args, LDOUBLE); else fvalue = va_arg (args, double); break; case 'G': flags |= DP_F_UP; case 'g': if (cflags == DP_C_LDOUBLE) fvalue = va_arg (args, LDOUBLE); else fvalue = va_arg (args, double); break; case 'c': dopr_outch (buffer, &currlen, maxlen, va_arg (args, int)); break; case 's': strvalue = va_arg (args, char *); if (!strvalue) strvalue = "(NULL)"; if (max == -1) { max = strlen(strvalue); } if (min > 0 && max >= 0 && min > max) max = min; fmtstr (buffer, &currlen, maxlen, strvalue, flags, min, max); break; case 'p': strvalue = va_arg (args, void *); fmtint (buffer, &currlen, maxlen, (long) strvalue, 16, min, max, flags); break; case 'n': if (cflags == DP_C_SHORT) { short int *num; num = va_arg (args, short int *); *num = currlen; } else if (cflags == DP_C_LONG) { long int *num; num = va_arg (args, long int *); *num = (long int)currlen; } else if (cflags == DP_C_LLONG) { LLONG *num; num = va_arg (args, LLONG *); *num = (LLONG)currlen; } else { int *num; num = va_arg (args, int *); *num = currlen; } break; case '%': dopr_outch (buffer, &currlen, maxlen, ch); break; case 'w': /* not supported yet, treat as next char */ ch = *format++; break; default: /* Unknown, skip */ break; } ch = *format++; state = DP_S_DEFAULT; flags = cflags = min = 0; max = -1; break; case DP_S_DONE: break; default: /* hmm? */ break; /* some picky compilers need this */ } } if (maxlen != 0) { if (currlen < maxlen - 1) buffer[currlen] = '\0'; else if (maxlen > 0) buffer[maxlen - 1] = '\0'; } return currlen; } static void fmtstr(char *buffer, size_t *currlen, size_t maxlen, char *value, int flags, int min, int max) { int padlen, strln; /* amount to pad */ int cnt = 0; #ifdef DEBUG_SNPRINTF printf("fmtstr min=%d max=%d s=[%s]\n", min, max, value); #endif if (value == 0) { value = ""; } for (strln = 0; value[strln]; ++strln); /* strlen */ padlen = min - strln; if (padlen < 0) padlen = 0; if (flags & DP_F_MINUS) padlen = -padlen; /* Left Justify */ while ((padlen > 0) && (cnt < max)) { dopr_outch (buffer, currlen, maxlen, ' '); --padlen; ++cnt; } while (*value && (cnt < max)) { dopr_outch (buffer, currlen, maxlen, *value++); ++cnt; } while ((padlen < 0) && (cnt < max)) { dopr_outch (buffer, currlen, maxlen, ' '); ++padlen; ++cnt; } } /* Have to handle DP_F_NUM (ie 0x and 0 alternates) */ static void fmtint(char *buffer, size_t *currlen, size_t maxlen, long value, int base, int min, int max, int flags) { int signvalue = 0; unsigned long uvalue; char convert[20]; int place = 0; int spadlen = 0; /* amount to space pad */ int zpadlen = 0; /* amount to zero pad */ int caps = 0; if (max < 0) max = 0; uvalue = value; if(!(flags & DP_F_UNSIGNED)) { if( value < 0 ) { signvalue = '-'; uvalue = -value; } else { if (flags & DP_F_PLUS) /* Do a sign (+/i) */ signvalue = '+'; else if (flags & DP_F_SPACE) signvalue = ' '; } } if (flags & DP_F_UP) caps = 1; /* Should characters be upper case? */ do { convert[place++] = (caps? "0123456789ABCDEF":"0123456789abcdef") [uvalue % (unsigned)base ]; uvalue = (uvalue / (unsigned)base ); } while(uvalue && (place < 20)); if (place == 20) place--; convert[place] = 0; zpadlen = max - place; spadlen = min - MAX (max, place) - (signvalue ? 1 : 0); if (zpadlen < 0) zpadlen = 0; if (spadlen < 0) spadlen = 0; if (flags & DP_F_ZERO) { zpadlen = MAX(zpadlen, spadlen); spadlen = 0; } if (flags & DP_F_MINUS) spadlen = -spadlen; /* Left Justifty */ #ifdef DEBUG_SNPRINTF printf("zpad: %d, spad: %d, min: %d, max: %d, place: %d\n", zpadlen, spadlen, min, max, place); #endif /* Spaces */ while (spadlen > 0) { dopr_outch (buffer, currlen, maxlen, ' '); --spadlen; } /* Sign */ if (signvalue) dopr_outch (buffer, currlen, maxlen, signvalue); /* Zeros */ if (zpadlen > 0) { while (zpadlen > 0) { dopr_outch (buffer, currlen, maxlen, '0'); --zpadlen; } } /* Digits */ while (place > 0) dopr_outch (buffer, currlen, maxlen, convert[--place]); /* Left Justified spaces */ while (spadlen < 0) { dopr_outch (buffer, currlen, maxlen, ' '); ++spadlen; } } static LDOUBLE abs_val(LDOUBLE value) { LDOUBLE result = value; if (value < 0) result = -value; return result; } static LDOUBLE POW10(int exp) { LDOUBLE result = 1; while (exp) { result *= 10; exp--; } return result; } static LLONG ROUND(LDOUBLE value) { LLONG intpart; intpart = (LLONG)value; value = value - intpart; if (value >= 0.5) intpart++; return intpart; } /* a replacement for modf that doesn't need the math library. Should be portable, but slow */ static double my_modf(double x0, double *iptr) { int i; long l; double x = x0; double f = 1.0; for (i=0;i<100;i++) { l = (long)x; if (l <= (x+1) && l >= (x-1)) break; x *= 0.1; f *= 10.0; } if (i == 100) { /* yikes! the number is beyond what we can handle. What do we do? */ (*iptr) = 0; return 0; } if (i != 0) { double i2; double ret; ret = my_modf(x0-l*f, &i2); (*iptr) = l*f + i2; return ret; } (*iptr) = l; return x - (*iptr); } static void fmtfp (char *buffer, size_t *currlen, size_t maxlen, LDOUBLE fvalue, int min, int max, int flags) { int signvalue = 0; double ufvalue; char iconvert[311]; char fconvert[311]; int iplace = 0; int fplace = 0; int padlen = 0; /* amount to pad */ int zpadlen = 0; int caps = 0; int index; double intpart; double fracpart; double temp; /* * AIX manpage says the default is 0, but Solaris says the default * is 6, and sprintf on AIX defaults to 6 */ if (max < 0) max = 6; ufvalue = abs_val (fvalue); if (fvalue < 0) { signvalue = '-'; } else { if (flags & DP_F_PLUS) { /* Do a sign (+/i) */ signvalue = '+'; } else { if (flags & DP_F_SPACE) signvalue = ' '; } } #if 0 if (flags & DP_F_UP) caps = 1; /* Should characters be upper case? */ #endif #if 0 if (max == 0) ufvalue += 0.5; /* if max = 0 we must round */ #endif /* * Sorry, we only support 16 digits past the decimal because of our * conversion method */ if (max > 16) max = 16; /* We "cheat" by converting the fractional part to integer by * multiplying by a factor of 10 */ temp = ufvalue; my_modf(temp, &intpart); fracpart = ROUND((POW10(max)) * (ufvalue - intpart)); if (fracpart >= POW10(max)) { intpart++; fracpart -= POW10(max); } /* Convert integer part */ do { temp = intpart*0.1; my_modf(temp, &intpart); index = (int) ((temp -intpart +0.05)* 10.0); /* index = (int) (((double)(temp*0.1) -intpart +0.05) *10.0); */ /* printf ("%llf, %f, %x\n", temp, intpart, index); */ iconvert[iplace++] = (caps? "0123456789ABCDEF":"0123456789abcdef")[index]; } while (intpart && (iplace < 311)); if (iplace == 311) iplace--; iconvert[iplace] = 0; /* Convert fractional part */ if (fracpart) { do { temp = fracpart*0.1; my_modf(temp, &fracpart); index = (int) ((temp -fracpart +0.05)* 10.0); /* index = (int) ((((temp/10) -fracpart) +0.05) *10); */ /* printf ("%lf, %lf, %ld\n", temp, fracpart, index); */ fconvert[fplace++] = (caps? "0123456789ABCDEF":"0123456789abcdef")[index]; } while(fracpart && (fplace < 311)); if (fplace == 311) fplace--; } fconvert[fplace] = 0; /* -1 for decimal point, another -1 if we are printing a sign */ padlen = min - iplace - max - 1 - ((signvalue) ? 1 : 0); zpadlen = max - fplace; if (zpadlen < 0) zpadlen = 0; if (padlen < 0) padlen = 0; if (flags & DP_F_MINUS) padlen = -padlen; /* Left Justifty */ if ((flags & DP_F_ZERO) && (padlen > 0)) { if (signvalue) { dopr_outch (buffer, currlen, maxlen, signvalue); --padlen; signvalue = 0; } while (padlen > 0) { dopr_outch (buffer, currlen, maxlen, '0'); --padlen; } } while (padlen > 0) { dopr_outch (buffer, currlen, maxlen, ' '); --padlen; } if (signvalue) dopr_outch (buffer, currlen, maxlen, signvalue); while (iplace > 0) dopr_outch (buffer, currlen, maxlen, iconvert[--iplace]); #ifdef DEBUG_SNPRINTF printf("fmtfp: fplace=%d zpadlen=%d\n", fplace, zpadlen); #endif /* * Decimal point. This should probably use locale to find the correct * char to print out. */ if (max > 0) { dopr_outch (buffer, currlen, maxlen, '.'); while (zpadlen > 0) { dopr_outch (buffer, currlen, maxlen, '0'); --zpadlen; } while (fplace > 0) dopr_outch (buffer, currlen, maxlen, fconvert[--fplace]); } while (padlen < 0) { dopr_outch (buffer, currlen, maxlen, ' '); ++padlen; } } static void dopr_outch(char *buffer, size_t *currlen, size_t maxlen, char c) { if (*currlen < maxlen) { buffer[(*currlen)] = c; } (*currlen)++; } /* yes this really must be a ||. Don't muck with this (tridge) */ #if !defined(HAVE_VSNPRINTF) || !defined(HAVE_C99_VSNPRINTF) int vsnprintf (char *str, size_t count, const char *fmt, va_list args) { return dopr(str, count, fmt, args); } #endif /* yes this really must be a ||. Don't muck wiith this (tridge) * * The logic for these two is that we need our own definition if the * OS *either* has no definition of *sprintf, or if it does have one * that doesn't work properly according to the autoconf test. Perhaps * these should really be smb_snprintf to avoid conflicts with buggy * linkers? -- mbp */ #if !defined(HAVE_SNPRINTF) || !defined(HAVE_C99_SNPRINTF) int snprintf(char *str,size_t count,const char *fmt,...) { size_t ret; va_list ap; va_start(ap, fmt); ret = vsnprintf(str, count, fmt, ap); va_end(ap); return ret; } #endif #endif #ifndef HAVE_VASPRINTF int vasprintf(char **ptr, const char *format, va_list ap) { int ret; va_list ap2; VA_COPY(ap2, ap); ret = vsnprintf(NULL, 0, format, ap2); if (ret <= 0) return ret; (*ptr) = (char *)malloc(ret+1); if (!*ptr) return -1; VA_COPY(ap2, ap); ret = vsnprintf(*ptr, ret+1, format, ap2); return ret; } #endif #ifndef HAVE_ASPRINTF int asprintf(char **ptr, const char *format, ...) { va_list ap; int ret; *ptr = NULL; va_start(ap, format); ret = vasprintf(ptr, format, ap); va_end(ap); return ret; } #endif #ifdef TEST_SNPRINTF int sprintf(char *str,const char *fmt,...); int main (void) { char buf1[1024]; char buf2[1024]; char *fp_fmt[] = { "%1.1f", "%-1.5f", "%1.5f", "%123.9f", "%10.5f", "% 10.5f", "%+22.9f", "%+4.9f", "%01.3f", "%4f", "%3.1f", "%3.2f", "%.0f", "%f", "-16.16f", NULL }; double fp_nums[] = { 6442452944.1234, -1.5, 134.21, 91340.2, 341.1234, 0203.9, 0.96, 0.996, 0.9996, 1.996, 4.136, 5.030201, 0}; char *int_fmt[] = { "%-1.5d", "%1.5d", "%123.9d", "%5.5d", "%10.5d", "% 10.5d", "%+22.33d", "%01.3d", "%4d", "%d", NULL }; long int_nums[] = { -1, 134, 91340, 341, 0203, 0}; char *str_fmt[] = { "10.5s", "5.10s", "10.1s", "0.10s", "10.0s", "1.10s", "%s", "%.1s", "%.10s", "%10s", NULL }; char *str_vals[] = {"hello", "a", "", "a longer string", NULL}; int x, y; int fail = 0; int num = 0; printf ("Testing snprintf format codes against system sprintf...\n"); for (x = 0; fp_fmt[x] ; x++) { for (y = 0; fp_nums[y] != 0 ; y++) { int l1 = snprintf(NULL, 0, fp_fmt[x], fp_nums[y]); int l2 = snprintf(buf1, sizeof(buf1), fp_fmt[x], fp_nums[y]); sprintf (buf2, fp_fmt[x], fp_nums[y]); if (strcmp (buf1, buf2)) { printf("snprintf doesn't match Format: %s\n\tsnprintf = [%s]\n\t sprintf = [%s]\n", fp_fmt[x], buf1, buf2); fail++; } if (l1 != l2) { printf("snprintf l1 != l2 (%d %d) %s\n", l1, l2, fp_fmt[x]); fail++; } num++; } } for (x = 0; int_fmt[x] ; x++) { for (y = 0; int_nums[y] != 0 ; y++) { int l1 = snprintf(NULL, 0, int_fmt[x], int_nums[y]); int l2 = snprintf(buf1, sizeof(buf1), int_fmt[x], int_nums[y]); sprintf (buf2, int_fmt[x], int_nums[y]); if (strcmp (buf1, buf2)) { printf("snprintf doesn't match Format: %s\n\tsnprintf = [%s]\n\t sprintf = [%s]\n", int_fmt[x], buf1, buf2); fail++; } if (l1 != l2) { printf("snprintf l1 != l2 (%d %d) %s\n", l1, l2, int_fmt[x]); fail++; } num++; } } for (x = 0; str_fmt[x] ; x++) { for (y = 0; str_vals[y] != 0 ; y++) { int l1 = snprintf(NULL, 0, str_fmt[x], str_vals[y]); int l2 = snprintf(buf1, sizeof(buf1), str_fmt[x], str_vals[y]); sprintf (buf2, str_fmt[x], str_vals[y]); if (strcmp (buf1, buf2)) { printf("snprintf doesn't match Format: %s\n\tsnprintf = [%s]\n\t sprintf = [%s]\n", str_fmt[x], buf1, buf2); fail++; } if (l1 != l2) { printf("snprintf l1 != l2 (%d %d) %s\n", l1, l2, str_fmt[x]); fail++; } num++; } } printf ("%d tests failed out of %d.\n", fail, num); printf("seeing how many digits we support\n"); { double v0 = 0.12345678901234567890123456789012345678901; for (x=0; x<100; x++) { double p = pow(10, x); double r = v0*p; snprintf(buf1, sizeof(buf1), "%1.1f", r); sprintf(buf2, "%1.1f", r); if (strcmp(buf1, buf2)) { printf("we seem to support %d digits\n", x-1); break; } } } return 0; } #endif /* SNPRINTF_TEST */ nagios-2.6/common/statusdata.c0000664000076500007650000003553510336571237016032 0ustar nagiosnagios/***************************************************************************** * * 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;ihost_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 nagios-2.6/contrib/0000775000076500007650000000000010532717566013653 5ustar nagiosnagiosnagios-2.6/contrib/eventhandlers/0000775000076500007650000000000010532717566016515 5ustar nagiosnagiosnagios-2.6/contrib/eventhandlers/disable_active_service_checks0000775000076500007650000000160507436604431024436 0ustar nagiosnagios#!/bin/sh # Write a command to the Nagios command file to cause # it to disable active service checks. This can be # referred to as 'standby' mode in a redundant monitoring # environment. # Notes: # 1) This script is not intended to be used as an # event handler by itself. Instead, it is used by other # event handler scripts (like the redundancy examples). # 2) In order for Nagios to process any commands that # are written to the command file, you must enable # the check_external_commands option in the main # configuration file. echocmd="/bin/echo" CommandFile="/usr/local/nagios/var/rw/nagios.cmd" # get the current date/time in seconds since UNIX epoch datetime=`date +%s` # create the command line to add to the command file cmdline="[$datetime] STOP_EXECUTING_SERVICE_CHECKS" # append the command to the end of the command file `$echocmd $cmdline >> $CommandFile` nagios-2.6/contrib/eventhandlers/disable_notifications0000775000076500007650000000147107436604431022775 0ustar nagiosnagios#!/bin/sh # Write a command to the Nagios command file to cause # it to disable host and service notifications # Notes: # 1) This script is not intended to be used as an # event handler by itself. Instead, it is used by other # event handler scripts (like the redundancy examples). # 2) In order for Nagios to process any commands that # are written to the command file, you must enable # the check_external_commands option in the main # configuration file. echocmd="/bin/echo" CommandFile="/usr/local/nagios/var/rw/nagios.cmd" # get the current date/time in seconds since UNIX epoch datetime=`date +%s` # create the command line to add to the command file cmdline="[$datetime] DISABLE_NOTIFICATIONS;$datetime" # append the command to the end of the command file `$echocmd $cmdline >> $CommandFile` nagios-2.6/contrib/eventhandlers/enable_active_service_checks0000775000076500007650000000160407436604431024260 0ustar nagiosnagios#!/bin/sh # Write a command to the Nagios command file to cause # it to enable active service checks. This can be # referred to as 'active' mode in a redundant monitoring # environment. # Notes: # 1) This script is not intended to be used as an # event handler by itself. Instead, it is used by other # event handler scripts (like the redundancy examples). # 2) In order for Nagios to process any commands that # are written to the command file, you must enable # the check_external_commands option in the main # configuration file. echocmd="/bin/echo" CommandFile="/usr/local/nagios/var/rw/nagios.cmd" # get the current date/time in seconds since UNIX epoch datetime=`date +%s` # create the command line to add to the command file cmdline="[$datetime] START_EXECUTING_SERVICE_CHECKS" # append the command to the end of the command file `$echocmd $cmdline >> $CommandFile` nagios-2.6/contrib/eventhandlers/enable_notifications0000775000076500007650000000147207436604431022621 0ustar nagiosnagios#!/bin/sh # Write a command to the Nagios command file to cause # it to enable host and service notifications # Notes: # 1) This script is not intended to be used as an # event handler by itself. Instead, it is used by other # event handler scripts (like the redundancy examples). # 2) In order for Nagios to process any commands that # are written to the command file, you must enable # the check_external_commands option in the main # configuration file. echocmd="/bin/echo" CommandFile="/usr/local/nagios/var/rw/nagios.cmd" # get the current date/time in seconds since UNIX epoch datetime=`date +%s` # create the command line to add to the command file cmdline="[$datetime] ENABLE_NOTIFICATIONS;$datetime" # append the command to the end of the command file `$echocmd $cmdline >> $CommandFile` nagios-2.6/contrib/eventhandlers/submit_check_result0000775000076500007650000000223607436604431022477 0ustar nagiosnagios#!/bin/sh # SUBMIT_CHECK_RESULT # Written by Ethan Galstad (nagios@nagios.org) # Last Modified: 02-18-2002 # # This script will write a command to the Nagios command # file to cause Nagios to process a passive service check # result. Note: This script is intended to be run on the # same host that is running Nagios. If you want to # submit passive check results from a remote machine, look # at using the nsca addon. # # Arguments: # $1 = host_name (Short name of host that the service is # associated with) # $2 = svc_description (Description of the service) # $3 = return_code (An integer that determines the state # of the service check, 0=OK, 1=WARNING, 2=CRITICAL, # 3=UNKNOWN). # $4 = plugin_output (A text string that should be used # as the plugin output for the service check) # echocmd="/bin/echo" CommandFile="/usr/local/nagios/var/rw/nagios.cmd" # get the current date/time in seconds since UNIX epoch datetime=`date +%s` # create the command line to add to the command file cmdline="[$datetime] PROCESS_SERVICE_CHECK_RESULT;$1;$2;$3;$4" # append the command to the end of the command file `$echocmd $cmdline >> $CommandFile` nagios-2.6/contrib/eventhandlers/distributed-monitoring/0000775000076500007650000000000010532717566023222 5ustar nagiosnagiosnagios-2.6/contrib/eventhandlers/distributed-monitoring/obsessive_svc_handler0000775000076500007650000000223307436604431027515 0ustar nagiosnagios#!/bin/sh # OBSESSIVE_SVC_HANDLER # Written by Ethan Galstad (nagios@nagils.org) # Last Modified: 07-19-2001 # # This script is intended to run as the OCSP command # on a distributed monitoring server. The script calls # submit_check_result_via_nsca to send the service check # results to the central monitoring server. # # Arguments: # $1 = host_name (Short name of host that the service is # associated with) # $2 = svc_description (Description of the service) # $3 = state_string (A string representing the status of # the given service - "OK", "WARNING", "CRITICAL" # or "UNKNOWN") # $4 = plugin_output (A text string that should be used # as the plugin output for the service checks) # # Location of the submit_check_result_via_nsca script SubmitCmd="/usr/local/nagios/libexec/eventhandlers/submit_check_result_via_nsca" # Convert the state string to the corresponding return code return_code=-1 case "$3" in OK) return_code=0 ;; WARNING) return_code=1 ;; CRITICAL) return_code=2 ;; UNKNOWN) return_code=3 ;; esac # Send the service check results to the central monitoring server $SubmitCmd "$1" "$2" $return_code "$4" nagios-2.6/contrib/eventhandlers/distributed-monitoring/submit_check_result_via_nsca0000775000076500007650000000226710015307355031043 0ustar nagiosnagios#!/bin/sh # SUBMIT_CHECK_RESULT_VIA_NSCA # Written by Ethan Galstad (nagios@nagios.org) # Last Modified: 02-19-2004 # # This script will send passive check results to the # nsca daemon that runs on the central Nagios server. # If you simply want to submit passive checks from the # same machine that Nagios is running on, look at the # submit_check_result script. # # Arguments: # $1 = host_name (Short name of host that the service is # associated with) # $2 = svc_description (Description of the service) # $3 = return_code (An integer that determines the state # of the service check, 0=OK, 1=WARNING, 2=CRITICAL, # 3=UNKNOWN). # $4 = plugin_output (A text string that should be used # as the plugin output for the service check)s # # # Note: # Modify the NagiosHost parameter to match the name or # IP address of the central server that has the nsca # daemon running. printfcmd="/bin/printf" NscaBin="/usr/local/nagios/libexec/send_nsca" NscaCfg="/usr/local/nagios/etc/send_nsca.cfg" NagiosHost="nagioshost" # Fire the data off to the NSCA daemon using the send_nsca script $printfcmd "%s\t%s\t%s\t%s\n" "$1" "$2" "$3" "$4" | $NscaBin $NagiosHost -c $NscaCfg # EOF nagios-2.6/contrib/eventhandlers/redundancy-scenario1/0000775000076500007650000000000010532717566022533 5ustar nagiosnagiosnagios-2.6/contrib/eventhandlers/redundancy-scenario1/handle-master-host-event0000775000076500007650000000376410015307355027274 0ustar nagiosnagios#!/bin/sh # REDUNDANCY EVENT HANDLER SCRIPT # Written By: Ethan Galstad (nagios@nagios.org) # Last Modified: 02-19-2004 # # This is an example script for implementing redundancy. # Read the HTML documentation on redundant monitoring for more # information on what this does. # Location of the echo and mail commands echocmd="/bin/echo" mailcmd="/bin/mail" # Location of the event handlers eventhandlerdir="/usr/local/nagios/libexec/eventhandlers" # Only take action on hard host states... case "$2" in HARD) case "$1" in DOWN) # The master host has gone down! # We should now become the master host and take # over the responsibilities of monitoring the # network, so enable notifications... `$eventhandlerdir/enable_notifications` # Notify someone of what has happened with the original # master server and our taking over the monitoring # responsibilities. No one was notified of the master # host going down, since the notification would have # occurred while we were in standby mode, so this is a good idea... #`$echocmd "Master Nagios host is down!" | /bin/mail -s "Master Nagios Host Is Down" root@localhost` #`$echocmd "Slave Nagios host has entered ACTIVE mode and taken over network monitoring responsibilities!" | $mailcmd -s "Slave Nagios Host Has Entered ACTIVE Mode" root@localhost` ;; UP) # The master host has recovered! # We should go back to being the slave host and # let the master host do the monitoring, so # disable notifications... `$eventhandlerdir/disable_notifications` # Notify someone of what has happened. Users were # already notified of the master host recovery because we # were in active mode at the time the recovery happened. # However, we should let someone know that we're switching # back to standby mode... #`$echocmd "The master Nagios host has recovered, so the slave Nagios host has returned to standby mode..." | $mailcmd -s "Slave Nagios Host Has Returned To STANDBY Mode" root@localhost` ;; esac ;; esac exit 0 nagios-2.6/contrib/eventhandlers/redundancy-scenario1/handle-master-proc-event0000775000076500007650000000231610437072212027251 0ustar nagiosnagios#!/bin/sh # REDUNDANCY EVENT HANDLER SCRIPT # Written By: Ethan Galstad (nagios@nagios.org) # Last Modified: 05-30-2006 # # This is an example script for implementing redundancy. # Read the HTML documentation on redundant monitoring for more # information on what this does. # Location of the echo and mail commands echocmd="/bin/echo" mailcmd="/bin/mail" # Location of the event handlers eventhandlerdir="/usr/local/nagios/libexec/eventhandlers" # Only take action on hard service states... case "$2" in HARD) case "$1" in CRITICAL) # The master Nagios process is not running! # We should now become the master host and # take over the responsibility of monitoring # the network, so enable active checks... `$eventhandlerdir/enable_active_service_checks` ;; WARNING|UNKNOWN) # The master Nagios process may or may not # be running.. We won't do anything here, but # to be on the safe side you may decide you # want the slave host to become the master in # these situations... ;; OK) # The master Nagios process running again! # We should go back to being the slave host, # so disable active checks `eventhandlerdir/disable_active_service_checks` ;; esac ;; esac exit 0 nagios-2.6/contrib/.cvsignore0000664000076500007650000000001207623045550015636 0ustar nagiosnagiosperlxsi.c nagios-2.6/contrib/Makefile.in0000664000076500007650000000455010336237260015712 0ustar nagiosnagios############################### # Makefile for contrib software # # Last Modified: 11-14-2004 ############################### CC=@CC@ CFLAGS=@CFLAGS@ @DEFS@ LDFLAGS=@LDFLAGS@ @LIBS@ # Source code directories SRC_COMMON=../common SRC_CGI=../cgi # Generated automatically from configure script SNPRINTF_O=@SNPRINTF_O@ INSTALL=@INSTALL@ INSTALL_OPTS=@INSTALL_OPTS@ CGIDIR=@sbindir@ BINDIR=@bindir@ CGIS=traceroute.cgi UTILS=mini_epn new_mini_epn convertcfg ALL=$(CGIS) $(UTILS) CGI_C=$(SRC_CGI)/getcgi.c CGI_O=$(SRC_CGI)/getcgi.o $(SNPRINTF_O) CGI_H=$(SRC_CGI)/getcgi.h COMMON_H=$(SRC_COMMON)/config.h $(SRC_COMMON)/common.h $(SRC_COMMON)/locations.h ############################################################################## # standard targets (all, clean, distclean, devclean, install) all: $(ALL) clean: rm -f convertcfg daemonchk.cgi mini_epn new_mini_epn core *.o rm -f */*/*~ rm -f */*~ rm -f *~ distclean: clean rm -f Makefile devclean: distclean install: $(INSTALL) -m 775 $(INSTALL_OPTS) -d $(DESTDIR)$(CGIDIR) $(INSTALL) -m 775 $(INSTALL_OPTS) -d $(DESTDIR)$(BINDIR) for f in $(CGIS); do $(INSTALL) -m 775 $(INSTALL_OPTS) $$f $(DESTDIR)$(CGIDIR); done for f in $(UTILS); do $(INSTALL) -m 775 $(INSTALL_OPTS) $$f $(DESTDIR)$(BINDIR); done ############################################################################## # rules and dependencies for actual target programs daemonchk.cgi: @echo "This doesn't work with Nagios 2.x yet..." # daemonchk.c $(CGI_O) $(CGI_H) $(COMMON_H) mini_epn: mini_epn.c perl -MExtUtils::Embed -e xsinit $(CC) $(CFLAGS) -c perlxsi.c `perl -MExtUtils::Embed -e ccopts` $(CC) $(CFLAGS) -c mini_epn.c `perl -MExtUtils::Embed -e ccopts` $(CC) $(CFLAGS) $(LDFLAGS) perlxsi.o mini_epn.o `perl -MExtUtils::Embed -e ccopts -e ldopts` -o $@ new_mini_epn: new_mini_epn.c perl -MExtUtils::Embed -e xsinit $(CC) $(CFLAGS) -c perlxsi.c `perl -MExtUtils::Embed -e ccopts` $(CC) $(CFLAGS) -c new_mini_epn.c `perl -MExtUtils::Embed -e ccopts` $(CC) $(CFLAGS) $(LDFLAGS) perlxsi.o new_mini_epn.o `perl -MExtUtils::Embed -e ccopts -e ldopts` -o $@ ############################################################################## # dependencies $(CGI_O): $(CGI_C) cd $(SRC_CGI) && make $(CGI_O) ############################################################################## # implicit rules %.cgi : %.c $(CC) $(CFLAGS) $(LDFLAGS) $< $(CGI_O) -o $@ nagios-2.6/contrib/README0000664000076500007650000000244310012055623014514 0ustar nagiosnagios##################### Nagios Contrib README ##################### This directory contains various programs, scripts, etc. that have been contribed by various people. Read the source code if you want to find who did what. Here is a description of what you'll find... Conversion Programs: -------------------- - convertcfg.c is a program to quickly convert old "host" config files to the new template-based object config files. It can also convert extended host information definitions. Type 'make convertcfg' to compile the utility. Additional CGIs: ---------------- - traceroute.cgi is (surprise) a CGI that allows you to do a traceroute to a specific IP address. Simply do a 'chmod +x' to make it executeable and place it in the CGI directory (i.e. /usr/local/nagios/sbin). Requires Perl. - daemonchk.c is a CGI contributed by Karl DeBisschop that can test to see whether or not the Nagios process is running. Miscellaneous Goodies: ---------------------- - htaccess.sample is a *sample* .htaccess file that can be used with Apache to require password authentication for access to the web interface. - mini_epn.c is a mini embedded Perl interpreter that can be used to test the feasibility of running various Perl plugins with the embedded Perl interpreter compiled in. nagios-2.6/contrib/convertcfg.c0000664000076500007650000005430010336571237016154 0ustar nagiosnagios/************************************************************************ * * CONVERTCFG.C - Config File Convertor * * Copyright (c) 2001-2005 Ethan Galstad (nagios@nagios.org) * Last Modified: 08-12-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. * ************************************************************************/ #include #include #include char *my_strsep(char **, const char *); int main(int argc, char **argv){ FILE *fp; char *temp_ptr; char *temp_ptr2; char input[8096]; int notify_recovery; int notify_warning; int notify_critical; int notify_down; int notify_unreachable; int option; int have_template=0; int x=0,y=0; char *host_name; char *service_description; char *host_name2; char *service_description2; if(argc!=3){ printf("Nagios Config File Converter\n"); printf("Written by Ethan Galstad (nagios@nagios.org)\n"); printf("Last Modified: 08-12-2005\n"); printf("\n"); printf("Usage: %s \n",argv[0]); printf("\n"); printf("Valid object types include:\n"); printf("\n"); printf("\ttimeperiods\n"); printf("\tcommands\n"); printf("\tcontacts\n"); printf("\tcontactgroups\n"); printf("\thosts\n"); printf("\thostgroups\n"); printf("\thostgroupescalationss\n"); printf("\tservices\n"); printf("\tservicedependencies\n"); printf("\tserviceescalations\n"); printf("\n"); printf("\thostextinfo\n"); printf("\tserviceextinfo\n"); printf("\n"); printf("Notes:\n"); printf("\n"); printf("This utility is designed to aide you in converting your old 'host'\n"); printf("config file(s) to the new template-based config file style. It is\n"); printf("also capable of converting extended host and service information\n"); printf("definitions in your old CGI config file.\n"); printf("\n"); printf("Supply the name of your old 'host' config file (or your old CGI config\n"); printf("file if you're converting extended host/service definitions) on the\n"); printf("command line, along with the type of object you would like to produce\n"); printf("a new config file for. Your old config file is not overwritten - new\n"); printf("configuration data is printed to standard output, so you can redirect it\n"); printf("wherever you like.\n"); printf("\n"); printf("Please note that you can only specify one type of object at a time\n"); printf("on the command line.\n"); printf("\n"); printf("IMPORTANT: This utility will generate Nagios 1.x compliant config files.\n"); printf("However, the config files are not totally compatible with Nagios 2.x, so\n"); printf("you will have to do some manual tweaking.\n"); printf("\n"); return -1; } fp=fopen(argv[1],"r"); if(fp==NULL){ printf("Error: Could not open file '%s' for reading.\n",argv[1]); return -1; } for(fgets(input,sizeof(input)-1,fp);!feof(fp);fgets(input,sizeof(input)-1,fp)){ /* skip blank lines and comments */ if(input[0]=='#' || input[0]=='\x0' || input[0]=='\n' || input[0]=='\r') continue; /* timeperiods */ if(strstr(input,"timeperiod[") && !strcmp(argv[2],"timeperiods")){ temp_ptr2=&input[0]; temp_ptr=my_strsep(&temp_ptr2,"["); temp_ptr=my_strsep(&temp_ptr2,"]"); printf("# '%s' timeperiod definition\n",temp_ptr); printf("define timeperiod{\n"); /*printf("\tname\t\t%s\n",temp_ptr);*/ printf("\ttimeperiod_name\t%s\n",temp_ptr); temp_ptr=my_strsep(&temp_ptr2,";"); printf("\talias\t\t%s\n",temp_ptr+1); temp_ptr=my_strsep(&temp_ptr2,";"); if(temp_ptr!=NULL && strcmp(temp_ptr,"")) printf("\tsunday\t\t%s\n",temp_ptr); temp_ptr=my_strsep(&temp_ptr2,";"); if(temp_ptr!=NULL && strcmp(temp_ptr,"")) printf("\tmonday\t\t%s\n",temp_ptr); temp_ptr=my_strsep(&temp_ptr2,";"); if(temp_ptr!=NULL && strcmp(temp_ptr,"")) printf("\ttuesday\t\t%s\n",temp_ptr); temp_ptr=my_strsep(&temp_ptr2,";"); if(temp_ptr!=NULL && strcmp(temp_ptr,"")) printf("\twednesday\t%s\n",temp_ptr); temp_ptr=my_strsep(&temp_ptr2,";"); if(temp_ptr!=NULL && strcmp(temp_ptr,"")) printf("\tthursday\t%s\n",temp_ptr); temp_ptr=my_strsep(&temp_ptr2,";"); if(temp_ptr!=NULL && strcmp(temp_ptr,"")) printf("\tfriday\t\t%s\n",temp_ptr); temp_ptr=my_strsep(&temp_ptr2,";\r\n"); if(temp_ptr!=NULL && strcmp(temp_ptr,"")) printf("\tsaturday\t%s\n",temp_ptr); printf("\t}\n\n\n"); } /* commands */ if(strstr(input,"command[") && !strcmp(argv[2],"commands")){ temp_ptr=strtok(input,"["); temp_ptr=strtok(NULL,"]"); printf("# '%s' command definition\n",temp_ptr); printf("define command{\n"); /*printf("\tname\t\t%s\n",temp_ptr);*/ printf("\tcommand_name\t%s\n",temp_ptr); temp_ptr=strtok(NULL,"\n"); printf("\tcommand_line\t%s\n",temp_ptr+1); printf("\t}\n\n\n"); } /* contacts */ if(strstr(input,"contact[") && !strcmp(argv[2],"contacts")){ temp_ptr2=&input[0]; temp_ptr=my_strsep(&temp_ptr2,"["); temp_ptr=my_strsep(&temp_ptr2,"]"); printf("# '%s' contact definition\n",temp_ptr); printf("define contact{\n"); /*printf("\tname\t\t\t\t%s\n",temp_ptr);*/ printf("\tcontact_name\t\t\t%s\n",temp_ptr); temp_ptr=my_strsep(&temp_ptr2,";"); printf("\talias\t\t\t\t%s\n",temp_ptr+1); temp_ptr=my_strsep(&temp_ptr2,";"); if(temp_ptr!=NULL && strcmp(temp_ptr,"")) printf("\tservice_notification_period\t%s\n",temp_ptr); temp_ptr=my_strsep(&temp_ptr2,";"); if(temp_ptr!=NULL && strcmp(temp_ptr,"")) printf("\thost_notification_period\t%s\n",temp_ptr); temp_ptr=my_strsep(&temp_ptr2,";"); notify_recovery=atoi(temp_ptr); temp_ptr=my_strsep(&temp_ptr2,";"); notify_critical=atoi(temp_ptr); temp_ptr=my_strsep(&temp_ptr2,";"); notify_warning=atoi(temp_ptr); option=0; printf("\tservice_notification_options\t"); if(notify_recovery==1 || notify_critical==1 || notify_warning==1){ if(notify_warning==1){ printf("w,u"); option=1; } if(notify_critical==1){ if(option==1) printf(","); printf("c"); option=1; } if(notify_recovery==1){ if(option==1) printf(","); printf("r"); } } else printf("n"); printf("\n"); temp_ptr=my_strsep(&temp_ptr2,";"); notify_recovery=atoi(temp_ptr); temp_ptr=my_strsep(&temp_ptr2,";"); notify_down=atoi(temp_ptr); temp_ptr=my_strsep(&temp_ptr2,";"); notify_unreachable=atoi(temp_ptr); option=0; printf("\thost_notification_options\t"); if(notify_recovery==1 || notify_down==1 || notify_unreachable==1){ if(notify_down==1){ printf("d"); option=1; } if(notify_unreachable==1){ if(option==1) printf(","); printf("u"); option=1; } if(notify_recovery==1){ if(option==1) printf(","); printf("r"); } } else printf("n"); printf("\n"); temp_ptr=my_strsep(&temp_ptr2,";"); if(temp_ptr!=NULL && strcmp(temp_ptr,"")) printf("\tservice_notification_commands\t%s\n",temp_ptr); temp_ptr=my_strsep(&temp_ptr2,";"); if(temp_ptr!=NULL && strcmp(temp_ptr,"")) printf("\thost_notification_commands\t%s\n",temp_ptr); temp_ptr=my_strsep(&temp_ptr2,";"); if(temp_ptr!=NULL && strcmp(temp_ptr,"")) printf("\temail\t\t\t\t%s\n",temp_ptr); temp_ptr=my_strsep(&temp_ptr2,";\r\n"); if(temp_ptr!=NULL && strcmp(temp_ptr,"")) printf("\tpager\t\t\t\t%s\n",temp_ptr); printf("\t}\n\n\n"); } /* contactgroups */ if(strstr(input,"contactgroup[") && !strcmp(argv[2],"contactgroups")){ temp_ptr=strtok(input,"["); temp_ptr=strtok(NULL,"]"); printf("# '%s' contact group definition\n",temp_ptr); printf("define contactgroup{\n"); /*printf("\tname\t\t\t%s\n",temp_ptr);*/ printf("\tcontactgroup_name\t%s\n",temp_ptr); temp_ptr=strtok(NULL,";"); printf("\talias\t\t\t%s\n",temp_ptr+1); temp_ptr=strtok(NULL,"\n"); printf("\tmembers\t\t\t%s\n",temp_ptr); printf("\t}\n\n\n"); } /* hosts */ if(strstr(input,"host[") && !strcmp(argv[2],"hosts")){ if(have_template==0){ printf("# Generic host definition template\n"); printf("define host{\n"); printf("\tname\t\t\t\tgeneric-host\t; The name of this host template - referenced in other host definitions, used for template recursion/resolution\n"); printf("\tactive_checks_enabled\t\t1\t; Active host checks are enabled\n"); printf("\tpassive_checks_enabled\t\t1\t; Passive host checks are enabled/accepted\n"); printf("\tnotifications_enabled\t\t1\t; Host notifications are enabled\n"); printf("\tevent_handler_enabled\t\t1\t; Host event handler is enabled\n"); printf("\tflap_detection_enabled\t\t1\t; Flap detection is enabled\n"); /*printf("\tfailure_prediction_enabled\t1\t; Failure prediction is enabled\n");*/ printf("\tprocess_perf_data\t\t1\t; Process performance data\n"); printf("\tretain_status_information\t1\t; Retain status information across program restarts\n"); printf("\tretain_nonstatus_information\t1\t; Retain non-status information across program restarts\n"); printf("\n"); printf("\tregister\t\t\t0\t; DONT REGISTER THIS DEFINITION - ITS NOT A REAL HOST, JUST A TEMPLATE!\n"); printf("\t}\n\n"); have_template=1; } temp_ptr2=&input[0]; temp_ptr=my_strsep(&temp_ptr2,"["); temp_ptr=my_strsep(&temp_ptr2,"]"); printf("# '%s' host definition\n",temp_ptr); printf("define host{\n"); printf("\tuse\t\t\tgeneric-host\t\t; Name of host template to use\n\n"); printf("\thost_name\t\t%s\n",temp_ptr); temp_ptr=my_strsep(&temp_ptr2,";"); printf("\talias\t\t\t%s\n",temp_ptr+1); temp_ptr=my_strsep(&temp_ptr2,";"); printf("\taddress\t\t\t%s\n",temp_ptr); temp_ptr=my_strsep(&temp_ptr2,";"); if(temp_ptr!=NULL && strcmp(temp_ptr,"")) printf("\tparents\t\t\t%s\n",temp_ptr); temp_ptr=my_strsep(&temp_ptr2,";"); if(temp_ptr!=NULL && strcmp(temp_ptr,"")) printf("\tcheck_command\t\t%s\n",temp_ptr); temp_ptr=my_strsep(&temp_ptr2,";"); printf("\tmax_check_attempts\t%d\n",atoi(temp_ptr)); temp_ptr=my_strsep(&temp_ptr2,";"); printf("\tnotification_interval\t%d\n",atoi(temp_ptr)); temp_ptr=my_strsep(&temp_ptr2,";"); if(temp_ptr!=NULL && strcmp(temp_ptr,"")) printf("\tnotification_period\t%s\n",temp_ptr); temp_ptr=my_strsep(&temp_ptr2,";"); notify_recovery=atoi(temp_ptr); temp_ptr=my_strsep(&temp_ptr2,";"); notify_down=atoi(temp_ptr); temp_ptr=my_strsep(&temp_ptr2,";"); notify_unreachable=atoi(temp_ptr); option=0; printf("\tnotification_options\t"); if(notify_recovery==1 || notify_down==1 || notify_unreachable==1){ if(notify_down==1){ printf("d"); option=1; } if(notify_unreachable==1){ if(option==1) printf(","); printf("u"); option=1; } if(notify_recovery==1){ if(option==1) printf(","); printf("r"); } } else printf("n"); printf("\n"); temp_ptr=my_strsep(&temp_ptr2,";\r\n"); if(temp_ptr!=NULL && strcmp(temp_ptr,"")) printf("\tevent_handler\t\t%s\n",temp_ptr); printf("\t}\n\n\n"); } /* hostgroups */ if(strstr(input,"hostgroup[") && !strcmp(argv[2],"hostgroups")){ temp_ptr=strtok(input,"["); temp_ptr=strtok(NULL,"]"); printf("# '%s' host group definition\n",temp_ptr); printf("define hostgroup{\n"); /*printf("\tname\t\t%s\n",temp_ptr);*/ printf("\thostgroup_name\t%s\n",temp_ptr); temp_ptr=strtok(NULL,";"); printf("\talias\t\t%s\n",temp_ptr+1); temp_ptr=strtok(NULL,";"); /*printf("\tcontact_groups\t%s\n",temp_ptr);*/ temp_ptr=strtok(NULL,"\n"); printf("\tmembers\t\t%s\n",temp_ptr); printf("\t}\n\n\n"); } /* services */ if(strstr(input,"service[") && !strcmp(argv[2],"services")){ if(have_template==0){ printf("# Generic service definition template\n"); printf("define service{\n"); printf("\tname\t\t\t\tgeneric-service\t; The 'name' of this service template, referenced in other service definitions\n"); printf("\tactive_checks_enabled\t\t1\t; Active service checks are enabled\n"); printf("\tpassive_checks_enabled\t\t1\t; Passive service checks are enabled/accepted\n"); printf("\tparallelize_check\t\t1\t; Active service checks should be parallelized (disabling this can lead to major performance problems)\n"); printf("\tobsess_over_service\t\t1\t; We should obsess over this service (if necessary)\n"); printf("\tcheck_freshness\t\t\t0\t; Default is to NOT check service 'freshness'\n"); printf("\tnotifications_enabled\t\t1\t; Service notifications are enabled\n"); printf("\tevent_handler_enabled\t\t1\t; Service event handler is enabled\n"); printf("\tflap_detection_enabled\t\t1\t; Flap detection is enabled\n"); /*printf("\tfailure_prediction_enabled\t1\t; Failure prediction is enabled\n");*/ printf("\tprocess_perf_data\t\t1\t; Process performance data\n"); printf("\tretain_status_information\t1\t; Retain status information across program restarts\n"); printf("\tretain_nonstatus_information\t1\t; Retain non-status information across program restarts\n"); printf("\n"); printf("\tregister\t\t\t0\t; DONT REGISTER THIS DEFINITION - ITS NOT A REAL SERVICE, JUST A TEMPLATE!\n"); printf("\t}\n\n"); have_template=1; } temp_ptr2=&input[0]; temp_ptr=my_strsep(&temp_ptr2,"["); temp_ptr=my_strsep(&temp_ptr2,"]"); printf("# Service definition\n"); printf("define service{\n"); printf("\tuse\t\t\t\tgeneric-service\t\t; Name of service template to use\n\n"); printf("\thost_name\t\t\t%s\n",temp_ptr); temp_ptr=my_strsep(&temp_ptr2,";"); printf("\tservice_description\t\t%s\n",temp_ptr+1); temp_ptr=my_strsep(&temp_ptr2,";"); printf("\tis_volatile\t\t\t%d\n",atoi(temp_ptr)); temp_ptr=my_strsep(&temp_ptr2,";"); printf("\tcheck_period\t\t\t%s\n",temp_ptr); temp_ptr=my_strsep(&temp_ptr2,";"); printf("\tmax_check_attempts\t\t%d\n",atoi(temp_ptr)); temp_ptr=my_strsep(&temp_ptr2,";"); printf("\tnormal_check_interval\t\t%d\n",atoi(temp_ptr)); temp_ptr=my_strsep(&temp_ptr2,";"); printf("\tretry_check_interval\t\t%d\n",atoi(temp_ptr)); temp_ptr=my_strsep(&temp_ptr2,";"); if(temp_ptr!=NULL && strcmp(temp_ptr,"")) printf("\tcontact_groups\t\t\t%s\n",temp_ptr); temp_ptr=my_strsep(&temp_ptr2,";"); printf("\tnotification_interval\t\t%d\n",atoi(temp_ptr)); temp_ptr=my_strsep(&temp_ptr2,";"); if(temp_ptr!=NULL && strcmp(temp_ptr,"")) printf("\tnotification_period\t\t%s\n",temp_ptr); temp_ptr=my_strsep(&temp_ptr2,";"); notify_recovery=atoi(temp_ptr); temp_ptr=my_strsep(&temp_ptr2,";"); notify_critical=atoi(temp_ptr); temp_ptr=my_strsep(&temp_ptr2,";"); notify_warning=atoi(temp_ptr); option=0; printf("\tnotification_options\t\t"); if(notify_recovery==1 || notify_critical==1 || notify_warning==1){ if(notify_warning==1){ printf("w,u"); option=1; } if(notify_critical==1){ if(option==1) printf(","); printf("c"); option=1; } if(notify_recovery==1){ if(option==1) printf(","); printf("r"); } } else printf("n"); printf("\n"); temp_ptr=my_strsep(&temp_ptr2,";"); if(temp_ptr!=NULL && strcmp(temp_ptr,"")) printf("\tevent_handler\t\t%s\n",temp_ptr); temp_ptr=my_strsep(&temp_ptr2,";\r\n"); if(temp_ptr!=NULL && strcmp(temp_ptr,"")) printf("\tcheck_command\t\t\t%s\n",temp_ptr); printf("\t}\n\n\n"); } /* hostgroup escalations */ if(strstr(input,"hostgroupescalation[") && !strcmp(argv[2],"hostgroupescalations")){ x++; temp_ptr2=&input[0]; temp_ptr=my_strsep(&temp_ptr2,"["); temp_ptr=my_strsep(&temp_ptr2,"]"); printf("# Hostgroup '%s' escalation definition\n",temp_ptr); printf("define hostgroupescalation{\n"); printf("\thostgroup_name\t\t%s\n",temp_ptr); temp_ptr=my_strsep(&temp_ptr2,"-"); printf("\tfirst_notification\t\t%d\n",atoi(temp_ptr+1)); temp_ptr=my_strsep(&temp_ptr2,";"); printf("\tlast_notification\t\t%d\n",atoi(temp_ptr)); temp_ptr=my_strsep(&temp_ptr2,";"); printf("\tcontact_groups\t\t\t%s\n",temp_ptr); temp_ptr=my_strsep(&temp_ptr2,";\r\n"); printf("\tnotification_interval\t\t%d\n",atoi(temp_ptr)); printf("\t}\n\n\n"); } /* service escalations */ if(strstr(input,"serviceescalation[") && !strcmp(argv[2],"serviceescalations")){ x++; printf("# Serviceescalation definition\n"); printf("define serviceescalation{\n"); temp_ptr2=&input[0]; temp_ptr=my_strsep(&temp_ptr2,"["); host_name=my_strsep(&temp_ptr2,";"); service_description=my_strsep(&temp_ptr2,"]"); printf("\thost_name\t\t%s\n",host_name); printf("\tservice_description\t\t%s\n",service_description); temp_ptr=my_strsep(&temp_ptr2,"-"); printf("\tfirst_notification\t\t%d\n",atoi(temp_ptr+1)); temp_ptr=my_strsep(&temp_ptr2,";"); printf("\tlast_notification\t\t%d\n",atoi(temp_ptr)); temp_ptr=my_strsep(&temp_ptr2,";"); printf("\tcontact_groups\t\t\t%s\n",temp_ptr); temp_ptr=my_strsep(&temp_ptr2,";\r\n"); printf("\tnotification_interval\t\t%d\n",atoi(temp_ptr)); printf("\t}\n\n\n"); } /* service dependencies */ if(strstr(input,"servicedependency[") && !strcmp(argv[2],"servicedependencies")){ temp_ptr2=&input[0]; temp_ptr=my_strsep(&temp_ptr2,"["); host_name=my_strsep(&temp_ptr2,";"); service_description=my_strsep(&temp_ptr2,"]"); host_name2=my_strsep(&temp_ptr2,";")+1; service_description2=my_strsep(&temp_ptr2,";"); temp_ptr=my_strsep(&temp_ptr2,";"); x++; printf("# Servicedependency definition\n"); printf("define servicedependency{\n"); printf("\thost_name\t\t\t%s\n",host_name2); printf("\tservice_description\t\t%s\n",service_description2); printf("\tdependent_host_name\t\t%s\n",host_name); printf("\tdependent_service_description\t%s\n",service_description); printf("\texecution_failure_criteria\t"); for(y=0;temp_ptr[y]!='\x0';y++) printf("%s%c",(y>0)?",":"",temp_ptr[y]); if(y==0) printf("n"); printf("\t; These are the criteria for which check execution will be suppressed\n"); temp_ptr=my_strsep(&temp_ptr2,";\r\n"); printf("\tnotification_failure_criteria\t"); for(y=0;temp_ptr[y]!='\x0';y++) printf("%s%c",(y>0)?",":"",temp_ptr[y]); if(y==0) printf("n"); printf("\t; These are the criteria for which notifications will be suppressed\n"); printf("\t}\n\n\n"); } /* extended host info */ if(strstr(input,"hostextinfo[") && !strcmp(argv[2],"hostextinfo")){ temp_ptr2=&input[0]; temp_ptr=my_strsep(&temp_ptr2,"["); temp_ptr=my_strsep(&temp_ptr2,"]"); printf("# '%s' hostextinfo definition\n",temp_ptr); printf("define hostextinfo{\n"); printf("\thost_name\t\t%s\t\t; The name of the host this data is associated with\n",temp_ptr); temp_ptr=my_strsep(&temp_ptr2,";"); if(temp_ptr+1!=NULL && strcmp(temp_ptr+1,"")) printf("\tnotes_url\t\t\t%s\n",temp_ptr+1); temp_ptr=my_strsep(&temp_ptr2,";"); if(temp_ptr!=NULL && strcmp(temp_ptr,"")) printf("\ticon_image\t\t%s\n",temp_ptr); temp_ptr=my_strsep(&temp_ptr2,";"); if(temp_ptr!=NULL && strcmp(temp_ptr,"")) printf("\tvrml_image\t\t%s\n",temp_ptr); temp_ptr=my_strsep(&temp_ptr2,";"); if(temp_ptr!=NULL && strcmp(temp_ptr,"")) printf("\tstatusmap_image\t\t%s\n",temp_ptr); temp_ptr=my_strsep(&temp_ptr2,";"); if(temp_ptr!=NULL && strcmp(temp_ptr,"")) printf("\ticon_image_alt\t\t%s\n",temp_ptr); temp_ptr=my_strsep(&temp_ptr2,";"); if(temp_ptr!=NULL && strcmp(temp_ptr,"")) printf("\t2d_coords\t\t%s\n",temp_ptr); temp_ptr=my_strsep(&temp_ptr2,";\r\n"); if(temp_ptr!=NULL && strcmp(temp_ptr,"")) printf("\t3d_coords\t\t%s\n",temp_ptr); printf("\t}\n\n\n"); } /* extended service info */ if(strstr(input,"serviceextinfo[") && !strcmp(argv[2],"serviceextinfo")){ temp_ptr2=&input[0]; temp_ptr=my_strsep(&temp_ptr2,"["); temp_ptr=my_strsep(&temp_ptr2,";"); printf("# serviceextinfo definition\n",temp_ptr); printf("define serviceextinfo{\n"); printf("\thost_name\t\t%s\t\t; The name of the service this data is associated with\n",temp_ptr); temp_ptr=my_strsep(&temp_ptr2,"]"); printf("\tservice_description\t%s\n",temp_ptr); temp_ptr=my_strsep(&temp_ptr2,";"); if(temp_ptr+1!=NULL && strcmp(temp_ptr+1,"")) printf("\tnotes_url\t\t%s\n",temp_ptr+1); temp_ptr=my_strsep(&temp_ptr2,";"); if(temp_ptr!=NULL && strcmp(temp_ptr,"")) printf("\ticon_image\t\t%s\n",temp_ptr); temp_ptr=my_strsep(&temp_ptr2,";\r\n"); if(temp_ptr!=NULL && strcmp(temp_ptr,"")) printf("\ticon_image_alt\t\t%s\n",temp_ptr); printf("\t}\n\n\n"); } } fclose(fp); return 0; } /* fixes compiler problems under Solaris, since strsep() isn't included */ /* this code is taken from the glibc source */ char *my_strsep (char **stringp, const char *delim){ char *begin, *end; begin = *stringp; if (begin == NULL) return NULL; /* A frequent case is when the delimiter string contains only one character. Here we don't need to call the expensive `strpbrk' function and instead work using `strchr'. */ if(delim[0]=='\0' || delim[1]=='\0'){ char ch = delim[0]; if(ch=='\0') end=NULL; else{ if(*begin==ch) end=begin; else end=strchr(begin+1,ch); } } else /* Find the end of the token. */ end = strpbrk (begin, delim); if(end){ /* Terminate the token and set *STRINGP past NUL character. */ *end++='\0'; *stringp=end; } else /* No more delimiters; this is the last token. */ *stringp=NULL; return begin; } nagios-2.6/contrib/daemonchk.c0000664000076500007650000001427407436604431015753 0ustar nagiosnagios#include "../common/config.h" #include "../common/common.h" #include "../common/locations.h" #include "../cgi/cgiutils.h" #include "../cgi/getcgi.h" #ifdef HAVE_GETOPT_H #include #endif #include #define CHARLEN 256 #define max(a,b) ((a)>(b))?(a):(b) void document_header(void); void document_footer(void); int process_cgivars(void); char *strscpy(char *dest, const char *src); char *ssprintf(char *str, const char *fmt, ...); void terminate (int result, const char *fmt, ...); int main (int argc, char **argv){ FILE *fp; char *status_file=NULL; char *lock_file=NULL; char *proc_file=NULL; char input_buffer[CHARLEN]; int c, age, pid, testpid, found; int wt=-1; int ct=-1; struct stat statbuf; time_t current_time; #ifdef DEFAULT_STATUS_FILE status_file=strscpy(status_file,DEFAULT_STATUS_FILE); #else status_file=strscpy(status_file,"/var/log/nagios/status.log"); #endif #ifdef DEFAULT_LOCK_FILE lock_file=strscpy(lock_file,DEFAULT_LOCK_FILE); #else lock_file=strscpy(lock_file,"/tmp/nagios.lock"); #endif if(getenv("REQUEST_METHOD")){ process_cgivars(); document_header(); } else { /* get arguments */ while ( (c = getopt(argc,argv,"+c:w:s:l:")) != EOF) { switch (c) { case 'c': ct = atoi(optarg); break; case 'w': wt = atoi(optarg); break; case 's': status_file=optarg; break; case 'l': lock_file=optarg; break; } } } /* find status file, get lastmod time */ if(stat(status_file,&statbuf)==-1){ printf("NAGIOS CRITICAL - could not find status log: %s\n",status_file); exit(STATE_CRITICAL); } time(¤t_time); age = (int)(current_time-statbuf.st_mtime); /* find lock file. get pid if it exists */ if(stat(lock_file, &statbuf)==-1){ printf("NAGIOS CRITICAL - could not find lock file: %s\n",lock_file); exit(STATE_CRITICAL); } fp=fopen(lock_file,"r"); fscanf(fp,"%d",&pid); fclose(fp); proc_file=ssprintf(proc_file,"/proc/%d",pid); if (stat("/proc",&statbuf)==0) { if (stat(proc_file,&statbuf)==-1) { printf("NAGIOS CRITICAL - could not find proc file: %s\n",proc_file); exit(STATE_CRITICAL); } } else if (snprintf(proc_file,CHARLEN-1,"/bin/ps -o pid -p %d",pid) && (fp=popen(proc_file,"r"))!=NULL) { fgets(input_buffer,CHARLEN-1,fp); fgets(input_buffer,CHARLEN-1,fp); if (sscanf(input_buffer,"%d",&testpid)==1) { if (testpid!=pid) { printf("NAGIOS CRITICAL - could not find process(1): %d\n",pid); exit(STATE_CRITICAL); } } } else if (snprintf(proc_file,CHARLEN-1,"/bin/ps -eo pid") && (fp=popen(proc_file,"r"))!=NULL) { found=FALSE; fgets(input_buffer,CHARLEN-1,fp); while(fgets(input_buffer,CHARLEN-1,fp)) { if (sscanf(input_buffer,"%d",&testpid)==1) if (testpid==pid) found=TRUE; } if (!found) { printf("NAGIOS CRITICAL - could not find process(2): %d\n",pid); exit(STATE_CRITICAL); } } else if (snprintf(proc_file,CHARLEN-1,"/bin/ps -Ao pid") && (fp=popen(proc_file,"r"))!=NULL) { found=FALSE; fgets(input_buffer,CHARLEN-1,fp); while(fgets(input_buffer,CHARLEN-1,fp)) { if (sscanf(input_buffer,"%d",&testpid)==1) if (testpid==pid) found=TRUE; } if (!found) { printf("NAGIOS CRITICAL - could not find process(2): %d\n",pid); exit(STATE_CRITICAL); } } if(ct>0&&ct0&&wt\n\nNagios Daemon Status\n\n"); printf("\n"); return; } int process_cgivars(void){ char **variables; int error=FALSE; int x; variables=getcgivars(); for(x=0;variables[x]!=NULL;x++){ /* do some basic length checking on the variable identifier to prevent buffer overflows */ if(strlen(variables[x])>=MAX_INPUT_BUFFER-1){ x++; continue; } } return error; } /* get date/time string used in META tags for page expiration */ void get_expire_time_string(time_t *raw_time,char *buffer,int buffer_length){ time_t t; struct tm *tm_ptr; int day; int hour; int minute; int second; int year; char *weekdays[7]={"Sun","Mon","Tue","Wed","Thu","Fri","Sat"}; char *months[12]={"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sept","Oct","Nov","Dec"}; if(raw_time==NULL) time(&t); else t=*raw_time; tm_ptr=gmtime(&t); hour=tm_ptr->tm_hour; minute=tm_ptr->tm_min; second=tm_ptr->tm_sec; day=tm_ptr->tm_mday; year=tm_ptr->tm_year+1900; snprintf(buffer,buffer_length,"%s, %d %s %d %02d:%02d:%02d GMT",weekdays[tm_ptr->tm_wday],day,months[tm_ptr->tm_mon],year,hour,minute,second); buffer[buffer_length-1]='\x0'; return; } char *strscpy(char *dest, const char *src) { int len; if(src!=NULL) len=strlen(src)+1; else return dest; if (dest==NULL || strlen(dest) -1) if (nchars < size) { va_end(ap); return str; } else { size = nchars + 1; } else size *= 2; str = realloc(str,nchars+1); if (str==NULL) terminate(STATE_UNKNOWN,"realloc failed in ssprintf"); } } void terminate (int result, const char *fmt, ...) { va_list ap; va_start(ap,fmt); vprintf(fmt,ap); va_end(ap); exit(result); } nagios-2.6/contrib/epn_nagios.h0000664000076500007650000000127010173611575016140 0ustar nagiosnagios/******** BEGIN EMBEDDED PERL INTERPRETER DECLARATIONS ********/ #include #include #include #undef ctime /* don't need perl's threaded version */ #undef printf /* can't use perl's printf until initialized */ /* In perl.h (or friends) there is a macro that defines sighandler as Perl_sighandler, so we must #undef it so we can use our sighandler() function */ #undef sighandler /* and we don't need perl's reentrant versions */ #undef localtime #undef getpwnam #undef getgrnam #undef strerror #ifdef aTHX EXTERN_C void xs_init(pTHX); #else EXTERN_C void xs_init(void); #endif /******** END EMBEDDED PERL INTERPRETER DECLARATIONS ********/ nagios-2.6/contrib/mini_epn.c0000664000076500007650000000474010336237260015610 0ustar nagiosnagios/* mini_epn.c */ #include #include #include "epn_nagios.h" static PerlInterpreter *my_perl = NULL; int main(int argc, char **argv, char **env) { /* #ifdef aTHX dTHX; #endif */ char *embedding[] = { "", "p1.pl" }; char *plugin_output ; char fname[64]; char *args[] = {"","0", "", "", NULL }; char command_line[80]; int exitstatus; int pclose_result; if((my_perl=perl_alloc())==NULL){ printf("%s\n","Error: Could not allocate memory for embedded Perl interpreter!"); exit(1); } perl_construct(my_perl); exitstatus=perl_parse(my_perl,xs_init,2,embedding,NULL); if(!exitstatus) { exitstatus=perl_run(my_perl); while(printf("Enter file name: ") && fgets(command_line, 80, stdin)) { SV *plugin_hndlr_cr; STRLEN n_a; int count = 0 ; dSP; command_line[strlen(command_line) -1] = '\0'; strncpy(fname,command_line,strcspn(command_line," ")); fname[strcspn(command_line," ")] = '\x0'; args[0] = fname ; args[3] = command_line + strlen(fname) + 1 ; args[2] = ""; /* call our perl interpreter to compile and optionally cache the command */ ENTER; SAVETMPS; PUSHMARK(SP); XPUSHs(sv_2mortal(newSVpv(args[0],0))); XPUSHs(sv_2mortal(newSVpv(args[1],0))); XPUSHs(sv_2mortal(newSVpv(args[2],0))); XPUSHs(sv_2mortal(newSVpv(args[3],0))); PUTBACK; count = call_pv("Embed::Persistent::eval_file", G_SCALAR | G_EVAL); SPAGAIN; /* check return status */ if(SvTRUE(ERRSV)){ (void) POPs; pclose_result=-2; printf("embedded perl ran %s with error %s\n",fname,SvPVX(ERRSV)); continue; } else { plugin_hndlr_cr = newSVsv(POPs); PUTBACK; FREETMPS; LEAVE; } ENTER; SAVETMPS; PUSHMARK(SP); XPUSHs(sv_2mortal(newSVpv(args[0],0))); XPUSHs(sv_2mortal(newSVpv(args[1],0))); XPUSHs(plugin_hndlr_cr); XPUSHs(sv_2mortal(newSVpv(args[3],0))); PUTBACK; count = perl_call_pv("Embed::Persistent::run_package", G_EVAL | G_ARRAY); SPAGAIN; plugin_output = POPpx ; pclose_result = POPi ; printf("embedded perl plugin return code and output was: %d & '%s'\n", pclose_result, plugin_output); PUTBACK; FREETMPS; LEAVE; } } PL_perl_destruct_level = 0; perl_destruct(my_perl); perl_free(my_perl); exit(exitstatus); } nagios-2.6/contrib/new_mini_epn.c0000664000076500007650000001362110336237260016457 0ustar nagiosnagios/* new_mini_epn.c */ #include #include #include "epn_nagios.h" /* * DO_CLEAN must be a pointer to a char string */ #define DO_CLEAN "0" static PerlInterpreter *my_perl = NULL; /* * <=== Align Right * 56 spaces from left margin * Do N O T use T A B S in #define code. * * Indent level == 4 spaces */ #define DO_READLINE \ "$_ = defined($term) " \ " ? $term->readline($prompt) " \ " : do { " \ " print $prompt; " \ " chomp($_ = <>); " \ " $_; " \ " }; " \ "die qq(That's all folks.\\n) " \ " unless $_ && ! /^\\s*$/ ; " \ "$_; " #define INIT_TERM_READLINE \ "use vars qw($term $prompt $OUT); " \ \ "eval { require Term::ReadLine; }; " \ "unless ($@) { " \ " $term = new Term::ReadLine 'new_mini_epn'; " \ "} else { " \ " warn qq(Install Term::ReadLine for arrow key access to history, filename completion etc.); " \ "} " \ \ "$OUT = $term->OUT " \ " if defined($term); " \ "$prompt = 'plugin command line: '; " void run_plugin(char *command_line) { #ifdef aTHX dTHX; #endif SV *plugin_hndlr_cr ; STRLEN n_a ; int count = 0 ; int pclose_result; char *plugin_output; char fname[128]; char *args[] = {"", "", "", "", NULL }; dSP; strncpy(fname,command_line,strcspn(command_line," ")); fname[strcspn(command_line," ")] = '\0'; /* * Arguments passsed to Perl sub Embed::Persistent::run_package */ /* * filename containing plugin */ args[0] = fname ; /* * Do _not_ cache the compiled plugin */ args[1] = DO_CLEAN ; /* * pointer to plugin arguments */ args[3] = command_line + strlen(fname) + 1 ; ENTER; SAVETMPS; PUSHMARK(SP); XPUSHs(sv_2mortal(newSVpv(args[0],0))); XPUSHs(sv_2mortal(newSVpv(args[1],0))); XPUSHs(sv_2mortal(newSVpv(args[2],0))); XPUSHs(sv_2mortal(newSVpv(args[3],0))); PUTBACK; call_pv("Embed::Persistent::eval_file", G_SCALAR | G_EVAL); SPAGAIN ; if(SvTRUE(ERRSV)){ (void) POPs; printf("embedded perl compiled plugin %s with error: %s - skipping plugin\n", fname, SvPVX(ERRSV)); return; } else { plugin_hndlr_cr = newSVsv(POPs); PUTBACK ; FREETMPS ; LEAVE ; } /* * Push the arguments to Embed::Persistent::run_package onto * the Perl stack. */ ENTER; SAVETMPS; PUSHMARK(SP); XPUSHs(sv_2mortal(newSVpv(args[0],0))); XPUSHs(sv_2mortal(newSVpv(args[1],0))); XPUSHs(plugin_hndlr_cr); XPUSHs(sv_2mortal(newSVpv(args[3],0))); PUTBACK; count = call_pv("Embed::Persistent::run_package", G_ARRAY); SPAGAIN; plugin_output = POPpx ; pclose_result = POPi ; printf("embedded perl plugin return code and output was: %d & %s\n", pclose_result, plugin_output) ; PUTBACK; FREETMPS; LEAVE; return ; } SV * my_eval_pv(char *pv) { SV* result; /* * eval_pv(..., TRUE) means die if Perl traps an error */ result = eval_pv(pv, TRUE) ; return result ; } char * get_command_line(void) { /* debug * printf("%s\n", INIT_TERM_READLINE) ; */ SV *cmd_line ; char *command_line ; cmd_line = my_eval_pv(DO_READLINE) ; command_line = SvPVX(cmd_line) ; /* command_line = SvPV(cmd_line, n_a) ; */ return command_line ; } void init_term_readline(void) { (void) my_eval_pv(INIT_TERM_READLINE) ; } void init_embedded_perl(void) { char *embedding[] = { "", "p1.pl" }; /* embedding takes the place of argv[] ($argv[0] is the program name. * - which is not given to Perl). * Note that the number of args (ie the number of elements in embedding * [argc] is the third argument of perl_parse(). */ int exitstatus; char buffer[132]; if((my_perl=perl_alloc())==NULL){ snprintf(buffer,sizeof(buffer),"Error: Could not allocate memory for embedded Perl interpreter!\n"); buffer[sizeof(buffer)-1]='\x0'; printf("%s\n", buffer); exit(1); } perl_construct(my_perl); exitstatus=perl_parse(my_perl,xs_init,2,embedding,NULL); PL_exit_flags |= PERL_EXIT_DESTRUCT_END; /* Why is perl_run() necessary ? * It is needed if the code parsed by perl_parse() has * any runtime semantics (eg code that gets eval'd, * behaviour that depends on constants etc). */ exitstatus=perl_run(my_perl); if (exitstatus) { printf("%s\n", "perl_run() failed."); exit(1); } } void deinit_embedded_perl(void){ PL_perl_destruct_level=0; perl_destruct(my_perl); perl_free(my_perl); } int main(int argc, char **argv, char **env) { char command_line[128]; init_embedded_perl(); /* Calls Perl to load and construct a new * Term::ReadLine object. */ init_term_readline(); while (1) { /* * get_command_line calls Perl to get a scalar from stdin */ strncpy(command_line, get_command_line(), 128) ; /* Perl Term::ReadLine::readline() method chomps the "\n" * from the end of the input. */ run_plugin(command_line) ; } deinit_embedded_perl(); } nagios-2.6/contrib/p1.pl0000664000076500007650000006223310173611575014530 0ustar nagiosnagios package Embed::Persistent; # $Id: p1.pl,v 1.1 2005/01/20 02:12:13 egalstad Exp $ # $Log: p1.pl,v $ # Revision 1.1 2005/01/20 02:12:13 egalstad # Core dump fixes, embedded Perl changes, new mini_epn # # Revision 1.5 2005-01-18 13:52:15+11 anwsmh # 1 Set log level back to RETICENT and log file name to a placeholder for dist. # # Revision 1.4 2005-01-18 13:26:12+11 anwsmh # 1 Major changes for Perl >= 5.6 # 1.1 tieing STDERR to ErrorTrap caused a SEGV in libperl because of # misuse of the open statement. # 1.2 STDERR is now aliased to the handle associated with a log file # opened if logging is enabled. # # p1.pl for Nagios 2.0 # Only major changes are that STDOUT is redirected to a scalar # by means of a tied filehandle so that it can be returned to Nagios # without the need for a syscall to read() # use strict ; use vars '%Cache' ; use Text::ParseWords qw(parse_line) ; use constant RETICENT => 1 ; use constant GARRULOUS => 0 ; use constant DEBUG => 0 ; use constant EPN_STDERR_LOG => '/Path/to/embedded/Perl/Nagios/Logfile' ; use constant TEXT_RETICENT => <<'RETICENT' ; package OutputTrap; # # Methods for use by tied STDOUT in embedded PERL module. # # Simply ties STDOUT to a scalar and emulates serial semantics. # sub TIEHANDLE { my ($class) = @_; my $me ; bless \$me, $class; } sub PRINT { my $self = shift; $$self .= join("",@_); } sub PRINTF { my $self = shift; my $fmt = shift; $$self .= sprintf($fmt,@_); } sub READLINE { my $self = shift; # Perl code other than plugins may print nothing; in this case return "(No output!)\n". return(defined $$self ? $$self : "(No output!)\n"); } sub CLOSE { my $self = shift; } package Embed::Persistent; sub valid_package_name { my($string) = @_; $string =~ s/([^A-Za-z0-9\/])/sprintf("_%2x",unpack("C",$1))/eg; # second pass only for words starting with a digit $string =~ s|/(\d)|sprintf("/_%2x",unpack("C",$1))|eg; # Dress it up as a real package name $string =~ s|/|::|g; return "Embed::" . $string; } # Perl 5.005_03 only traps warnings for errors classed by perldiag # as Fatal (eg 'Global symbol """"%s"""" requires explicit package name'). # Therefore treat all warnings as fatal. sub throw_exception { my $warn = shift ; return if $warn =~ /^Subroutine CORE::GLOBAL::exit redefined/ ; die $warn ; } sub eval_file { my $filename = shift; my $delete = shift; my $pn = substr($filename, rindex($filename,"/")+1); my $package = valid_package_name($pn); my $mtime = -M $filename ; if ( defined $Cache{$package}{mtime} && $Cache{$package}{mtime} <= $mtime) { # we have compiled this subroutine already, # it has not been updated on disk, nothing left to do } else { local *FH; # FIXME - error handling open FH, $filename or die "'$filename' $!"; local($/) = undef; my $sub = ; close FH; # cater for routines that expect to get args without progname # and for those using @ARGV $sub = qq(\nshift(\@_);\n\@ARGV=\@_;\nlocal \$^W=1;\n$sub) ; # cater for scripts that have embedded EOF symbols (__END__) $sub =~ s/__END__/\;}\n__END__/; # wrap the code into a subroutine inside our unique package my $eval = qq{ package main; use subs 'CORE::GLOBAL::exit'; sub CORE::GLOBAL::exit { die "ExitTrap: \$_[0] ($package)"; } package $package; sub hndlr { $sub } }; $Cache{$package}{plugin_error} = 0 ; # suppress warning display. local $SIG{__WARN__} = \&throw_exception ; { # hide our variables within this block my ($filename, $mtime, $package, $sub); eval $eval; } # $@ is set for any warning and error. This guarantees that the plugin will not be run. if ($@) { # Log eval'd text of plugin. # Correct the line number of the error by removing the lines added (the subroutine prologue) by Embed::eval_file. my $i = 1 ; $eval =~ s/^/sprintf('%10d ', $i++)/meg ; $Cache{$package}{plugin_error} = $@ ; $Cache{$package}{mtime} = $mtime unless $delete; # If the compilation fails, leave nothing behind that may affect subsequent compilations. die; } #cache it unless we're cleaning out each time $Cache{$package}{mtime} = $mtime unless $delete; } } sub run_package { my $filename = shift; my $delete = shift; my $tmpfname = shift; my $ar = shift; my $pn = substr($filename, rindex($filename,"/")+1); my $package = valid_package_name($pn); my $res = 3; tie (*STDOUT, 'OutputTrap'); my @a = &parse_line('\s+', 0, $ar) ; if ( $Cache{$package}{plugin_error} ) { untie *STDOUT; # return unknown return (3, '**ePN' . " '$pn' " . $Cache{$package}{plugin_error} . "\n") ; } local $SIG{__WARN__} = \&throw_exception ; eval { $package->hndlr(@a); }; if ($@) { if ($@ =~ /^ExitTrap: /) { # For normal plugin exit the ExitTrap string is set by the # redefined CORE::GLOBAL::exit sub calling die to return a string =~ /^ExitTrap: -?\d+ $package/ # However, there is only _one_ exit sub so the last plugin to be compiled sets _its_ # package name. $res = 0; } else { # get return code (which may be negative) if ($@ =~ /^ExitTrap: (-?\d+)/) { $res = $1; } else { # run time error/abnormal plugin termination; exit was not called in plugin # return unknown $res = 3; chomp $@ ; # correct line number reported by eval for the prologue added by eval_file $@ =~ s/(\d+)\.$/($1 - 8)/e ; print STDOUT '**ePN', " '$pn' ", $@, "\n" ; # Don't run it again until the plugin is recompiled (clearing $Cache{$package}{plugin_error}) # Note that the plugin should be handle any run time errors (such as timeouts) # that may occur in service checking. # FIXME - doesn't work under both 5.005 and 5.8.0. The cached value of plugin error is reset somehow. # $Cache{$package}{plugin_error} = $@ ; } } } # !! my $plugin_output = ; untie *STDOUT; return ($res, $plugin_output) ; } 1; RETICENT use constant TEXT_GARRULOUS => <<'GARRULOUS' ; BEGIN { open STDERRLOG, '>> ' . EPN_STDERR_LOG or die "Can't open '" . EPN_STDERR_LOG . " for append: $!" ; } package OutputTrap; # # Methods for use by tied STDOUT in embedded PERL module. # # Simply ties STDOUT to a scalar and emulates serial semantics. # sub TIEHANDLE { my ($class) = @_; my $me ; bless \$me, $class; } sub PRINT { my $self = shift; $$self .= join("",@_); } sub PRINTF { my $self = shift; my $fmt = shift; $$self .= sprintf($fmt,@_); } sub READLINE { my $self = shift; # Perl code other than plugins may print nothing; in this case return "(No output!)\n". return(defined $$self ? $$self : "(No output!)\n"); } sub CLOSE { my $self = shift; } package Embed::Persistent; sub valid_package_name { my($string) = @_; $string =~ s/([^A-Za-z0-9\/])/sprintf("_%2x",unpack("C",$1))/eg; # second pass only for words starting with a digit $string =~ s|/(\d)|sprintf("/_%2x",unpack("C",$1))|eg; # Dress it up as a real package name $string =~ s|/|::|g; return "Embed::" . $string; } # Perl 5.005_03 only traps warnings for errors classed by perldiag # as Fatal (eg 'Global symbol """"%s"""" requires explicit package name'). # Therefore treat all warnings as fatal. sub throw_exception { my $warn = shift ; return if $warn =~ /^Subroutine CORE::GLOBAL::exit redefined/ ; die $warn ; } sub eval_file { my $filename = shift; my $delete = shift; *STDERR = *STDERRLOG ; my $pn = substr($filename, rindex($filename,"/")+1); my $package = valid_package_name($pn); my $mtime = -M $filename ; if ( defined $Cache{$package}{mtime} && $Cache{$package}{mtime} <= $mtime) { # we have compiled this subroutine already, # it has not been updated on disk, nothing left to do } else { local *FH; # FIXME - error handling open FH, $filename or die "'$filename' $!"; local($/) = undef; my $sub = ; close FH; # cater for routines that expect to get args without progname # and for those using @ARGV $sub = qq(\nshift(\@_);\n\@ARGV=\@_;\nlocal \$^W=1;\n$sub) ; # cater for scripts that have embedded EOF symbols (__END__) $sub =~ s/__END__/\;}\n__END__/; # wrap the code into a subroutine inside our unique package my $eval = qq{ package main; use subs 'CORE::GLOBAL::exit'; sub CORE::GLOBAL::exit { die "ExitTrap: \$_[0] ($package)"; } package $package; sub hndlr { $sub } }; $Cache{$package}{plugin_error} = 0 ; # suppress warning display. local $SIG{__WARN__} = \&throw_exception ; { # hide our variables within this block my ($filename, $mtime, $package, $sub); eval $eval; } # $@ is set for any warning and error. This guarantees that the plugin will not be run. if ($@) { # Log eval'd text of plugin. # Correct the line number of the error by removing the lines added (the subroutine prologue) by Embed::eval_file. my $i = 1 ; $eval =~ s/^/sprintf('%10d ', $i++)/meg ; print STDERR '[', time(), ']', qq( **ePN '$pn' error '$@' in text "\n$eval"\n) ; $Cache{$package}{plugin_error} = $@ ; $Cache{$package}{mtime} = $mtime unless $delete; # If the compilation fails, leave nothing behind that may affect subsequent compilations. die; } #cache it unless we're cleaning out each time $Cache{$package}{mtime} = $mtime unless $delete; } } sub run_package { my $filename = shift; my $delete = shift; my $tmpfname = shift; my $ar = shift; my $pn = substr($filename, rindex($filename,"/")+1); my $package = valid_package_name($pn); my $res = 3; tie (*STDOUT, 'OutputTrap'); my @a = &parse_line('\s+', 0, $ar) ; if ( $Cache{$package}{plugin_error} ) { untie *STDOUT; # return unknown return (3, '**ePN' . " '$pn' " . $Cache{$package}{plugin_error} . "\n") ; } local $SIG{__WARN__} = \&throw_exception ; eval { $package->hndlr(@a); }; if ($@) { if ($@ =~ /^ExitTrap: /) { # For normal plugin exit the ExitTrap string is set by the # redefined CORE::GLOBAL::exit sub calling die to return a string =~ /^ExitTrap: -?\d+ $package/ # However, there is only _one_ exit sub so the last plugin to be compiled sets _its_ # package name. $res = 0; } else { # get return code (which may be negative) if ($@ =~ /^ExitTrap: (-?\d+)/) { $res = $1; } else { # run time error/abnormal plugin termination; exit was not called in plugin # return unknown $res = 3; chomp $@ ; # correct line number reported by eval for the prologue added by eval_file $@ =~ s/(\d+)\.$/($1 - 8)/e ; print STDOUT '**ePN', " '$pn' ", $@, "\n" ; # Don't run it again until the plugin is recompiled (clearing $Cache{$package}{plugin_error}) # Note that the plugin should be handle any run time errors (such as timeouts) # that may occur in service checking. # FIXME - doesn't work under both 5.005 and 5.8.0. The cached value of plugin error is reset somehow. # $Cache{$package}{plugin_error} = $@ ; } } } # !! my $plugin_output = ; untie *STDOUT; return ($res, $plugin_output) ; } 1; GARRULOUS use constant TEXT_DEBUG => <<'DEBUG' ; BEGIN { open STDERRLOG, '>> ' . EPN_STDERR_LOG or die "Can't open '" . EPN_STDERR_LOG . " for append: $!" ; } package OutputTrap; # # Methods for use by tied STDOUT in embedded PERL module. # # Simply ties STDOUT to a scalar and emulates serial semantics. # sub TIEHANDLE { my ($class) = @_; my $me ; bless \$me, $class; } sub PRINT { my $self = shift; $$self .= join("",@_); } sub PRINTF { my $self = shift; my $fmt = shift; $$self .= sprintf($fmt,@_); } sub READLINE { my $self = shift; # Perl code other than plugins may print nothing; in this case return "(No output!)\n". return(defined $$self ? $$self : "(No output!)\n"); } sub CLOSE { my $self = shift; } package Embed::Persistent; sub valid_package_name { my($string) = @_; $string =~ s/([^A-Za-z0-9\/])/sprintf("_%2x",unpack("C",$1))/eg; # second pass only for words starting with a digit $string =~ s|/(\d)|sprintf("/_%2x",unpack("C",$1))|eg; # Dress it up as a real package name $string =~ s|/|::|g; return "Embed::" . $string; } # Perl 5.005_03 only traps warnings for errors classed by perldiag # as Fatal (eg 'Global symbol """"%s"""" requires explicit package name'). # Therefore treat all warnings as fatal. sub throw_exception { my $warn = shift ; return if $warn =~ /^Subroutine CORE::GLOBAL::exit redefined/ ; print STDERR " ... throw_exception: calling die $warn\n" ; die $warn ; } sub eval_file { my $filename = shift; my $delete = shift; *STDERR = *STDERRLOG ; my $pn = substr($filename, rindex($filename,"/")+1); my $package = valid_package_name($pn); my $mtime = -M $filename ; if ( defined $Cache{$package}{mtime} && $Cache{$package}{mtime} <= $mtime) { # we have compiled this subroutine already, # it has not been updated on disk, nothing left to do print STDERR "(I) \$mtime: $mtime, \$Cache{$package}{mtime}: '$Cache{$package}{mtime}' - already compiled $package->hndlr.\n"; } else { print STDERR "(I) \$mtime: $mtime, \$Cache{$package}{mtime}: '$Cache{$package}{mtime}' - Compiling or recompiling \$filename: $filename.\n" ; local *FH; # FIXME - error handling open FH, $filename or die "'$filename' $!"; local($/) = undef; my $sub = ; close FH; # cater for routines that expect to get args without progname # and for those using @ARGV $sub = qq(\nshift(\@_);\n\@ARGV=\@_;\nlocal \$^W=1;\n$sub) ; # cater for scripts that have embedded EOF symbols (__END__) $sub =~ s/__END__/\;}\n__END__/; # wrap the code into a subroutine inside our unique package my $eval = qq{ package main; use subs 'CORE::GLOBAL::exit'; sub CORE::GLOBAL::exit { die "ExitTrap: \$_[0] ($package)"; } package $package; sub hndlr { $sub } }; $Cache{$package}{plugin_error} = 0 ; # suppress warning display. local $SIG{__WARN__} = \&throw_exception ; { # hide our variables within this block my ($filename, $mtime, $package, $sub); eval $eval; } # $@ is set for any warning and error. This guarantees that the plugin will not be run. if ($@) { # Log eval'd text of plugin. # Correct the line number of the error by removing the lines added (the subroutine prologue) by Embed::eval_file. # $@ =~ s/line (\d+)\.\n/'line ' . ($1 - 8) . ".\n"/ge ; my $i = 1 ; $eval =~ s/^/sprintf('%10d ', $i++)/meg ; print STDERR '[', time(), ']', qq( **ePN '$pn' error '$@' in text "\n$eval"\n) ; $Cache{$package}{plugin_error} = $@ ; $Cache{$package}{mtime} = $mtime unless $delete; # If the compilation fails, leave nothing behind that may affect subsequent compilations. die; } #cache it unless we're cleaning out each time $Cache{$package}{mtime} = $mtime unless $delete; } } sub run_package { my $filename = shift; my $delete = shift; my $tmpfname = shift; my $ar = shift; my $pn = substr($filename, rindex($filename,"/")+1); my $package = valid_package_name($pn); my $res = 3; use Data::Dumper ; print STDERR Data::Dumper->Dump([\%Cache], [qw(%Cache)]) ; tie (*STDOUT, 'OutputTrap'); my @a = &parse_line('\s+', 0, $ar) ; if ( $Cache{$package}{plugin_error} ) { untie *STDOUT; # return unknown print STDERR " ... eval failed in eval_file, run_package returning (3, **ePN '$pn' '$Cache{$package}{plugin_error}'\\n)\n" ; return (3, '**ePN' . " '$pn' " . $Cache{$package}{plugin_error} . "\n") ; } local $SIG{__WARN__} = \&throw_exception ; eval { $package->hndlr(@a); }; if ($@) { if ($@ =~ /^ExitTrap: /) { # For normal plugin exit the ExitTrap string is set by the # redefined CORE::GLOBAL::exit sub calling die to return a string =~ /^ExitTrap: -?\d+ $package/ # However, there is only _one_ exit sub so the last plugin to be compiled sets _its_ # package name. $res = 0; } else { # get return code (which may be negative) if ($@ =~ /^ExitTrap: (-?\d+)/) { $res = $1; } else { # run time error/abnormal plugin termination; exit was not called in plugin # return unknown $res = 3; chomp $@ ; # correct line number reported by eval for the prologue added by eval_file $@ =~ s/(\d+)\.$/($1 - 8)/e ; print STDOUT '**ePN', " '$pn' ", $@, "\n" ; # Don't run it again until the plugin is recompiled (clearing $Cache{$package}{plugin_error}) # Note that the plugin should be handle any run time errors (such as timeouts) # that may occur in service checking. # FIXME - doesn't work under both 5.005 and 5.8.0. The cached value of plugin error is reset somehow. # $Cache{$package}{plugin_error} = $@ ; } } } # !! my $plugin_output = ; untie *STDOUT; print STDERR " ... run_package returning ('$res', '$plugin_output')\n" ; return ($res, $plugin_output) ; } 1; DEBUG SWITCH: { eval TEXT_RETICENT, last SWITCH if RETICENT ; eval TEXT_GARRULOUS, last SWITCH if GARRULOUS ; eval TEXT_DEBUG, last SWITCH if DEBUG ; die "Please set one of (use constant statements) RETICENT, GARRULOUS or DEBUG in code.\n" ; } 1 ; =head1 NAME p1.pl - Perl program to provide Perl code persistence for the Nagios project (http://www.Nagios.Org). This program attempts to provide a mod_perl like facility for Nagios. =head1 SYNOPSIS Edit the text to set the values of (the 'use constant' statements) the log path, B, and any one (only) of the boolean log level flags B, B, and B. The default is to set RETICENT, and to use S</var/epn_stderr.log> as the log path. The log level flags determine the amount and type of messages logged in the log path. The RETICENT log level results in similar behaviour to former versions of p1.pl. In particular, the log file EPN_STDERR_LOG will B be opened. =head1 DESCRIPTION Nagios is a program to monitor service availability; it does this by scheduling 'plugins' - discrete programs that check a service and output a line of text describing the service state intended for those responsible for the service and exit with a coded value to relay the same information to Nagios. Plugins, like CGIs, can be coded in Perl. The persistence framework embeds a Perl interpreter in Nagios to =over 4 =item * reduce the time taken for the Perl compile and execute cycle. =item * eliminate the need for the shell to fork and exec Perl. =item * eliminate the need for Nagios to fork a process (with popen) to run the Perl code. =item * eliminate reloading of frequently used modules. =back and all the good things mentioned in the B man page under 'Maintaining a persistent interpreter'. Plugin syntax errors (possibly introduced when the plugin is transformed by the persistence framework) and run-time errors are logged depending on the log level flags. Regardless of the log level, plugin run-time and syntax errors, are returned to Nagios as the 'plugin output'. These messages appear in the Nagios log like S<**ePN 'check_test' Global symbol "$status" requires explicit package name at (eval 54) line 15.> =over 4 =item * GARRULOUS =over 8 =item 1 opens an extra output stream in the path given by the value of EPN_STDERR_LOG. =item 2 logs a listing of plugin errors, followed by a dump of the plugin source - as transformed by the persistence framework - each time the plugin source file modification time stamp is changed (either by correcting the syntax error or touching the file). =back An example of such a listing is [1074760243] **ePN 'check_test' error 'Global symbol "$status" requires explicit package name at (eval 54) line 15. ' in text " 1 2 package main; 3 use subs 'CORE::GLOBAL::exit'; 4 sub CORE::GLOBAL::exit { die "ExitTrap: $_[0] (Embed::check_5ftest)"; } 5 package Embed::check_5ftest; sub hndlr { 6 shift(@_); 7 @ARGV=@_; 8 local $^W=1; 9 #!/usr/bin/perl -w 10 11 # This plugin always does what it is told. 12 13 use strict ; 14 15 $status = shift @ARGV ; 16 # my $status = shift @ARGV ; 17 $status ||= 'fail' ; 18 19 my $invert = 1 ; 20 21 $status = lc($status) ; 22 23 $status = ( ( $invert and $status eq 'ok' ) ? 'fail' : 24 ( $invert and $status eq 'fail' ) ? 'ok' : 25 $status ) ; 26 27 $status eq 'ok' and do { 28 print "Ok. Got a \"$status\". Expecting \"OK\".\n" ; 29 exit 0 ; 30 } ; 31 32 $status eq 'fail' and do { 33 print "Failed. Got a \"$status\". Expecting \"FAIL\".\n" ; 34 exit 2 ; 35 } ; 36 37 # print "Mmmm. Looks like I got an "$status\" when expecting an \"ok\" or \"fail\".\n" ; 38 print "Mmmm. Looks like I got an \"$status\" when expecting an \"ok\" or \"fail\".\n" ; 39 exit 3 ; 40 } 41 " Note that the plugin text (lines 9 to 39 inclusive) has been transformed by the persistence frame work to E<10>1 override the exit sub in package main E<10>2 create a new package from the plugin file name, here Embed::check_5ftest E<10>3 wrap the plugin in a subroutine named hndlr within the new package E<10>4 handle the argument list the same way as for a method call, restoring @ARGV from the remaining arguments E<10>5 Setting the warning level to trap all warnings (note that the -w option to Perl is no longer significant because the shebang line is not fed to exec()). =item * DEBUG This setting is intended only for hacking this code. In addition to the garrulous messages =over 8 =item 1 enter, leave messages =item 2 dump of %Cache data structure =back =item * RETICENT This is the default verbosity level and recommended for production use. One line only of compile or run time errors is reported in the Nagios log. There are no other output streams. =back =head1 SUBROUTINES Unless otherwise stated, all subroutines take two (2) arguments :- =over 4 =item 1 plugin_filename - string (called from C) or scalar(called from Perl): the path to the plugin. =item 2 DO_CLEAN - boolean: set if plugin is not to be cached. Defaults to 0. Setting this flag means that the plugin is compiled each time it is executed. Nagios B sets this flag when the Nagios is compiled with the configure setting --with-perlcache. =back =over 4 =item Embed::Persistent::eval_file( plugin_filename, DO_CLEAN ) E<10> Returns nothing. eval_file() transforms the plugin to a subroutine in a package, compiles the string containing the transformed plugin, caches the plugin file modification time (to avoid recompiling it), and caches any errors returned by the compilation. If the plugin has been modified or has not been compiled before, the plugin is transformed to a subroutine in a new package by creating a package name from the plugin file name (C) turning off subroutine redefinition warnings (C) overriding CORE::GLOBAL::exit from within package main (C) This allows the plugin to call exit without taking down the persistence framework. prepending the plugin text with code to let the plugin function as a subroutine. This code sets up the plugin argument vector (@ARGV) from the subroutine arguments and turns on warnings. (C<$sub = qq(\nshift(\@_);\n\@ARGV=\@_;\nlocal \$^W=1;\n$sub)>). writing the plugin as the subroutine named 'hndlr' in the new package (C) The plugin compilation, performed by C, caches C<$@> if the transformed plugin has syntax errors. =item Embed::Persistent::run_package( plugin_filename, DO_CLEAN, '', plugin_argument_string ) E<10> Returns (plugin_return_code, plugin_output) run_package() =back =head1 BUGS This framework does nothing to prevent the memory leaks mentioned in B, relying on operator intervention. Probably the best way of doing so is by periodically scheduling =over 4 =item 1 A check of the memory used by the Nagios process (by running for example the standard Nagios plugin check_vsz) =item 2 Restarting Nagios with the (supplied with Nagios) startup script (restart command). =back If you do periodocally restart Nagios, make sure that =over 4 =item 1 plugins all set the PATH environment variable if they need other system binaries (otherwise, if the init script is excec'd by cron, the PATH will be reset and the plugins will fail - but only when reatsrted by cron). =item 2 that the group owning the Nagios command pipe is the same as the Nagios group (otherwise, the restarted Nagios will not be able to read from the command pipe). =back Nagios installations using the persistence framework must monitor the memory use of the Nagios process and stop/start it when the usage is exorbidant (eg, for a site with 400 services on 200 hosts and custom Perl plugins used for about 10% of the service checks, the Nagios process uses ~80 MB after 20-30 days runningi with Perl 5.005 [Memory usage is B greater with recent Perls]. It is usually stopped and started at this point). Note that a HUP signal is B sufficient to deallocate the Perl memory; the Nagios process must be stopped and started. =head1 AUTHOR Originally by Stephen Davies. Now maintained by Stanley Hopcroft who retains responsibility for the 'bad bits'. =head1 COPYRIGHT Copyright (c) 2004 Stanley Hopcroft. All rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =cut nagios-2.6/contrib/traceroute.cgi0000664000076500007650000001232710140502775016506 0ustar nagiosnagios#!/usr/bin/perl # # (c)2004 Andreas Wassatsch # released under GPLv2 # # based on traceroute.cgi of Ian Cass Knowledge Matters Ltd # (c)1999 Ian Cass Knowledge Matters Ltd # # This script should be put in your Nagios cgi-bin directory # (usually /usr/local/nagios/sbin) # # It will perform a traceroute from your Nagios box to # the machine that the check_ping plugin is pinging, # output includes links to host status and status map # for hosts known to Nagios # # This software is provided as-is, without any express or implied # warranty. In no event will the author be held liable for any mental # or physical damages arising from the use of this script. # # Legal note: # Nagios is a registered trademark of Ethan Galstad. # use strict; use File::Basename; use POSIX qw(strftime); # Global Settings #---------------- $| = 1; my($nagios) = "/usr/local/nagios"; my($urlbase) = "/nagios"; my($refresh) = 30; my($self) = basename($0); my($traceroute) = "/usr/sbin/traceroute -m 20 -q 1"; # Generate HTTP header #--------------------- my($mdate)=`date +"%a, %d %b %Y %H:%M:%S %Z"`; print "Cache-Control: no-store\n"; print "Pragma: no-cache\n"; print "Last-Modified: $mdate"; print "Expires: Thu, 01 Jan 1970 00:00:00 GMT\n"; print "Content-type: text/html\n\n"; # accept either traceroute/foo or traceroute?foo; default to REMOTE_ADDR # if nothing else is specified #----------------------------------------------------------------------- my($addr) = $ENV{PATH_INFO} || $ENV{QUERY_STRING} || $ENV{REMOTE_ADDR}; $addr =~ tr/+/ /; $addr =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; $addr =~ s,^addr=,,; $addr =~ s/[^A-Za-z0-9\.-]//g; # for security # HTML Head with META Refresh info / stylesheet #---------------------------------------------- print "\n"; print "\n\ntraceroute to host $addr\n"; print "\n"; print "\n"; print "\n\n"; # Info Box #--------- print ""; print ""; print "
    "; print "
    traceroute
    "; print "Genereated by $self
    "; print "Last Updated: $mdate
    "; print "Updated every $refresh seconds
    "; print "Nagios® - www.nagios.org
    "; print "Logged in as $ENV{'REMOTE_USER'}
    "; print "
    "; print "

    "; print "Traceroute to Host $addr

    \n"; print "\n"; # read in nagios hosts #--------------------- my(@cfg); my($entry); my($bla); my($host); my(@hostlist); open(HOSTS, "$nagios/etc/hosts.cfg"); @cfg = grep {!/#/ && /host_name/} ; close(HOSTS); foreach $entry (@cfg) { $entry =~ s/^\s+//; ($bla, $host) = split(/\s+/,$entry); push @hostlist,$host; } # open traceroute pipe #--------------------- my($i)=0; open(TRACEROUTE, "$traceroute $addr |" ) || die "
    couldn't open pipe to traceroute! $!
    "; my(@arr); my($class); my($known_host); while () { chomp; s/\&/\&/g; s/\"; print "
    "; print ""; print ""; print ""; print "\n"; } else { # class for odd/even lines #------------------------- if ($i/2 == int($i/2)) { $class="statusEven"; } else { $class="statusOdd"; } # parse traceroute lines #----------------------- s/^\s//g; (@arr) = split(/\s+/, $_, 4); if (grep(/\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/,$arr[1])) { $arr[3] = $arr[2] ." ". $arr[3]; $arr[2] = $arr[1]; $arr[1] = "-"; } $arr[2] =~ s/\(//; $arr[2] =~ s/\)//; # check if host is known to nagios #--------------------------------- $known_host = 0; foreach $host (@hostlist) { if ($host eq $arr[1]) { $known_host++; } } # print table row #---------------- print ""; print "\n"; # hop print "\n"; # ip print "\n"; # rtt print "\n"; } $i++; } close(TRACEROUTE) || die "couldn't close pipe to traceroute! $!"; print "
    HopHostIPRound Trip Time
    $arr[0]"; print "\n"; print "\n"; } else { print "$arr[1]\n"; } print "
    \n"; if ($known_host) { print ""; print "$arr[1]\n"; if ($known_host) { print ""; print "\n"; } print "
    \n"; # host print "
    $arr[2]$arr[3]
    \n"; # footer #------- print " 

     

    "; print "$self by Andreas Wassatsch"; print "\n"; # end #---- exit 0; nagios-2.6/html/0000775000076500007650000000000010532717606013152 5ustar nagiosnagiosnagios-2.6/html/contexthelp/0000775000076500007650000000000010532717567015515 5ustar nagiosnagiosnagios-2.6/html/contexthelp/L10.html0000664000076500007650000000157207436604471016742 0ustar nagiosnagios Context-Sensitive Help Unavailable

    Context-Sensitive Help Unavailable

    Context-sensitive help is not yet available.

    For more information, please visit the main Nagios website at http://www.nagios.org.

    nagios-2.6/html/contexthelp/A1.html0000664000076500007650000000157207436604471016647 0ustar nagiosnagios Context-Sensitive Help Unavailable

    Context-Sensitive Help Unavailable

    Context-sensitive help is not yet available.

    For more information, please visit the main Nagios website at http://www.nagios.org.

    nagios-2.6/html/contexthelp/A2.html0000664000076500007650000000157207436604471016650 0ustar nagiosnagios Context-Sensitive Help Unavailable

    Context-Sensitive Help Unavailable

    Context-sensitive help is not yet available.

    For more information, please visit the main Nagios website at http://www.nagios.org.

    nagios-2.6/html/contexthelp/A3.html0000664000076500007650000000157207436604471016651 0ustar nagiosnagios Context-Sensitive Help Unavailable

    Context-Sensitive Help Unavailable

    Context-sensitive help is not yet available.

    For more information, please visit the main Nagios website at http://www.nagios.org.

    nagios-2.6/html/contexthelp/A4.html0000664000076500007650000000157207436604471016652 0ustar nagiosnagios Context-Sensitive Help Unavailable

    Context-Sensitive Help Unavailable

    Context-sensitive help is not yet available.

    For more information, please visit the main Nagios website at http://www.nagios.org.

    nagios-2.6/html/contexthelp/A5.html0000664000076500007650000000157207436604471016653 0ustar nagiosnagios Context-Sensitive Help Unavailable

    Context-Sensitive Help Unavailable

    Context-sensitive help is not yet available.

    For more information, please visit the main Nagios website at http://www.nagios.org.

    nagios-2.6/html/contexthelp/A6.html0000664000076500007650000000157207436604471016654 0ustar nagiosnagios Context-Sensitive Help Unavailable

    Context-Sensitive Help Unavailable

    Context-sensitive help is not yet available.

    For more information, please visit the main Nagios website at http://www.nagios.org.

    nagios-2.6/html/contexthelp/A7.html0000664000076500007650000000157207436604471016655 0ustar nagiosnagios Context-Sensitive Help Unavailable

    Context-Sensitive Help Unavailable

    Context-sensitive help is not yet available.

    For more information, please visit the main Nagios website at http://www.nagios.org.

    nagios-2.6/html/contexthelp/B1.html0000664000076500007650000000157207436604471016650 0ustar nagiosnagios Context-Sensitive Help Unavailable

    Context-Sensitive Help Unavailable

    Context-sensitive help is not yet available.

    For more information, please visit the main Nagios website at http://www.nagios.org.

    nagios-2.6/html/contexthelp/C1.html0000664000076500007650000000157207436604471016651 0ustar nagiosnagios Context-Sensitive Help Unavailable

    Context-Sensitive Help Unavailable

    Context-sensitive help is not yet available.

    For more information, please visit the main Nagios website at http://www.nagios.org.

    nagios-2.6/html/contexthelp/D1.html0000664000076500007650000000157207436604471016652 0ustar nagiosnagios Context-Sensitive Help Unavailable

    Context-Sensitive Help Unavailable

    Context-sensitive help is not yet available.

    For more information, please visit the main Nagios website at http://www.nagios.org.

    nagios-2.6/html/contexthelp/E1.html0000664000076500007650000000157207436604471016653 0ustar nagiosnagios Context-Sensitive Help Unavailable

    Context-Sensitive Help Unavailable

    Context-sensitive help is not yet available.

    For more information, please visit the main Nagios website at http://www.nagios.org.

    nagios-2.6/html/contexthelp/F1.html0000664000076500007650000000157207436604471016654 0ustar nagiosnagios Context-Sensitive Help Unavailable

    Context-Sensitive Help Unavailable

    Context-sensitive help is not yet available.

    For more information, please visit the main Nagios website at http://www.nagios.org.

    nagios-2.6/html/contexthelp/G1.html0000664000076500007650000000157207436604471016655 0ustar nagiosnagios Context-Sensitive Help Unavailable

    Context-Sensitive Help Unavailable

    Context-sensitive help is not yet available.

    For more information, please visit the main Nagios website at http://www.nagios.org.

    nagios-2.6/html/contexthelp/G2.html0000664000076500007650000000157207436604471016656 0ustar nagiosnagios Context-Sensitive Help Unavailable

    Context-Sensitive Help Unavailable

    Context-sensitive help is not yet available.

    For more information, please visit the main Nagios website at http://www.nagios.org.

    nagios-2.6/html/contexthelp/G3.html0000664000076500007650000000157207436604471016657 0ustar nagiosnagios Context-Sensitive Help Unavailable

    Context-Sensitive Help Unavailable

    Context-sensitive help is not yet available.

    For more information, please visit the main Nagios website at http://www.nagios.org.

    nagios-2.6/html/contexthelp/G4.html0000664000076500007650000000157207436604471016660 0ustar nagiosnagios Context-Sensitive Help Unavailable

    Context-Sensitive Help Unavailable

    Context-sensitive help is not yet available.

    For more information, please visit the main Nagios website at http://www.nagios.org.

    nagios-2.6/html/contexthelp/G5.html0000664000076500007650000000157207436604471016661 0ustar nagiosnagios Context-Sensitive Help Unavailable

    Context-Sensitive Help Unavailable

    Context-sensitive help is not yet available.

    For more information, please visit the main Nagios website at http://www.nagios.org.

    nagios-2.6/html/contexthelp/G6.html0000664000076500007650000000157207436604471016662 0ustar nagiosnagios Context-Sensitive Help Unavailable

    Context-Sensitive Help Unavailable

    Context-sensitive help is not yet available.

    For more information, please visit the main Nagios website at http://www.nagios.org.

    nagios-2.6/html/contexthelp/H1.html0000664000076500007650000000157207436604471016656 0ustar nagiosnagios Context-Sensitive Help Unavailable

    Context-Sensitive Help Unavailable

    Context-sensitive help is not yet available.

    For more information, please visit the main Nagios website at http://www.nagios.org.

    nagios-2.6/html/contexthelp/H2.html0000664000076500007650000000157207436604471016657 0ustar nagiosnagios Context-Sensitive Help Unavailable

    Context-Sensitive Help Unavailable

    Context-sensitive help is not yet available.

    For more information, please visit the main Nagios website at http://www.nagios.org.

    nagios-2.6/html/contexthelp/H3.html0000664000076500007650000000157207436604471016660 0ustar nagiosnagios Context-Sensitive Help Unavailable

    Context-Sensitive Help Unavailable

    Context-sensitive help is not yet available.

    For more information, please visit the main Nagios website at http://www.nagios.org.

    nagios-2.6/html/contexthelp/H4.html0000664000076500007650000000157207436604471016661 0ustar nagiosnagios Context-Sensitive Help Unavailable

    Context-Sensitive Help Unavailable

    Context-sensitive help is not yet available.

    For more information, please visit the main Nagios website at http://www.nagios.org.

    nagios-2.6/html/contexthelp/H5.html0000664000076500007650000000157207436604471016662 0ustar nagiosnagios Context-Sensitive Help Unavailable

    Context-Sensitive Help Unavailable

    Context-sensitive help is not yet available.

    For more information, please visit the main Nagios website at http://www.nagios.org.

    nagios-2.6/html/contexthelp/H6.html0000664000076500007650000000157207436604471016663 0ustar nagiosnagios Context-Sensitive Help Unavailable

    Context-Sensitive Help Unavailable

    Context-sensitive help is not yet available.

    For more information, please visit the main Nagios website at http://www.nagios.org.

    nagios-2.6/html/contexthelp/H7.html0000664000076500007650000000157207436604471016664 0ustar nagiosnagios Context-Sensitive Help Unavailable

    Context-Sensitive Help Unavailable

    Context-sensitive help is not yet available.

    For more information, please visit the main Nagios website at http://www.nagios.org.

    nagios-2.6/html/contexthelp/H8.html0000664000076500007650000000157207436604471016665 0ustar nagiosnagios Context-Sensitive Help Unavailable

    Context-Sensitive Help Unavailable

    Context-sensitive help is not yet available.

    For more information, please visit the main Nagios website at http://www.nagios.org.

    nagios-2.6/html/contexthelp/I1.html0000664000076500007650000000157207436604471016657 0ustar nagiosnagios Context-Sensitive Help Unavailable

    Context-Sensitive Help Unavailable

    Context-sensitive help is not yet available.

    For more information, please visit the main Nagios website at http://www.nagios.org.

    nagios-2.6/html/contexthelp/I2.html0000664000076500007650000000157207436604471016660 0ustar nagiosnagios Context-Sensitive Help Unavailable

    Context-Sensitive Help Unavailable

    Context-sensitive help is not yet available.

    For more information, please visit the main Nagios website at http://www.nagios.org.

    nagios-2.6/html/contexthelp/I3.html0000664000076500007650000000157207436604471016661 0ustar nagiosnagios Context-Sensitive Help Unavailable

    Context-Sensitive Help Unavailable

    Context-sensitive help is not yet available.

    For more information, please visit the main Nagios website at http://www.nagios.org.

    nagios-2.6/html/contexthelp/I4.html0000664000076500007650000000157207436604471016662 0ustar nagiosnagios Context-Sensitive Help Unavailable

    Context-Sensitive Help Unavailable

    Context-sensitive help is not yet available.

    For more information, please visit the main Nagios website at http://www.nagios.org.

    nagios-2.6/html/contexthelp/I5.html0000664000076500007650000000157207436604471016663 0ustar nagiosnagios Context-Sensitive Help Unavailable

    Context-Sensitive Help Unavailable

    Context-sensitive help is not yet available.

    For more information, please visit the main Nagios website at http://www.nagios.org.

    nagios-2.6/html/contexthelp/I6.html0000664000076500007650000000157207436604471016664 0ustar nagiosnagios Context-Sensitive Help Unavailable

    Context-Sensitive Help Unavailable

    Context-sensitive help is not yet available.

    For more information, please visit the main Nagios website at http://www.nagios.org.

    nagios-2.6/html/contexthelp/I7.html0000664000076500007650000000157207436604471016665 0ustar nagiosnagios Context-Sensitive Help Unavailable

    Context-Sensitive Help Unavailable

    Context-sensitive help is not yet available.

    For more information, please visit the main Nagios website at http://www.nagios.org.

    nagios-2.6/html/contexthelp/I8.html0000664000076500007650000000157207436604471016666 0ustar nagiosnagios Context-Sensitive Help Unavailable

    Context-Sensitive Help Unavailable

    Context-sensitive help is not yet available.

    For more information, please visit the main Nagios website at http://www.nagios.org.

    nagios-2.6/html/contexthelp/I9.html0000664000076500007650000000157207776147717016703 0ustar nagiosnagios Context-Sensitive Help Unavailable

    Context-Sensitive Help Unavailable

    Context-sensitive help is not yet available.

    For more information, please visit the main Nagios website at http://www.nagios.org.

    nagios-2.6/html/contexthelp/J1.html0000664000076500007650000000157207436604471016660 0ustar nagiosnagios Context-Sensitive Help Unavailable

    Context-Sensitive Help Unavailable

    Context-sensitive help is not yet available.

    For more information, please visit the main Nagios website at http://www.nagios.org.

    nagios-2.6/html/contexthelp/K1.html0000664000076500007650000000157207436604471016661 0ustar nagiosnagios Context-Sensitive Help Unavailable

    Context-Sensitive Help Unavailable

    Context-sensitive help is not yet available.

    For more information, please visit the main Nagios website at http://www.nagios.org.

    nagios-2.6/html/contexthelp/L1.html0000664000076500007650000000157207436604471016662 0ustar nagiosnagios Context-Sensitive Help Unavailable

    Context-Sensitive Help Unavailable

    Context-sensitive help is not yet available.

    For more information, please visit the main Nagios website at http://www.nagios.org.

    nagios-2.6/html/contexthelp/L11.html0000664000076500007650000000157207436604471016743 0ustar nagiosnagios Context-Sensitive Help Unavailable

    Context-Sensitive Help Unavailable

    Context-sensitive help is not yet available.

    For more information, please visit the main Nagios website at http://www.nagios.org.

    nagios-2.6/html/contexthelp/L12.html0000664000076500007650000000157207436604471016744 0ustar nagiosnagios Context-Sensitive Help Unavailable

    Context-Sensitive Help Unavailable

    Context-sensitive help is not yet available.

    For more information, please visit the main Nagios website at http://www.nagios.org.

    nagios-2.6/html/contexthelp/L13.html0000664000076500007650000000157207436604471016745 0ustar nagiosnagios Context-Sensitive Help Unavailable

    Context-Sensitive Help Unavailable

    Context-sensitive help is not yet available.

    For more information, please visit the main Nagios website at http://www.nagios.org.

    nagios-2.6/html/contexthelp/L2.html0000664000076500007650000000157207436604471016663 0ustar nagiosnagios Context-Sensitive Help Unavailable

    Context-Sensitive Help Unavailable

    Context-sensitive help is not yet available.

    For more information, please visit the main Nagios website at http://www.nagios.org.

    nagios-2.6/html/contexthelp/L3.html0000664000076500007650000000157207436604471016664 0ustar nagiosnagios Context-Sensitive Help Unavailable

    Context-Sensitive Help Unavailable

    Context-sensitive help is not yet available.

    For more information, please visit the main Nagios website at http://www.nagios.org.

    nagios-2.6/html/contexthelp/L4.html0000664000076500007650000000157207436604471016665 0ustar nagiosnagios Context-Sensitive Help Unavailable

    Context-Sensitive Help Unavailable

    Context-sensitive help is not yet available.

    For more information, please visit the main Nagios website at http://www.nagios.org.

    nagios-2.6/html/contexthelp/L5.html0000664000076500007650000000157207436604471016666 0ustar nagiosnagios Context-Sensitive Help Unavailable

    Context-Sensitive Help Unavailable

    Context-sensitive help is not yet available.

    For more information, please visit the main Nagios website at http://www.nagios.org.

    nagios-2.6/html/contexthelp/L6.html0000664000076500007650000000157207436604471016667 0ustar nagiosnagios Context-Sensitive Help Unavailable

    Context-Sensitive Help Unavailable

    Context-sensitive help is not yet available.

    For more information, please visit the main Nagios website at http://www.nagios.org.

    nagios-2.6/html/contexthelp/L7.html0000664000076500007650000000157207436604471016670 0ustar nagiosnagios Context-Sensitive Help Unavailable

    Context-Sensitive Help Unavailable

    Context-sensitive help is not yet available.

    For more information, please visit the main Nagios website at http://www.nagios.org.

    nagios-2.6/html/contexthelp/L8.html0000664000076500007650000000157207436604471016671 0ustar nagiosnagios Context-Sensitive Help Unavailable

    Context-Sensitive Help Unavailable

    Context-sensitive help is not yet available.

    For more information, please visit the main Nagios website at http://www.nagios.org.

    nagios-2.6/html/contexthelp/L9.html0000664000076500007650000000157207436604471016672 0ustar nagiosnagios Context-Sensitive Help Unavailable

    Context-Sensitive Help Unavailable

    Context-sensitive help is not yet available.

    For more information, please visit the main Nagios website at http://www.nagios.org.

    nagios-2.6/html/contexthelp/M1.html0000664000076500007650000000157207436604471016663 0ustar nagiosnagios Context-Sensitive Help Unavailable

    Context-Sensitive Help Unavailable

    Context-sensitive help is not yet available.

    For more information, please visit the main Nagios website at http://www.nagios.org.

    nagios-2.6/html/contexthelp/M2.html0000664000076500007650000000157207436604471016664 0ustar nagiosnagios Context-Sensitive Help Unavailable

    Context-Sensitive Help Unavailable

    Context-sensitive help is not yet available.

    For more information, please visit the main Nagios website at http://www.nagios.org.

    nagios-2.6/html/contexthelp/M3.html0000664000076500007650000000157207436604471016665 0ustar nagiosnagios Context-Sensitive Help Unavailable

    Context-Sensitive Help Unavailable

    Context-sensitive help is not yet available.

    For more information, please visit the main Nagios website at http://www.nagios.org.

    nagios-2.6/html/contexthelp/M4.html0000664000076500007650000000157207436604471016666 0ustar nagiosnagios Context-Sensitive Help Unavailable

    Context-Sensitive Help Unavailable

    Context-sensitive help is not yet available.

    For more information, please visit the main Nagios website at http://www.nagios.org.

    nagios-2.6/html/contexthelp/M5.html0000664000076500007650000000157207436604471016667 0ustar nagiosnagios Context-Sensitive Help Unavailable

    Context-Sensitive Help Unavailable

    Context-sensitive help is not yet available.

    For more information, please visit the main Nagios website at http://www.nagios.org.

    nagios-2.6/html/contexthelp/M6.html0000664000076500007650000000157207436604471016670 0ustar nagiosnagios Context-Sensitive Help Unavailable

    Context-Sensitive Help Unavailable

    Context-sensitive help is not yet available.

    For more information, please visit the main Nagios website at http://www.nagios.org.

    nagios-2.6/html/contexthelp/N1.html0000664000076500007650000000157207436604471016664 0ustar nagiosnagios Context-Sensitive Help Unavailable

    Context-Sensitive Help Unavailable

    Context-sensitive help is not yet available.

    For more information, please visit the main Nagios website at http://www.nagios.org.

    nagios-2.6/html/contexthelp/N2.html0000664000076500007650000000157207436604471016665 0ustar nagiosnagios Context-Sensitive Help Unavailable

    Context-Sensitive Help Unavailable

    Context-sensitive help is not yet available.

    For more information, please visit the main Nagios website at http://www.nagios.org.

    nagios-2.6/html/contexthelp/N3.html0000664000076500007650000000157207436604471016666 0ustar nagiosnagios Context-Sensitive Help Unavailable

    Context-Sensitive Help Unavailable

    Context-sensitive help is not yet available.

    For more information, please visit the main Nagios website at http://www.nagios.org.

    nagios-2.6/html/contexthelp/N4.html0000664000076500007650000000157207436604471016667 0ustar nagiosnagios Context-Sensitive Help Unavailable

    Context-Sensitive Help Unavailable

    Context-sensitive help is not yet available.

    For more information, please visit the main Nagios website at http://www.nagios.org.

    nagios-2.6/html/contexthelp/N5.html0000664000076500007650000000157207436604471016670 0ustar nagiosnagios Context-Sensitive Help Unavailable

    Context-Sensitive Help Unavailable

    Context-sensitive help is not yet available.

    For more information, please visit the main Nagios website at http://www.nagios.org.

    nagios-2.6/html/contexthelp/N6.html0000664000076500007650000000157207436604471016671 0ustar nagiosnagios Context-Sensitive Help Unavailable

    Context-Sensitive Help Unavailable

    Context-sensitive help is not yet available.

    For more information, please visit the main Nagios website at http://www.nagios.org.

    nagios-2.6/html/contexthelp/N7.html0000664000076500007650000000157207436604471016672 0ustar nagiosnagios Context-Sensitive Help Unavailable

    Context-Sensitive Help Unavailable

    Context-sensitive help is not yet available.

    For more information, please visit the main Nagios website at http://www.nagios.org.

    nagios-2.6/html/Makefile.in0000664000076500007650000000460310437071560015216 0ustar nagiosnagiosCC=@CC@ CFLAGS=@CFLAGS@ @DEFS@ LDFLAGS=@LDFLAGS@ @LIBS@ prefix=@prefix@ exec_prefix=@exec_prefix@ LOGDIR=@localstatedir@ CFGDIR=@sysconfdir@ BINDIR=@bindir@ CGIDIR=@sbindir@ HTMLDIR=@datadir@ INSTALL=@INSTALL@ INSTALL_OPTS=@INSTALL_OPTS@ COMMAND_OPTS=@COMMAND_OPTS@ CP=@CP@ all html: clean: rm -f *.cfg *.sub core rm -f *~ rm -f images/*.jbf rm -f images/logos/*.jbf rm -f contexthelp/*~ rm -f docs/*~ rm -f docs/images/*.jbf rm -f stylesheets/*~ distclean: clean rm -f Makefile index.html side.html devclean: distclean install: $(INSTALL) -m 775 $(INSTALL_OPTS) -d $(DESTDIR)$(HTMLDIR) $(INSTALL) -m 775 $(INSTALL_OPTS) -d $(DESTDIR)$(HTMLDIR)/media $(INSTALL) -m 775 $(INSTALL_OPTS) -d $(DESTDIR)$(HTMLDIR)/stylesheets $(INSTALL) -m 775 $(INSTALL_OPTS) -d $(DESTDIR)$(HTMLDIR)/contexthelp $(INSTALL) -m 775 $(INSTALL_OPTS) -d $(DESTDIR)$(HTMLDIR)/docs $(INSTALL) -m 775 $(INSTALL_OPTS) -d $(DESTDIR)$(HTMLDIR)/docs/images $(INSTALL) -m 775 $(INSTALL_OPTS) -d $(DESTDIR)$(HTMLDIR)/images $(INSTALL) -m 775 $(INSTALL_OPTS) -d $(DESTDIR)$(HTMLDIR)/images/logos $(INSTALL) -m 775 $(INSTALL_OPTS) -d $(DESTDIR)$(HTMLDIR)/ssi $(INSTALL) -m 664 $(INSTALL_OPTS) robots.txt $(DESTDIR)$(HTMLDIR) $(INSTALL) -m 664 $(INSTALL_OPTS) docs/robots.txt $(DESTDIR)$(HTMLDIR)/docs for file in *.html; \ do $(INSTALL) -m 664 $(INSTALL_OPTS) $$file $(DESTDIR)$(HTMLDIR); done for file in media/*.wav; \ do $(INSTALL) -m 664 $(INSTALL_OPTS) $$file $(DESTDIR)$(HTMLDIR)/media; done for file in stylesheets/*.css; \ do $(INSTALL) -m 664 $(INSTALL_OPTS) $$file $(DESTDIR)$(HTMLDIR)/stylesheets; done for file in contexthelp/*.html; \ do $(INSTALL) -m 664 $(INSTALL_OPTS) $$file $(DESTDIR)$(HTMLDIR)/contexthelp; done for file in docs/*.html; \ do $(INSTALL) -m 664 $(INSTALL_OPTS) $$file $(DESTDIR)$(HTMLDIR)/docs; done for file in docs/images/*.*; \ do $(INSTALL) -m 664 $(INSTALL_OPTS) $$file $(DESTDIR)$(HTMLDIR)/docs/images; done for file in images/*.gif; \ do $(INSTALL) -m 664 $(INSTALL_OPTS) $$file $(DESTDIR)$(HTMLDIR)/images; done for file in images/*.jpg; \ do $(INSTALL) -m 664 $(INSTALL_OPTS) $$file $(DESTDIR)$(HTMLDIR)/images; done for file in images/*.png; \ do $(INSTALL) -m 664 $(INSTALL_OPTS) $$file $(DESTDIR)$(HTMLDIR)/images; done for file in images/logos/*.*; \ do $(INSTALL) -m 664 $(INSTALL_OPTS) $$file $(DESTDIR)$(HTMLDIR)/images/logos; done install-unstripped: $(MAKE) install nagios-2.6/html/index.html.in0000664000076500007650000000122207436604431015551 0ustar nagiosnagios Nagios <!-- This page requires a web browser which supports frames. --> <p> <center> <h2>Nagios</h2> <a href="http://www.nagios.org" alt="Nagios Home">www.nagios.org</a><br> Copyright (c) 1999-2001 Ethan A. Galstad<br> </center> </p> <p> <i>Note: These pages require a browser which supports frames</i> </p> nagios-2.6/html/main.html0000664000076500007650000000455310532717361014771 0ustar nagiosnagios Nagios

    Nagios
    Copyright (c) 1999-2006 Ethan Galstad

    Version 2.6
    November 27, 2006

    New Installations:

    If you have just installed Nagios, read the documentation for instructions on getting everything up and running.

    Click here for a brief overview of new features that have been added in this release.

    For More Information:

    Visit the Nagios homepage at http://www.nagios.org for information on bug fixes, upgrades, support, etc.


    Monitored by Nagios

    Nagios and the Nagios logo are trademarks, servicemarks, registered trademarks or registered servicemarks owned by or licensed to Ethan Galstad.
    Nagios is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
    nagios-2.6/html/robots.txt0000664000076500007650000000003207436604431015216 0ustar nagiosnagiosUser-agent: * Disallow: / nagios-2.6/html/side.html.in0000664000076500007650000003036507737136650015407 0ustar nagiosnagios Nagios
    Nagios
    Home
    Documentation
    Tactical Overview
    Service Detail
    Host Detail
    Hostgroup Overview
    Hostgroup Summary
    Hostgroup Grid
    Servicegroup Overview
    Servicegroup Summary
    Servicegroup Grid
    Status Map
    3-D Status Map
    Service Problems
    Host Problems
    Network Outages
    Comments
    Downtime
    Process Info
    Performance Info
    Scheduling Queue
    Trends
    Availability
    Alert Histogram
    Alert History
    Alert Summary
    Notifications
    Event Log
    View Config
    nagios-2.6/html/docs/0000775000076500007650000000000010532717575014107 5ustar nagiosnagiosnagios-2.6/html/docs/images/0000775000076500007650000000000010532717604015345 5ustar nagiosnagiosnagios-2.6/html/docs/images/activepassive.png0000664000076500007650000003763607436604441020743 0ustar nagiosnagios‰PNG  IHDRºÍ^Ê÷PLTE@€ÿ @ € ÿ@@@@€@ÿ``@`€`ÿ€€@€€€ÿ  @ € ÿÀÀ@À€Àÿÿÿ@ÿ€ÿÿ @ € ÿ @ € ÿ @ @@ @€ @ÿ ` `@ `€ `ÿ € €@ €€ €ÿ    @  €  ÿ À À@ À€ Àÿ ÿ ÿ@ ÿ€ ÿÿ@@@@€@ÿ@ @ @@ €@ ÿ@@@@@@@€@@ÿ@`@`@@`€@`ÿ@€@€@@€€@€ÿ@ @ @@ €@ ÿ@À@À@@À€@Àÿ@ÿ@ÿ@@ÿ€@ÿÿ``@`€`ÿ` ` @` €` ÿ`@`@@`@€`@ÿ````@``€``ÿ`€`€@`€€`€ÿ` ` @` €` ÿ`À`À@`À€`Àÿ`ÿ`ÿ@`ÿ€`ÿÿ€€@€€€ÿ€ € @€ €€ ÿ€@€@@€@€€@ÿ€`€`@€`€€`ÿ€€€€@€€€€€ÿ€ € @€ €€ ÿ€À€À@€À€€Àÿ€ÿ€ÿ@€ÿ€€ÿÿ  @ € ÿ    @  €  ÿ @ @@ @€ @ÿ ` `@ `€ `ÿ € €@ €€ €ÿ    @  €  ÿ À À@ À€ Àÿ ÿ ÿ@ ÿ€ ÿÿÀÀ@À€ÀÿÀ À @À €À ÿÀ@À@@À@€À@ÿÀ`À`@À`€À`ÿÀ€À€@À€€À€ÿÀ À @À €À ÿÀÀÀÀ@ÀÀ€ÀÀÿÀÿÀÿ@Àÿ€Àÿÿÿÿ@ÿ€ÿÿÿ ÿ @ÿ €ÿ ÿÿ@ÿ@@ÿ@€ÿ@ÿÿ`ÿ`@ÿ`€ÿ`ÿÿ€ÿ€@ÿ€€ÿ€ÿÿ ÿ @ÿ €ÿ ÿÿÀÿÀ@ÿÀ€ÿÀÿÿÿÿÿ@ÿÿ€ÿÿÿ£0bKGDÿ¥òÅ pHYsÃÃÇo¨d IDATxÚí ’¤ªEwěƭ)ö”ë †p#|]étìÎÌÊ4E‘Íâ>j0 óšÈ C†:0 u`êÀ0Ôa¨ÃP†¡ C†:0 C–Eúk¡¿v6L?ž¨ß+CbJúñfc™vñœßÃ&ý³ûJø6–§ fØÓÃÕ—ÝRruE×.ëéß{ÒïPB9ˬT‡nP‡ïúS‡Þ¤ŽËmŒÃüÎ’xê•-©Ž«§Ðµ:„:’²ªš:†«ê°ŠË=âð½­Ã¯LçŒ:®Ž[.¬6 ÔÑœ:\¸ºµ˜'¦¢PVh)³ ºÎ=e"®N÷¤´s¼ŠW‡¼Q$ûÇ¡,K: ¶γ“7¿ÍêhuÎÔÙÖÚȼšq‡î/"mªcÛø´Õáû6\m{•ã$­ŽÝfqàª%o¸Jð‹y[ 6‡œt›2ä9‹m£]Vö†b»êP8•Á—~uz*ôVÇNY‰U‡û‹Xuì{Á:-úxƒµVuÄ%ÇÚ9¯À1$ª#.÷´S×%zûêØÖ8ƒÇU ¼Q0 ·,m+5Ï/ì¡çw1)ůï—ÛæIøèY{ûêØ9‹ýL݃I\Ón7÷v¯¦¢´š{’GÃqÖ“±e6ìxnáO*I‡qÇëj†qà;äáÂYìªc8ØI0SýY{Â=¼t!uz—êˆ*â}º¾úÁþÉ0ĪÃI*"¥ÔãÝù‡3(*ËŽÏ"¢Fî$˜©Iîþ˜Ùú>ñpÏ'áÔl]WGè²RÇÎNv·œÆÉ~RA6VÇnóf7`uò,N«CáLõù{ ê©ìdhêèHé>u(àÍVPG8r£P± ƃãÎ"MöNöÔ±wœYÔáóËã½/u Ýu(6/Ô1ªCŸ!Yû£ãhê…³Øò'·:†”˜êô•‡úÔUÇЂ:üð°Z>s!µ\V‡ö%ƒ:ÒÔá´Q¯”¶mf$©CCÔp#JÔ ¸ï~œ>‹p_y°ouWØáÐ\~¿cHlÚFG îR‡|1ŸÃ¨¤÷duB{1«©Â³STÁxhL–%Ÿ…?—¢Ž€Ç3O¢IˆYééêØŒ¿ÙëLˆ€1™Èþ·\%Ì@9詎<^ÿæò:ÜŠUG„È}o¢ÊÁQǃâ¯õwD©c8AÓ’:¼™@åá\Îv´†è¾òM@žèã”âw·e•Öa}ê,†ãùÞ„Ž.ÛÞ¥jÚÅõ•ûøuèªãxÒ¡W¾×I,}Á±:»tßI*”RÚñ¸¶‡Gœ±y¡ rÜYìÄ$›#8mœ•Û#è ªÃ;"îhŒn( é¤ÔüE5mw´5uäL·½‰`WûNuÜ;׫- Ôq® AoF·W[Õ3ìÆ5n0®v'ê ô¼IêHÈ1ÊΛôÑíñs 1 u`êÀ0Ôa¨ÃP†¡ C†:0 u`êÀ0 u`êÀ0Ôa¨ÃPGóy¥õYž åýõ²Æ‰}ÓŽí-h<ßa¨ãÑêó‹éoÙߛϓÅPG/yµÖêfÍþ[”§/Æ­ó‡òªcùñ`ÿm>s•PGyåÖí«:4}$ãëõË6aup•PGOì˜K»­»1´0D²J¸§ÄoQ‚:PGÇìX˰W;Ÿ:d4ÒÖÏ%K?¨ut§Å´¬´ß²ÒI’ ÔÑQ^-m*-qY³­e{å³^\¯ÜÆ`,²ì¦BDu•—”¬Ä¸¤†:0 u`êÀ0 u`êÀ0Ôa¨ÃP†¡ C†:0 u`êÀ0ÔaêÀ0Ôa¨ÃP†¡ C†:0 u`êÀ0ÔaêÀ0Ôa¨ÃP†¡ C†:0 u`êÀ0Ôa¨Ã0Ôa¨ÃP†¡ C†:0 u`êÀ0Ôa¨ÃP†a¨ÃP†¡ C†:0 u`êÀ0Ôa¨ÃP†¡ ÃP†¡ Cþ3úköÿFŸç/wS8ÚNÔ:¨£ou¨˜:„:PG³êñz\ÊO¤€:PÇ3Ôa¾Ö/ÇϵÝ`‹‰!£Ä;êE«é·èuô Éyg–ýµ,¯ æ§Ö½êðl†:PG»êlÌX…aú› ÏÆluX:S`Ïêh_ÃàkümêßyÕa ¿u Ž­:lC/UÇ0x¿”Üm1ÔÑš:ü(¯Ë]ÁPGê°¼æ¯< ×+·RÂ+GªÃޏºßo"º^&¤Ft"º¨£au gÀÛXò9Ó^"¥7p †:ª: u`¡ÔùÔ#:°=y¨Ã0Ôa¨ÃP†¡ C†:0 u`êÀ0Ôa¨ÃP†a¨ÃP†¡ó|0,Ñ^¤*<,[‘yž:¾yðHyÀ ƒ°ƒì€ì€<`ìÀ`ìà;`;`Ø;0Ø;xÀØa°ƒØ;0Ø;xÀØÁØÁvÀ vÀ°v`°vð€°ƒ°ƒØa°vð€°ƒ°ƒì€ì€<`ìÀ`ìà;`;`Ø;0 vtVwµf°v´sÈÿ¶e‚°£º«5uÀØ;`쀰vÀØ;`Ç›Ø ¬ÁØñVv,"ø/d«L`ìx ;D ì€gGª.6°ã‘ì8/ ["°v<וa(vÀŽ’êÐT0þþ¯ÃÿrZª;`G;T/+3kcÒì€`G~m|ô;`Gÿì(#Ž¿ò€°£{v”S쀳£”8Rà;`G›ìP1vvÀŽÞÙQN°ãqììW·àî(i”×;þ+³úv<sñ>¯õæwéïÀïx&;Æâ}¢Ï?T_ìø/»>ÆÝÁŽ'²ãßU+ ~_ß. Њ ‡+ÓfZö`ËîßÍo7À¹!f•Qó®`Ç#ýŽ©X›ŽÄòÎøkãiìX7ßHÀ³KW)ì¸:cOÆèÁ°ã&u”Ë͉»-«åßüRÅø~ývÀŽ§Í üðc¿e¥U³\þûÏü v¼š¾ŽÓQ_)jÓjó;þò#ZëÇ+G`Ç»ÙaöoÇÈ#Aám+ÎïбßlY©v<Έì=†;ê¨<7pßïøÏôÊZV°ãáì°fküëŽq¾vK¼5ŠÄ?…õ¬`G¿ìðÌ1w† îµ²Ê3·YvÐW;"Øá‚=†}›îx¹CßåL„°ãiìØLh bw7ÜLÉ…°ãìXýŽ:ê¨ÏŽK· 4çI­1-Øñ vü»]CAÎwÿæmYUgÇŒº¤ë3ØñvXý†Wî¿+m¼ö3^ymvÈ\¸Gæ|Yç½õ½ÃóõÃŽèuQ`GÏýV`j³Z¢³²E±Ñm¦¿CúÏ*Ùáÿm|-«ß‘\Q+±ÃŽ®ûÊó -Lè ¼Gê0»·ê°Ù=ÊvtÎŽCnî+g‡öØáª¿ãÙìÈ(ø=ߵޮ=¦*ƒ:<óØaó;:[ƒÝð®——€ lßb×+^MvôÊîH_9ìx;;è+‡ëQZ;`ìÝ÷vÀØá‡~ì€îœêÙð;`ìЃ˜ì€z³‚°#ŒØ;`‡]_÷Dz3;ŠÉ#¡ÀŽ&rBúfvTì蔲ג}3; yú†}žÏºùôòfv„×C¼tçòLEvTU¹ïÞÍŽCsk#^°£Á\ònvLX6i(c‘w‘cö>`Ç2òìº2t&eØÑ˜Ëa)ì0;Î Cù‹ 쨫r(;¶£—“…q%EØÑܱþì%о(²ÜÛv´Kg®G v+;‚c™ÝƒÌw]`GS.Gø8åý?Ǻþœð›vr¯ÜpaGK±ª Ġ_v}~þú~šGiQöv<‡Š<Ì€62±c]ã©vXÈ(ƒØÑ9vŽÒ¯<ì÷£¾ØaÑ¢9`G/äjC™ÚU=ú&.Šx°£)r|ïÔ}n]¿ #K»JÉm«füŽí{Øñv(±²òè#µ=jWMìPW1+k+v<‚Šø$³:Sßï´«¦6š:bÇ=£ÿc—½°£+v(éƒñ\ejW%ú÷mäŸái¬.ìèŸiäøÎ‡ ·«æÂ¥~bVÞ‘Íôw<J܃òú%GVzÀŽ.œŽ½]ägGOSð‹^iØÑ'9|³Ð3‘:&GFöÁŽ>É1(§k¯Z—v´Qóéæ“ Õ¾µâ}e<ØÑÄq\Zi©;ú™„_ôZÃŽÉaŸK v4ìy(Ó6°£½óÑEØÑð,üŠv4mѵ½aG«ž‡òDµ`Gƒç“‡z'ÔËå×;Êeªçj°£MÏC™;Ú9ŸLè¨ÂŽ&¯¿ê^mØqw›Y—÷£V"iÍx°£?vh(‚ŽRìh°¨òå†7×{šeG³) G­`Gw䍯޿J€ØñPvä«KŒ‰RÁ^ƒêñ*ØÑ;ÚFGÎÃkäúÁŽ~Ø‘³n.2C­³C…·‡O G¡¹ÍÃCìx&;”3&¯¡;ŠZi€eGIt¼ƒºårÃŽ®z:^Ë}ÃŽg²#sµ\“ÍÜ©c€ÏdGæZ¹Ð,>•]Ý£¶×;ú`GîJ¹Ð,¾¦Ù¡v<“¹{¡KÍÏW»Ýë€]°#{,¨Ô ð†á¡v<’ùÇ/½ªôØÑ99Ê­<¥f‹Ámè€}ÌÜÙ£ ·íÕ¥×;ÚgGYåžÒ“ØÁš$í³£Àlíbìh¶ÇCÃM+ØÑ:ê³ãörpŸÛ;j×zʼOoßë­^쨠rïTÅ3H¯Eì¨[ë);`ìè‘e–,y£çx܉ØQÓëPšTÅ£Cê'b¥¿öû›¿6¿‡M²£ÌªæeïÑÔ<Òþ«†Ÿ¿öW_?O?‚m²Ceêà²÷÷koU«ˆ´¥ñùg6-O?ŠŒLìh‡…nˆñ2v(‚3.B6)ÁŽFØQê^J…ï ÛÚªVÚ!ÆHAy¬:MœO­YªG-²Ãp1âM¿š‚·³£ÖHZ ïd‡~"˜á§ˆ`ÇÝçS¬ŠWásj ûè8g)5¼•Ú³ªÄˆÔ\Äê¼:Ƹ¯`Ç}çS°†WásRóìPª»á'츉*ØnWa@³c¬ú/«#ް£xJ»$T'›bÇuY¤Àv”®ñJöH¨R}ÝLÄ*›8`Ç]çS´z/ÎŽR½üm¡#°£l§’{W­ûìˆê÷€EÓQg{÷ï¶vdGÔ¸+ØQ²Ý^8¦¤J‘¢fØ‘U¾ì(˜ŒzÜÿP|0×ytdWì¸êrÿ…ûk.Œ Ȭ ØQÿ|TÏ+P¥¬jÃí1äw8ˆæY¦'anÆn*UÙ¡Ò5nv”í±9{Ž <(1ã|ÏþÜsØQ(u §:½*Éñ³UÇ8/ðg$…ƒ“ñ£ùyÁÉV%ì¨ÅÕ«×ÕmŸÍïÇ£ý,ÿf•ØâY5d¾&ô|ÀŽ"i¨ó4jt«œt;l8XÅ~Ó²Z›.±¡+ØQ¢¾SÙ4¦U8jÕÜ­²#¬Žµ¥ØQ“*œÆg!³Ò磱‡a´ûÝŽHuÑ,K;êÀï¨ÄŽiŒÒuªÎ®Ï”î߬.í­ìð ¶êäuÕñ£@à vT9ŸuúZ¡×„ÇÍ7Î:Vǧ Ä왢Wií`GÎÚ®FnÖç*NÛÈa{>¹Æ&ŽÖ…Ù+õ¡;T>Çnt<BÇ¥õˆYÝË•ïSQJ©“üŽjã­`Gþ:½<ªdÙm!«¿ã§ÖP]ØQÀ¨Â¨Jõ÷]äpûë Š¿£Âù¨ž?P¯:¿Ù[ÁŽÞ"VcJõÆÉª™eÅŽZÁެ}ÏéºYO«Qt8“84 ;Ì:Áväð6rÞ«îiÎîÌåÌ?ON¤¯¼ÔùLÀø]Ùõ3ªd¶=5­˜Ë¥pÏÞÔnÌ”;»c~Nž];N¶üÇg;³´8²îU÷š´RÖvñ7¬œÁTö@DwVÇŽ<`GÎóùŒ¦Ò~Í¢L­ö§¦•ËïªÃ3»ƒþŽ’ì˜kψüÑÕTŸšV.v˜¥ßQǶxwšVøYÎÇhЧüèT0ë©ieó;~~œ¹åÖ„ZyƯãw”dÇÉ«–´JŬ¢Õ +Ö$Éq>ºòÓ|7;í:­Ó‡µm­Óc e¸“Ê×Ù!qœÍØá¯cÏÆGEZ×Vó­ÙK;Ë*ÀSÓººWU  ;bc:y‚˜zqZîAU°ãÚù¨â<5­;Uö¡¹G7ñ€ÛåéGðÔ´š»óÓèsƒ5kF½5­L;U=—vÔfÇqÿÀSÓÊvçôzñ*ØQ½^”^™V¾ŒßYµ vÜÀU<Ч¦•óz“‚M°CªwOM«À•!bué`Çwƒ^—VÆ<}ãГ‹íØQ" ‚“žšV{ðP49aGŶùÚ¨yQZeØ1ÍQ,r§YØq:‚þ§¦Uô‚©L¨ vTîéØÌ[Ò*ÆŽµ÷CIþ†¾aGÛìð@}hZØÛÀR2Ü`ìh•1cÅ>+m©C©þì¨ÝŠ>¨ÎšV½LŸV´Êzog‡*ËSÓ*ͧÝvD–ûÎëtÁŽ|ç³³ÌÑ´Ðú¦:Rô”¼—¤UÝS;ú–™ãŸ%àåìÐA!ømï^˜’ýŠ´ê±Ã¤Èú<œ¦ì8_o¬¥h®j—¿" —^‘V[n ì¨âwlK‘ƵkÖ—Ä£yjZ¥{¿#àÐ^Ø÷SÓê°£î¼@ëü©iõµ‚÷œ¾^‘ì€×å©iõîyÀŽ[Î_/I«sxÀŽæwHoI«sÏvd‹×\:§¦Õ7<`G}~è]iÁŽG²c¨vK¼G§Õ1<`Ç ‘+½+­~£V°£n½µ7\é©iõ ØQ×óؽWÝSÓêÖó€u+.½2­^á;êÒCïL«SÏvĵ©sÝŸB/M«OxÀŽø•öêÔ±OM«GÏvÔ¬Àâë駦Õ<`G¾q­ÒêËó€uöÜðÔ´º‚ìHô?¤Ji?5­žè;ªìF¤Õ#<`Ç¹ÞØÌ™Ö$­.ãV°ãÜn¢ïhq©]þÔ´zìH¯ÃÆ{ÕÅ6ÒêÙó€çc™»UíØòiõ ØqµÝn°ÏGßy[åOM«mÏvd¨l?bË ‡ñÏ’ii¾•@´*œW£ð€¹j[eºW]TZ³•OKC¥ójÑó€ñQíDdXÑ”"Üô'ÓvdêA¯Ø*Ö·!ÂäÐí÷°#G;9õΣ9â}2=`G–öS‡«bä¦9šcGݸìÈRÃV„‡l`•%ÇËá;²Ô°ŸØNzMß5Ø!S¯¥ìÈUÉÖʲµ{®lµÞ*;jLØ‘«ž­QYûŠÓªQvԌŽLÕl¥<“õ¦ð­j¤û;Èï,š°#O]6õ'«v½©ÂΧ¯üû­ô€y÷\{qŽ7rÒ«.&ì(Ø««*é©{†ßÙg;2ï¸ö¢€5ˆøZxÀŽÜõ˜ÇŽ£V•è;zòj²C­—ÁŽØ¡šñ”zìÐwÛì¨AØ‘}¿ª{5NKÃ;é;ò×`ªç¯q§W}7JÁ޶kÕÌ8ÝsZzÛE…åZ¿‚Ïè5‡öªþÙ¡nÊ‚`G»ìPÝhJ-/G·¯aÛ=`G‰V„G"êuv”‹¹«;ê±ev”ÌmØQb§z;/ ìhªÞ®R«WíÃi¸ßv”Ùg-xÔ ÄéWvjñª ;Ìb}?‰ºË`‡jî²;¬u¬žÐ‡c&òçìPÕÖnÑ•+G¬ªE­nSì¨ÊŽBí`gõÜŠ¡Ø;òÅÙU²U^Û뀰#ïUªŽJë<ÂŽw°£L½n³C5û;`GËììµ×5ÀØÑ';JÅ“vÔš';`Gþ\ó}(7´¨þÐ1ØñHvèâ÷WfS×»^+j;^ÃŽ’c­î˜'Ø;ZfÇ|©ùžå°#—:æÛýý;êì0oŠÕðõ×~ï7ó÷ù÷éK°#;|7~„ç(S”j|þšMËÓ×|·ÛŒ÷Ô7쀰ãW#.B6™)Š¥vÀ޳™u­_ãw.‚òXu;`GìPÉ$ #Þ>7úƒ°ãáìÐW3üQ1oJ°väÜŸ® ãœ]È­v¼‰§Ó<¯Ž1î«g;`ÇíìPª»á'ì€÷±CßEØ1Vý—Õqš°vTÛ]j¢ò6–öR™á;`GµÕ÷”Áß8©Žìg;`Ç­ìØU‡&Û| +GùÏJ°v4ÊŽI óË×òW@ùÏJ°vdÝ.£Ã£Ž%;­®S½°vT\õ;)ÕuŒow£[‚°ãv¨@ªJP‡K’L®ì€ï7¤´žŽx¿#J=¬²;ÞËŽxÈì ™âSnÌêHÉ®‡†vØ!MOŸ3?Y^çM–·°£GvDG­®w\óŒg¥šìШ S%‹d´ (‡<`Gãì(#ŽÔÐÕ=Kt…Øa¨ã!ƒõ3 / \>ß/ªrö;zdG1u$õ|4ÆM%]êÐúé" m>°ãRèª-vü‘éwì±c‘’!‰?ÛO`GkìˆÜvlÙñÇrÇ÷[Vóæ'Õ;nÚ[Ô–R èh–ÿmªŒÆ–-Ûƒ‡O`GAr$õz4ÆÓ»¶JüŸUa-Àއ°CþŽt%\‹Yݶ2pJ‡¥YoÖ ÖÿV,v´ÆŽˆW¾Þñ3òÐ5¿£ÒêŽô•ÃŽ„MƒêMéøô’{6¸èxT^xŸŒ³‚^¿CÆì½ç£ÐòW‚°£_v„üŽþaˆÎEØ;ºcGÔª‰vÌí¦µý´§Ži ÿPüØÑ,;ÒmæÅ*ܲ2gž_j;`GÅ™‘5nÈ+9òû—ç˜ÃØQ}gJDÇ×âgøbVÖœY;šuu”.ì€í±£•¾rØ;ÚcGau³‚ò;î£ ;`GýéFtÐß;šfÇñÍ¿ð;`ìhÚïPåL„°#ªN.§ åíÓ‡°£6;†À|Žà<Øáí™ck°vÔgG€×o•¹_vÀŽØá÷=ìõÖ×)ƒ¾¹åg•ÃØq;<‘+yÇ®7'0?,>«vÀŽÛØá‡‡;v}eåÌíð“G°v4ÎŽ kZM˜ÂêzîßyWÑ…°£Èή,ˆhcÂËŽL·ï€°£]vÄÌ/'B}ÅøÉõ<ì€ ³cZQV¬Ê½Á¬Ìyµ{1+Ø;ÅŽß=ÿön«îØ\Ø;z`Ç®Rî¾°vܵ&ɉ±­—úÇ?Í®2ç;`ÇM™à¡_÷¥Ð9ÁØq?;>þǹV*yN°v4àxœˆJžì€ùipªÎÝ_Ã-àoèvÀŽ÷°#a.‡Túœ;`GìøþLŠÒaKý¤»TeÇ];:d‡ÓƒnR}šUUNJ5/WÂ)ý7Þÿ°£v8=è¶#2Ç´>ßÔPxU㑦 åÑìèD>}ËÌñÏš'Õ&;$Øñbv˜YŸ‡lÔèš“8`ÇËÙq5ÈŽÙ³†°£h̨Cv,a'Ø;`ÇÆ‡ͱ£Èª$°#™‚ ²£ø ]Ø‘¨Ø;`GÀ÷€°vøûÉaìx;ŠÎž‰ÌØ;šdG ™ ;`Gïì(—·°£Êî4ÀŽþÐ;Z¹c9ì€øD=ý+IDATOªbôaìhý²cXêý_£Žûª.=æ”ÞÕÝñ˜kÚt&¡Žç•QÔñJuì-ê@¨u Ô:PÇ͹¤u ÔñŒŒê@¨u ŽÛ³ u Ôñ˜Œê@•²Iêx¤:5N†QCXÖqVzR½®›ê/=‡‡ofu ŽŽæ%ŽÏ×M«b¨Ã|c݈ù°#C;º…ì(^uÈŽÐ1ÃØ‘·þR÷;`G)Ï£Ë<„°£J¦á9ð€°#o Ög vÀŽ*uÌcàñ®ÎÂŽò5˜:Í;õq.°£}vt42 vÀŽÊìï»ß쀅+=#ïÚ=ÁŽæÙÑÑȤg±ãÎ{?ÁŽ«µŒ†ÁvÀŽœìPǹ§.8;:`G7ËÎHì€ë0u{°v¼«ƒàÂix<`GIÏ£ïüë‚E v¼­ƒàüÁØ‘±¬¾sÏ=~Ø;žäi7ÿ`ǃٱ­Åzg‡}Fêƒp°£ÑºOC‡} ^Øñ¶vúé3‚°#c]ó„…ˆ;`GÏãì0ÏA]xG°£Ý˜‹†ó,4¼°£@XzDÄÊ!†ºðŽ`GÃñúO"ãÚö¹ÿ‰ÚG¡`Gìë±ñÞß`ÇÒªWÞìh¹¯WÃz§À£ùóì胿õØzï ‡xÆÍ`츖¦ž ·…­`GÁºö1žGÛä(µ‚åà1<Å:`¡`Gì˜êÚáû1µ…ìèƒcažd°P°£v Ï"Ç÷äGu5v´ÊŽáaäáÑÕµ†ء֬™š¹ [ËgØamò¿¶L®™=©ü¹Ç;bØÑš:Zñ6¦w¥yv›:`ìHô4¾~mnüy7LŸÀØñBv˜¬øZmþCËß2Y’‘&°v4ÊŽQT˜Ú™ÖͲ´`ìhŠËø)¹¨8”‡%Ø;žÆŽÅ¹"%&IŽ>Ø;Úa‡¼ 8'*ƒ°ã!츬‰­F. È‚°£EväÇô;`G¿ì˜ªøìì0ÜØ;J«CÓ5úû?gœjn}“G_ìä3ìhÊ>Ê©œ&®ÒãNvøòv¼ŽUÄq®vÀŽ{ÙQG°vôÈŽZê쀰#¬Ø;`G6ßvÀŽ;ÙQ2Š{Ý÷€°ã6vT•Æ™^Ø;îb‡¶#¢Ò†ˆìmïý.uÌì€7±CÇ¥9·:&ÀØÑ8;0øù?þ‰âyqÔáÛjG9ñ°ãv¨cQˆïE–:œ¯Mý\ô?`ìh„s?×ü¦´UW+JöÕ;`G—~ÇÜx2…° 'BFà vÀŽ.Ùá¨lƒ 9b©Ã%É•~Ø;n`Ƕìæó;bÔ;`G»ìP`xjÌÊôU̳z;¤õu^®{üÛ};où?û¯FØ¡¸þŒ’aÇãØ1sSúŸ¥”€:òè#;îVG¬çáU‡4=}²uüdy]7·ø£Í>;J±c„Ë‘E;® =µäw|ÝkWØa•ûéýü‡ y¥ñÇûìÈÃŽÿí¨ã;êøß “B¿;œ@äÊÏÇ›|1+Ý,ŽKì°‹¾)‰é½ñÕ ™ù)B°ã¤ß1•òv¸-««bÈļßÐò§ÝT+Ôßq§<¢×i©Ã*ç‡êX¤¡O`G&vÿ#ýûuU“ñfÝ¥ùô?:žÁŽXz„ü™~G¼:þÄ«vœŒYé fµÓ²š›NËö«L™ïžéwDzAu˜îx„:–í`GavÌÍ«µÚ·Šñßá4±’Õ‘»¿#mZ‡u?‚à/cöw«ÿmùr[ vTéïOx>–ù*èwlFUðÎF~%]‹Yýù#OÌjùÛRÂÉ–ì8É;të†q÷ú;¶î·­Ó+¯ÆŽ/s ávŽÆ8nd»3$w…oë¬ã¬Bý¦:ìþŽõ{ËOEúÊeǬ¡£¿dÑÁ†v‡JAvȽÍFx¬Ô:¦Äµ»|wÀ¢3 ŇÆY1ΪáqVòLëÏä0ÛP«:¾´λŽÐÚ çe~ctû£k²Ãlù'?™ê˜¶0¦9­£·êð6­`ìèbŒ®6]nYmïÆlcÂËæwÀŽÞæù¾Žfrxüy9E²üŽ„uaì¸i^¹¬I~;39ÖÉkHj™Ça¯A"{®­'f•´¢ì€÷­…xK'9k!ÂŽÖÑUÃC¬`ìx!;¾X vt±{íE¦…ß;º¹Gmu ‰w€‚°ãÆûwÔ½E÷ï€}ÝûIÜû vÀ޽Žs%uØ;`‡Ýs>ÎôV3=°v4ÁŽZ1¬ ;`ÇýìpG_å]dzá~å°£kvbiÑuòh`ìh†‹rcœ vÀŽVÙ‘Ùýе#…°£-v8óÎ/8ç| Ø;šf‡ÙrÁÙÈp°v4Ç£$AºÐ³;`G7ìØ:!®ºÖ鸹҆°£Iv#±6=é²iXç‹/ÛÂØñvl:CFbv¼ç·*qL°v4Η#¦g²~^æzÁØÑ ;ê_/Ø;úaGíë;`쀰vÀØ;`ÇØÑš½å3ìØû­çÿ'ú¯áò÷šþ›¥åçÔ)“á?ìˆz”½¿ÚHÓÙ÷ËiÚÈSgÁŽ+u×Té_¿s4ì¸Î޹u;îe‡r]‹ävì8ÐìhÁï<~Ü™v•ÀŽ ì0=kØq+;´Ôû×ôa]Ïèë ;ü †M°CvÙÖŸÃú½`Çy¿CYX;®²Cöõ2±#Ú7‡{ú`G;~Gmh ¿#_Ì vÜÊeêôù‘‚Wû;`ÇìpÚAWëªñЦ´­`ÇN^°£2;œYrΞ¯ÙwÞý½ø¡JåvÄí)Cm®!óßkºe×°c¯nW^v@ØÑ-;”»ÆÒ<šGì8[?egGÉ:ðÑsB¾aǽìÐPžÐvôÉe¯³T¹Ä뀅ءüu–àÑ<:`Çéú)?;ð<Úò:`GSìm¡v´Ä<ØÑ;JÔó€ìx;JÔóº!;`G×ì-¡vÜUÏkÀóh¼·vÜæ#Ø;Rk=<ØÑ;ÊÔò°v<ejyØ;`Grµ<šA츭–×-|z;`GìÀñ€°vÀ޲C¥*&à;ºg‡JÅ[ˆZÁØÁ8]Ø;§ ;`ð€°#_½Å8]ØñLv¨\Ý;Zì8Yë\Ý;g;–µ‚œß¡‚uì€ݰ£è𷬧 ;Ç•¬ý`ìè‡eo¶Á<`GÏìØþ2g¾p(ØÑ5;ÜŸªl;Z숬ߥb5÷Ÿmµ·vDíGãýâ ÕW²2ÓÂ`Góìøµ‚õ•ì”F@†Û=ØI޵>WÉãôh°#Š;T´„°£#vÈ©ÍUöHAìèkŒ®UŸ—ª«f6Éöqxܵ‚ñø(\UÉÃn…ìˆ÷=Š·r5±"ÀŽŽú;Æ*½Ê[«Çw8Ï“ŠðÒ—ãác‡£ŽmËjuPlºœ ]=Áïøôyxë'¯ßӱ˭œ—È«¢bV×S9¨™[Ç9Ï#Ik3*Juû;tv† þ þ2vÁîò]v qåvS¥G{q1«,©¬Luœо‚¿<Üß©™y‘ê0¢Y–"vÔQÅïS’ÏÈC§é›ãáüå ~šwO î¥Ïô•_HE‡ì˜zHÐï8½zAyHuæ•ËšÀ´¦¼39ÖÉkHj™Ça¯A"{®­?fuÜM|P”ºÇnH%:$¶ø¾˜•;$µÎú°Ö!qç¸ «ó‹Ø–mY©8;îYC7~5ݘµ«D’ê¤ÒÔºW×#)+ޏ¨U–utïŸ{‰C­›•V¿%êÞ¯ú {::gÇÑjº1k°jôÜ’J‹ì8=«ÜÛ‹'{æ“~T.b•éþ7ÈcöF.³#{µî U'•Æà1¹$Ùüg<º1±Ðìò,÷ïÐ-GÌ܆˜š6÷­¾¥ÛRiäž+5.åN¿÷4ZĘO+wîÓü|ie«<÷~jôöwÜûiЭ©D^®nßhX9C íaºîœ§°]šÛQŽ*ØÇñOBË=‘Wo乃:©ÜÁZÆqeaätK±ã»Œ>B+äcÇ•r§ïè1³uR¹)‚•~•ª¶Ò­ì˜™5rñž¡Š>ìâž@TR¨Á{”z"; øºz¿é5FÆ1OuR©Þƒžù•}ôa½utãƒWºælä¨jÓæÑ%Œ85ä©N*§bW:ím˜È’ýöÕÖ`÷?η±”rW¼œìˆ^Õå¤'P'•´þ¸•ÛÂÞF‘£ª>«£;c-¥´õÏû—Ù1»qu-gЧrââc¼*ãl¤GÅû&ÖLñѺñµ4¯yû+Në¨]Ï—©œòAŽ×ÿ\pS–i{kïtÍŽ}ŒÈ^ÂĘ/.e˜Ž}’þÖ¾ŒÏ¦ìQ®|©Ê¹Kµ‚%]¿¥çГÙaÇZWÀ]æ1qò˼ÈÇëNQ㌊a:ÎÑ£:©¤Å¥a¼Gh•&F $õˆk²cSøþÈZ]eÇà–±o¡\©‘Ê…KeÞÀ¶úÁé’.” Ž»ØQ¯¶©ÔWÀ£ÊC—üm’»ØQ©¶©ÑÏŒÕu‡Ê»°ƒG¯×´ø]ÊaÖë% ߊ<ìoh€°ã=ìˆm`]c;°C]Wü ØÁ£ók»?y|ZÑ*cùX_YoL+ûfOyÆÀ½÷‚|0ñ½ÌÜûýò—ØuJ«÷>[7>ìàÁvÀ vÀ°v`°vð€°ƒ°ƒì€ì€<`ìÀ`ìàÁv`ì€<`ìÀ`ìà;`;`Ø;0Ø;xÀØÁØÁvÀ ƒä¡Û ‹¶[W‘ ë)uy¹î)jåèкh ñIªæ@% ª¢‡ØÑ]Éé•U4u*JZR⡊×è#5µqÁÉÛó¸F¹ÛáĨäõYZöPOí]^RdòÆ,vÐ'w¬Ö/2ÅýUVäøOïT\tTñl}\Ø¡z+åñ¹‘ó¤®íK}÷hå]'å¯ïDNì É“ez`–ö[¢^®‡L…<_æééyÛxi‚ÈZØóæ¢Þ•ËQÖYZD!Šå'—çBѦзquÊ¥EvcêÀ0Ôa¨ÃP†¡ C†:0 u`êÀ0ÔaêÀ0Ôa¨ÃP†¡ C7ž°vò`bÍÞ¯´¿Å ‹Ùá,¥&/‚^'Ežþ˜»ÉÏŒk‚:|¹’¨ª[/ê8È™“kÚ udQǽA¯»J2€=>µŒÁqmè®ßJLÆnæ­×_É¢ýõ²›mbïhÎúòlÍ”/ÂKÕaeïZÉÈ­y,BËÜLöN<µ£›y{‹:~mð"èmâØS‡“¹sm³Ñ•ã ´ܯ×4¥—e½6%]ÛFPƒáê[!­”µA;5¿47Á¶Äþ•ïÂL_×{mݽ/d5¿3þn÷"¼Jv^®žêËÓ6ÞVò¶ô²ì—ÛÐñ9Ï ^„w©Ã—×Z³/îÂ(Ð8ð4mˆ—ºîÛÑâEÐëÄá÷Í,oĺN+x…–¯ŽýÐwªCêhä"¼SK\ÏÉ «Ák5•'öî%íêmÌðõݹ™¿—)m]ÆYaêÀ0Ôa¨ÃP†¡ C†:0 u`êÀ°·ÙÿÙ¤ø’Yÿ¡IEND®B`‚nagios-2.6/html/docs/images/cgi-avail-a.png0000664000076500007650000001305107436604436020134 0ustar nagiosnagios‰PNG  IHDR–sMV átIMEÑ ‘XQ* pHYs ð ðB¬4˜PLTE !!#O !!!!!!)!!R))!Œ˜¬=Z)-)-A09=5?LAOVDQ\RZZ99Z--kMO^ai_[]jZ[ž"$¡41¹((»85unew{y³GF´dT}{{ˆ„vz–us½‰ˆ‰†„¤”„ŒÆŒ{Ÿ+½ J³*FØ#mÇJ‹·{føB†ènŽ——–”’¤œ˜ ’¡žœ  ˜«˜™Å–±—†³””¥œœ» –©š¢·žžÀŸŸÆ¥œ¹³s¥±œ¥Å˜¯Û”¥¥¥¥©©©±¥¸¬¥•—¶ ¥µª§¯§¥Ã¥µ­­±­¨±¹­­Îµ­¯­¹µÁ¥­½³­½­µ··µ»³¼¸³Ñµ½½½½µ½½½Æ½¹±Æ¹½½Æ½Æ½²Ö²Æ½Æµ½Î½½Î½½Ö½½Þ½½ç½ÆÆ½ÒÎÎ11Ð<<ÎJJÖDGä¸|é²eË–\ö}â'KW¬X±|…{…ál nÏ õu{ê÷ì¯oÜ¿§±±Æý/ÖCñEÄþ÷ïÇ4ÉŠý/N¼tçØÿÂóXƒÌP‡nh¢ho¨ŠnÐtU]EÓ !UMBÏßC„t°IDìÝ+¦.¤œÆWޝ os7€wd ­AÈ>ûÔ–½bhï³O=Õ$B¦q ~Y(T÷~gHîmÆÆU ZéƒÓ˜´­IU#–v{ùÑKþ¸Ð]+܆3 O?òˆN‹V@ki „_YW…ìvÓç›÷†B õ«ñÃM!J£Ç¸´y¾~Ò¢8í—ÌTT{Cg¬ô kœV“û¬l¢qG£ÕP[‡_EÓAü9*|shwÆ"4ú™+^§ÎÞÎ q¯®rë´ñȪIl†“Àx¼ †8–ãBâ^6°¢Àzëê8j½p',ô H'À…Ä»4¾p|‡þöGõ?pè´X†ƒ* .H!‘^/ƒµË@;£y Gy"°Ú±¬—ÅÏ@eü¦ÒŠGKôGóMV€Û Âo5’l'ÄÏœp¯À󤡮IHá ‚„BÏ­nà–a¯°·i•(63ÐU‘Ñ{…X]ÅŠ4ÅÐ EþZÿNBÏ×®‘'ðœŸzD—¯Ñº5z뜾½íV·¦)e‡[£2Ë?RÀñAH“ €æa œR8Tn?iât[~&˜ì>´u8.ê6pß+ƒÇ0)b÷ldÝŽ0¡VN’Lî-%<5¦~$"1’e9+“µÄbƒ±ØÐЈþ㣱‘ØÈ‡‡†‡bß ÒÊU­¢Éøcƒ1?×mÈÏ5˜ŒHK$¢$I­­’D$µ˜(Á»UêÈSÒ"Œ,²„¥)‘ó2Y‹+==ý=ï½×Ó÷yßΞ÷5V==ï÷õõ¿Ýr¹ïm8Ž*’FK‘ #Z‚K¶Ù1@i´ì·Ëíq»9f\‡‡Â2%MG+Ž(ˆaŠaða___Oÿwß}‡RÓžàhV ÝIÔ„EVØþ•»(¸¥œd£ÃùH+H‚,‡:Àƒ­Ç —PïÌ`àÈá¡‘ 0®F½2*“pÊØÒiy–{ŒV³‘æ\fƒÅ”k5kÒb@»Q´‡á|še¼MsçeÅÌ„V8<4ÈÆÕ\QGwe"-ƒÉdúO©O¢È !é^ãîVHZ¥48ôŸýSëבqÀvñMTŒÄi•šMÅÅÅ&S©)‰-/ ¶ Ã{½œŠ´× o¯7-­‘¯F¦¾ØßóvOÿ®¾Ë-;ûÞWZzÞ†ÁÞÓ‡zú´l.7¨T»Ë>¦',@ \6à rëå[á‘LBJGkZÜ',MZZ6)±D'.±ÙÁ—(p˜ÇÓ pA ¡lE]ÑÝ-IxÜNK¢ÃD§MâÑK("Øhp€§‰Ä²A ´ÆX[Q–%Ký´Êã=Õ‰c«¤¨HëÄ䣴(†òýŒñ20ò}>Å0”¼»'yE lI€W8Ü+‹P#†¡R)E±Ê$óŽ£¥hú-:VžÝ /[îxãóuKKË®]-;áhÆdgË®›4Þ’dF¬·7Ü TÏL¦º@Ë}x%µ&EÄ&Ð2ÌŸ_PRlÊ™@Kܹuë3ø†óŽ; ™–n­§¦UUøEÕ¾H¬Å•¯¾úߟOýXh´ríV›Åb±Áø²Ù-Ö1Z¾­[«wù~ÎQâÈ€V šB»ÕbÑœwZZõµõ û*S±Éµò¡ºCçÁƒ;;ÿ¹¯G‚§BIA&´ŠÐs0æX’¾i âÛëׯ^¿zõêu8_½þ?ÿ;¾²óСC퇾Žé¡6Hú{ÄáÏzÃ,u$--⫵ÐbÉ͔օsçÎZ##Ðj;xèÐÁNô^G>z>Në?H«(Š==àGô ¤9=­yãÄ”­ÆÚÚ5µ[R:q£Þ‰Îx'–ubGGÇËm§áY¥(¢EÏ[¥ÖŒļ%…Ú²kN~†´~½§qÏsO§ùMo­=Õõê«ÇÐ=Cóèš?ñÚk¯¿Ñõ›Þy@·€›ž–u‰psPÙhù?_º[ã/kîÖHÚ›ÝNœmè´þò‡ ^9sˆ¨S.``„+3-o¤5ÿ¾<£±ØT¼ °07kZa%ªDÕÁX4&)è(hžN!¢I†K²•ŠÍÂÐiåÚÑ qÙlxŽ›LoAQô*‡bD¢Y7d<à^ M ^ÊÃPEÓnÆå¡=<“iÔF—V^An© L¦ÒüâÂÂLi%×£ÃÐXÍ ]vhµ•–Z-¸Uj…¤X_ó™òC2n¹ ¡3~} V Ð[‰A‚Á±íYÐDÄ øAàõ-[‚œŽ–ËÊ0»éØ*7å2¤Yó‘"ú0ÒŒîñ5,€ûÅù ÑÖ‘…f”¹fââæ§fÒìÇ‹(ašžîz³X\¸¨ˆ9\!›ŽV8H4‘ûÕñ7˜<ñÛ5œÆä—ÉÜéÓ§ñøep·ô´æ•,,ÅeÌ3d¢·®ûõÅ ¤üvSeå† ÉéþZœí·i3ü•ÇÆfþm0Û?ØÖõ¯’Ü+ɉÀBMG˺ÄårÙ¬v‡ÛeÉ€ÖŪÚúÚÝ”O+ÑNÀ`¯[¿aeù¢²Š—U,*[| óÎÅ‹*w¼üÊ+/wœ¨æ–å.|‚qéh¥Xœ|c&Òzçܹw>ˆD~·ùáT¾uâäÑ£¿8¢á“'ÅÌÑ_èxó³HDќӤ‡ÍœVF6Qi|þ…Æ$í7p=:[ë7®_¿±råCNçKœœNgÛaÈ€|…ó@;¸6íÇ·ÃSÈIwj4„ï2­³àm­ÖhMèIJРg™³¬¢¬­3™_¬Ózõ1†¥&u w·i]{pñÂ…OÇuâæ·ŽŸ8yäÈÉÐ'ß8¡Gâø›ÛvÌe1¶2¢uqÿ»{Þ=·ÿÜßUj½Çtb¹» ÄÔ~ä¤ç_êxÐqâ4 ‰¼¤ö>ÂãnÓºP«cËæu×ëìôN|©Ì d-gÅKs.ŽÓÚNDPõzôtvhý÷Å?üá"`’NÝ´¡rk-©\«Yærí8–´Ôåmmíímm]¿µŽK‘Öݦ•æ€Ü°>'ÔpóæÍ7†o ߌÇå³ ÌψV f²]~iÝeü¿¥LÆà‰OD­´ô˜Ó¾B‹GßcZªÛë¥(–VÉA7Ì i/Ç0^•gX/çõÐÍÓ´—bÜM¸ìæ‰3“VDpj$²7ÏSDµX<Ì©U5¢âζÔ_S"Q5ªd5«ÎžV´·W ÷¦ÄäÏÈòX)œÈ÷joTW©¶°·wžܻFK%~³Àb Þ'ð8Iä‡1y–p‚'Œ~‡Ë<§/š‹~,øá"\ÎÏ-ŽçŸŽGå·haù-[««kj¶Uo«Ù¶ítMu"D êÛkjvúX\=÷¥ü5e6hÅ>þ"òûÔôÍO®Õ—Ë1}óº´•s UbTþÕ®¹ÿe0U¿þz0u =¦üñZ4:8¨UL¸Í7ƪKΈ$ô\Ó™Ô?!KÂø?çÎ$YÛüÖ/ÉòœEkß,ã^8´ôœa·Ç¨ZÝ@RiÑEy(p”(jiõ’finá86ô4àµÅf‹›ú§ýŸ4€ûÐxþ^þ‘”g†ò0 í¡jH À°Œçÿ(GjM@Gñ IEND®B`‚nagios-2.6/html/docs/images/cgi-avail-b.png0000664000076500007650000001351107436604436020136 0ustar nagiosnagios‰PNG  IHDR–sMV átIMEÑ  ü…µÁ pHYs ð ðB¬4˜PLTE !RZ Z #  !!!)!!!)))%!!Z!!c335/"]!'Ÿ?B<=O=@KGBHaš´'(¡QÀRT\P\^p£TRÏPGnza}~€À†½U~~Œ…ŽŒŽŽ¥’Šdd¦kkÁ…ƒ¢€€½”™œœ””™¢™˜µ¢Ÿ™ ¥¥­–™»ž™¥”­¹œ¥¥œ­¥œ½,¹E½&AÚQÝ-aå4‰Æ"lãNÒ[¦«–ª§­ ·—¢Ó•¥¦¸µ©­©­½«½·À¾ÇÈ!ÄÊcÅ¿Ÿµ­µÁ­®¹µµ»Ó²µ¹½½µ½Æ¹¹Ò··½½½Ê½½¿Æ»Å뺠¥Ê©©Îµ´Ê²±Ù½½Æ½½Î½µÖ½·ÞÖ½½½ÆÆÆµÆÆ½ÆÆÆÆÖ½ÆÃ½Ø½½ç½ÈÐÆÆÎÆÊÒÑÇÉÎÆÖÆÆâÎÆçÆÆïÊÖÆÆÖÎÎóÁÎÿÆÎÎÎÎÞÎÎÒÒÎÑáé”ò—÷œÿœÞƒ,ë”*â˜1õš"á«(ó¡-ÿ«"ÿ­1ë£<÷­Bÿ¤;ÿµ1áRSâ``ó]_ÿccìt\ð¡Pï­Nù­Lçckëgkïkk÷gkÞsséoqéŽ~ï©©æÉ+ÞÞ%÷µ=üËBâã*Þã:òð.ïì?ÿÿÿÿÿÿ!ÿÿ)÷û9ÿù3÷÷Bûÿ=óµJûµNáãNùæGðøMÿ÷BÿûFÿÿJôëXûÿRæÿ`ûÿZÞÊ{ëûkÞÜ†éµ²ÞÆÆÞÐÐÖÖÖÞÖÖù¿½ùÌÎçÖÎóÖÖÖÖÞÞÖÞÖçÎÖäØÞÞÖÞÞÞçÞÖïçÆÖÖçÞÞçÖÖïÖÞïÞÖïÞÞïÖÖ÷ÚÖûÞÞ÷çÞÞçÞçëâÞ÷ÞÞçÞ÷ÞÞÿçÞÿÖïÖÞïÖÞïÞççççïçïççïïçççïâëóÞçÿççûïç÷ïïïïï÷ï÷ïï÷÷ïÿç÷çç÷çï÷ïï÷ï÷÷÷ï÷÷÷÷÷ÿ÷ÿç÷ÿïÿïïÿ÷÷ÿ÷ÿÿÿïÿÿ÷ÿÿÿ'‘½wÜIDATxÚÍ[}pešŸ#Fr3»J&5'SŒÃ‡3ÉLv¶£±{¦; I€f‘Nb'ÌWÈî¥ ›dcíyí Šxž«Q7w ¥¢{RŸ·§i` «ã…(–,Uþ3‹[u•º[‹ÚXwñàžç힯 “‰¬¿é~ûížNÏ/ÏóôóþÞ÷í64TVÞ ¸çž{HñƽAŸßçó{ žÊù÷:×íwÜ{÷ÝówÏÿáí€Ûn'åmZy›¾«n#û©e¸ýö䥠úÃù¥ÓW9ß@ÍÜ=þw`e¾*9üÍ|§Ó‰«¡ÇïßÔU]Ž„"‘ŽP¨#‚ ì„:6C‘ŽÍ: ’¬ëG’:6Oüjúèèj'XbPhŠz(¡ÙCy£^Jð{)/,”·!êöxá”hûMDTk%D[›”ø"c“}0ûh4ûœ™^‘5t ÈjÕ*Ø—ÚÖ¬!_„*ñÇ¢a_3ªô¶áÉ`?Ü‹µ&^b‰—œ³ÁËçE/õÏE»!²œnC7ÒZóci­á8Ö|Îôû*‘]3¥´µE£ üãæ¨‡Ðcœ"œÓÞÆs$‘âÈ’¿­~f÷:í@KÄ=e3Å“¯üi5x—àOQ”€ÿŽßë†_Ž6óbÊ©õjÔ¹™qfôgѺµDš˜©YûF ½~Ž—¢·iq<Ïsïõúý<õrø,  ã幨4ƒñýé~ðW·8‰µD–FZýrT?ͱèZž£€ìpg‰‡öåX–Å¿ƒúåiò …vë`½Ùp$°@´YSç ú–Gø« L<˜ô´œ 4pÍ|WHb4ö4p4KÓ4ÃKÍn ŽáWnâïñz% @SÅ -!ÚîóDE$Í ‚ÄÓº¥­ËW._&›‰¸|½ÜpùŠÂr^?KäE±YàkàÝ@Òƒ¡¢¦õ wc°WU¦øs/› ÊÀAörQW!ãøü~s:  nä»i‘u5T‘BZ)2…iZqõÚ¸ÞÝ Kª*Ç”¸¨Nþý¥qÀØØÅ±±K—Ƶ~tl|l|vÇ/_ûö O!­Â„]2›Š &c¡Û`,2˜HKeYq‘DÈIb'ìâÚ*Ëm±ëÒâY9êö>ßÛ;Ø;8ØÛ{á¡–ÞA ô¶¶žìmý ·÷╸LhÅcq-ÙTÁ¥ØÅ£-‡ÛMÃêtcÓI¹ÎNdÖz}Z7ÂÉ^Àà·ß~‹V»¬Ó\º<ž<¢J„–êøÆ.ˆ)à–œl§T#ÒÄ€(ŠÈž‚Ȉ"lj-×mn@ëºéBQ/‹¬#‰óW”LŸë´Ü·Én5Q¼Ëj°–Ú-ÄZ4fÊMs,O± ©ÎKó°ÀÁ|¬¥ª—.r|Ö‘óÆEîüDZs±ù`b1gÞ‰I~ƒ  ÏuFÿ°¡3º!Ú)+×ÿåK½½×6Øxð<Ý¡Éã:-‹ÕL`1'QR ´ŠaxŠ R+#ÝOQ÷ßOÝ¿äþ%7¤5þõøµ¿ìmÅoêý¤¥ ¶pæ…–‡êm…ðÂ/z“´ì.·àr¤ó„ ­Ù—g(Y¾SîLC–óqâå,ck‘jÊbI'ZÐF§5MËJhAàÂ’Úä$&Ò’)U”A´É-Ñ"%Ê*ÏŽ 1j,+P"a^IQä—ù× ¯™‘ 5Zsçk¾+Ny±hqÛè ÃPn–—R|k«–»&ÒŠC UeY‰ÃWðQUE!G$Ž@)ÇÓç*bbŒÉ¢±@ëÇ»Ã^”ÝøüYjiijjij[’[ÄÖÎI­•a7¬1¦(ªT»'˨˜ËOžÏ<26Š›@Ë0g¶©Äl.˜HK\¼¸ (M¦û°ÒÒzZ£‰üBÕðÙ¹sŸžùì,°º&IQl1YLfè+šÌŶéõªc‚(ó2“$TX"ô›IŠC¡f´*¹Ð*k™ etئßÙKnÆ2ö²¾ÊÝZ%³µ¸Ø\búžŒAè±-¢ÍârØ‹¿G´àN¡eicÿ~Ykn‰Ëìjìež>­Qì%¢Žb—a4÷KdZë¯MŶ"« >V›#ZŒ›÷œq3 è(7û9ŠqÓ¬4mZ35ì6OÄGÕ„ª&bPÃ%þUfúò«¦ ¬sM……°XŠ ÍÅ…Æ¢©ÓR2¡N¡®Lé²IZ'¤yT§.®)Óº¼ ÀÐ:ÄϱzpÐ)çY°yÜãyêÜ”âM£5w® •ƒ©Àj(Êɉÿƒ´VýXÇ2NÒâp¤šgX`'qèÇàXm´î¼Óår»\. hØØ¦Nku}«7þbrÇ}<='fEz¡)ký©v^Ͳ¥–­X½ŠaÝò¼›•HQ ˆ1 Øâp¨GΖqVáôîÄ?Õ×._¾ ÅòúÕ« ŒDˆ"Ù+¬ã8JgL›âǩӂtꀙ« gZÿWñ£ üÇÇq5~l6p8,ã9XkέF“©¸$wk—.Z´`Á¢²»îº«¬¬ôý‘W0Ž \pÚHÔª²,’c¸›‹µîtÙ ÿœÎ…ÍxéÂ… ,,#(}?¿Îƒê€$òGh©ª(êr±Öœb‹Ål)1[r¤õ¿{v#þ±{χf8.‘éÄ äb-VÔ56»9gk-,ká¦ôý&¬ÕÖ‰cMŠq/hctЉV”;s yÃì9V‹ÉducË•¸páp$lK›(šâ(Ч( Â1Ki­8oLéõhÝê¸ô²Ãj·[m–ÜhUìI£âÃÁŒtK×ãÓL§`-+è@޽åFëô)øœ:ýáà ªÈqXâJ<#»ÀhÊá4™µ¬F‹l5+gaÓRU宨¨ªª¢Ÿ<ÙÊH<ÎòÓˆCdñ"-ܹ%v[±ÕV˜3­D&¾Ê¨fÔ§KkV–™r£uñâhââW½x©ü1Ipt4MnT«À€)IA]oMdÚµÀ˜+-ðöÒ§7pŽY¤y<¨@ÜÐÚ°´Â0vl~ £ÂÇaý~Ð2 qt '…-F³É”;-7/2E$J¢Ôn)0ä@e±¬(q’ЖÓåôIa‡ÅbÇY(m£ÏùärI¥NgŠª$É *dyL•)¡Hñ䈩%†lZ.;ø+)öË(ì½âœÏÄs³šTër>1 F³wÿ¸>®A 'm !­âÄ¢>çs•EðÙ)–…N4ö£ŽY¹’e˜•«†fV`v+Yv%9•… 9„YJHõ¸‘°/K,ÇiWä'§5kîœbH\¦"ƒézY^ ø¨ƒ éU éQ3Z§z%ÁºŠuëÖávÝ}÷¬ƒeÝ}MPkÒŠ¦ÅM<Ë.À "Ðp ZØ«vÁ­èt»lצ5”©æ~ñèê,ü{þ-¯£×^CšPü¶W™ˆk81 £ñÚ´ºªÃ¡" Îœ‰?úHí¼eóæ-«7—ºúÊ×66®m,ol¶}ûÓeè¾…º_¯Àç=¤N9¼iá קѪ]šFݾ}{À{‘V¦·n}º W¦9±ôýÅ òyIîœ!ZÿùÅ_~1òå—_Žœ;w¯ 'ëz÷À¯ßE@'þÓsI'öï~å•Wúw÷¿Bœ?=íßÿ>‘Zó¢Õ ùú"Á`_( ÿt#qb 8±†8qí"âB(ßzKsb9:qÑcoàÄ*>À3±tÀOr'æBk8‰ttD"›ñ]žGê—kÃZË—ÃZwüà¾ýû÷ÜwðÐÐúÕ“€¸nÛþÌ3ÿðBYÙÎ8z²³l×®Ó¨Ššu#æGkKW`S__¬=ë5RúÛÁãû¯ƒûßHÓBbÏ ­]:¯;wî:ÕDž3Wz“˜äµœBÞëõVú«+½a¯¯Ò»ºvÞRðá'–_íÄ­[Ÿ¸+Ée¯WÐ,K‰òL݉[Âáöp{;–áðšõ©_ž ùo@ÄÞûöÛ‡µßëÓò/`È?¿BþyùŸˆQaÑÖüòÖð–‘‘>\ùh#$ˆš¥8ž»LO{!E4 ¼¥'ˆ'IŠØ®%l"i¢ôt °ÔšŸµ|Õ¾Ma_ug­?z$É5èD’NËË1o­ÍpbV:]€y‹ç%VIRÊ;äGúú6cÐ÷m† æ­ìÆçıc‡ ñ9±?Ùø¼xï¹Tã³» tâ‡ñ‰È‹VצyØ_åjoƒ,¿¬ÚêššZXêê÷­m õ@²©Öœ¸›j=Ã/$!_Ń윱,®Ä§<¾ÊJOå  "Bw"ˆÒ( ‚@'–—7j bú"–Þ0cw"*Ãè –g8ñø‰#‡¿{䨱#ZãóÒK/=÷šûû±õéŸ\Aä›N»ÚÃ]]]á¾®ž!Mo'¢ÑZ ¸Ð\äNc¡‚(O+Mt¡ ”D‘Wg,¶z|ÞpØç ƒ+}=IX“¦5@œ¸wm2A )pâV¤•–¥(e1¦Î­s#Ÿ>+”ÃCĉ$“êNÒR ìoZ¿*ß¶íÉ'±(ß¾};Ê@ ;ású'ø(ìÌ%ˆ-]÷õ=ÜbpË–ŸÿÝÆú´®xüÐÞ7¼»ð:ñ©‚O?Kdà®»žß¹ ?{N=(K²|ý^unw"†|,>”i-?¯®®.%'ubf‡lfe`WHk¦ÉÚ°~Bãsüè¡CûŽt=˜H’ê4^Sž•Œs<°á‘–––GZ¨w<÷Ö±cÏïÜÞyþxç[oïì<Þy|ûñ÷;·o?ç:þ4(ä¥>DÞP—×zÁç ùø ßëó‘gWÈçÝ "ÇÆË“2*OŸN®!U™<&ß8ù1²—’%tBÖÓs;âYL!ÙØHª‚º`òæ,)ôˆ§)$Ÿ;÷Ô+äйWöž€¿u¬…€Ÿêì$' ©„ÊS]¯Ö½Fêö°Àyºk{lE|¬_Ê›`1² ¤hÿѽ÷¶P¬§ì…ªsÏ?v…Nïø¸:uüir4ß>x6º6ú .x¬Åu{èV =ýú›äˆ—ųéÖÆÍ¿mi·dùÀïRµŸ´¥ôí> §Ã~?¤~$ÁÁ ×„-ÉO¨$yŸDÚÓ×uŠ`ýÁÙƒ …6®{è!‚ ƒôÚ øˆXw T,㆓ ¬Ûeá †kwËd…¨„œáž%5A¶íŽñĸÖÜyç-:Ö‘+aß/í—p 8è÷û!c¨ß¿?€õZìÇøTùõƒ³Ô~ >èÀ‰I¼w/æ©Ázf¯ !,!I>ÁÊÈÑFr(Íûòæm0B "æÀ#Y$!ܱ1$ð¼ÈòXÞË^±€¼òµjÄ÷ò“{}!„y¼ñ^‚…nÛÖ^1U^ïM´KÆÞëõÆNLJ,…Z[[!MI€Hôê y—7™Û‹Eñ¦5ùiºxªšB¹lÂ)$,3e2hÌ“X£Ó+GXµZ=6×Z,Uå´¹Ür{­°¢'§grÀ%SmTÕ°*Û  8qŸ)­Š“`qñB»(r,˳œ§a;<¼Q"JްjEæˆÀ¡V´Ù°ÜìÁÕÅ!Q€Ñ º†^€ ‹(Jn°Ú©ªV§Íb1;Y·™2›©òÛ‰[ˆc¸g·¸‰…1°éáãñ¹œ#¬)Ô•%‚¤`ñ(òÊ™[ÖæPuSU\ͺ[`Âoø|ߨ½ûÝ'hppPÉíj{öYšÞ’ðªÜ’bI E‚»c ækùÂ%`Öâš„[+‰["ãö ìæ8)£B–+¬âÆùKÊÊ,©£|TFb@ÜØØÓسgO +:\nˆ¢…‹lk¬M©!ÿÍÀ¡^¢]»z{»õíêíÛyölØpìVbM|seÂÀ*n\´¤¬¢ª¼²¦¼®¼*æÖ7ݽ/ö¼Ø½«wgwoïÎ?vï<ÔÛmØuK±þár}sëž%«š¬ÍMkš¬M+›xçÐ@8ðN`àðÑÃï œÀ’r«±&\?¶ž0B¾æ‡U•ÕU••Õ• òµ€%aß1â9ìAHà…äÖcýá'¶‘k–MtÒ›´ÃÙæªL Êôº¥±õUôZ k•µ¹Ù¶ÂZWg¥«¡K–•¯ÉƒùV[Ñüù%ær³©¬Úl2—™‰2ÆšH)_½JRx\Í«½xõ2›Ýµ†®w9 %i·9³Ù騯ÆÇÆA—ÇÇ¿øb|ìË+ŸC~yìËËÃs| öŽ]ž˜ùGêXEóïøLO-U‘ŤùÊGúøÌG}ünOß»}=Ÿõ}Þ×ßßÿçž¾Ïúú?ëïí9s¦ÿã3gúv]ÉÔ­ÆF»ËÕQïpÑŽÄp:óO˜¸Óx"IÒøx¢.S·ÌÕÝ*œâì—$”&H[]™˜ˆ5ÙÕ ]„üœÆÆ‡Á­Z;ít8c†ÝkÄÈFG®E£3?Ócï†÷Œ^û–A†¸µh^i‘‰*µPE3Z +¬{‹Ð.H"Ó}Ï ©¢úá çÁ +±¬±ß‚u[Cƒ¦7U;u¹2ˆ­‘™{•á;‰[KçW[Ì¥ee$º,in g,h hVwH¢)XËîs:Û[›lS4bÒE'’~Š\a"ÓÄ‘ø£izöo¢ò§ñ°6¬ O–õ4kβóKË-Õ5%%Ó`E& "ÆÌ9>YUŒitª’°´ÉsNBĉb;µ8Y*VÑ¢e«`|_âpÚ§s+’jˆÎQnˆ%!¬H8€„Ž(ú½3I"BH  # 6e8#ÃlC)«­¸aQEUmUeEYm]|‰(Æš,œH®C‹XšªhÊ'ªªÀcª‡”!2•l ©²¬ ɰöÊš"ÁêO‘•4·.«Y\ßä°;êlΕéX‘ðÛgÃ1½¯³ïAjÔÀBrʉO¬eŒdâ…ˆd‘xDZ,r³,nw³‚„°üÀI„a&'¥7bÒp5E#êééÛÙÛÓ÷ÒK=ýÝ==/õôBÚ×ݳóíAQ»¾oÇÜÒ4üQAÏt¯Ý6E"Ó\U#Þé(d·–[ +ŠÉ=¤òrª´ô:¬p¸ïÌ»g õý¥.¼zñ,¼ÂƒÊèè×ccÆí¥±¯\3°`ù+ ’Ä!$‚SÈë$ɬ‰e^–x™eADŠÈ’ÀÃXà1RS°Š6§ƒ®Ya§­´‹N‹­pBgÃ)z/¬‡YÚ0ŽÅ–j81D¢IÕd²9$iCCЦª`$T’xÓ7Á9iin-]ð}‹Éd)Y\\j2™¦·¦µô›ItFOÄÁ,Œ`1ÀЇŽtGÌK¸v‘›AƒXU†*qRÖòU´}“£¹©ÙawºèÚÔ‹r#E¦¬Œ¹΀4M²!x‚9à>›4M(Ø RPÓC~2æ‹J¨»e„¯>@ÿ›ªÆû¥áÏsÐ9™ãDÙƒX ÈÐ-y°‹ÅH¡F+/‹nqNÓˆys«dšžxC¬OÈ1, ÍÃxX„böÅz¢j85©ôíë”ò«—-w:;š²À‚‡çȉœJ±!—`iIו4i)Yr!Õ­ùóЍrª¤¢4c¬Dˆ%†R!SÄ,4œêVãj—ËIÃò•Î+}˜È~–âÖæ•RfK¥©¨,S¬HJ/Î V뜆Õ§³Î᦭ö뱌n>4ýid±¼fáf€>±YPj©).ª¤Š-×cýD¦ ¿´“5$y„U´lîm¦²ª S†_E 1Dez…|”ÔEGÉ"a£0E&Âm†K8rkdéÒUtm½µ6C,«ÝÌ0ëfdÌ*³(A!_ÈðVfŽ4$0lÃÈ ñ¬›eØ¡™ºE%Ö;™a¥JÑW¥#Ã#qgFt£®Á+ó®©§¥Æ•Çt3XÈ—!$ÈsÈÉE‰WXqÙŒúpºü>ÝJ;\õ™c EÕh4J–ýQm”1wt-šú!É%Àu’  MIßÛ;YgcŠ©ð=év÷í¾ÛýÝÛ·oÿœdÛßùäƒH?ŒÁƒ?ò(Ò½:ºZ¹«¤GÚ·{ÏîݯwØ::¿ÿó«W¯¾{Å“­€Äýß¹ë®ïÞÅÈŒò4†½Bö5ÑÝßûû«]«6u<`ë|à¾{—¯^±üžåËW,_¾÷Ü_¸X\ˆ0ÏdMºß’¾NtïÊ•+Xµj¥í½»ÿúîk›ß=°ïÄ Þ·ïwðÙwêÀ¾ßþãô)ƒNÃçÔéÓf:Ÿyz¤hTþ5ÓéSïž`´Ãö>‰ìèèJïïìÓáD:±)±©+–èÚ”;;÷R'Ò'ÆÒå9׃Ò&%lŠ$—Yø6‹° åÉä,™iCÄ*4yJÿˆ0Xo¿ýâ¯Ññ?ý±5üz4•>±g÷ lrXÎ@æž=‡0÷ƒ03ÛÛ‹’»º¡ ÄÄɃcªIŸô­e°Ž¿ôøÏ¬_bêxíÞ´œI¼Ñ@ä8Q0wOÇTÏ¡Î.ÈÌÆš{±’:P_Ü6¦ßI¢ÂÇ>yßó+ï[k{;ñØúXðÖS«}3ÓÖ€øKŒÄ˜"éC›;÷ »wS/D™m!Š’ûw‹Ø©D¼.OxríÚŽC[”ê)Ì~ ÒŠL"]ÏÆ@†K`cR,ãe9œØ´c‰‹!žï s‰˜¡¢t¾âk”6Mùä×fÞrK‹M¡Gä7w ; "Ø$DÐÈ€( .(& ÉÒ^ ™C)€Œ$ŠD–†Ù°‘&¡§cÇ̶‡ZZZ‚!Ж¢¼ó&•“d EÁ>Êdòr –£à7“ͧ™†×)#Sz¬s`o[A ²"¬ô¡7V¥I„ GÂ\¿ü ²ÜÃñ<ý¢ht)òë§ŸŽÉ$Ìq„ÛÐŽÈÄ& {÷oîÜ›)¥x½¸‘%DA/Ðg@úøÄŠðc0Ö‚±‚ò*{õùí£™ð6!±H‚Þ`Ú»wËÛ"uuu^ÿX H7”[È6UϲÆ#aym§+g±ƒO?Í'ŒèóbÀª¸Ô®;Zƒå­AW¨¢ÙãZçAXgå :æ,LÊâwxxXÑ‹«\U>¯ +>‰~S&½¶ ¬3Ñp¨u]hC(ZÇ™„°þUmIušW\‚â§~‘÷ña„¥Jý%™a˜œ 3q¶(Úªhmi)·ÙfñÄa1yU. s”ôpÝ$²ç¶EF¶‰aŽE[ãDU”¨Dûá¢TꕲF:‚Rmù‚n8/·Ï‘'Ó!„ò<á¡+ ‘·uumûE׳;b¶8&X#p…›8ÿˆ®¼‹"t“ƒˆI0b¿Ù"ÁºóÎZ Gk´¶öwKƒƒƒ)*IG2ÙŒ’É(ÃÆˆ,J'–ÍŸ]=ýÖò±¶uFþÉÖçžxî‰-[·FÃ=ÏtGŸ‹öd2†£( ¬yó–—.ƒ•ùýáWŽ>:xèðàQüìú§RDX³«Ë¦M+ŸV^YYY>­k×áWïb¤]8zxW¦ˆ°æÏ÷ËšAcíþ 'KŠnݺu×–íOôlÙÞ½eûög¶nÆ ã׊Ëf¯¶;ì&&ïB“WŽ fäÌ xu¸3ýƒC˜€É§8Ú²y¸€×ôy}&ÁAäô‰©(+ˆúÖ` ýXl,Àº¡„°œÕù.´Ï)tâ†5}é¼:OCS}ƒû xš¼“Yæ$ýóK_$ÿýŸÜ¥Ïr“ÓÖŒ¯Î©sÕÕ;í5µ5Η{R‹f¹}C»Æqa>ܺîÚ,ÓÖ7–º½îªen¯vÒkùK@Fˆñµ’„ÚšQßPçq¸këÌš:[ŒéKç/©k¨­ ¸ÝuÞZ·}ŠÀmÍ÷Ö/p4Ô»íÞz·Óºó 7Æå.ê/æÓ…¤EðâX±Â}óå£kÍ™7ŒÑ‰`[ß®]P[¨©¯_àªÉâùx<ÎóýAl¡I‚§5$ ë°”$˜iðD°„Ä—L¦ºw»“e ñxjgÒ",¤°(ŽPiæuÃ…<1´U6cÆÂ&wƒÓÝàq»½5~– "Ý+ÙÃj7ˆ@4™ìŠ'RRr$Í“”Ð÷›—ó\2…Q²"ôd?áSB²…‰LR„·'YšçSXgòe,£Ô„5ýók<®ŠF‡ÇiYØH)=õƒ$4$“‹tÓ¡ ã©d\x&.lDuÆ¡¥î8(‹gªM‚6»A,¯ëxC9ÙÈÊQXèîîÆ2ÂÇi’ŒCÞ´­;f,ô-ð:\ ÕXÔЧâ‚¡ú> YÛJöa2ï.%¥£ÃñaRo¥ãb1¸lˆö y„û™0{û¡³N’‡5}ɼ…ÎzgE«ÛUn¥šÛÕ³Êh:gI.S'dŒû†-ÜûÖòásÖ"Å´­;îhô549ýMÁ*+,9F¡3°oU²2,—]¿&ažëa B•íh³Æ9 ¢Žå¬jÆFÈd <;C(«ìL0_fŒÄ›ývŸ«ÁYç¨ ¸·Žt"ÇK¬i¦XžpîGvŽR¶4<,sÑ0:B" ŠÈq<ÜÁè ܉„ ãÂ2î™àa¢°ŽBÈgò#¼ÄqÀ<"á(×ÓSV„Ïkköì9Þ Ÿ¯ÁWë÷-³íDC½xzÊžšðìÙi„ЏQc‡ª±e3önæíüf-½Š{:&œ9ØÈ*g ®ÌpwVÙ|'ÚÊÊÆÛUç4æÜ´±ËAä5]I3vicxÝ*«_¹ÌÔVÍm•€Ãfƒyºªr–"J¡Å„,IòeUhº( ”€e@(ëŠ$R‘ª‚¢ËÀY•0ÒŒzÈ—eJI×%‚µ*²‹JŽ@¢,cDMX勿Û‚Á Çç ®i¶7°à¡?Ñ.œ¿ZÓ4up႞»p!g\çY¬kg ÿ jÌ'éÚ'ª¦B‘ÉiªvÖÕ!ÿ¼j•ÕtUgÂÔ£êŸ@ÎY-gjkîìJô Ó¶iÖ‘È ˜¸L%µ…/$Y³ ekúJBývt=&¬E‹×··77·º›Ö¬ÿñú ³Ìɇ^v?`²£¾‚ bœ Ž2ã|KÙ‰Q"ߘrð&JaŒgò•#"7©æ&4ÕÜ„Ìåç¿DØ„uóMeãŒDsLi9,,„1XE„‚ “56 Lºœ*B"ŒœÀrA%°>àÑä úä"*Þ'P̵"謅yÌÌ©*¨OSéùe༅>À?–Ba½‹¦/è@Q"’ñdà¯ác8Lå­M7úE3òt£«4ý»v™lA‹ #f^[3nž^]e·£­q;Q’¨bxôø‚††¢¢+YUÄHÕ%Ì•—c;:cy£"–œ•˜‡Ízä[÷䬜>" õûÏ1£ÈÔÖôYvOm¥Ó9Ö ßUG7VÙâ9Õv§£¬kJÁš;·Þçkòú›S ÖkùkîmÆ ¾¢¼b Á*_ü-_Àß¶!èok«˜:°ÊfϨ´åýh…™š°/jló7ÛÚÖø›Ýmí®©ËvÛlóÅÊÈë•YS–á îO­{I}-&M‰·Á%E›šßè÷7·­oöNXsñåŠÃmô"{¹â™°Ê—Ì÷9\Un‡ËW[>u„­zŽ×Ûè¬õz½Á)ôº`Š® J°J°J°J°J°J°J°J°J°J°J°J°J°J°J°J°J°J°®V¸¼|æÌ™åchÖ…%ÙÞOIÿíÐ;i|Ï<<|ü8þÖŽ½Š—èÿE²¢~ôñ¹Õ€Þûè#UQÏ}üñ‡ø[°ÙŸî¬ÿˆ‡ùІ…'ó§ä+‘:œJ‘ÔP*‘Hˆ{D™&¨,í$øËb8ÿ3ÍÿCÍ.“ ©ëHø³ZÖÊÆ(âx>Šñ¡XŒ !$ô_îŒûÿ‚ÃIEND®B`‚nagios-2.6/html/docs/images/cgi-extinfo-a.png0000664000076500007650000001232307436604452020513 0ustar nagiosnagios‰PNG  IHDR–sMV átIMEÑ 0#uå pHYs ð ðB¬4˜PLTE!!!'1!!!!!!)!))!!1!!=%„))))1)11)RZ Z!!^))c)9)361+?11J1999;H99ZB7;^BJ=JGRG[GOZRZZRWdVce`“WNRWkNN‰hcuwkmhhªok¹kkÆkkÎluv}zzU»>}¡vx{ˆ„ˆ„†’„œ‘”„”Œ”Œ«†„”””¤”””œ’˜Ðˆ‰ŠŸ–”¢œ” œœœœœ¥¥™Ÿ­œœµœœ”¥œœ¥ ¥¥œ¥¥¥¥­œ”µ¥œµ¥­ïœvy³‰‰²”˜­””¹™™² œ­œ µŸœ½¥¥­©©¥µœ¥¯§§¥¥µ±¥±¥¥½©¥Å­­­µ­­¥­µ­­µ§­Àµ­µ±­Á­­Î¦µ«±µ±­­Öµ­Ò­½±­Ð©µ¹µ²¸É¿‹‹½ ¥Æ¥¥½¥­½­±½µµÆ­­Ò±­½½µÆ­µÆµµÆ½µçµµ½µ½ïµ½½µÆµÎµµÖ¥½½½½½Æ½Æ½½ÆÆ½Öµ½Ö½Æ½½Æ½ÆÆÆµÆÆ½ÆÖ½Î½½ÓÃ·ÞÆµÆÆÆ½µÎ½½Î½ÆÎÆ½ÎÆÆÎ½µÖ½½Ö½½Þƽڽµç½½çÆÆÖ½ÆÞ½ÆçÆÆâÆÎÆÆÖÆÎ½ÆÎÆÆÎÎÆÆÎÎÎÆÎÈÈäÎÖÆÎÎÎÎÎÖÎÎæÖÃËÖÎÎÖÎÞçÌ˵焹ç½Þ±Àñ¤Îç½ÎçÆÎÖÎÎçÎÖÖÎÖÞÎÖçÎÖïÎÖ÷ÎÞÞÎÎÖÖÖÖÖÖÞÖÞÖÖÞÞÖÞïÖç÷ÖÆÖÞÎÖÞÖÖÞÖÞÞÞÖÞÞÞÞÞçÞçÖÞçÞÞççÞç÷ÞçÿÞïÞÞÖÖçÞÖçÞÞççÖççÞçççççïçïççïïçïÿçÖÖïÖÞïÞÖïÞÞïÞçïççïïçïïïïï÷ï÷÷ïÖÖ÷ÖÞ÷ÞÖ÷ÞÞ÷÷÷÷÷ÿ÷ÿ÷÷ÖÖÿ÷÷ÿÿÿÿéå fIDATxÚí[PW~WÍi’Ó&[²îs±%¢HäÊ)ñ’[gcƒWgW~—ËYVÀëèÄó#¯“Yì:Î1ñqnW¾†i»áŒaj¦qÇ>' !¾LâÆ3ý±Á7µÐ^Üöˆ'šv˜f¦\ý¹Éõûv%@Â`ƒâÎäƒöýÚúð}ß÷}ßï{+C[ÃÞG´ä±Ç žx‚O,#ÏhâñÌë×>w„Ìç>þØ[šÂ¡¦H½¡¾¡zïæÍn^·á‡n&…ï¬<¸NKÔÓSÕT’Ñð VŸþÜÖ­K? Šß©>©ßlØdhØT]]½¹ºzÆêj­´~Æ p¬lЋӉޢ×f•ôêúÙ-‹ÃúõÕ›¶lÚ´eË&ÃP8òf¤9z¤åÈÙ–èÀ‘è{®¥åÈÀ9‚s$ÍÄtÃÀ¹Ù§îý½ü™©om¥[;ëü±Æú¶pcCcc}cC´Ö7Â%±Þ"¦ƒ5H"ÁéÓbàDF–ݘÝ˾f)@žÈºVÏ=wZŒ>ýÊa(‹±hù²Ø©¦vò1ùb¹¸±U« јtcLÑÔØFj;÷ß=í‘]¤ÐçÞ²Åí5\"´^yúiBë•üX­j`‹…›»CôÕŽÓ±X[¤žÜÜ«×èíôpMo[´A£EùµÿänEu:öóª†MN¯¡O UTØŽ5êá­aB«5øùªF“Kkp+|s¬3LZ]Û<­¤5ÜØH®é¤ýKÓ™±Ÿ{·½@‹Ež ôÖ8x¦1¼‹1äß=sRì±ß ïç u'>‹~͆\³DúEô;ö³òò?ø†.-!À h’à„̲,ËÂuØÏpœÈ#Öh Ï·ú¸.×{üˆI=TºCñh‰>tHYp8ŸA¹ÄA˜¾ŽOå Ç¿ôB'Îà BˆÅÚ·¶"†e†Å§Jìê`‹’¿/T×ý"M14CQÍv±†ó|¬·©>&`„9„yñðv`ËÁ¿Ië‹e¥%³ûƒMDa1tÆ<ÒBM××ûÙ9 ? ( ¥$ ôT/ByÖ¢ ñgœ]´ÛýÙhƒßív{¨Y )ô•‚5ø 91U0ÍÊÐ*š&cœ¡5/ A˘tˆ–2³ÁTjôJK¡¥Ìgl–›—`  FUVí¬hWxìäáV(Bëc¨4B48Är4ä ¢Á‚HËO ¤¥¸¾tò‚SÄ>©INZ)Zq–òù€ 4šfšfa @½»»«§ÒZ”“*wT–3ÈSi°YŒŽ "­x+Á2³AÂQˆÃÆ" "+-ƒÅbù†d™#Q!v ƒ]íìì„"'ð‡øNQàEÌ]!hY+-f³Ùb©°Là ´†òzmÛö=Š(•¯³»[ê€j„–Óës×¹k½®;a'Ò‚™@Éð0™ B !Ç(„–ÍUëp8LîÊlZ,K±&OmcsèGßýîÎðñ×ww‰ÿ»ì´(Ã7W­Ò:1¥@‹ÇàF`(<Û%iý×]ÀN,®û—£Öiœ5ù(ø Ë:Ñ £ð –@­zzz€aUÝZù‡ekÌ–¢Ù´Dß³Ô¶m0›³Û(2©ƒ7ÖRëéé.-c]UÝaw‚~9kíŽiZ='^½ëõ®'»ººÈÑuòÄÉ“„H¬Ò*.·Xm6k¤Ó´ºì>¶ûÙÝŽïÞ}|×ñÇwAéÕ®ž‚u¢Íe·Xì6ËÛš”Æ9 µk÷®ã¯íÞ½ëauàØñãŽ=‹zˆz†Ky¶»½>ªvûž¢!|ñàÁW_ÔpâÅW¿wð ô™º h¯q8\UŽ{•Ë—’ÐRåyPZ«V>`XQb()6 Jîïô¾šÕ5·»Öc¯·¾ÎM•ß´V¬¼ÿ"ãŠ"‹¡h…©ÈPd¼G¤åzÄ br€ÀÜî{(ÄXyYiIi±¹ØXZ\tÏÐ*®{Ä ~½ÖãvÔºkkHKÔ¤ Pâ|RQ’²¢.áêñ þøþ2³É\b.5•”˜L¥ ¤Åñ˜öŠ4-QxûàÑâRKËíªuÙÜWM­ÓµPi&'—ŽÈZ [«¬åV“Df¶˜¹h©xâ8nO¾à¼ç>yãŽiQE -§ËQér¸ìù‚ýkd5¥ƒËèHç|‡þuvz7ÒZ¹f­¥Ô5¦|´’_ ÐÓ '¤ÔyA˜nÕŽ; ­âº‡Ý§Ãê­u˜óÑšTEQ®)¢¢È¢¢êHç€d‡|MVU)¦H2™Ê‰,Z Ò*Ÿ.­µ¶ Û[¥3¯´&9m­PD #4ËÏb¥&%ñ€(¨*!–¤€("Z¼ ZÅuß\ã¶@ðc¯¨«­²ä¤5,2iÌF2O{ÖS¦¤T!í%ç£e(-7ÛK*í6‡Ínw妕DÏ#Ð,tBÖ%e¡[ ˆ\‡pñ˜—X JÆ!ˆ-ÅìNL2ÈÇx& ¡žÏCyY3­,»%9šÁ ÄŒOdZfAa8šbE3 ¦9²:Ìò4Ó9K·¦¦&§&'§~? Ôæ¡µâáÕeFc¹Ñh5-fci.bž(=h|*ŸéÞÏH!®ªñx\oÕ3–<2¢äÃUí¹iÁ”‘µ½ªŽ8Þ\´Z‡ålU×0ºu½ÈJ 5>–:?š€\QuZ#õZ">®#3¿ ÿÄ5í¹h}kõ*â9˜ŠlÓ¾éZ³ 6’ çVí{õÕ×^HŒ¦FFšùØouZ?>öi8z6Ú}¹¿¥e ž=Û}ùl´=žPóÒªªòz|àŸV¸=n×ëÈÓ‰óáÆOïŽÎiOIëÏŽ}‰¶´4¡hËËÑæ}--¤þRd(®ÿ·Sy£)·ÊSˆ¡1ÙÛ€Ñh.[å/oüö·7ýk=Š”Rkp¤t럯Æ'21>þßZz3‘lN±ÂxÛ‘5ÂqH€îä³Xõ\Þ8z²G_¢H/U¤iõðßÿ—ÆÞÞö¶ÁH{oÛ›í½gúb§ÎœêMwaNZÅuߪq:k=EóКÊaA“7nÜP՟ݼ¡þúWïÿò—ï¿ÿÁ¯nä4§²ïj<Ž„šÚ#Á¶—‚ ‘H8Ò‡ÉÉ+­•÷=`2™­óIk’,'ñ2&â’Xc‰9RãGÉS?þǧž<%1‹–®òòÕwÆ&&nݺ5¡¥Z>¡ Çy¥Uñ…Óír»ó:6“’$Ë’‡¤0C=©«ÆµÚ¬v<ÿQîÉçüsOÿkÓÀßE†ZÞ:wd``x<ˆƒf%òKkå*ëZóÚ5fk~Z‚L‹à¤¨AYËôöwìxrÇŽçÿrvô­ëÖ;ßêMÍûö£¶ì …"§ˆéM#‘_Z¸¶ o­Óî°äSyzYGd…žå &—M2²hO1̤ŸÜñç ýYc!e ._NŒg#>‡ðšG·V=d5™*¬•yiM/Š—.¤ R"ƒòÊ‚çÿ>·´ÞÝøÌh[ï`|php°—ä}}CCC±ÁÁ¾¡ø<ºE)]k›Ãš–¨jÓ¡*©ª,©²LÒw0ñë7>¼råÊGO+Uªsô§Œ<³ñÝ`(ØÖ 6CõÑ`0 Fš"¡pb^iÙÀ´¯µÙ*óÑ"1—ˆ ×(VÀ,UÒÌsŠZR`ѵDB™M+݉?ýd‚Œ?}ÞJF’ŒÇ‰îç–ÖÃT˜AV+e·á^Þxô“7ßžœ{{øÉßžx{ømÈû¡8œ[Z«×8f[•1?­$¢ØI^M€óä=g¨¶Œæ¸`*ùèÆwC{£ ¡æ†Púno(ØÐÞHº²-RßjÊIkE–˜rÓ‚~ƒ‘ÇP¤Á%¤!Ë$"CtŸÖÈOòÉøøðø{ׯ¿7<>xý:ß{ïz\ÃuÈ9h­x¨¬\Ûv-*Íoå5¿n´>£Ó.ƒšÇ³HÑòMœ^ÃÄ4 é1jbll,>6–Û±yÈ. €.ËùœH€%Á x鼬f8VIhÏ¥[)#1iÞÛ<Ú‰œ 67‡ZÚR¦!ž×±Y@'NJ#«.BT Êà°0óÝ È°@ÆåÇ9iüÍk‰þl¼5>³OB»ýZZ”áîKó*Ê߉óºRñßçvâ;o럓0œš¦µT3öóšÓ²AV¸òN>Û0áñYòšf¡€»gTžE©Zw•?ÿ̉MÁöp(j ‡^Š4ƒ¡PÛ á±ùÌéýÅàØXÌ%åfc>Zð@‚€ˆ'ÈaN£—9áLwÞ‘xñêÉxÆûmÓ¥>5‘7Ä0ÖÕÔ8k®Z§ÓnÛ’›Ó‘gv28>1<>ñôþóø§`à¯]Ë'­âR£ÕdÑ6…­¥f“9—nÁ˜ÄÕËs…1æ1‘Y*Ib¢òŠ:–ÉIIÓ‚‘x)ÜÒ²¯y`_p |›æ–ȧcdÒIû¹h9\V«Ãn­°BViµšõ=ŸlZ#`.i~Ÿ(ŠÄ×B²šŽ¨‰´Ý@ŒeZ™‘øã£‰ö³gô÷÷C(Fðfï8hÕh<}y®‘èvlgݵ{hÇ|>ÚcÐ÷|²i‰3Ί”‘¦‘o'F§¥þæ7ŸÝ¼ùùçŸßÌa¤§êÜÅ`MZU‡Ý۠ఓî´Í ÈXFs9Š/‚a”¥Ú2•9ùtÏRùŃXùÕ+Í`¸LÅSI~s ýÖE&ç ’ö ”--Eç‘ÖѪyÄëñ¸.·×cÏkNaÖÓ´HI­sA5C‹’"QxèÊ„æàC0¢Å w¼“–U—–壅ZàiBj³†§ûYVÖÇ·’ˆÏ"V0O#EV”°4´â¦Õ4UÒ,Vr¶ÝJ‡±ËL+)ˆ‚Ð%Jˆ9íeÐìI¦{„ãaòéž3ûüç2Ób)‚t€ÕF¤¡qjÈuk<ºG P›=ùúÿ¢ó¯ê.hIwéi_ÓúšÖÿZ`øÅŸñÑ"8a<̓¥g (ùŠi!‹9²›Ó£¨Jà5JòrÐJæÀ%— ¦Å#vY[ª vö>käÚ¦…ÓÂÇóüžŒ/ÛÎææ¶ç!¡Ù¬:»0jhÁ´®^$àåKäóþàó¤Eóõ  J’V½v/Hzû…Ôù¼Gä¦Ó1¸¢=2øéE†+hë¤WÔÌ8'Çl©Ü¦¢dÖgmfÜŽ–, "&?® ðBê9}°#Mkl,cþN?\Qçlf+¹Èe¶)êâhåX!ú‡ÿ‚ßN-=L ‘7À± į\ ÀX¦¿´¹-I ¿Ò_ôŸ â@·5§ÄOOo=™LgIu~£8sZ¿aaw-ÊœJaˆTɦÂ"”y¤Þ¤x#·öñ,²˜:Ér¤$Õ8)qŒ$ŠCÞ]ÂX¢°ª€9‰Ã"‡AÂp_àyV‚~@E¨¼ÊKZxsDj2ê+²|ñ¢¢oQAEÒ#Ät@K¶$­U$×CLšüÌ:¢ïiw²ŒNë+Â×´G‹º7iÝ£ÒúšÖbhQåeÙ(/›Ì?¡~ù%S¿›šúâ R¸KüŽ< ³Q0\…X{{_æ%œýãÜå$Ÿ'Îåˆ$ú†d©C&ö™l4#C§Ï¿¿qk«I‹¦hÊGÑ,EÑËHë¢ÐÁ³'9äµúíä·ÚbÇž=¢@~)Œh„ö“U Že¶S>pá©z†¼ Í0>8Œïÿ93lor¤•IEND®B`‚nagios-2.6/html/docs/images/cgi-extinfo-b.png0000664000076500007650000001321607436604451020515 0ustar nagiosnagios‰PNG  IHDR–tPS;YtIMEÑ (0}I pHYs ð ðB¬4˜PLTE!!!!!!!!)!!!!!!!)!))!!)!)!)!!1!))!)1!#++))1)5)11))11)1915-3631B59999B599BBB9BBBDJ?JJB9BJJJJBJRJJRJRBJRJJZJRRJRZJZRJZksk^!#e)!c))cAGWVZRRcRRkR@DsRcZII‡PR¡Z`WcZc^c^ckZccc]`xjnqyyzjqŽde¥~~†{{ŸZZ¹ZZÆccµso½„„„{„Œ„„Œ‚ŠŽŒˆˆŒ„”ŒŒŒŒŒ”””Œ””Œ”””Œœ””œ”œ”Œœ””‰Œœ”Œœ””œœ”œœœ””œœœœœ”¥œ¥œŒ¥˜˜¥œ¥œˆŒ­””±œ ¥œ¶¥”˜©œœ¥¥œ­¥œ¥œ¥¥¥¥¥”­¥œ­œ­¥¥­¥¥¥­¥©±¥­µ¥µ­­¥¥­¥­­¥µ­­¥­­­­­µ­µ­­µµ­½µµ¥¥µ­­µ­µµµ¥µµ­½­­½µ­½½­Æµ­œ¥½¥©½µµµµ½µ©¨Ç±±Â¥¥Ö­­Ö½±µ½µ½½µÆ½½µµ½½½½½µ½ÆµÆ½½½Æ½½Î½½Ö½Æµ½Æ½Æ­µÆµµÆµÎƽµÆ½½Æ½ÆÆ½ÎÆ½ÖÆÆµÎµµÎ½Ö½ÆÆ½ÆÎ½ÎÆÆÆ½ÆÆÆÆÆÎÆÆÖÆÎ½ÆÎÆÆÎÎÆÎÖÎÆÆÎÆÎÎÆÖÎνÎÎÆÖÖÆÎÎÎÎÖÎÖÎÎÖÖÎÞÖÎÎÎÖÎÖÖÖÎÖÖÎÞÞÎÞÖÖÖÖÖÞÖÞÚÞÖÖÞÖÞÞÞÎÞÞÖÞÞÞÞÞçÞçÞÞçççÞÞçÞççÞïççÞçççççïçïççïïïççïçïïç÷ïïçïïï÷ïç÷ïï÷ï÷÷÷ç÷÷ï÷÷÷÷÷ÿ÷ÿ÷ÿ÷÷ÿ÷ÿÿÿïÿÿ÷ÿÿÿ!¢!IDATxÚí[pUz×L¬–‰uÃSu4‘ŽAÁ¢ÒÉV qM{se]ï‚Î86$)5Æ'‘lÓGl©Ý(‰Ï[.2$ÕŠô’CÉ÷"ä͈6¥#1̸£§igb0ÛzÒ0“Fánˆø“‰¦G ÉØý¾·’%Ù+7ޱá:ülíÛ÷ö­öçï}ï{ß÷í³&´gëcüñmXnÛö§•˜_W¹¨ÒeÛ¶EïSÿ²mÿÙ?¼ÚÛ{lïVÍ“nÞ´é±Ç~øà¦‡7mÚôðÃ}¿ ßCNiµ¬yîJáÚ÷oß+}'âþxÓ_ïÙÒÑýÄfMoÇæÍnݺé!àöØ£[ûáC>¤àÁâɪáÁ‡6oííîØòèfÍɾgíݳç•Wöì}>¯ì}EÁ«¯îÝ ‡ùøÅ«êøEµ KñcÃÃÃÏû4™¾ÞááÞþ矶72Ò»wd¸ÿYŠá‘=Ïö{H¼^@élÿøz$ªVCâäIxÈHPC"üèèáã£P&ž@ŽŒD"#‰‘ÈH,‘J’€c"•z=CÆÆ J°–É@s"sòd&£\M$ÆŠHPŒ¥…“¹¦€+Å;ø8þkæõÌhH“H±Sc/¼06FÆFGGEB2o÷'2HzúŠbœN"ïaˆ1l86£}Žr| ®-‚ůÒËøí‰ÌðO>±e‹†ˆâØèßýù_ŽÁ…Ã?;ŒW?ùqhô÷ Ð(„‘V*Ñß;’€Î Û9DÆ@ {ûc$%†z‚$¡Æ ±8SÅ^s´ÎôÝ×vß}mH‹ˆ/øŸ;uJäÙÃc@8Ñ·%´ÏcðŒP/Ž%2¯õý$‚´„¥µ«“ƒ.±H(4 ¬CLˆ¨=ï†PX)Hë‰ÎŽ ‰%Dî©-@ ÉãÈ„üÝ>VȈýþ¾C„DüÝ~NL°½O?ÝŒÃÃqœÖ×ãã3$ÒÿT?T‚#e#é°¦”ʧü¼xoƒÇ+ÒòoøÝßþ½i±Äè0ä Šˆ£cc\_‰ ÎçŠå#A¿ßÇ„B¾î¾>àÇó|$Âóìv†éb"<Ëø™¿\D„Qªµˆÿ Þÿûß½¿C“€¦Ä¨8* Ž‹âñãcÈP  ÍáâtCE‹DŒá>˜q¼_„#=”Z\é7¿¬€ ò¡Ã¡+ÜÆƒO&FüÏp,ÃFGültlÈOfU03¯º(æ÷®Šs¡ÃÝOX†aX¦§ Æ„ÓDØgúžÜÒd;p;Ÿâ`lØ>Ÿûå—>Èe¡ÈårÙ_ÂáÒ¥ÜXfñô®\½z?Ÿa‰gŸ}vŽW?ƒCþJºP\*žÌGyÑ÷Ì“ÝA.ÈÀ•çC¡PP€9†:/’Sqªbb+ FUÄAeß}w"ýο½üòÄON¤Óï¤ÓpL¿ó.œÜÀ(à6 r¡ày‹†ÙÒÑÑÙÕÝÝÕÕÕÓUD+N”,Ï)"&aÊ£ 8U1óÓé—ã“é·Òo…ÃïL¾›ŽÇáw‹‰·âÿ¤ªIª ópœ×´é4*hg1ôÑG æy²‡z>)ûÁ¥ d+j9è’ûäãO>ù‡[òÊ¡¬T|'Ø,‹HK ? ôEZÍd6WùéÙÙéJ|1­‚™‚Ò˜®®óØof¿Té•#š6M£¯­³ùn»±±ñž‡Ýnuè5Úf)'J„H§OÓ¢Pƒ2wƒSìfAiµgy‘a8¯éèa0¼h™Íã8ÔEgZN +ÉN/ÿÑÿ'­f®‹íb¢í~¦£‹˜v¡¥•e¶ãØ‚úïïêñáY‡jK­-í=mm«Ãçk¼Ód2éé ’Ûà õù¶Ì‚ (ÆÇìÚ¾›ÛͱÛùìʲBZíßÒÞi2êjjtŽF“î·tJ‹Û #DZ° q!îÐÑ.G…£‡ÄÕ–Io5™,V«&¤V§«Õj: •åøC/VS+·ôtn¥i05v´´z[[:,Eë`2i[ÉE4¸€0„.òBL,dÅi¡´ìÞxÝ®6»NO¡slÀA úƒ<ǃ0Y.6ôôî¡Ý»‡†vZ+ËŠJ«Ál·Üa6ÔêuÚङ\d™í,˜\ÕùT2•¢¢‚_1µ*¼Ö`4šj+Öªò ³k»ŸÝÅø¸Ø‰#GÆRãã¸b‰+8ˆŠ;Òòšo³9›Üv}½®^¯«W–!ЭOìÛ¿ßOöï‡Ï¾}O$“)’Z9Z@iúêô •–×Ö°±ÉÕèv·6µz›[MiþôÄK/½ô~Þxãïá󯉗N¼'ÉT2¹bƒ8su2> ÃA4à šÍ&‹ÙbµXM¨÷¨[@ Øü3²*âÄI Vnñ¹6Ñù‡ñé5J«Îâq79.—Ãå²%ÕjMzÔ-Äý?ß¿o?"?Ýpß~!¹’kâLÚ]Ûqe†ÎDƒ«ó‘G<žö6wk»—z6w~G{?¹,p VуÜÁ#ð{Ôëà° òÉ•SùKà(Ìf¢Ñ’r6:­Vw«å[0†V“öþÌ´| gçÏ¿Ÿ=ÿ>²2â|þú Ñ*iÙîhh0Zl&£Ýn²X`©ÖÖ 1;]K¥õZ?2¯©»£Îd5Õ­FƒÕa·j5”ÖM ÀwŽ÷ÍŽ5ÒZ·¶ÁÝäv9íöæ‹Ñ`2Ö,™Ö4x²¢”ê½fÁ²Yåñ7ß|ûÃß{{üüùÊÿ a}“÷ÓÙÖêñXÖ­ü’håÁ‰e è„ÀŠç‚¼À±;ø ÿС¿ý›¿ú—מJå—,­?YÛú; õ5µVcm}]mMÍMЪ¢‡Ïž=ûÞ{ï}ûòÒX!­¬»åö»l6³Ñb·m»ñfhUÇõë71k‘ÖúÛl-^˾±Õív{<Ôhå¥y˜”o we%¹„IY>#Ë´'-àÚd¡óëŒ*o[ïlÚè4[Zö&›ÃeR£%û0C˜;”!0ÿt'”]2Þ‡-þàb˜>á†>¯BkÝ­Ãíß®©5ëõZ¾^V–E÷9‡5}1 pè·òáü‹|TˆòÑApú…è`;Â@ëZ<1m7<|p DOA˜Ç‘‡v. ‡…h ªFË|ë]®Ö»Åær ^©ª¼ì;YD€ ì„S8AË6˜…*G¥µƒÅ6Ší²˜©cسcG/³¾UhyÖÝû€×ãpx½v]É ¬¤•ÃZ\LÓÜ™€9%¯VȤáµ8M³)8¯À]„?~ ;`Êœˆf‚„˜RDãi"@òb:>¡N«Áî´M-ncM5ZyÐÓ÷}ÍÒÔVv2-M —0uE³ YI”.)¹,Ä…«8ôDú ¸é¬|F:“•ˆ|A–³ð-S2š[œ$-]˜œÌª ¢áƒÙj·Ün´Ùôk«ÑJG“fŸ9;55•• / <‘qíž’ñi"+â%Zàä’Džã@xí çx³|P”y^ rD&Q!-†yIVƒÁ鶺ÚÚ<­Þ6¯Ç¤>ˆ„LH4õ”)æGH)W2×P|Ò"ÍÏ\Ú‘>­YUZkê kuf‹ÅhÚ`±ÔªÓÂÌkR$è1S$AG¡üy"Už9à“$OBTRØs½ðNàTà% U]DžÒ‚Qˆ<¥j·~§"ʯb·ˆ²êSùË€zsâÁÉ.WJ+ †‹þ~‰,îWŽàTÀ¡j·êŒ†:I_Áná⣖N¯^¥º•/%·¯äŠùô¹¶¼RÏ+‰ë´ÖÝRg°ÛlÖEiQû€& G2Ã)Q!<ããI%-ê´Ò€ƒfÃgg?ÿœ¶Bu¦B®«ÐZo¸·©üx‡ÍR}©Ædù¹çò,ÇËe(°,Ÿ,U—轫 âú¦œÎ˜‹Š ¨nåA§Æ ÊuCX.-ðå×™¿ Ab}­âª«<¬ÊV㬬Ìt ”Ï+A7N=\ëæjSòòiÝÚàÜh6º[›<-U=t;&:ÈCLˆ¦Z‚i4Dà#ƒ H Ü‹¢X­†»6þw£ÍÕænõèªJKy犆­£$£iËC©²ºlZëÍ÷ÚlN»¢ k5ZÓ¹ïµò寷J3¾ˆeåtÐʯ[k¨3`n¤V§×V¡µÊ kâzç½§ÍÝT_Ýn}´À ¬3×iëê5_­}y¾-³vím­V[£×}Y´èëÍ¡V¥M»™ÌV«ÕfmÜðåI«ø¼* ˆ™y¥ -ýÅjÞ`µØM7KëZþ ×0õ€kàÇÊLüü×ׯÏ^_ò¬¤™ffÍü7èKM»%yÖ?tˆåǹí¬âá#øÊVȼö^&rhèâÒiyÍufDŠÀ:¬7KK&NH"ÿ8øùä!£<˜ýÌÑ7_{nˆ]êkQºTÛšœ®f¯ÇånkÆWŠ_¦˜¾üᇗ/_þüfhÖßa4 õF}m-¦v«Ò*ß=£ì Q>Tq ‡ºy`N•¯_¯šw[d¦^® xµ@À¯7ZÖZ5Zy1Z¹#¾ãô´p!^±w%J®ÌÎ~1†@w-ÇüIqûR\¹™fS 2# -“Óbs¹lv—ÓŽÛ ô:½n­ì Ë rl`€„ß@```ÙA7؉%ËâU¾fŸø¶»”Hòï`ÑÇõ3á0¾¨„®ìà` šS£er´·€sêñ4¹=-­ÍÖZ­mÃBZx£á0 €2<ˆoe!,BPåàƒaZ‡*ü"­«â>€´ü…|áˆf™Ì‹²åx¸3Ì"­™…´¬Þv¯ÛÓÙáv{Ümm0ñUÔ,„ƒ0¡ 6wiÓKS·Ó4—»,à3{œ$ÀÁ$ñrepé\î‘ÎÒ4—dèöfîêæÎÜLjj÷yW’%[’¿€ŸVï»ûJ²~z¾ÞçÙw׆€Çó8à‰'žÀ-îï%¼~¯×ï14zÖ=¾ð‡}}ýúØùÚÜ;|­!á÷¬÷zÖ<ëÖ=Ö°¾¡á±Çk¬oø£{‰u ΆuNgƒá‡þDÂ/„£¡D"!„á‰Da¢=°×s—‘ˆé@™lìèjÄO#&²Éƒ1§§1v·ÑÇ»»–ˆ±¶Ó[1ŸÜç0éh_®ïŠ—yq¾@‘ÅtvµaFû÷ìÂß×nêì†/êò‡»ñJ'þ^»»È€þ‘¾>Iœc`0h ÀQüùÆÆÎùÓh÷1‡Óél4çà`Ok«Nk×üR,¼Î‹iùýüUhuwwùõOÇH/¥œ´N+ѨÓr:æMKGw·ÕÓ`uŽaZ¼£ñ£¿æwzq×é%]7é¡ñûMë;ñh‡}Í„eÖáõèou:;D}ݯ3K‹G;(Ì ¤7À€jº£Žè@€^$ô0Ê"«bvR0§½ø="KÓ CKì~øá¯ü^žº„Ÿ š@&@‘$ðdIix r“`R,ÒiA`Ò$¡‹[ÿDÁæŒx§à4ˆ ·®NžŸx!¿GÑ3aæwÜ(Š Ð\9ÒŠw%<Q!Š÷»`˜`(–¿[PÑŽF/͉@:­î.ocœbqGkVR }×hÉ4íñï9ŽæX¾™Z´ø5¢RP“Ä2¸ e1r¡ˆD%ZwͰʌÓ’,È”%ã,ÐR¦‹.üÈbÒ’8–&Ÿ¶R¬å(ë-¬h“D –f!fpˆå`Á¤Î"NŠK’$.*­¬—*Ž1âìéˆuò L‹p¹§ËéráX‚\Ð; §“RqI¼½ø´ .³Ëä´›ÜÈm_j·×8캴8˜çX„E³<ËpË@ÈeŠÆ³âb²ÊKËf³-&6{M‘É+ W¾xÐM14ÇàÃ2IêíÖhûÆ#7¾:^Yi­ª«G´Ú¬V;D° %îkÞÚÞ¾©}û3ííÏlÝÏöolݾO—W\›†Ö`uäÛó¦e2ƒÉ×õg‘Éï{æõg_ÿܼþ쳸|c§”|¦“Ö‘¿}íÈ‘¿™7- rÚ!DØ]6—ci!nAqÓ¼u{3ÑÜŒ¦™rST3ìf­kº9qôÈË_[Zu ;‡Åj³X®bZÓ%6Ó|éè‘k×nœ›ÇtÎÒZ³z•q“–,ƒ;ùÓ£ßyðý¹ÐmoÇ.¬ÓZf_o³8,Øâí6;¤5†ªñáp8‰0nú…ØA!›éïj²¬(Ÿ¼ýÌ[ç§hš6[Yµ¿úʆW¿ÌIëÁVÕ™Mæºj£©Î´ÊdÑ9~=Áá& –i©Š¢?úéÑ£é_-u¶ÂzuÑ¿ÚðÙ¨Në{½¢X˜Õb/Dù…P( 霂ÑPHN%•9(f6´>Û¸qÃwFÇrÒzÐlÑ&‹¹@+‰ÖÅé‰à&‘J¦™ÖØèÿ~öÖ¹±‰9Ñn±ZŒàŠfè-Òò}=ôC¡`$ }‹G+ï£ÇÆÆÇòsâòzæcZ È<­Hê0–V4ÚóQ4:I\Z#”(É2 ËŸèåñ3YiÕYÍ–º6£OŽ9=Ž_‡BÑØW$„™á ‹DëVFûmæ¿3íæÍŒ6¢erJ\¹,‚©5O L>òuj¡ˆ/©.- ÜWUUTGXMÏg¶5£ÙXk†0Q”o%à Œhb'OË‹BKVdES!ž(D½LžÖš•v¢V‹ÍVLk|ü6 ßàÃEáTYZÖ5æZSMµÕR»t­{†œ´VÛ6Ô?NËýD«~åCÖZÓCµKªÍæ¥KîZXµ‡Ã e™Óv¿Ð2TUt·ô¾Q¢á«¯*RáÂ~‘L0RœE!‰ÀçÜW9Nd6h°9–,<-MEFeE$qªÈÐ"ÍÁ|3ƒ´üêCÆÚjتk5ÆZÓ‚Jk4øM&‹Üü6“ùõ¯sûÐU¢µLÌ:«œ6œžZ”–ŠW!ZsØMÎq³”¾@QN•Yi-{HÏàWÕ˜!Gµ™ JëóÝÛöì)ÐbxžÊÓ¢(Žç*ÓZÌ3Í·¾ø“-<·§°´”]õoV¢Ue]m^±Âh™žV¦Ð‘qešÌx¶v¸ƒ âÖ­7aKk‹DdF22ƒÓÌ•û#¹Ég9>éæX2--‘`Su.‚ÝÁ¸—“%f:+8öïâq¤‡Ÿ3»©¬FÏÿä“ëxAæF2ßÂóúõô$KÍCÑJh­Y5g™²VÉ Z†\”ãŠ`hII«7%JÂl Zb˜ì<\"­ÑïoØt>64ÔóâÏ.¾8Ôsñò‹Qh %’Så!ö‡þy…½á°îô{1ŒÍ‰–ˆ¯-ƒRŒ$À!¡q¨7~ªåÑœ'Nøb¼TZÿ´óx3ˆÁ3‹®@, Ãl±ìXßœh©²TT=ë]^ZOÿxZi½÷É»g?žŒTªh7¥·×çF ò[ŸÉPDÇt§W¶´lnÙràýiçĽvÛ›B4Š\ŒF|‡¡ ÑžàP$é‰ôD#Q!ÔI©9Ñ’)‘CC Ž¥ð5Ħu+qË;ƒÅ)@ ­w·ÿñ›^zO@ }(`‹âõxïê‡Ît³¤•)NâÏâ/ðäsêÂçxÿÓ ´nígþùÜÇ9ueõ5œ*E2—Q§5;ié÷#ñ4ÇA£ßðæ}ºm[kÛ®ý½ñÜ•‚åN»Ýjc6}7Э;ÖîÇw­ùáþ>ˆÁŒ…»b±®~ì`Óir&O¤]º/’.²AáäôS#m03öÎP–«¯Ð:gÜñ øÃqùaÖ†€ÑÂABÁ»~ü“hi*;» _ž¥(ŸŸ:ðÎ)œÙL“AÜ~ï½sÿùï×ðéÈöù£¼~sÊœ-Pˆ Yâ0y¼~óÎ`qPbòomØt.|ø/¢Ñˇ£‡£ýóèGC=‡{]î¹ê¹ú׋8±O—šüÐb%šÃ—ÄÒ"ÍB‘ÁP<öÄÍfi©éŠžø6T>~(z|a!sØñE }êJÄytÐÿNs™äìheO1*X,éìO* ÄN *i¥P¼L¥5vbpPMbïK¦ôú'Yä|Ð| ý´’Ïo•ÙÑ’Dœ@@Ëây&7ÓœnmÝvPáÓ¯7Y(üg)­ÜB÷dü¦ÌX©OÈ?ÎybÃÃù6ë†IÍìmkθýMçÀÕÄGÿ644|åÊå¡¡+WàyñÊÐÅËÃЧÀ®&ʦôݤuîÏ:. A\¾ú|‚?Ñä×½êžC>¿®>%?¥êêÝ¢%§ÁÄûûz3Éì WìÝÊ\ÄÜi)êÿ8uÎ¥T¿^íàÂg¶¤^úàz\½´Æa:ºŽ•ìñù¢¾ /„¨¯ªXAhHgË}ån›ü¸’ÉÜ8ÔÓÓsèPOôСÜ-ù‡‡0pу)ÝZ¸xüU%h%(Ž0šÊÜ÷'Jˆ0›†mÅd˜îåÝœ<Ð:þ<'vuJÅ÷HÙ[äõ2°xä§OÈòiI> c6AM*ŸÐ‹QÊð¼Ñd#ËÊA—JBÂE,"-‰Û»ᛥ½ñ€—fE²'Qø~sd  Šöû;&n>¦ðöòJ7çî[&ZÝ.¢™hôžF’$A­øž5È \ÿ´’³‚ "xIEND®B`‚nagios-2.6/html/docs/images/cgi-extinfo-d.png0000664000076500007650000001345707436604451020526 0ustar nagiosnagios‰PNG  IHDR–r† ØDtIMEÑ 0:nÔ^ pHYs ð ðB¬4˜PLTE!!) !)!%!!!!!!)!j))!)t(|p VZA&.60º»£ÝÝÝÛmG%1Úº½5º½U޶ ¤I^­¡¨ÐÚ¥€O¦ô•>ï¦H£‹Cîªi¶¨†Ú§=Ú»vÑh(%²Ï ŠèYÓ¾Þ^ú9Õì …ò>X>²Ñöi›mGµ(Ú·¯‰Ú·SÞ‡z£±/a®¶¨„LTÇð/Ýê¶nr6´ þ»w+ÁI(¸Ž|®õ~_抅?elÒ§Ï»ÿàÞ{½6¬­¦Õ”V“@Þˆ­¿Ÿ('lïÖü~*‘õ^ò¡m^r™µ.…ô…½1è“—‚V4w ˆ^B !YiŸBv²&kZ4ªµ†@ŽHRèW ¦ý˜Œ4è‹*2| `‡ÈTû"µHÿ?êu¥¥üŒlªõ#‘ñû9`ÒDåÄûý¬†Xÿ£ŒGHôó´!G‰õ‘_þæòYõ"ÓÒé‰ëߨõØЊîÓf^V¼¹÷µFó6 š­SšD^ÉD&¢$ãë7S‚¼iS«Ì±¬ØÄ1,Oh)QMØ•€ /+HZŠ([Ñšžž¶¼èôõÅ"%lÀm*Фh²$Ë@Kô³ú…|ˆ‚H^7ä{Å,ÖÖär¹ÜÞàäß*$Îæ³Y€¹™–5 Ç­eöe &{–Ö”QR7„VBfl^›}Êì^»Ããô-s;ë}@Ž™@XëÃ#ŒŒ5Ò /¬idá¨OƒOàÄ‘"ÒªŽhnŸ {XÅëKxD7¡Åz=>¯Ïãñq¬Wöð¬Ÿî¼ãõù8¯‡ñzoŒIÓò¹×ëÆÎù ¥¥(¦Û'~¶¥C“&ÒH Ñ^²ÝPi¹ÝN°'·Ï‘5yv‚¢ ”†‰:Óè/8½‘´êҨϠ¤2Q¨X´tø–ì$YËq¼´¼6·Óát:®¬¬@KnæDŽmâ5—9IÁÁ*Š()|3 ¾>+Zº‘Ôãñhc't¤O`I)k¨šÒZíq{<ÎUî%R\#X´m®&¯·ÉŸ]LSUÖoõîØ±ã©'aƒ£ÉlG/ž¥E+Z×¾¼zõËEñ2i5ÜuWÚÏ;L7a'(oË“k·®ÝÊneA[YÎÏ—Dëꃋá•q õÎz{ƒ«¡¡Áa¿×4ù¾Þþ^x`é0 {5øþym‹ÒZù—+_~ðËÅÒª¸í6{ƒ½ÁYc·; á4i%’ @¸lk)¤E`wÐ\é ÄLvªj§…T5 wª¯·ª}%Кÿë/ñÞ—×~91Qv|ÌØÖ]`ì5u uw6Ô›þ”ìŽD"áð›á7ßT#‘7#‘#oë%Ð2°†èlF0vs•Hlëλ«++kënÍI«;¼˜"f¢—›>•--‡Ãíöy`ó¦sgöú¯,pSiÙ**²Ê«ùÿ1cC•øõ[(¯ŠJØ2¶eùñ)s›2SÙ¾B«jµsµÓírA†êtÞUœV'Ê"Oðsˆg‘}¼Âß iÝv[MUeuMemeueuUuq%Æ“ºa$Ÿ%ñÑDÊ0↑ÀzréGÍå«V­öº}àOÁ桾®ŸAËȤ\30«Zs3$¡;kS9;°–1+[%üÙ*+«k+gš|¿$‰Š,‘¨¹¹vmrPHÊÏåoˆsÒòAá)"Yö ‡ýœ÷‰X,N«*7m³M^ƒkA ËÏÄÎ ßܰaCaŸ4'-œ4ŒQ]7HΛJbœÄz"Q”VÕ*HK]ž‚j?OZ:MD'3ùs?zecccãÆ®‚Î9”h˜ O$ŒÜÇ;”5­ŠåË+jµªÒRZˆgý~‘e},Ÿ›­éÇÏín\ñ;5îJ—éþ¢¬¦ÿnçOðM0ˆŒî5Qè–´¼U«iHkw[IËг›N7 yj7Ák…ïeõß»@ã@¾vŠ¢$˜:WÀÈ¢5-ê *+kêª*ë­h%µ8ÆqdÎ4ƒe€}ƈñÁ‡/¼ð®ð±D<Ž%0•9hín4±ñoAÖ‰>œÀ(¡ÃU.¢DpÛá²Úae[² >T–5EÐädvF~Ä€n2s‰e$!M J¥õ_V¬xŒ ñ Fbd†mbýfaP²ÅlëŽÛn©¬«„xX]mAë²n ê¯(­ÿ|$õxãã7¾’ÌjݼĄ%-ïלd–ÒEÌËeA I"ÇK +ðœ”?3’äÙk'8VŒÖÿþæÕÇMüÍ«)tñA7’XQ £­Š»—WØjjkŠ8ˆ¤Fæ›ûd tu £Ð‘6‡¡ãð9v ›câ9Ÿ–Œ$ƒîÁòEhù¾f·¯òØn»5-úô¸ÅrORïÇ¥.MÿæÕü5Á_ýàïgÚAZ$ß*U!­/°q™gÉÔó(\æ~+…ž9¥õ?ýîJøƒ×SÏŠ›y‘CX8¦èH¬¸}¹9­UaI+E¿09[ZV+fÅiý韘xé/È­ ¢&€ÈÊV1u¾ÛCÐ`E k²,Až…YF™ðí )Y­Ðæ‹ÒúõËߦøÎwÞÓñˆ;: 8QÌäç[æD¯H'* Ãg×U€V\AB¸Ei]{h¥‰¿Ï˼,ŠˆÓ ¬H|²(­*S‡•¶eE•hµÂ¹ UÏkï}7«_|ñÅÀܦ¬i‘È |N—;«Å¼PG2-Jâ*6ý»1 ñç$§ÀÏfd¤)<€öÏQIþòŸþÅÄ3YiAxKemUuEeeÅ2Û­³qËÉ„¡çìþʸæIý$d&I’<“|…|Í OØ/³Ç+¸——Y…áDŽ1çY®hLt¬vyÁ˃¯·»=÷Î4y².Lb*¼4âžD—‡YΓÀ9*ejZñâ´tðÄ/#Kʘ,*H×ÈZjZ¶»nÏÌ4§¤j LÞÏ‚“|«Éiãe?Ã’àÁ+À©Ìs< D}så[ ‚IË UµÇápÚ«Ž:/Ÿg[ÆR„ê²h­v¯‚ZßÓà†ÒÇa.ä>“L€ÀqÆ™ë`î£Ô«§po£~¤eý¼¾à‰¹9ie×3+à ´EKw¡3ˆ'’t>2?(-!-s’²Á•u½…ß2H%/,I±`¤kÃ|,Q%kJkYí­u Ëêë물<ÏB¦ÕÌûxNɺ€!ŠJ£ç¥]ó|]r’,8^GiG:¡OÍAkîàcoZsÑ5 ҩ׺ºví:ÇÉ’ 2‚ïãü¬_%¿å<>Î/›–ŽIIÕÔHÇñ$¢^õÔÓ™oÜTƒëƒma«1\’´òÆ~]–‚`mz=ë#¬¥•Tô·Ïž?þç??þgd—ÃÙñá±±áá2haE“5r'ª&)ä•]¦&s`cЍôe« kÛÒ•Îýþ§cã³ê»|vå(1Ù­¨@ZŒ$™Ã‚¦$FÍB£YD…uvQZ¾µïF»‡ÎÄŽžˆuýxààÀ@’^FÏhîT's¯$Vë$Z#O3Iá„^¢´¶ºßQÁm° 4TÕ@8Ñ‚2G"DçxœÎüÄ¡E²‰8…Žâ‰ø $­iõþÃO>¹téÒEsO0~™²ÒË£…2¥ ùˆŸóAEå÷3~Ä$κ›«ˆÉ?ÏqoE: öôD{"/ö|4؉ŒŽšŽt¤,ZEJ È·wu½öA %Æó.ß[*YÆmW#A²noW‡†‰c†mdd”nòÄ(ä¶a-Õ!Ær\Ã3ZgóòIñÏò‰©7 Ú"Ãp쓱4NK‡0­@J†"½U%aE«˜É?/²ï„Bᘪýc( ©1h…º;Âjl [E;‡—J‰¯=Mó­×JPâQ÷Ú¾d3ÁPL?ÈkਆB!8‹554¼`/¯@‰!1ϰ"'°,ϘsGdã±»J0ùÓÏlùô“‹31ž×) J±-:û@&îÈ,ž–ö?ÚM×|^˜ßALÿÔíø–ÚÞa¢}P…ÝGáž`O{GOÞÒJÊü¶i6“lÎÎP+úð‡tMâÔüîtú§/?ôþu€S ´"‘p¤#rÚ‘Ž#8†//œF~$ ¬(ò ÔŒÈc:æÀä‰K uíý—_þÅ?_Ìw¦ãižÍœŒ-˜VʘcHAFKŒ§K¢õïP0x\ «-*ì ú¨Èî``? 2ÔÑKK!O#‘|Š Ò©qïÝØ¸bEãÆœÉ“:Ãzãýïo=Ý‹uǺ÷‡÷‡cúLcŒ¾HãH¬{á´$Mâ5úÜ&°¼Èh4èìÝ ~«ñ›…%†5­Ók?6 2PרîìøP¦ ¾Lýé•h‰Ï>;uêð©gä`–´F¥íCaHþ‚ØzÚ¡u ªa¢Îàøe3-”"*‘ òÒdAN»ô‘;y¾éäÈü¶u}xøÀÙžžC‡z,ðæð¨Y ”aòfY¸¢“Yˆ”Aoí„‚¬«ëð©Ï \#EÚs³–Öõ¯þý£ —/ ^¸táü…Kç/]:{ñüY•—.\4‰Q}¡´Ž!™<‘¡‘ÇVzÉ䮜öòP¾nØURù:55 5uK ÜT[¶A@¸E…Ó@àÌèèˆQŽ9Ìär~œ¿‰•³Ágņ'ž+aqE"càøñ²'GÀÛi ³gôKRâ¬(MgC>ø1YA?üÁèü¡zrbbbrr’î&iƒ"ך˜q3hÊÐæŸH‚„™Öz6…ùà$¿wçμñR’5æZ¸[J‘VRÓâJØL™3š™Ì O’!' ì@‰Ä¨¾t3Í)¼´¦oîÉh¤Ü{»tž±!ˆ(ð*xjQF´Ë93pâÄ쩎âX¡‡x&ùÉüû‰Ì'OžÌÛŸˆ'²F %ìÒ‹I¤ˆ6Í'µnÚ¬å=&,³, =V`~qJÏò\!xj—¢¡ÖVYSXèdÈzo“übk µUÊ!ï‰TI”n džkòûyÎïÛ¼iÝæÍ2¾fÎÏpœÀûÿë8DÚ$ÆIEND®B`‚nagios-2.6/html/docs/images/cgi-histogram.png0000664000076500007650000001167407436604464020631 0ustar nagiosnagios‰PNG  IHDR–mtŠh tIMEÑ ()L pHYs ð ðB¬4˜PLTE FRZ&&&28BLLO`UJEE`izmkmqp„o}x„„}†}…¥ˆ„ŽŒ•””Œ™œ™˜•””¥¥œœ©¥˜‘•²œ˜¥œœ­œœµœ¥¥¥œ¥¥œ­¥¥¥”±žš©±¥®¤¥­²­© ­­¥­¥­­­­µ­”µ­œµ­¥­·¢­µ­­­µ­µµ­½µÆ¥¥µ­­µ­µ½µœ½µ¥Æµ¥µµ­½µ­µµµ½½¥Æ½¥µ½­º½²µÎµÆ½­Æ½µs{Æ{wÁ{{ÆssÎs{Î{sÎssÖ{sÖ„Œ½{{ÒŒŒ½‘‘½˜˜½œœ½”–Èœ˜ÆœœÎœ¥Æ ¥Å¦©Ç­­½­±Áµµ½ºµÃœœÖ¥¥Ö¥­ç­­Î­±ÖµµÎµµÖ­­çÆÆµ­Æ½µ½½µÆ½½½½½Æ½½Î½Æ½½ÆÆ½ÆÎ½­½Æµ½Æ½½Æ½ÆÆÆ½ÆÆÆÆÆÎƵ½Î½½Î½ÆÎÆÆÎÆÎε½Ö½½Ö½ÆÖµ½Þ­µç²·ì½ÆïÆÆÖÆÎÖÆÎÞέ­Òµ±ÏÀ®ÞµµÎ½½ÎÆÁÚ½½âÁÁËнÎÎÆÖεÎÖÁÖÒ¹ÖÎÆÚÖ½ÖÖÆÎÆÎÎÎÎÎÎÖÎÖÎÎÖÖÖÎÎÖÎÖÖÖÎÞÆÆÞÎÎÞÖÆçÊÆçÎÎÞÖÎçÖÆïÒÎÆÞ½ÆÞÆÎçÆÎçÎÖÖÖÖÞÖÖçÖÖïÎÖïÖÞÖÖÞÞÆÞÞÎÞÞÖÞçÖçÖÖçÞ½ïÖÖ÷ÖÖçÞÆïÞÆçÞÎïÞÎ÷ÞÎçÞÖïÞÖççÒçïÖïçÎ÷âÒïçÖ÷ëÖÿ÷ÖÊÎâÎÎçÖÖÞÎÖçÎÓñÖÖçÖÞÞÞÖÞÞÞÞÞÞçÞçÞÞççÞïÞÞïçÞ÷ÞÞ÷ççÞÞçÞçççÞççççïÞçïççïïç÷Þç÷çïÞÞïçÞïççïçïïïÞïïçïïïïï÷ï÷Þï÷ïï÷÷ïÿç÷ÞÞ÷çÞ÷çç÷ïÞ÷ïç÷ïï÷÷Þ÷÷ç÷÷ï÷÷÷÷÷ÿ÷ÿï÷ÿ÷÷ÿÿÿÞÞÿçÞÿççÿïçÿïïÿ÷çÿ÷ïÿ÷÷ÿ÷ÿÿÿçÿÿïÿÿ÷ÿÿÿ]sQOIDATxÚí[ÔÖ}_î–Ó­îV²nÍÞažÃ…S¦acCF¯0˜@M0^b'éЋ2Gz;ÈÁ4Îà°Œk°fòhKpê!aÜŽSbÒ‰Hiæz2ž€Ç'7L œ`¯µÃi{R¿ß'í®v÷~sœ™ÆßÝÕû¡'½¾¿Þ÷+i#Ú0½~Ñ¢ûàS ûØwÑ}K/[²déâe°ý£eË>½x1t,†æ²e‹—.]•¥K—,ÁzY7ôŽ™–,ƒ/‚ã­hll𾢩.R×PS3­„¦,ª­õ+¥të­S†¤av…nùÙcB]튆êH]uUÕ´iõ ,§Ý2…ª™v+Ò”[óT¬…;¦„wV #ÝR[SSS][[ÙÔаbõòXµråªU«V._¹êÁW­†ü>Ä6…âÑ*ü4Íœ9³©i¦y&)›’3k6­„ºM3àW'À§¡VØÔØPÛ°i2)ãS2¢Ë²¢"« QUYCI¥R²,«2‘‰úÑd,¿ô%¿Ýæ—ÀÍÊ à/9 £–u´®}‚ý’Ñ??¹më¼kC™ù|m+×Ô¯õñ»X±¶)Å`iÁIÚ3Øþ¤ O ªL¬jjÕÔXDK!³îŒÍbL»ó¶»°Üô…iµ8]ÇšÏÖeAMµùêgëkÝL&Üv>ª`™nZ2ã‚QNu5õ5UKap¸Öwù\ªpšµkš‘™/N¯o`Ó§}îĹ¹¬lhhV'Wæ#uµ·ÕÄ"Ï̃†4k^½¢¶µ!JYJ¦ä; rG²¥ûIªYBª1ÕÒ‚#Òì„Ìž‹ý™ }h 5nj$‰E6£¢(ݨ5²ÌK<â$’G’ ˆKILÄS.YDRÃÊ6.LHEX@1f‰™L[oÞ*Á=LÉu”Ú7s™Ç:„-²"+ðUÕfù¤ÌQˆ5d(Í©iN’QNÈ<°ü¥„*Ÿiš^›‘„8/ÆxQm“â‹H\ö&ƒL±¹±®™¨"$P!ZâsëkkÖyøå»>ˆ\1S@†ÙÕõï]¦a†‰íSæ)çS§þõT¾Îš¡ÆhéTféxH)Õ6€EÔLsS ¨¶ù}mI’†aÌ&3ÉdÚ¯¡B›ˆ™4V™Áª™uI¢–r|:_K•OÕÉÉ/Ç@†‰¸Ú!ˆIž„2ÓÀ«<ƒºO<É7'pbLàeŽÏdêYày šâu£+ãV›Ò’ž‡ ¯(i%¡Â:ö[ó•6…´)"étš´ÉDIméT liŽâ3´À;%ÏÔ’ŽßÉ»”|ƒ%ëc¡gÇ4zÜD"hn®ëùÛ|&»Òx(ü,üQÓ¢®e±†gÙ?‡…GXùÃ,k\Ö),EiUJHé„DW‰Š—$9±˜É™§²Hx-.ñTiÓ–âRÌ$2º#œd–ë–]4ëAÊå î{çDRž*¶¶‚U©‰„"«„E„añ«•žFÖ4 ËõdóõS3Á kšb›Êë”R¢É&¥Š+)Uharç·R¿Sz2'Dý8(Ǹ°8.ÆE9^Œr\4ÎWsÑj¾Cùg;·=¹íhçÁÎm¥¸.m‡¾Î¸»óî£ß|ò›/|ÇaÜ’=µUm <ÓlƦùâ\ˆ¤g«°A©ŒG%#·Rˆ¾W8"ØÉ`‰1\y8‘‡AâãRBˆ'™ÍÇdb@éZA$ïªE’#s¼VdÔìÙà³7B ºQ-ÖG7í»ç/¸ÃímT@ƒa–”.)’æ™âér¾Z IB Im/5/5o^*¤ðF ëÂw‡‡e¾UTm»Ç²®ü\ÕX?´/Ü2,º&t*%0?5- 3) ÔxÚ'VåÃÆï8¿ígFèSIˆ:-ˆh#RfDXÖë–n˜àÍç©õ¬IuÛötü+ÕuæÔÄzÖùmOvn;øíóÛ:ûC;ξpwçù»¿µ­óèÁmßêüN. K„ŒUnII-² êU–ò K':!:ÏqŠL$ŽðåÀÑ¢È<ÇÛ²¢q`F• ›»T渠ßË3u —Ü\‘[ á¼ ñI¦ A(&‰’$Ë6m˶L˲M 1M³ïÍÿ4­+&ÔLÛ† t–,[–ˆþÛ·Ä–Ò³3n©+@|î}¾9´e´–(kЍi†F”È!F¢bÁa”·D$ˆÑ ˆ©§'TMf‰À­‡‰@T%JbŒˆü˜ÄH„L “ |¶aë†úaß(‹¤àâS_¶ª£Ð­‰#?Ñ(å0®‰ Ä—q ý{,ƒH@ŒKqjñIe«I&e© êV)“É-[á!Û‘Ä X›+ŒC/¤&/ß`XôÐ!jP?rÎõ»>¬¹Þæoœ¼åë}ý‘-[¶¬zdËÃþ³Ÿžü—Vw´*:ׇ5Ç{hzýýÖßÿýõõË—?ü™ú•õÓêû `yzü£nž[›·nÝú8ûúô­[7o~öåù¹ƒuÒ‡°þßÁrÇ}ž ‡• ¡zï|%0Ûôl#Ï¿£`ú· ܳٽ z`'Þw`aß8ï: ëÒÁó—*F˜ošB5ÙÖD]шgjª©A’/ž¢P–=*˪¨m ³« DCÕî š>ôà‰àØa½cºj•¯­SK£† Ñ Ý ¤œ×¶jXºIAžèh†ŠýÂ+ñ‰l¡ ݦ瘄à,ÅôKõLÌ¿`—ýº=ŠIÇÄ­"Œ‰¹âë96ás@"bS´+°.—Y Ç ÑË›c`“v0&Øzùa~úà…ÆPÏÄ'/¶*“¡!klT ¦WA•UÙ ¤wÞ¡¼—ÈN·{Ö£¿Ø÷è™_ìÛ÷ogÞ|[€FX–™œeQJ­2·RËXÙ/g'Ò­R÷WûK Ó§OÿõéÓgÎ@Êk˜åê㪠®P–Iî¯?~5ë‹ÏÎyW˜$ Bô†b‰ ½ÝÓõ½ïýÍž>ýËïÿÌvÅxwl…Õ¨°ßATÞ½÷W Užã 1è?QXƒË»ËAqظ Ÿ«WÝlv´jQ˦¦Ù;ë w”SŽfL»Ûùòeø]-ª†‰š„«­Ã†ÚÆH° só°Ü‰€å¶»×~ó_ìboîFmb°À+ÈSÝõo'È’åå°¼pm»3Ð ) ÏÞOž{ÿѵs¹AÕy•}ã´;ï¾ôÒ~|ðÝ‹ÅY‘GEÁ’*¯Ë“Q·,£÷ãoO¤ƒØîô÷¿íý÷ËÙê_݈?ν—Á $8J„}l;Ø1Û÷ÿç½ÿ~¨ˆ u 8j¯¡«°+ƒ,KCAjjwk7SyÇóEY"Dø9ƒú­>¶Íá— 1›Í ñÂѳçÏ¿ðÂÑb,gXè·,\ì@’:Nåm0Þxt¾°à’¯xƒZ™ãó%[Ö}Åod cü= ýçƒ=½šÂ°Ðת`û–8ôYX}ecJ¤hÄ¿7&<•°<´DB§Ös`‰že, 1ÐOÛ-ˆÏaœAa»ƒD°×qgÅ1 +¸\w×q¼Ààd}•ǧɅ »œO9üº³'€[,êÖþ]N Î®klñ º ªì¡)ØÈ#Xɳ}}¾ ¿Ð ,tzZ¯VÂÃǼzï‘Ý£]¯–s/¼çJ¡æ8Ç7Œ'j «|pWÕ=²wxXh ~|á >&‚uözay˦ª½w§ËÄ—÷[¾.,,}v_‰Êƒ sŽESð#fϯâÇéšnÙ¶é>ýtHQŒâA‡……‹zøÀžÝ6ìÒè!È}ÿåö…;^ܵcþ.È~é‹ nÿä§>öÔïßsdý‚õ;n?°`ÁÎ ë÷î¾gÁÛw/øäÇîùʆC‡èŽÃë7ì;ÇÒ#ó+r@Ê#"NR4jè*ácѪêhŒçøa`AÆ ‰’Óíºšã²<¯ ß À»|Evyî[½nï9×…1]®{oyXë¶Ý‹=®Ý QÚëv]³TH”‹ RÒiHÐ)hÃÀÂA¸ X¸mï`<ÃRÕô( wk¬;h謑|ŒZ ø>ñ$ðLãåžnjB{´'Òy@Ë3/€~Ű×ϰøÜ tÓÂù™Ï‡°Š°nR!~ëCX¿c°nR‘ÌöwÞ™”¿‹ EÅé{zX!G6¦„u5¦2rÉŸD$¿)K²rcH×Ú×/l×v´â+’›::6kŠÜ¾YÛ{»æÿÏg^-Ÿn¬kH—¼Õ©‰qˆ¹¸$Åc¼z#HWæÿ”P[I!“nnlÌÈ»Ä;2ÊGEüÿ…"EˆœL”üe01öŽ^¹( |(Ô "¶â¢]‚$I±ÿÂ4ë—ËÈCIEND®B`‚nagios-2.6/html/docs/images/cgi-history.png0000664000076500007650000001327207436604436020330 0ustar nagiosnagios‰PNG  IHDR–sMV átIMEÑ ‘¿é pHYs ð ðB¬4˜PLTE !! #!!!!!)5!!!)J&] E"'")))-1)-5-)A+5515?59B9BB9@F@?OELNHL[KT]RƒJAZZ))c))k16e<ÞýôÞï{ß{ïNŽ[©”ß½…òÈ#}]‰Î¾GGÇÆÄæ­[·þΦGÙ´iëÖ¯ÿö­”‡v Û›Âæ7nݴ顇Þ´iÓæMýÊC7‡B›CÛBŽWº:¿}´3qt_ÿÁ£}ûöƒì;Ø×?´¿¯ïà“C¶< Ÿ¡'Ÿ,ìK{Ë‘'‡Žá":N ±žCQ!}@ºÒÑDZL$A€%Ý%DØ½Ž¤\-éö—'邈*c„¯Ÿæ‡·€¦¹ ˨$›…Ma« \NiÄ ÕÕÌRsnA²Ï~šµrùl6[Ù…HQ€Uo…uW(T º#õ¡fwØ‹°TC>=h»…ûpp Œ Ò3•מƒëæí 31ÂDYŒÇÂB\Tñ¤9séÒ¹ÙK3Ùyaͼ8I Œ g2j¹U#«ŽQÓ¥~Yò‘xPK!+‹„Âá°Î-†."D"ñp(ˆD‚´âÒêÄÔä…©©éÿø(Ϙ¦ë2iD§†Æàìôøä¹ÌXFÖÙ“™“™Lfl,srô„Y +âX-7j>Qt‹4(Ř_ˆrXèÏ%¹ˆ‹3,+²$ã f•—ž¾pnì¹÷  oè¦fhnu¼Ovv8365¹‹Ø„j¨l@«²V†Xõ ‹:‡c­wUP^#ñX,Áø 0 ÅÄd4*Ð çs¹ìñÝÿ4óÝKóÛ0ŸË^%ss%Xþ ·œ—×ïrºPœN?‡n¶T$Hqœ–w ÂÎ.]ƒWÁÊg_hÄ‚•ßóÒñÝÿ¹ÀXœÊìKMí'†ÏõNœ¶ °‚¡±pÔõ—tåCXR¬ïÄx\„a8X“Õ°òÙw˜¬SE¥ ƒBe»×žØ–s ( dnnvn.›ÇÁœË!ø¹¢¶=ËëvÚÚr¹¸¶zº‘ã ˜QV >€ ad¤f¨ùEÄPµj¿6³ ßÃ(e¶‰TpkÕ†õëêê몹µ:¯*áx< ¬‡otO<Û=©híú°ôj+."Œª¤›P¶•«`mCÁk(ŸêîÝ7Ð=ÀEQøfß0óz°j˲ÊtŸµ®ÒÖª;£®¡¡¡îŽ2¬}½{{÷vïëÝ×ÛÝÛݽVûR\Wƒ+kd¦ræ*a5¶‚ªÃPs ‰åöÅöDöàΰ#ìˆK0b-°´ìtª{2³Ï0LA© Xç:'8[\ÜI¸£DIÁgAø¦ºíSÎû3ËCsµ ûšÍ•†« «)ôùC~Ÿ?蔄NOŸ>uª¼@ĪLËQ©-jÛ7C –Ì;zƒÁXÖϼ÷Æ™×^{ãÌ{¯½ ì¾¶Â:15k:Õ;9<žIfÆ2°\ëœ%ڞ˃°vîììO$vöu ýûwöïÜß™èZqX WM>%Xw646·ø½>o[ss³¿ÅgSþýG‡öõú‡ýCêeÅ1YtæêYZ©ˆÚºç7ÁÃ{½.§»Ñãö¸½Xý¶ôÁ²Ÿ:|!F˜ÏdFÇOŒ½øâð´êZ#üÕ@S Éç]ò6û=ewj~p­|FÌe-ŒmÁ­^ÌfgfQ[†.ƒ¶î¾ÛÛÒØäjjô6¯½É)†E }¹9ŒgÊ'‡õÕÀ†6¯¯±!èm‚×y3a™‚1ýâð$ÄÍãS£S£•°@[`ÃfW‹×ëôÅnjBfå²— ;UÚjÛà÷4{‚¯·Ùíq"ˆ›£-M›˜˜½*ã°V­¹§Ùßäsy[šÀŠÿM5¢‰†c¢5¬º¶ ­ž&w½ÏÕT™bÜ1pš%ò|°kÖøüÍ>w‹»eÝí‘ìµås{]õ!¯»î6‚µjÍšV‹ßðKnëfQ~X_n»÷k~w‹«ÑÕlr¯¾m´µ~½ËWï…yþóvåXµê6«oÙÚò¬kÌÓ +À­¹Òj9°ê|‚aÈ1šü¾P( ‡nT[s×FNËÑÖ½kÐ3Ô¯v:î¨l>4MÓ€ÏõzáÕÆÆá³7›ÙÛ;Ö»÷{{ÏASîƒ%ü¼,U°Z[Ãá0äc^( ‡¹—¨/†¹%ÿÙÉñÉ©©É SS3S“S“—–üËyµUEù†Õ7Î-Ûˆ¹|sË0¡ +âøÊ—¯Š·ÜFê|~0P ëÊÇ?ûøÊç·„_¹{ÝZ§³Úo}üöí¿¿ƒŠ´GaI"k#¢DðUœjD–‰&*=:QDMñÑ”$>N_§¢¬K&¡Õ4‘R"Àô&š¬—k‚uW[k” „‚îJXmßøÙ•Š¾‹Ô†æl'u¥2>ÉÕ0Xæ5¢ãžßúÏ\Î X?ÚþyÕÔLÈì5C35ÃÐq1°}‚ýÕ \óÐÝ2óXr6-í£tÃ2¬¼nÁI³†¢— ë®@kØçk …>9ó¹òöíó÷¯3MÕ XéLGË茩Ô0eªFaO§LgЮ1F5´ëªÉ¨uÊ04ñ ¿25]§T¯ –ãž{îs®­_ëqº|ewšû¯ï\¾q;,K Üj^ù½A¿Ïï,Ã:~{Jd2Sˆ*kD—í題P&QÊ@k™ƒRIW$ÆøÃM–d‘Ñÿýè0@…*¨SÕR‰Ö ¸uŸÛåô¸]nWÙˆÙgï\˜µPò| ¬±×¦}\hÀâ–_Û¿Èç?·>+tÌÛW¨Y[¦uÍ.ÐWå ²ÿ½ë¥sø€m–ÎI Ào“C€¯añ©ÌÒ‘î–É©ŸÏ}ö96ˆÝòxgÍš b6·îZëôzÜîjXÏ<ðàŸ¥ð Ó©®j¾¸ËÑ |bÆØKjTf*3°>Žbž2(´S¢ Õj†5ŸÔgßnéÓ[IùU­÷­sº]°TèkõåìÚýýnp7­1xMP5ȯ«ÀpFTªéØNœHDa\‡*Ó ô%*Cm© Ep B¹Îsm­º÷Þ&¿ßób…¶.ÿuû®wgx¸e!» À'p¸A–b$Ë^†ƒÁwóÿîC(†„£Z8o,Ÿ»üîåƒÇpIobðÅB·ŽÂµòFÞÆep—~¾0ììAÈç- ?Âä'øõø05†…µS;‚¯¯«¯H1.ž5Gä¢ÑKå€Ñ:ãáš2K³2ŒÊ’ÐAVÁiÁ˜0àÌØDŸ§ËÍS‚oãPœˆBEÃÀa!ãü®,¢­ºÖf˜©·„a¶Þ²º¬­wž'wK)¿~Mƒ£˜ñÔ;Ö`ýd×c'dð ¶Št¢©Àjœœ3À_LEO¯qe ù)Ì}ÌŽ^“™…0e‚¢(]:¹ #±¹u D5ÈBM[ÂÖ_µÇÞ9kp6A`g@p!Ít³è_ …‰' ?²Ü²x»eèyÓ)µÁr¬Y﬘ƒêsÿûw¿:Þ2ÿ'ƒ©òÂùmÏ)|Ü«Md5Η(Ÿç„/®LËyîú­üÂ3’ +ÐâõùZ¼-Mž¦6o#“|ŽÕ¹‹ç/ gi°pW¡8ƒ9À”„ÀšR›ò‘uœ¾ÁuwÓÁŽà£˜&Êàý‰¦p¶+¾zÅ/%ôüøJ… 'ôE`ÛÂ1(   ù8¬ú¹sÏM-'{Y.å#ŽûЈ.où!™Ë “Ï îW€ë|N¢ëèÎupìD…°X ̇ÙQ…}è †ðºŠ¬=áÂZƒ9Ö2WÛ¢mƒßånðºÜ~O©îVŸýî[ÞšÆ[`L¬[üÅ t—G˜øŒ ßÁ1 A´Îû÷¨¸ÖxÀ“ž­ÁÉŒ¸n½Ïçsy|-¾PE¼õË]o]Êæí€)_tèW3Õ*ºt¦Lv›Ý¸²ŠµÁš?‚xæ-"“pTb=š(útBEVNÈ€ÌÔ £S…AtÊÐw©hBI¤Ì¦9†³"YX¹—ÜûießšþÞåÉb°ÞÞý'ã#ŒfNnƒ;jˆï€å<7"ã‹>Œï0ÀÀb;ZØÂ@± ÌcÀ³¥ç=‹Âºüí‘ñ ýu$6)9 dš8¼àÖç5dkx l×ø«hšÉÓIÌÈà,¢GÊk5„§‹Áúé7rK²`AøXœ&±!2x{m B*Ö ðÕPY¢²$1pÞ&D³"øxA1dbÉ’¦‹À{iéžk1X?hßû«JmÝ”Ͼµåøä¨©rŠÀr•á.ðÛö›< Óì5xN ¬OX<¨ÀŠ+8åñhe`ßW'€×:ÐBNœçÌ0qÈé0áF€Œ³ ã> Ç®S,^ nÆJDH_ßÊ.§Šýñøý[ ”OÒxEÙM¬,»Ny*ã[dLNb9&vhƒø_ÄpÈPˆe¡·Tk8Ÿ¬Îýéý±÷+)?ß\k]³©Žìnp˜,æåÿý÷þñߊe7îP‹e7­ºìfÚe7£¢ì)oÕyz©|¬¬OxÙM³Ën:3Ëe7ÂËnxh…²)—Ý 8Ó°ìFLÔ< ƒ=¸ Yº›_ Ö·ÿè“+K¾ÒŠÊbîôŸÛw=/2YŲ•xÙM*•ݔ겛 ! ¤±0 m]iLV˜*Rˆ¬aî+Ë5&d M>îúùÅbÝÌ\JÙ­X{+yÓþ±™· o+£­Ÿ~óoß}³XvÓ«ËnðS¬NØ77xÂø¬>°Cf+ ùÏ9ó| nt)°þ¼½ýûJ¡ì¦R,»ÑRÙ V˜[cf…ïŠgÔg€â˜\3m„''̬×Ro»>¬ÜÏããµÕ V. ZV>wùF+#Ùå‚\Ö \8—»ö%Ò†eÕ$xµé 3ïO gÇ3cSc““ÃWíW¹¬‹ÍRµÝªpWyÏ~}/˜Íô>÷ÜØð¹Ìsß›žÌ \€¶9sÉ–ë8µ¢ÐW V™aËøñõ`ÕLÚ•t= †/<¸{LáEJ¬¸Xj$ødI'С‚AU¢bœõ7)Å`ò}Hpyö‘ò!ÌqÏòHº±š`-üî؜åõHœi »bS.RêÅ"¥fê“çÏŸå»&¯që†õ ¶0ø2kz zÑ9q×ÛïÏ–†\Þ´§d{S¬Nòz¤Y˜Ë “vÍiwäá)/ùWÖj˜#ÏïÁÀ†ªŒÉ¯*R–k:D0¬Øô`ÅÆþG¹QhfTQ0}źH …XÐs9Y®%:•ÔÖ¿¶ÿå'KJ_s¥ÕJ “bŽH]ÝwÞYW)wÕÕ­½òãíO½zÌ®Øga(Ï+6Ä®Ø`® ´¢¿8¡a%’A" ÍšùÃÏuþŒH× 5ÌpÖæ¯ýƒl©n‚¢ŽÓi’þö·N¥ñŸ?FFŽÚ0XìØSO“Kÿ@óĹ'@^=yB=òÊ™3ø`þÕWO¨pRt(a±KèåÊÿºFb‘pDŽF¢ò ü÷BÂFäÇâÝØ-Ši¹«+I$HDe1Nàž‚CŒâ¿H'Å[ B,‰Å„hX"‚ À_Qˆü?_YN¶E½”IEND®B`‚nagios-2.6/html/docs/images/cgi-notifications.png0000664000076500007650000001673107436604436021503 0ustar nagiosnagios‰PNG  IHDR–tPS;YtIMEÑ ècQ£ pHYs ð ðB¬4˜PLTE  !!!!!!!%1%)!)))%1!&9(11!.9)§9"Â7#VZc-:@9F6BJBKYK[_Uc??cNOkWXpws~z{–qqÁ·M<œ„fІœŠŒŠ’”‘Œ––”°“Œˆ‰Ÿ˜˜œ¥œ”­””Šˆ«’’¨”±–‘À4Ú <ü Tà(oã.‰¥‹œœœ„äQ‹Ê{¶¾/¤Îu¦Â“§ô‘¥œœµœœœœ¥ªÇ–œ¯œœµœ¥­¥œ±¥¥¥¥¥­­¥©½¢¥¡©±­­©µ­­Ã­ª°²¯Áµ©®É­½ÿ©”œ½œœ½  ½¢žÅ§§À­­½ªªÆ©§Ð±±Áµµ½·¹»Á¹·±±ÎºµË±±Øºµá½½½Æ½½µÆµÆÆµµÆ½½Æ½µÎµ½Ô·µ½Ê½½ÆÁÁÆÆÆ½µ½ÖÀÀξÀÜÁ½ëÎ!Î%%Î--Ô/-Ó36Ø63Þ99ç11ÓB+Ò=Bç99ï9<ÖJ1ÚFFóNNíTêooÿccÿckÿkkæuuÖ’’ß§•便β¯ÎÁ¤Ö··Ð¿¿Þ·±ëµ³÷±±ú»¶È÷ ùî Ë÷>êðAäè{Úô˜Êå°éá±ÆÆÆÆÎÆÆÞ½ÆÞÆÆç½ÆçÆÖã½ôÙ½ËÊËÊÆÖÖÊÆÓÎÓÒÖÎÖÖÖÎçÊÎïÆÞÆÆÞÎÊÚÖÒÖæÎâÎÎôÍËæÜÒÞëÒÆÆÞÆÆçÆÎÞÎÆÞÎÎÞÎÎçÎÖâÖÎÞÖÎçÖÖÞÞÖÞÞÞÞÞçÞçÞÖçÞÞççÞÈÈõÎÎóÎÎÿÎÖ÷ÖÖçÚÖëÖÛôÛÖüÞÞçÞçççÞçÞÞïááóÞÞÿÞçÿçÞÿïÖÖïÞÖ÷ÖÖ÷ÞÖïÞÞ÷ÖÞ÷ÞÞÿÞÞçççççïçç÷ççÿìéìôéìÿççÿïçïïï÷ïïÿïïçï÷ïï÷÷ï÷çïÿïïÿï÷÷÷÷÷ÿ÷÷÷÷ÿÿ÷ÿÿÿ÷÷ÿÿÿÿÿÇð›ÌlIDATxÚÌZpWzWÜ›‰)`b¢›èO Z6Ò"%¶I!›áŠã³ÈZñ¶‰e ÛkŒ—4ô¢Ù æškz×¹„˜\î.ÜÝ6mïÖ(Ê‘ÄÉS9±¬ö&žÚà)a†É¤‘qˆÃ˜™³ ¥ß÷ö¯lc É‘þVÚ¿ï­~zï{ßïûÞ®#ª®ú³ÿ7¨nÄ"±*GUheõÝ€»îZw÷Ý«`ç›&î°vî°Žîø¦ÅG3owܱjO<äo­r„V­\¹òî•+ïºkåJ²w×׉•«ü«Vùý«½ñøžî–øŽ­;vt·nïê‚m×8ìêjÁ•ý ëc§«øò—EOWwwŠ Þ¡2tc’¢Iš%Ãt¢Ót |6§¨•º!$o¬ølw €–„xâ Ɇd2)ÃF&kI6Omeý ©W’¥¯xGÖ! ’´ë‰¦Í»à¾O‚›äöê6 LÅH,©ûkäXG²Ü›m'œÛ£p”l«Ž#¯ÑúvÂí†ÉÉÅUä”@9T¸Ý.ávÁæñ¦ÍX&¹}U=”N6Å«’øûìnB+J ‘äÃa,¥‚x”èÆ2’\ÏYù‹Ñ²Õ‘“OÞZu§ß¡ ؇þ´Ö®Ç<ö…¯ªÇVj¯©Áö ÓÖn¯ö7!‘ÆP6;9?Ô1B= òj­i&­Úì÷“ÖÃ<çEX°@`s›ÀKÏ5%à¨1‘ˆ/¦1žhä¡T ± ~œÛ²…k„Â\cS»~Ï/ÈH.êÊä“ô'@ ¨ˆl€ÅØ¥ý].†f“.Œ=ÓÎXV’ÂL}=d‘〤Äë˜ Òª§ÒÂ’‚«§5vÊ’6±vû¿CâÑöEÑ,gìqˆFnfœø² 7lO4‰í6®,t¢œÜJpaŽe9VØõ§žø+7 ®©ªa³ÈÐL˜ h†Õh=ÙP•€3Ž »ø²å¢‚xÓh©\c(Þ$ 'À—ã ÕH€a=;_uo]a†­¯/bp4ú)Šºy®“¨ƒrÌŠ±É¯‰¾­ñâî¿l[_“Úwòj×/OÁÛK—õÛ]‚s—/OY%$†ÐR\l…FÆ_bÐÊ:fõ6ã³ÿ¤DsQ¿à SŒŸfT81eÀüGSÇ÷íë;ûññãÇÏ÷= Ÿ³¿Ã™EÐ*¨ª›ãÝ O w ¢G bkå–£9å¶bXôà6ꢻÁí)c•)ü£—.á¿ý¼P.Æ …¼ÏçÇ Á.êëûðøÙão˜¿yùÂyÄÜL}öÙعðÙùÏàÈ,’Ö:1ã¿âaŸ DÇù‚*´Ýx&à§üT Ø Å2ES”½±bµÖÔ‘Ã}‡?&MpITò¢¤f4SÅ ^>9غ¨ãXTVÑ 6Ñm‹rR•~_%ü¶wÏ·ÀïÃÖʈ8/hExêÛ9,\;Ë 6Z€×~x6ú™¼š·._þèøÛo÷·u´Ì¥e/VTT³¶›¢F«Äëñ.&ßËäŸáYޝcÙ:¤>ŽAœÛ£í@W´uâ•+çŸ?øÒCV{ä3›éMõ½´öüÔ%ëı5pd5ù?¸R”™´*fb Ð ² ÇQ(~Ž òíõõ‰F®1šˆŠÅ¶…´ž?tíX°_Ío}éùµl'>….ýôÂÔ¥©O§¦®Ì –Ççõ¼«­<؉"Ol•|Ë–-ÑÆ(`­ËçïÙÒ;…±Éññ|!ƒË8¬-úžµ‡l†s飾ÿëƒQðQßÙ7¦æ åöS>¿ÏEM£UÇRS'Pa*HÉÅP”ibÒì>%ŸÉ+¸òÂ}òÍã[§ìïó³S3ÝâÇ ÆtZKo-Gõ¢c|PkÁFs7‹×UüAZHìÇÅ?~E»JßM †IÕÄ<ïrw¥»²dš—ì¨CDX1[ꢰ0Gv*ŠrMZcã““s\¿ÚÅ1Ž‚¨SµÖš·h©Ëíö”N£•ÙùÐ#<òÐÖG¶Â‡,ÁÞNy÷îY:ñ«EFo-Wye¹«¢ÂåôTT´òG¶*B‡FK¾ ´ËÜ8½nŽHKƒ÷ï­ é ¬ 2t” )J7ù±/ÿã×¢åt:ËË`òNË𡵊ÇÞn±èð&´–ë^¿×ïõù`í+5Ääxa.L~ùŸ‹V[ Ü©Ïåñº\>jé·þ¿{]­µl18®ŠrÍyá‚âóµÓšï[ŠÚãò¹¼D‚¼³D§7™vâÂo”WV:++KÁöNq¬¿/d4ä3ÓQ0÷НåóW«‘Éü6sÝÈk­õ ßrŸÛãvz=n—Ï lDŽaX&Âu¸ÃÀ®4ñÙÓ¯@¼¡UÁ³¬VI»[Å+°ƒ±ªy»àtÛZ´Ðå¾Íír¹œn—åå1tàáB¦‹Ö}VDœŽàýw (;::D‡ˆ£ʈp78ŸÑwÁ鉙ƒ’xyËí*w{\•°Õ™Kú?fÔÛzßZ[µ¶`ŒÖÒŽ<&g‚µ¾¢†&.‚>„„|u7?>šÎfÓ€|6ÛŸÍjûo¼ýüs?xî¥7Ò6€Qå ÒYxö5‚¼¾}íµôµ1[Ë]ér.ñ,©t‚8ê¢8™kljB‡žn«‰ÔÆâ›þÈË«Wì]ñôÞ§<{ð>4(ºò£ Ǩµ4ÚDbñx$ÑHÜE¨ ³ñQŽ DõÔY¿6 F±tQD7 Q½~ÖD®¦&BnØþpCC¤¡ÁNëïØ`ÿ3ÏܺEÀî ŽåѤÕÑРӂOƒy "k()áVàMÒ³Òò,s•;ËÊ*—8+­Àfâ“Ó§NbFOžœÍë8ûös?üG‚þèìoó6èŠ45N ŽY©¿ntZËû|ŸÇíõºì´Nœ81œÏç Ù®žž÷ßï¶h­~zÿ¾ýûŸùÞ³/+Hª¤ˆ²hКèïïé914Ô3ô³RAUU‘U•¾ªšV¥«ðÒi¹—.++/½Åí*oѺx®¦6–#.¤š×­ky,’³ÓÚ·oÿ¾}@ëP‡¨Š‚¤xY2[+iinŽ577· B… ¡i§}-B§KðWÐëÌMkùRŸÏë÷ø|”½µÆFGIFGOŸÖ÷¯·MX=sc@Z‹¹K¥¥óJ•f{MääTŠ˜|2™l3Ÿz&ÿôÀ䡵$ô’`ø’¨ù,CÔO™•ÒÚä-ÎÚÊ¢"‰ Ù›ªÙ‰.¤d~¹ü^ƒÖpUUo›n¬ªªª®ª*v{÷>µhÝd9–®‹†Yše Z£¡PU¨VUqy·á šæ¨0Ó[ǃá =«0h9æÍ³ún¾Ñ\§O õ£?̽è7ü©zìWkÖ|Ÿ`͋ǎiç`?¨Ó:—íÇP­¿Ÿ\Ä»èåL¨éég¦¹Sˆ 4^6ƒZçFNžã( Ÿ$£}dú-ø­Ÿ?¸AÛ^ÏSÓlk] T9uzä Ø–Ax—C åsc†qª¯D£ÕØoÊ ÂHŒÇS‰x<þä FëõG×ßÿŸ#Öoz À‰ÍÉAŽ–Â&­ÞD,ïl‹mKäô˜/–£ÀB§GÁY!Œ³?sÄ… ƒ7­(/--¯(«¸µ’´Ýä9°Ø^ QHëúðeïõG7lXO°aÓ/ß$!Òà ” ZFToÞÉÂôØLÐfˆ·æù0Áð¸}e~ÔݧNŒfûûß#7è×Í@¿g2éWvô§:~öªMy36Û2ªdÓr)'k­œ¹ÎÌ%ÕŽ[Ê*œV,€ˆËå­¬ÐGbl[K,…škÙ¶­¥µ%!Cê cçÅ£?ݸqã7þø'¯½7’à l AY´G;·57·´¶¶´ÆM‘†Þ«£9– ×±È"˃hsìlcщ³bb¸!‰ ­¶Hs¼¹ù±æ„ž"¾xôè+?!xåè_¢Tƒç†•ÄSg ÕÍëÀÇ7G–¢Ó‰H£Dƒƒ' Uçô[‹—•RO£untdÝtav†Ë~çW¿¯ãåwþcV/?2R\Å>ÍTs®‘ˆ^~6>ÿ-ÓhõæzSY‰éÞw³©áÞK¥5_ðÎÛ«W¾ûÝ¿_}ðp‡‚(©2|“V& ÖþÞ»½Y³ è4x)k3ñ;Rd)­¤e¸ HjvÌ‘èZ´l~Y9´—³ÄN«!ÖkCQÛ\‹Ejp(¢Tƒ—zÅÞDª‘i½ŽfL©†ªÐ…‘H"gxµ‚‚Å«‚hN} N§¡ÿENŽb~å!c´Ör·–èÃÚØ|pæÌ§GóçNŸÑqzt†Th—jc`ÜVctF'^¿T/\6ßqËm¥·Ì+µ›üžîn¢‰É=ä}Œž®”Mª÷ƒRO—jœXEû5£ÓTwWWWwwO·¥ÕiQ×i9o>ÙÁó¢ kÏnÉEÝ4y7(´Ûï£|~kút"ªjÊ™ªn-oB!ãêÈK«o¿ýö·¯ÛZ‹RM±D?Ñ&ÕÕ55ðµhEYš ÒQ:˜1:1ÏDiLø‚A&L±Áp]¦©`PR¯@ŽGbùE޲r‡£ÔQj×ĨšêUyØjP5ûÅš57®ÁåÅcª i½ *NÙj2ÖžéÎÕÙ‘¹RÈ ËCkeQø±;Í0 ùÑâ±þÖ/¿õ ŽŸ¿Ud¶0päË„„–cñBPÁ²²yÅâ“ø¶m¨´×µ¶Æ´°F"‘êõ(Õ6=Àp"Oó +1‚)Õ½ÛZZZwloÙ®ÍØ2‰… ™Åׄ¨ˆ‚ ®… ¬æ,Ô[Ëëqù@ ý Šiuî iE!ÛMÞ2he@ª )Œ þå5»ð´°Ø|W×o†MQ$Ôiû ŠjάÑr8æ•,¨p”Ï€_}oà], ’=4Ôß?`ÞóÕG4#ˆW_ß ž±¤:72=Ð?0ð^næÜNzÚÍŒcƒVqï´r‰DBK_"‘¸– üÍ&[¼ÅpQÈ•¡KÞ–U'°Fâa«’’æŽëxòhžgÃu <b‚Íspž“,M$´æû–;ÉüƒÛkÓpzVÝ©­o£µá~£ÿ‚çÁ7c‚Á –ßjÃ,’ê뿤¡¸qâãƒZ—DynVà£"ÏO§åX¸h™‹ÀS6-h†p¶§ þÅ}">ƒ¯Û:ñ_Ñ"µ¡`ÚÖ˜fF†1 Äz};H!åÉ1î ×´¯Ñ‰³õâÄ'ýCýÄäû{Þïyè„F+¯ÍFkýÕã ¾"´æÕ¦ÉAþŸC€áœŸf ˜‘§?éµåÁ•éÙI5<Ÿ>]ZQ2~IÉ’ùöÖª©h¢¶¶ö±Ú†"Z†m}[ R­Š*o%ûã(înÕVW§rzÔ\€_R¢ ¾"$*X‹ ™.ÁGà á Ün7ÎÊû]~Ÿ•VOZY5&ÕDtGuZV'þúß-YäNOOK«oÜÎ[¶øV‡aU\²Ä–Uc*–“Ú 0yÓo}ûqò “L†ZYµñîbR1¢b }D̨A{ëI$ò¬è©µ=ÁVMñvÂ7ò`í2²êPޤt¢¡:T[] ßêêPbšƒ„¹0J5 S¦T' $ô|¨¶A—jENs ÏòÌã³@l–ÁLŽÌ ƒLÓ”Œ`ŒÄÅÚcNøÈ§Äqñ4xénÛ\ïÛ«¡pâ;›\¿^§õšMª{»õÒ©Þ™R}M¤uZ^—Ëâ6¯û6b^‰'ÏœÂÀlëÌ™SgÀGè¡ Ø–Ù‰¿¶kõ#q"È38íöÃ@–Ϥ|Þ{)¿Çï§ü~Í‘zœTç¶ØöDg|{s|[¬w°8«f QBô ‚L›Yu[<¶­³3¶½-7h¤¯šTã+t`\,ˆªÈ¡;…‘åD¥Úð[yBkéDýau%ÐJ¦:Ä`!Ý©!•‚UG¢eò¾E$™¨•UwUuW;]ªÓš”’tXÑï@Ü+úÃä—»+–”9Ë—¸+­ bbtx`•v470Ò GCx柋¥Ú›T“e`x©¾Ž‡+Z':^¯×Séö@Êo‹åc--m8†Ú¶C~ܺòê–ÖXçt©ŽòQ”jŽåÙH_;1ÞÚÞº£5ÞiDÍi†¬AªAY¾ò]Ã-Èv¢ ÞÑšhaÞ|­šÚÚ‰åjk×X7¯ƒAáýã8õÖ"RÍá$8¦c$ûmP~]$¥  k)æÒQQ%R ´ ÛŠÎEË®‰…á‘”´BvF†‡µ4ºÿ_¬Ý¨á[/¾óf^›Æ!0lkP«u¬0Pß’²fÈG¶3&næ¤u.—Ëfñ†él®7÷õfßíÍa²¿úvXì$ÓÚ ÕàÇMZ¹\o6 rzžÁ»€$ƒ C0š–µŒš·³»NZŸ„ª«;‰TÇ ój›«[`].COöW¬xvõ [yj}™W9+«†.‡œºº!‘3& *Dì¾h%pÄ\ä,‹RÆNmnZZV´Ê!94’Iîsh¥¥µ"%•©°•ñm §ž6‘=øRõо÷fÙ57oå]–Ý…‡gæûÞ÷ÞÌJITÕÌ¿“gPõ#±×#¦Å0°×ïáö]ÌØxn‘±éºô.ZãºüüâgeJ€¯é‹7õ5ÄùìâÏoU*Õʯï>¸žT55T]Yĉuä\“³üÌ‹ Óe- ŠZa†ùJw$º6“G"„Yu¸ÓÙÒ?Ç…?ú—¸ú§Nna—ߨ·~ú™”ü1€¡[[¡­ÁÝú3·®Ötˆ˜QM`áEE³a^Ä-§Å™¶Û²1—ýk‹ ÞxqÿÞ½û˜v{òXäØ kÙð¢üÿ¢êÑnùªz~i>“Ky#FbµZ]_Ç ÙûIEMcü -éSõJ情L.·”ËøòUEb–”®Ð”i`C%iˆxœ>†{"‹{C¹¸µŽn]O§5¾%/ž‰#/$âqÿ·4à6 ¼t‡@Pɬiy¤Wl¼[/A·šíÖ¡ÍkÕv³ÍÛ"Pæ|Œu•v°¸‚ªú€?ÓjµyË8ÈÈ^SúMÊüMèòìïóDÒ/{;{{σµêõ;T«®qª6Ì‚OÕ'öþÎÎîÁÁþþs{Ъ¥˜”¡AkzT=\ø[Wb×È­2¨±·qÑ­êíêí Öª?LkQuÂq JÐèÀֱĒïS€ª!„W€²U\G!Øiž×-®ª·­ãnC£'Öö¶%RõŸÛ‡’Fâݯ6`ƒ.¿YähZxäQµá­ëó¸®ì×ÃejvÎ.oÇc×øHŠþ"-cÕ‰œª+U¢êÙ$Qµ’ÞôU56"¥Fr~|V¤êèl¨š Ñôd€ø}9«×cÍ’žÍfuÝd®Õ]~˵ojL°†W.Ðo‚&M_«»×šìÜ6žª_öû}o„ȺOà£26'½¾öÜŠÌTõ#1—»…ñFM€·HU£a’R……SýýüV~ 4õ²žÏgre÷»4%J&@èÐŒ¥€¨Z€@ºp&Æ»•ÉÜ¢l6‚ãU5èÄ«<5Íc"UYû%ô|.Ÿ×aËçsu×­˜Æ€Š5Â@eXpBŒ¯±nõ]¦"YQU+ªjªwm{—’”¶ýš©ÚÖ³:Åòþ`øø=¿ßòU¢À¾²”–˜—i† £3ˆ¸t½ìŽÄ$ò´ "\Qˆ°œx Àž® O¢êX‚fš,p*¸Ebÿ*oÄw­e•/ia>@ÄæÜbK.@hj|ÒÔdTI'qa/[Ãc BÄUí†WÓÿäï>¡Y#cÑnñp«5ˆÒœWiDk¬[vÕgz3ä˜Qty·¿Xe ²ÃÀͯU£W «ín×¶Û :¨'x¦Ñ€.ŽóËàvÃ|=AU_In²">ÔÄZšTа앲N^€üsœOÄâ© §c¥¶…™ dtx]Š FàlBÌ•dC:5»Œº¼r¦['€‰½C§sìNpœN‡^‰púô7‹_ãvä¾è‹:¼OWŽGÍn·„Gû—Iá©ð%wÅ‘ho\ú«UFM<‚6V¿¿<°VÅ 4_€ž(×Ëåz½L»W&óoMš™25µTZ ,íy€ ‹Ì„C°Ép0ÜÈEô«X#Û¬‹âºv¾±²zè-ºÉ4µª¡:WÊÌ¥TèwJá†$ã êèT:,§^ûréÉ–’"‘P(™ …£áé8F<3p! ýGtÀj røÅIEND®B`‚nagios-2.6/html/docs/images/cgi-outages.png0000664000076500007650000000721407436604447020277 0ustar nagiosnagios‰PNG  IHDR–sMV átIMEÑ  ¨Ù pHYs ð ðB¬4˜PLTE!) !)!)!)11!!!!L!)!!1))%)1)11)!9!)9))B)15-591-B11J1)19)-J9991J9A;7ÐÚJN _c 5@Xÿz”غ[jó|«Ö"$seˆP®€%–%ÅÇzà*ê]‚Uÿ½_ƒét}=¸ N÷x!8p¢Ž´ª‡¡Òº‚ö]°µ0Õ@zþ艂úL­|'½µ·fï®*𖢜ìoî'&/éKå8òx õHš[‰ {VZ0éÏX»`À¸sPÁàÞ]["XÁ È²’f €%Îíæ€ŠãÜprcY¤îÚz7«À>H‰#äÐ"×ËíÇ¡YžY®­÷Üs£a%ˆ\Œ@öbäóùº<ä~„ÀîõúfE„N‚É£5^¦¼t2°dÕSA‚UwXÀ¸‡SÎ’Ö'§’¨ˆx„«k–eADœ$ òƒ{ƒÏ‹”ÃÜY ’¨ÜH¢¦ä#Üa:¼’ ,”úÚFqNÂ\aýò…%põÍb¼8JtUW³Â-¿d T5•@îdva)Ë@éc4†¬k‹+IX…2ä›LÖì*C®é«…&Àšþ/ÃL¸–%VP¼x¨BV]*M°8—›ãy–gYžç•(DþC!5IXE"Û/rR•tXr ÅÎ#‚…$ˆ°ûå'êêòù|þ„ÞÚ´þ&½Þ”‘gÌÔëõ bkt‰NLD'Æ&&&>=þÐþ9™œŒF@áÈ$¤W#1S4:[t":>®­‰%[FNNŽ_uø‹WøËŽ<ÞÝÀŽ¿ƒ¦`Ý_²§ÂMÛKí0L¸˜ÂÛ±$íxŸ œyùÌÅ3g^úÅó>úèÚD‘° "ÆpAEU$*ÑhÅx4špxau;1¹êÚóK¯ïNgoç©ýÅÛzŠW…üBÌë2]‰ÚA#Ÿ]¼¨aýé/hÞúÇÄj8‰mSà5’ƒ÷³ޚ¥ºE‘辿=д¿¡¡÷ʧ¿kØÿ÷÷} °tëÖWÆâWâÙ΋iüóW~:F°´‹ë¼Ej7ïŠD‡#¯|îÜ•+WÞïë½òÁx4AÈ—9i¶dñâv³ùå3gêð›Ïoî¹íÛw UU‡„a*#ä“ÌÆäþ¨kîÁ&è¬Æ+Lsg¥}¯9=?nxd[çÌhoå¬ÓQÙT†9s1o‰ÚÑ/×ÕÕÔÕµ‡†Î=¿‚kû+Oó°å° s‚(d<âÏ!A$ÐÆHx^qÅ[ká›÷õÿæõÁ¡×zO½12òÎÐïGF“ ¼õÍu™”ÁdÑë²–8UÿKÓ¿o,[33ÿc&ÓÖò%•NºˆfGÅÒ°V_ÚÂf}¦)ߨ3SFS a­¹¿„® +’¤–®`í]ú,‹YŸZEé6m*e må…©…EÍß烙.'36óèS ËXr KÚeK%,Ýú{auªÏH±N\³e3q–sá1RJ`ů·RKw÷×t±ˆ7¥–±|KYE9ã.ah[ aéÖ®ý •e0Pzüg¤ –±lK…ƒ©$1Ïä3ÎâÁ¢ÌæÜ9™µWrSËMÑ¥¶bº¸ØVTl·ÛÈÌXœXÕMär3ù®r†)§´Ï|RËJzñ>‹9Ö‹‹%?°ŒŽ-»Ýjµ9ÖÔ \Ô]÷fYlkž5/•Æ-*ÒXi¬4V+•ÆJc¥±ÒXi¬4V+•ÆJc¥±ÒXi¬4Öÿ/Ö"ßL‚MúR/™¤MCChJ iä4@gB;yu‡i(i M³ip2&ëš‚ K¨”Aab¹|ý}ïíéN¶þÜIŠÝO§ÛÝ·o÷~úÞ÷¾ß÷}oO±ÊÀÀ–÷Ÿ)xÿÂò¦.‹õmCö ^:::ëèؼyËæßºèÒÍ[z7oÞüî÷œ&¿ùž³&ïîÝ?:P¸t 76Ð ÙÜÛ{ÑE½jï};y_oo!ß[(äb½ñ¦ÑÑöïÛ¿ÿ¦n¸éÀ¾ö“ìÛ`ßþ} %¢ßhgöùÓ;· ¢Ê¸éF)Ã1w°4Ríï¯Tû†ªCý{`H¾±¨õßx–¥ªDq‡äúë&¡3j#fgoë=«Í­Ëº“7 ÕïþáºþŠ+öЉ†lú¸+‰ŽÜE½/­à‚jõãdSëøî:ú½¡QUǵ~³Êœ%@;íï©~¬¹$Æm\18¨` ß,aõ¬Ñ}ô‘¶þa kt¨B@ªÃCt#³¤ã¨rÓWûóÃKSWu®jõæ ù …·p´§0(‡rДçF· I¸DmÍÌ£h4í÷BŠ1ÇDÛÛžé·'ÚêÆ\2b¬°ÈÚ•‘&øl "¦Ó@Å(:Är®¿Ä¡3,·v¶Dèfÿð°=X*—1¥A=‚ué–=–Xe˜”9¸‡4ešg–kŒüö¨Yµ,Ã2 ôØHIÓ´~}YéášWÈlg‹)‹¥3»ž=Ps•bsŠ®„¼ºh_L5äQ›p´ù`¾×,OEÛ¨?•ø/XàÂÂUÛÉÚ©S§æµ«#‡Ÿ™8„߉§ŽšŽÚœA ‹%Ëq¦ÐQ‡²3e|f7ÝøIôÑNIc%«¯\*µ2u:955==9=}bzXGš˜˜8|øÈÑ,fIX¾ënÐÍ3‹VÊ´7pm´ÅòŒ®T,ƒlJ¥‚)AGèxó}LLLN~ùhXãAèú>ô,˜ð|áÖ¡;þÑÝwßù‘ù`}âVà&Ávım‹Ù¾pJKjÊfŽi%;¯yCw£›p‘Lɲt»IYã³`:ôÌyæ?:Ró„ï /øWOü¶€tyâá7yã™ùPÕüéÆ)ôß§Y~d[}ñR¼‹—ÊZvM.·!+i«LžÝ -Sh(ÑÊkDü¥·o}ø[Û3ƒ{!žš|ãŽÉÉ“­ø/ŒIèÚ«#›É¬’LvMÃä2pånˆä,{|ü–[Ôë–[Ð2˶¦¯Ùú¹¿ÞÖ°ê°nìêô5Ÿßzû¼¦5§pǬžøÒ;:^‚¶ŒiH+—ÊÅÑš6„ßÓL¾V›ºjS©ÜtÌ‚æ³Ûþêö­´Ë÷,ÀJç³iH6ÓÐÕ ¢eš‘ D¾Ÿ«6uÝÑ£òÏü¤ïz³~<×QCÙ××wk[¨$¬¾XªxI.ŸK–Ò³`90#Ý4Ý”uëtWÁç¾\¡bz~„x©Ö“Ÿ8Õ:¤†¶Ö­ë!™5б£ˆ¨€KÓ à*›À•ÍÅ`)qmá·Š`~X«²ëS‰T¢c¶—?º×¹îjȘu¶»ñÂfïÞV`-[¬µë©TºótXcÛ¶nÛ¶ulëØ¶H°sõÞ³+³>ÙèIÆãÉx:ž˜uõØ5׌ág½á‡cÖÙ‚Õ‹'Rét&Ia2fêÓ1t®.ëFÙBìc–ieŠƒÊÆÙ„‡Á“É7,?ö“%ÎÌ–9ã¹ç, b,Y.f‹Ù|®˜)æ;ë"\þÝ— +‘ˤóÉt6™Ì_²¦ë…sKú-9€r,{$ùË¿û²`õ­Î®KÃÔ“¹dVRP¶GF§ç\[ç¿«'AÒǦeÇ2a-#·ë]ÙõÙT:•ȦS©\#–oÿnfNLMOLNNMLLM´GÏgjë×/H¦ð“L&Rɬ—üv„P]uû5wßuçÔ[o¿ëî;îØö-èìx[7 ša3@Õ“J'„n©Úš~krjjrêç“ÐÖääÏ'O,y(#N¼c˜N%ñ¢%â©éSxÉ(úÔôôÒÇPÍDpb*‘Œwgº‰$Œ_ÁzõwÞY¦å. ViÕºµ™L:‹ "MŽ¢ `½ò?O¾}®p)X¯‡’ººÝ3áäØ7ï½j—V6uÁÓrËB7Û†m:‰üƒ¶å9–!,™¦a ‚Y'û¾gL˜:sæ9Žp,—·j‘¶Öes™\:—Ú€õÊC;v¾Ý¬­Ir%ik]¢«§ó¼T²su“¶¾wßýß¹Õ÷¨˜àû2Eˆîy!ÞDD3Ú èìS5 zúæ9ö1Á} Ž|¯åHZ™üúu¹|6ŸAѤ­c|vÇzžç2|šð…å3W×ã®ë…ŽÜgÂ÷Ø'ÑC8®`\xœ#ñqYÈ}ŸyO»\ˆO Ÿ{>Ç9áˆö´µ~í…©ÎxgçªÎDbF_Çúì½ÿûÎ ŒÈ21YèÊòÅ|®PÌÖa}í+;vŽ !˜ @¦gÛ }KØ,D^Í]‡3Ÿq˜½-lÛ²lÇcP‹`.’E9³-! 'hÍÁ l§ÕN‘ϪU±[]W×±¯~fÇ?ÿ¹žO¯ =Ú£_›€ò@?P§Õy™R+vð¦öåAÔhã·ì¡ë„ÂÕdð4ˆ_¹ï‰ÒÝ|ú¸G{t@ ¨ÊvµFÍPAó ¥œµ¾‚S«)ŒtYËïL‘ÉäR©L6“Ã+'›WÈo]íº®ƒ´ΈëžCÉ…‡ÜÇ Mq½mqáŽËLn8ÌÄFn‡¶ðL$û8…9@ãǘà&k϶.8¿+ÞÕïéììŽwÅ»•O=zâ÷ž[òÉfòð¦é|WAòò/ý´Pù>“>‰s¾ŽŠL{nàÃo¸äÏ<×sW0'Q¶u^…¥‰øšd2žÌ$TõµnÞòo?xÚŠü(Õ½€j}Ø Õt2 *‹‘Bx­;ËÖ`õÍ]i~éäïÿô¬^³¶$ù€©gÃzåÉYTmÚº0¡jÛµl†éªö<Ër#ªDÕ¶Ó6U¯_‹€&W8o¬c_ûÌŽ'›½üœ÷ 8Zž¶À‰k«»z ¯æbÒ±ï¹ïþ¿•4+©Úo¢j/òd>\+&Q6ÌŒö`T9…Ÿr‰ÍÃ:UQ·GÕÐÖŹ|!SÈår…¬çø‹_?(¼G1ÁÊî U“+Uƒ±‰_@ÒpPx§Ñ‚ƒ 8®ù¾Cs˜®#ªÆÐ.ª/CŸ—è®@ÿeÃZ·öÂX2üÎXgøžýôÆý»² 2âD: úIòVíG碾 üjè³lX™‹‹…B>×—‡¾°þóòí?þ/ÉÁõÈ@Qu(©ºVŸšDÌ(ûƒS° ©:”]BÉÖrÍSš­ÀŠ­=DWתYâ'Û?¸qûDÕ&Qµp Ï–TmUÛܲ1tDϮŸ,Ê!³…é <íx`+f3Ïæ¦=D\¸|n ·×’¶²'@‰ÙšfX°­ËŸ=¾‚v\×m«ƒ‹­êXuÌ®€¿ðâ‹ÇeOƒ‘ÁÑøÛ÷9ƒÞÀ×P‹à)Ü<<ø‘“å:ѹôu urgäÓÈÅ„äøBt.99/X ÖìÑ«Ã:~üø£Bf4tcÜR}ŒüXâk|rH-¼MíËä£ãJ¸8_8ŠÉ}šÕ¡\Ô…+‹Áê[[Ÿ úC2•mâŸ~²ýÓ/®ø ¶&Q!im")%ÝÕd[p×6¨ZXVU‡6BOð·k"_†Å#Ãð Ÿ9H3˜)`ùHF„ËÍújÔ`õÍJ1šL~ãe?nÖÖi¬,g¹šõá–¼LÎV3ñ½ëâ«Wwtt¯Ž7ÁúÇË·?ö(ѬGq0CÕ¾|k$@¡ÌjM²QeAZ]Òåè Z‹Úù¤²¹|±˜,äiõ³ð[×þ¸˜;4|×FNˆYäÁ?ª-N\d "$Ê 92j²j¤ðSàÏ|î tÁ›K8EßqZ #êMw¬nUݬÇ/ßþü¹4yÒV¡ (WH€…T`óà—wîÜE“ÚÆ‡Fl_&X¾ÝLÕ2¢±ªâØAgNåx:—¼"´.VìBµÌYZòé@V½cÇ?}{†ªC2¯ÙT-ÓmY·‰bB™¢Ê°0T~PçÏ¥Àʤ‘º¦ÒTjΦ’)ÒÕʪxûeiÏ”¯«¤=”&eíÊ´•ÍG¶¯k¡"mÉÑâò¶ +—ÕJ¹¬^*¤ …¾b1‚…èt§…Á°AÕàb[÷èi=4쀪™í[›¦e#͆Ù;ä¦lË‚oC\jÁeÙS%|Ëä¦gµŽLù­„Ä´½hÝ.{î_vî|}jà¯rm¦ÒïîJôt§ âùÇ/»ò)yæp8®ð8öˆ ±'¤QIb&>ä’z‘_ÓÃ5ÒÉy’—ü¸\´ÌÏd³éD YYºÉomÜø¡?&ªv‰ªÁÍ2›öè!?„#-»Ò£ J<(H°| ›a\¬æç·V5jIÏ¿~å×ÏiŠ1w²ÿÖ—6múómœs¢jÃÖ=¢j¶c9¡ipl˜ÉñÆà¾] Ümø`j*:!T´„ìÙ®ÁìéÈ?4aš oKwyÙCxK‡õæôI¬×$ÇE5ÉÎÊ Dç¼­ZgN•×”Ã"¿.2c€uì{÷ýåÿP§jYë–±E¤ž¼¯Ìš1'|YÜ–þU•Å•w#Xä|ýåÞ‹¦­Â"¿µ«NÕàËwƒª‘/„`iŒU=(Yt•áÃI1"(L 6³q1“¥&&¨ZÒ¬y IÏýlç95ùy`=ÿØe—}ˆØé4ÕH[uªvéyF¤Q4„lƒÞ}*FQù-ÿà¤*ªA¸-ëkAŒ²jr˜¡de8Jù£¨Ú÷U^uó’ .Q%: °Qv—ñ¡JMÚ-€Ï)¯ßzõµÈv#FV³N%òõÊw0S §^ýÚÌt‹ŽÚÄùÄá·LîrËæ‹äÚŒ¨Úf‰ôæ-,[X&ò ×á&†S‚Ó,° ë`H½¦cj évŒöV1æ†õÝM[ßj^Øÿža­Ë…uì¡{îýûPBìÊLj)œwU»BP¦PNLI¬(K9dv”`ÐK Éë´È(™á`}õOwÜkDÕ  \Q§â#mÀgcÒÄ£‡we9ç8¦óeôPøЂŸçEç)Á_3ob½Ð ¾ýgßýåÿCªþ›M›î„É»0y—Y¨Ú´>{&#ª¶`áô„—Ë\­œjß8²M ÎÌÅä cÇÏa¢åÒwK°&§ÂƤŸY ÂpÆ;4µÍ-µºY)XoÞöù7KwªH¸™ªk”6øQh@)OM9ÕPVÀƒ(y–™µÌ|Úœ•‹ø­»öJòQTmJªæŠª‘ZÝ:"+ ‘—CKØ‚ÉnQ˜E̱|ZuuWpŸØt[{H¯œ,ä ¾yÏg¿€¬Úã’ª¹GYµàܧµPÐR…ð˜üDЋB‹)iø4¹Â/¨V¸Â°à·¾£Â@YAŠ•nTVMuH/biY lˆ§œ¾ÓèYðéˆN¹ÅBæÊ5;$P3ðHX´PÀ‘SpY™íyôL™p97‹M@¡×"oqMÛo–|ÆæåzÅ-Œjoô뫹 ¨§äÚžºBÜ‚ ñÙª´¼ %å· ë­'nû⛇UõQ•W­?cS‹ž QËvDÉž„%;4Qµ Ú¦jsAªÞõ)µú ïà $ ›¦çeTÍ#ª¦T,DÙpUEÕ¶å-…ª™®ÅJÝsÊË“¥±Ó+ò%Å3åµ×æl™ŽÚmÀâ»íjÕfÍß)f”zíÝ»kl÷²¾Á½ˆ08™ƒ”ÂÉ/Žý¡ëŽÛØÄŒà܈Ù}úÈP¿Yÿú0}eŒj¥>üèZ©ô+A$¿@Í9Bñ²Cßì«V†G*U[7«l€ÓœrlD3FFGWüëÒ‹‹©kå¾R¹¬õËÿó0T.•´²Ö§ÑJÿ®žôìÀ'IEND®B`‚nagios-2.6/html/docs/images/cgi-status-a.png0000664000076500007650000001662507436604445020375 0ustar nagiosnagios‰PNG  IHDR–sMV átIMEÑ 7'> pHYs ð ðB¬4˜PLTE  !!!!'))%6)>*11-6939B56Jפv¤‹Iq‚§Y:Ê8>ÄRúƒ˜8•½eZ¯yNR×ÏÉ:Í4P-ܲìq;BwRsl÷¤$ÛˆÉî*×:í¡vÕ’¦Mé½whµ!þÙÛpEû#½ï÷ÍŒí$vh)*|ÆóæÍ›7öÇß÷yß÷}oÆÖÛÔ´pÇwéW‹­É¶hk[´ÉæoªkÚøÛÛ·nÙR™¯õ}Ѧ-­Mõ¶¦úººº-õõ·ß~{]}]ý–Û¿Rúú††zÛT4Ú7œlKõ%ûúF’©‘¾dª‘9’LöAŒÁÔĈ™àq$Wúe`dxˆ!`Sy®+íßÖ›ðo ¤·mën4µ@.í÷oƒ*é¡›ˆ´€M¡ˆC‡hàBÁayaAQ˜.zñ‹¿J° Äd`õØc‡ä4=ôøã©LÓ©¦té¶hZèÁÊ-½ŒˆÂøÐI‚“¡(+MhØ–6ˆ~Q.ȘólãN„C𥇠ãµtªî»i¨mkÂß"ÛfúÓéÞ¨ŸÝœxà}iõ¦XX½ÿ†h©œ~ °Á6†´ú,>(HŒz´¡iõÅßÚ¶-†'ÚÒ´dJxå|š0`^FëFYf{¢Áh0há‘GàÒÁƒì ÑNøM1Ð ìdH»D*Ñhg ’À:A1ÄKétb[§ˆ´âÙJ¶ö'nù›¿ú†Ï DÆTsHB@ÀR16LKâ¶pOD‘Aq2ë$b°¹9ˆG‘£É1Q`6L\·ª i±>ƒùƒn@ƒb[$$Wïqó(JרõT^‰p˜|÷уR× M!étÊß+ò уw‚ÍxQ3Wot®³) @`‰´’ôP›?MºD),J1 K…­¥«KKpø¬Ä.} ¤–®ªÎÀ£`,"r,k‰~$ÈA yvQ|¶eÈ1´J‚â "(²_fg xÁ}q«p£¿tcl¶¢X¼iÊZ pHËž#“Ï-jk doXuU'?“5] -ù߈®kж(©PSÕ.^•8¤eϺ©³Òa«¬°7Ø*ì6gÒ’‰ HPY_6ÀÎ,¨%iËP©K$šFºÂ%é+DÇ”%Dì$•„%½ðª®0ZðÇjêÖ$ŸZGTï4‡´(×ÐèoôùAz ¾®F84"%¥(­ÅÀ‡–°ƒY™œÑòe˜ÉUZ€#;3êj”ÑÒ¼ŸÖRG¥Å+*uœVÖŠI1‚€d¤.ØŒ¡+AWÓZhnŽDšÁñ‘æfž„fŽ0xÍ̵…± ˆ…<õšyô”P îk&Až·êš´ëü·¸«*yÑWe«rÚÝ.f-ÞÏsßȃ!.È£ŸãùÀwAf5­ƒñx÷Þî—º{"„Ä)éïï!Ä)bÑZêÇ÷í{ö{Ï>»·§'ŒÃåžîït?ßýüwà<ÞOŒº-›Óéü0q9 {"•ˆ‚Ѐo%Ìe¶ ¢iÄÏ>Ú¿ÿ‹/~ñR^‚'XªLX´>;µ~hàÅAöMòK?Ç»^øçŸ+ùº-W•“Áå´àr µD0²(òàñq, (Ê~”"´þgç·¾‰øÁë³çÏÏ*º>;;«ÍÎΨp´h]Ù¿sgûsxîÅ?}pvöõ`·}óùˆ¿&åiÕú½_mÞOT£ä…`Pä9è…`"è=ñÃb´ÞdU¾Éü^V€Y8|f­êÚ§³ºÊ骶<w ^“îâC˜–¼+ØÈ ×J ~ˆ­ß^-…¨ÅhU5s>Áëkä¼ÍÍöœƒ@>»Âœ±20¼²²F#¾üãÞËš(Ûü._ñå7ß5ê­¦USëñÔÖÀ§¦¶Ñ´ÐRÇs0²àTtö°•<„ýK1±voÔÃd©XEƒÖ¦ meå¶òòJ0T¹©­ÿŸ:{vòɳӓgÏNMžŸžŸÕõ…«Ÿƒ% ×X­x=Fk]í­ŸŸ/;4: É÷¶öF[£ÑTïèh4}qnîói}9`´Ê6¬ß¸Î^fwÚÊÊe6»!¯Å¡¡äH2 {ßðS©áT_j89y3i­óÞ†k7nŽ×y/?–Jö¥’)üú`O¿™´ÀËo¬(¯(w–Û+ÊËr´~ûÁj|zi•ƒµÀN ,¯vïW?!ËY˱ÑYá¨ØX^QYYñ5¡…ÖªõÖVCQëõÔ~AkQ}!«/,\•t-£k rfaAÑ pYXЮ[‘†µ6¬w¸®J§Óáp8î/F‹÷û$˜“¨<Ìá|ýrŠÐH…FÞË5~!ZØ=µžªZw­;Ø\/­?]ýôê"Ü´xõO‹xÄEè!‹K‹W¯[0mmªr²i†ãë±ai cyWƒ×ãüÑkAHS !—§² :½ñoÿ¼‘ñó¬u«ËçôºÝ5.¯×mì ®3EÌõ&ÚI(Š,[…¢,…hœZuC‘ˆ“iãL#Ô¸!$‰DаB¨ÍîÁRÑJ–˜ÖÚx‹³æ¯«Ü°UW׿hMHR« ¸¤“j‰„$vX;[¡À•"’x0—"ñæf¡¹ŸD`Æ/!O{$¸rá}¬v&è‘8‰" Æ·¬‚hÒ*¾ì¦À4f(ƺ$•¤›£àœ%·´ñÐCÅÑVžEÀ8§Frñˆ2nÅ*k­JfqÛ&‡Ý—ÓîtØ+ÌâüñãcãGGGÕqEPçŽ? ˜€`ÕÈîØ¹›agÇ?޲0vâèQetb3˜U´ ¸*ŽÎ¨ Ü8#ó•­Aëƒso_@̬‚Ÿ8VЈ3ôbY]»VÌ[ͺŽJ§k-k͵¶¶´¶µ´>š¶:Â$ïvÄŽö;^à œÁÅ'AäDNàü'Ê*'˜õU_ŽpÇA=Þϱ5=ä:¡‰qËZ›}n¯\„·¦¤µ†Ì7Ð\3yk¹(y&YMÕ¦T| ²˜ÅÜ4³d§§QM3ª¡(M¥êjcMÏZÍ®‹Àg ZçNONž;sflNŸ7Ôrþhë[†µ:ö)T%O‰¢Ê (˜‚¢d å¢ÏgTUfa¤šGí3¢Z5¿ÓØ ´åsWa\SSÙ,§•‰F[[[S­­ ó¦4Ï¿VH+.ƒ+‚_#ØÇˆŠKÓ”†Õlî·3Ð(Œa"R‡¾U‰ùM¬ÿ™´ zâú ·¹•.W•Ë]ŠÖÇçÞzë­sçàsv…ä­F̵AIÉÏh׫׮ÜÞÚ*»Úí*å Z[›ÚÚÚZ›ZRŠ%O”ü·¶?“¼$Ïq83É£ôc*ÇËÆªä¤@#ÄøPÄÏåݺ¼ãykUW¹ªkª¥´…oÙ°÷lÎÍZk÷®aÛÝñê5:ˆ¼ÄÕ’æšÏM16ºœOuYiññðÈÈé·R§yêÌÓüyC[¦—LN€v@äT&(x"|cBËS[º®¢Ù0¡`A*) @ †}Ìž¸a“ËívTÕØKÓºmK&“©$´cïö,][F+>JN@gƒƺöDª¨E1ie ¯²Ž#웊Þ:gZ؈eËý{QkýÚü6zOk8Èž(ªO¨êxn¬Î ÀÓù¡ZSWüØ4» ˜—§YØlt°Ç®öŠÒ^¾ek´µ¥©ih̸”¼äLòÎ/ŠhY ¡äYD›Î{yÇb|« :„À„/ò8.ÀG)¾b4bÙæÛj ¬˜†ÛXÒZ“àM''ŽŠ…^þU8·®è’Ï|1ñ:ñýTj25<Ü744š·"Ë>v Hˆ’.“•˜,Q ÜiLÍÄ,Ég@Þ qM@œˆs&ð· ·0Š*†O].ùõë,^ö’´z£©ÞÞT2Mçî>ÿÓöÛFìèý´‚¦aœ¥©Š†ÁÆ[YÕtÆÃtì * ¾Í° sjÉ—{=µn7 ÔÕ^_)/ÿþS§OOžüúL.:…)ÆŽ]Ló»;â ìõ쑊G…E‚:þ¦!oÃ9`0HÑC Ÿ`Üq£Ë:BnV½®²Òét–;ö´Î6mmÝÚ´µeëÖ­kyÞ¼Ø@¼á0hbx.ÌžB‡ÁË Aëe˜â¤=>uxCò˜åé²×-»×ãá§Õ°y«‹ÐúäíwÞ~ûwÞÃ…ùùYÐ÷hk¹ä™ÚggYðË$®/“üJÍëËòx6Ë“|ùF;®náCaW…Óá(æNS¸ä<Û™ s8ÖCbHÞ˜ùq˜Óð•/²ÜEEƒæAò’&d Œ–%¢á$,HðY³,Ac8K4mµ;u׺\îjƒO¤€]ÕJÑŒúFR}És—3ãîS';v<ø J~WÇáꌢÎåÂ?•ŀЖÕ,5gUV¬S•M+ãÔt£ËÆŸŒIËçš}Þ Ϋ±ÃÙ+>óYn­¾#G`@< Ãõéɱ1Œ†žø>»:öõSŒ°ä+8¡° EƒÝÀ4Â5BÀ#Èø¨Ù-èQœt(PMáÞìñÔTû<ÕUøP±Æ|æ³ÜË[’omòûÓJ^òlúº½ã“¤ 8w1ÆI|ât$³jãé•䥀H1¤°Ÿ7$ÏCÕDäsð¹uÃ&p\Žr[eE)¿õÉÛ._¾xñ¢iìS…’?o5Ì#3ùÉæ›F¿f˜fÕ¾Z·×Ûà«)A+mJ¥{S½ipïFp«k¯ÂÌgs ÌäŠ1LщÇpñIP2bÌòò$ Å’Š QB |zz9F»ÂBLä‹EyTT” õÁÐÐøÆqj,“Ã¥S‡w¶·ï´¡«l® Íf05çÒYâ dÙE=#ÎBeNA7üˆ®f ]s}+Ï©ÄbãÒ•Nþ”áäGW¾Œ—óm³j "Ok!k²ðÁûïãÿ0Ï?uéÔ±v'O½kþSܲfŬqG–e³9k¬8æ*欕]ÃZsìmiz¼ÜT"NÌcV½#7!£ #,èÄhçe>˵¯Töb+”áK·2ó$1¬“WBY³‡üM‘„kjjz2¿ä¦¬o}—FŒ1111`Œ‰à0ÙçƒæÃn˜ìó]œ„S~oÄPQ肈Qä`Fd~§b½³¶­ (qV¬vfxdhèIãu$kI­õÀ}ß¾ÿþû·wôæ§V0«Îa:W¬Z+kÊʘ²âìèš´?,,,üþ÷‹Ÿ,~rù¿/Èû|r±ük…<[,›Õ¯™kì‰Ø7Z’­ÑLø{/äüVAtÚ~gX”x<–¾œN¡ÁÀo‰ÚùY },ŒÉ0t²KbLÄW·Aª‰RWRƒbÈyýÚia,ÿÔðäñã“—Ù«OˆK'ó“ýS— þmÖòéÓF̱»2æ@°,HΟ±Ë×ê·£Éä0>¶î=H À@e¬'2ìx¸Y 1(I!ü$B„0›PCÒ€Wþ¿wëûmÚŠÂý&öðÞÕbŽ[;N3ñÀڭ턹±Óv¢ÈxÕZµT}¬@jœš!¨„JhêÄê ‰šÀm bã´íq{¢³±½ïdy£ŽõõŸ×ÙR1¬{T¯~´Á×½ë-ü£Ñó‰DÂô¼oee¥ˆG±(n÷qüÓx<.Š33pã¦8#B^³ž/Ñ´X6M´‰›hŠE¼ÃžÓ¾+ÿÕ|og¸øðR€ò%ì-ÀôôtçÉ2bÃï"vá…ëpåÆX*¿K¡ÇñÎÿ—O|³·P9<25ãGûz| t’aE‚A®Hµµ!Å ^ß,)$[†B$Û0$")”*RF¡m O0 ‰[Í6Kªªt}ŽF®÷£STlú¡Iz—ë–Cü}«DiàÌÛ%³4‹_G˜‰$´t4G¡®É°ìÖd³0:}þàùo¿†|=ã­Ï9Ë_E‚"}½¬ÕêQJ„m†xê .}Ê/­Æ[Èòwi¥ÕÉû¾î ®4ïÚ½k7LÈöQ+&9N2–„Bv4än–§¨"ƒ5LÈÌEé&¢4 BX ø¤®92æu™òÀüú§¦Yþæ-Ä;÷ŸÔ{$Ë_Û uÓÆò-øÄûUD:}(¹—qq>,ß÷YOgyAÓ vªKD#™.Š Ž ¬RñY¾D ŽêDÒÐðT#ຈNˆV7kNL&‡%º»O]<Í,ÏÑ·ˆ­¶ÌçíœËåí¼ 8ç×lÛ7öò9¸upOƒBK¹áa¾bÓ7<½ÔËßF‚|IÞ Xçìñ€NOäçæ¼BÁóæà×¹r¨¬0ç_÷r´™ƒeŸ'¯üo¬7ÿM¬D"p‹‰D$RðV>¼h‰Ë}›æ¬2G›^´†&˜3³æLÜœ1ź€Yf÷¼âÛ@–o²Y¿‡|býc>1`ù!6¿Þ(½Éñ[uSðëÍ÷V5ªVGÒ§¦ÆNmÅòBp¸`E! &×DA‘{IR–'P L/‚0ÀvH†—À+MÀ÷…¼GñŒ©ò#ß2-p1Pû{¾`ŠÍ—_wP÷À\€SB±ƒO,ÜÕºÐÇÔ@^{ 6©‚9ãZY¶31 K—[ˆNoýp÷Ö»wï„cùù†bsì ¦ë–¹êx™g kn©öÔmh§P„ùs(-q}®ÆU9®(Aë[à­gêŽâùéê½{~ºúê|C±ùú€ìíºÖà`ÆšÐݤÌmiîË >…Î’ºŽ Q?’zJ‡0>åĨÌB{™º”¦à½…Xþª/Ù[–ÝÒ™Eàš%·´ XXæYƒE\zâêmÙöØÞXGÆ ý¹ 屨ÿýCöJ¿£Y‹Ö‘}²3NôبKgp¯¶s@ÓPÕ‘Ûtm{ôÔÿ¿‘4D¡]–¤ŽYèˆÈô„$Â!krû?;,(ñšk‡1IEND®B`‚nagios-2.6/html/docs/images/cgi-status-b.png0000664000076500007650000001436407436604445020374 0ustar nagiosnagios‰PNG  IHDR–sMV átIMEÑ ,BÛÒ pHYs ð ðB¬4˜PLTE   RZZZ !!!!!!!!!!!A)))!)))!!c3/1N99K2TÕ•)ÏÔWgKjüZ„á,.P–—óòô´X ÁdÁÊ0`8`J“`ÍÙ°æ91;À×ÉeÓ (‹î‹š„ovo FeVåErÎ,k2b<…´ Òd 3´b7À”£!ÁÆÃq>,Åâ!ئüm|< Å’îHFb ™È>ë¦VÁ¨NШÕ*uQ¡IUT¨Ò¨‘–ćRø2‰J¡P>Á`HŠLI üÛ(>ó*£&B0»”äø‘Ïññì³ñ¡ÄuŒ ‹ñƈžz)¤%P&3e6R˜8MFÎhFfHm2­dp@ R)`#­´Dæn¤…P“=Y6& ­Â˜~Bïöê·)l`Cz:VD´EàM•à2øTÜ1™V¢²šuTÒ4 “>”t% µ×JcUî!­ô[ñ M{+eAÚg¥«iºÚ+&² -³Þ¬ÖiÕ4kÔª´š–h ¼¸6mµr”üì›Y<EO¦õïÖõë[šZ·µ¶8¼~¿Ÿ‡| Ãç|>_ŠÖ¸ß·>…6œò þ––¦¦VxmY¿×Ëgh©4Í]*¬²G¢à ~xð­¼êC“»PšÜ‰W¾t:›Ÿ{ðr0ƒ>R†Â)ZWvTó/´…ÐNƒÁ—ñ[Ï=Ä}YV¦U¢Õk4ZMjèDç#œžyç"6”ÁdZjkÊJž:sr( ņ†ú"P§h]r‚Ô믾zøÕW_ãƒ30‡†ÎÅo•–]ÁâÕ¸ -XiF}ÆO,ÆNdª­,ÌR@ÏÊX·m•Ço'­SµKdZÏ|6 °ŽÆ"P§i5.YÒðêk¯~íµ¿ñ‹ÑÑHltô³g­Ò£M,*¸¬NÔ K¨ÚZ×€u ½“"ä^¥€Ë«­æÆæçŽ9vì•_‘‘‘‘sçFã#ñ4­öfgóë?F¼þÆÇxjtäW¯;väȱ£¯dh-º{!éÄ,“§h+ÅBEY‰ÓºA'Ž_¹ô›K_ýp~(Ž…N$u¶G½réÒ¥ßüðöÛo ËÅGÎÿ’|-ÛÅZwî5è úÂë&â o‹€a"8…––IšŠ–컬¬Ãj­„we¥µZYð¹î[Á¨NÊ‚,5ÔLèzZªw.,)ÖäÒúƒÀW¬¸Åýð¹¿bÕ Ø®hÚ&áØ‘¦ðòIž÷9x›¿­ ;ouýB8/-‡ß² Öôñ~܉¾žÖ]l‹|ÀÈR´$ïê«›V´¬niZÝXÝÔÒ´B âäÌKkü«ÖgÓx½nPúòÑúuFî…mm ÌõЊ;UkJ´ZpPjµéN” Û¼ø†BWºA'þñ·‡ôC‡ÿÌ> #ñb>Z¿8Œb(÷£Ã÷ëÑHFä¹I´´F£CV%ŠÅ¹¤ÀC KAA±ÔýÔŠ ÍL“Ö;è%€VbjZ?LÑ ñàEF&Óª¤Œ•£‰2TVdúsY;F nÁˆ”¦¢5þÕÏò7 ÞùxTA¾Øæ?ÞIÉýäGd¹É´Ð¬ ĸ &E[@+’‹0¼"a(ÃØ7yM~ðGã×nY‹ñ|’2­»ÌWÍ+Tª³ÁÿŠD?ü0ŠRE{ã1˜PNÂ'6z£ë)øßhÝPNö[ú»uF#L>:©(51ùNÅc³ylOÀæYeúÏ­X|ôÚM¡5oÁó çhTóÔªY_ÉN1°=l ttlÇ2 º¢gÐ5÷Ï -ðò¸øA /¿;€ B‚Ž’ tô÷öÏ-ôòE…E…Å…P¤}}R Ø:øØ0Ùaé°Y¶¶ÀàÑ*mA\ƒ–ƒ¢°d'&O‰šdeu”j`û‡±¹ÓVqQqÑÂ"ЙZ]”¢å±@[`ð«àx\dx,ìÜÙ–Á ×uz½Þ)Zâ#‹bôáG:~øñØìììŒζJÔ%jM±º e®N†$(z<˜ýíôà wÝÒ`ÿ9ˆЖ^¯ÓêÁÏgÅ[ccŸȵ²766Å|rS´µH«Ñb€ª¾MrÊHĈ«ÄdÐßF´T ` ýì´‹$ÉÑd2IâF"™äáŠÄcÉD<ƒƒ‰ýJE[‹JŒ\üàH3sZcdaõMónÊÈR”É¢9㨉QFÚÄ1&ÖL͑鷧hkþÂb]¡V¯Å:Ã,h%ðù:©à*|®]Mí%'&±™kë6L»‘âÞ»B¬UXXR\ )†yñv¡µ¦B\ôà”±ÄmBkÑ¢…9¨ ´ÙIÊ[Në^ˆ·0Ù§5{fºÛƒVŽ¥ªom©ŠæÝuFâÕYßÖH»S=Ä3Æ‚©huŠÝâYÏÞǺÏvï÷žèîÞ»w` ?·9ÏÙ³ÿ gú{Æ¢g÷þÓٳѽ=Ó®: <¶woÏÀ'Ñî³=g>ìÏCKµàŽùjuqÉ”ÚêïtG»»E1/q *Fwã¼{s›·ÛD8õXÔ3Ö¹Û;ÅÇv&ÓêÄvvâ6 rŠåÕÖ½°¾Ð0hÎC œô”@oNd®ÈÞ<¯Lúji§Ÿ¯9ÚZ°°D[¬-).ÉG+^O  Z°Ò4SI3Bu%CÓ´œæ Œ—©¦šg«1±IÓ^üÈe’ üž Ž%7»x"Ë0Õ<îÒÖD- šuZ­É«}ÍdZC¼×Ïá…ŸWàyŸÛ<ï:Þ§Ü}ˆ¼Ÿó±~8tD¾õò~’ÜÌкè€/a Àñ^ŸÏç÷¡$¼e}¾‹9Úº[[¢Vcd“ÖÇãýQ‡cS=b£ÃQí±àZ'Vž[MÊÖÕ2`Ób/^Ìh‹ãÉ]€o=¶Õ¸Ñ¡ èhÂæ®Ó&)µØèJ&Ó ÁÊ¢3Ô¶ÞYW³®¦®Ñވظ³µµµâþ I´|ýü~À‘XzzÿûÈ»eeeÏ|–¦uù!lÓ>ì»Ü˜Û²7nìjz®•bC‰m-ÀtÄ5™¤[­aX‰Y<’q‰}Íšµëjìuµ€úú®²²åF³W¦u¬tß¾}Oï+--Ý÷ÔãXÁþ!¬÷—Ì¢ÅÁ‚x½Ô¦Zhlí:{}-³­¬¬Âd åjkÑ|m1èj^^1ÌTYwÔl¶cC@ x-ZËËF#sN¡HÑ’óì¥@kÐ:ô» -›Åˆ¡`ÐZí¬…ÆVý’Ú%µõήee+ÍÆT'Jyä‰Ç‡žzyáîï/ÝŸe[‰r´°K¡Õh'h÷ĉã}±X6­yÚùjr¶ h–s"±­ÒC)ÛÚWš6µÛJôÆãñ¡Ó}ì[uëH'¢a-Ûzsuë#Ï¡#ÐH@Íš±­}“l«,Ƕ`®ñ Ƈ>V¼UCl«¹^ÆŽ.cÙÊrãL:qøïW–5z+h]K§±’¿ÿòË þõËßçÏoÍ1­éâÿ=­±±kŸÊYÐäµO±šÈÃ{ìòµ‰Q"uÎ&?U䳞€/O©äÄÄeعz½Üôiõ»¢h=¶=.[À%Ú<ñÉ´pý]ž×#º0]k¶œ,r´?*Z<–ÝЖ‹†5GÀâ²t»wy´.}‚›øDÆÙ‰É´>“…Æ&ÆäMعœ-‘L'm¥·qoZÚúƒÜL„¸š)ûSËð?°W`[Òj#,”•…½ÆÓ âp%ʵéÑ6¹4ãæO§…µÏÜŒ!×fºÖtr23.J¯³4s™N§×›ÜÄ3×¹:LzG1÷}oµ²° HNäð[íû§·ÒOßûöû¾÷ÞÊ¥«¾„øò—ÓÙgŠª¾†@CC ÊTI—^bVVö¥²/~–(Khªž.7ÑåeH¦ìÁ2OÙƒŸ%Ê<”§œ¢<¦Ñ@ 1°Å—Hô%ƒ}у˜|tK_bðQÄࣃƒ˜¦1˜N0|4ë­OˆÁI‚“5)´—UÒÁ—f%šè4R¥—îï’Cpô÷Kxb¡Ë’þÖBþÉ€Ÿ(‰ý’'k’Ã" §G̼#$Qêϵo`MRYíì^‘ž;!ÅhU ¿2Ö#ü”‘ÝðD:@.‘Ó„xù7ÔE±O˜árþ)·ÆPi:´vÒ´N«YI‰²~eÀGãw…èó»#b(P¥3”¡ìê}¼,6~bÉEÄÇÖÓžõ”i>](š'‚ðUv`3š´öê*Q†bH§å}ÈO¨Ó„OHÏ>!ªš …ðM› iª¬Îñ ôTTYg—Ò2ϸÃ6‹Õd)5o2•šM¶R¤% 2q),ʲÜ/J‚—d Êñ¸,*7¥Æn´–Tn¢›Ò—…~‘ÏÇ šäxmZðÜŒèRyJqÏ9/Ò½T…×KyQõ*)¾²  E¸-¥57 ø@’¥ ÚìB2f!'5£/¡¥–_q·ÈS²‡“Ý´ âš“áN Þ„­ž_w3áe¤5[SÃñ5 Ã5VW×TC.ÔV35L5›!‘«jk™j½_Mu5”û@;V˜t_B«Â]qÛa¡9ÊarÚÌ.;‘ã¥Á´U€»ä¼,ÃB©à†‡Æ¥´>຺:wìzn×îFü)þp8ì÷‹h‡ fКïéêÚ¦£³“D|7ܹcÇ.8vßЗ¨¼Ífû0±Û²ïDøLžó£ÿæx?\Àƒ^å‚d ­k¿íjï~þùïÿùŸÆ0FRyÄ uíX{ûþoëxy/ÑÓxü§ä²çǺÑiÙ6«Õj³ÙmìV” 2åÀ ùy”‹j…¯åtëÚ¿57µmFüý¥ät2)kZ2™T“Éó ä­«íMMÛ¿ApêÔä4܃ZòÒ3ä²Íß­åðÛøZnj„å”{ÁN8 Ö–? ôàX6t`k Ü„ÖvÖf"&3ÚÌŒª@~­“'O>}òäwNýjfFQgfþ¦õ|#“ >¸@Ëéö@,añ8n¤·- â'C.H­ˆ¹nB«ñ…^xæg¿L3º|i‘r†ÖþööS§¾ƒ8…´¿üÙ3/ë&‚Z÷®[G1 _@in³^}zMœ Ñ­eqþÚÕÿ½ú§ßýîÒ¥KÁŒ–γ-굫W¯þߟ?þóÇ/¿üòäëz‡wà¼î׋íVñ†õw¹Û¼Èù@LáÇ*L‘h¼¼œÝ"¶‹åxÔÅZ¸ãÁN‚0ÌbóM0âÛc o ^A:ÊKÌéÚµ»Õ¶ˆÖÿˆ~øôZ†©ACÔØXµFÐwrsÝ„ïï„×îÎðîN!ìçøxXY–ÜäþÎÎÝ{;wÇÁ–pþø’Å´Ìžõn§Ë冗»ÜåÎÐÚÑØØ¸£vGã®;˜Ô¿<­ù?=û-ßÁÐ<.Šç—£õŸßÌt|ö9˜ëÅ¡£²˜–©Øb³;v;¤v»ÝDIܵk˜:HvíÒÓpXºÅ þåãO?~üëO=uüø‰WÞ™ÑF@å?XŽÖ¿ž8~ü©§¾Ÿ>ñÃßÏ(#pG^^BËévÚlN‡Íî4,sêe¯ßËxk½5 ¼à„–hGZÿ13#­—¥…ýžÂŽ„–+¢-¥U㥪=Ô&¯§ºÆ¼` Òw1¾P £N7Üd_ù¡W~?“Ær±ÍeuüÕ;i+²Œ´ XN—{SZZ@KQNߨ+ئ(ïÎ,?û˜üEÇmb{½&óË÷DZëî.1›Š‹- ¨â´nýñô™·Þ:sNxyë̹DÚ4XuîVß—ÆíhݦÐZ³a›¢<Êå!Y…EWùh}4PØz z`ë@CìâTjjŠÐš½^p­¢µw•¬1™m¦5k,E&³®^s‰è`__ß`_âà`t0‘ˆOiê­¥õ)ÒZ³á~ˆ<)Jʳ`åÇeAxmIè;rq °J´Lkï²”—[‹‹KŠ‹2´¢õ·Ôù[|[›* =_4µJ´Š=÷ƒ <®rÊãÂUƒVâàA\Aí;ˆH@«‰Ão[%i•üµÅj±–XK-Å%K©aåAåûê}}€okýVP{ß_ýÄ6«C˼ÉIAÄåô€é‚ÀËÖ{ãPìÐáC?>|èÐáØÅÎ>|øÌÛ©©?®Ž´î¾Ûb‡Ã"³Ú¬.ƒÖ#!)ÅÒ)&Å  H©”º:´ŠáN3ïCïÊŠ·ÞÿÃßχP…ð­Ž´Ö®µ9l P-wÐ܉ V.;åq[ï ZEk×BH‡Ã½2iÍÕYfû"ÎøáœÓHQÓææÔYÛæòtXDZ÷Ú)[¹Ëåt€õ²­€Åx(Ú3SÁR]áá*•bE¦"H{+(…f71Ð!oZ¦/X¬ÎÏ;\p8å+ u}0;G2„‚ÅÒÕyL’syê„pÇ.»Ý¿Îb6ÃËn5Û¬æRóBë^p…`à]àÝ”‡ºChÝw¯¥xÉd)rfbÓ;Öúõµ ".; ¯;ƒÖ šn¶ä(­9\@øµfàÝw’±ú ]Ö×fH¯ËÚr°aÄ@™ó¿çX–©s Žaj8–­NžÇe2xárÃažÃ® 1§÷§.§Šò£Å ‚Àñ¼ r‹h B˜ø° 2<”#˜øž'íx‘-ÓÚ5ýYíyJ+,„Äœ‚ à7wnÛ¶m'„xœd.˜ê¥ioXa gî´®Äã œ’¨à¾zO{kk;Ù•ÁmÆx¤§ zq±Ds•ÖÚuv‡Õn·Úó¡UOÓt}UUUeM×ÁEhã ®ô´7=ÐÒCÖÈê@¤§"dÝ6WiAè°SåÚòV¤L)Í#ÞÕÖ¶S^ %Ç;ÛÚ¶Åõr®ÒZwŸÝb±ÛvW´.\ÌÂIp©j¸)ô“W)5]Õ믾ú/Ø¢æFk͆õ0ƒ ÙítÙs§…Ͻ Fp $`žˆŽ¦¦§aÒ­%SoÿíæÍ›Ú|)Vê|RK½ÍèËÉØ¢j¹KËé°;‡Ó‘Ç FûúTt Q(TÍ •BZ›™K©$ÐÒ¦ÒuÒ‚7GiÝ_b·‚¬Šò1WF/F/ŒŽŽžÕ¡ªŠ2¡hLL¼ö‹_¼öÚÄ„¢@ãèØØö#^:zt윢ä,-»ÛeuºÌyÙ-Q6 oè‘-=CÇã@\JW#]m͈ÖÖ®Hî*_t£}Ï•–¤¯¤ Š„V¤·«»—ðÒiµ675=ð@ss{î´Šî³Xȶ«¹4Z!I’BøˆTP‚É­$‹ö ’tµ´´õÄåiB«}»Ž®½¹ÓZŸâˆi¼¥yèV]UW‡Ö´ŠÆ£’M§"Kq9²sãÆ–ˆ ¼9.Å÷¶µ5oüÍ^Ü»-ä ^‰F‡38¨;žÁÌ.GöpÀ$…(øÈFÞïïÄ}¼œÍ郗9Z⎠&²œÞ"J¯ëB–2VžñVz*++½yXùâ pÙSîôP¹[ù9å&P—«>ö•¯}õ«_ûÊcOb%Wiݵ›õó«9Z££é/6 ˆ‰ 䡎eÓûAw»Žcc9Ó2{6€¬\îr°¨p¤£›Û›ÓÔÔtJKá+•š6âTJÅ,99~vL¼6­ý“¦M¾ˆ¢©©¹õÅÉœ­¼©¸Äl·ØÈ¦°½Ôj±¬ÀUƒŸFJZ“/vwZItFêäKÛ·£9ݾý¥¢O¡I°*Ë•l>ÓוѺu`3<|t8«úDÿÑþþ'”<›• âicF&e P•‰ócG»»{ÇÀŠZÊØ“CÃð˜Š-¥ðÁŒ5xÜ×·¥ï@CÂ×€IlŸ¯x¡ñîÝU§]wòlKSÓÆ%Ñ÷–VöÒ‘¬å¤)níkii7|"8ųq5·¼x6™»O\!-%{ä²*S¨>#ÀŒnݯ§ûŽX·²fÕ7ºåÆVçAÄù`tšÏ¬z…´¤ì¯—ôœÌ|¤bRÚù´fœThŸ(?H éáQ<˜Ÿ‘Òó³x–óÉ}ž¸2Z}[¸Äˆ¥ÿÞ‹Jiç#Olné‘À¨ŸÖÏ·Nl®>QÝölÓ×úÄ:]åoHè:œ÷Ót°Š>q#®Æu–ÏU§—ݾ[pZؤO’u—8” läHoïžÞQy "}oóC:þQ*´ÊCˆ4ÈÃfé»r–þÔ°ç ­G¶<ò½‚Ó³ï@ÃU•Ùà%K#²´µÿ™YY/ÚU_ÅEãsSKÿy€Éù±ñññóX"kËêÔ›oþæ7o¾yAÍ}¥y…´†ÈÒ)Y@]A ã¢ÃpÖJÉ“½íí{žT AQΆú†šµ+§Ÿ8ÞÝ„®Z͸êñ¶¦¦–³I2ñ.¬´ú†FIBV²–F¦µä±¶Ö=ø`:Ò‚w“ɇ[[ö$“S§õø‘#G?sä7Î,DôÆÃûÃÊÈHzG†Þ·ïááU}} „X[ú|bæn̬ö‚léMÛ hô†H>‹”+Ô­ºúºú€¯®¾^¼Á@¤i*õ! EöDäBÓšƒ`£åÅ7búNÜßݽoؘ쓌¶Æ >ˆsòÔ…©‹ߺxajJM¯ÖLA²šÜßÚÚ5®fÍ]­­mgõxµ°ƒHƒsö¡‡®cSI-c$H\œìÞ¸±J™õ®ñ–!–'+<¥uñ=ÿþÞ{ O¤-9”ý·]9ýïX^,$d°¶`z'd2mUä0Þ4)œ)TÉvЕA!ûÚëõVx½,d¤5"~&¼›ãX1ØÐÁãµE¡–Å¿w3&ÿ÷Êu°ŸÁ?I««½4ƒÿ'¿3X©ÞäÅg_*þ[%‰ì"97IEND®B`‚nagios-2.6/html/docs/images/cgi-status-d.png0000664000076500007650000001262707436604446020377 0ustar nagiosnagios‰PNG  IHDR–sMV átIMEÑ ´I2ö pHYs ð ðB¬4˜PLTE  RZZZ!!!!!!)!!Z!!c*-))!)+9)1)11)-3N+R/9F5HD;HOIGGjEHF¥AZ]bZ~gjnfiqy“MXµR\„sƒ„p~ŒŠ‰ˆZZ˜kk¹y}ŸxxÀwŒ”–Œˆ˜”Ž’£œ’”¢–©’œ¥ž¢ž²Ÿœœœ¨¡š¹7·.LÚ5O³OOÒJ\ÊPlÃd`ëGoçbŒ³ ­¥œ¥±œµ­‡Ö‚“ÆŸó—í•©« ¥µœ§¥¯¨­®µ©¥­±®µ±®À®ª±ÈœµÁ°½¹µºËµ«ç•­â£²Ø¯µê«©§À²ªÃµ³¿³»ÁÆ­µÆ¹µ½½½Ãû±­Ê½½Æµ±Î·²Úƽƽ½Îúֽ½çµÎƽÊÁ½ÎÆÆÆÆÆÎƽÆÎÆÆÎÆÆÚµÖ½ÁÖ½µÎλÎÖ»ÖȽ湽ó½ÆïÊØ˜ ï¥)ÐbpÒ‡„ÔoÐ’˜Úƒ”÷‘ܯ3ï­)ä§>Ö·bÎÎ{Ö½ŒÒ½”ν¥Úž§Öª­Î²²Ú³µè®¯ÞµÆó­­û¥­Î½¹ÙÅ®ÐÀÃÎννÖÎÆÒÖÅÆíÆÈÖÖRÞçkççkñ÷bçç{ôñsëóåå”ÎæÆÞÞµéä½ïÞ½÷Þ¥÷Þ­÷ÞµÿçÆÎÎÎÎÎÖÎÖÎÖÎÎÖÎÖÞÎÎçÎÎóÎÒÒÖÒÖÖÖÞÖÖçÖÖ×ÞÑïÚÖÓçÐãíÔÎÆâÎÎÞÎÎçÎÖçÖÊÞÞÎçÖÖâÞÖÞÚÚâÖÖïÖÞçÖçÞÖÞïÞÖïÖÖ÷ÖÞ÷ÞÞÞçÞÞïÖÞïÞÞÿ½Öÿ½Þ÷ÖÖûÚÞáããçççÞÞïÞÞ÷ççïïççïçïýääÞïÞïïÞïïçïïïï÷ïïÿç÷ïÞ÷ïçÿÿÖÿÿÞ÷ÿç÷ïïÿïï÷÷ï÷ÿïÿûïçç÷ïç÷ïï÷÷ï÷÷÷÷÷ÿ÷ÿ÷÷ÿÿ÷ççÿïïÿï÷ÿ÷ïÿ÷÷ÿ÷ÿÿÿ÷ÿÿÿÿëÈúW*IDATxÚÍ›pU~Ç•à¹"÷îjI¦uÈë³*%–—æ¢hE6rbYvâ8DYyåxýy¬$K2I×8 p@Bo¸ö„-É¥…æèµ›\;X„2Ž!3Œfè\¥›éá¹ëµ!“sð05çþÞÛ]IŽåp^Ÿ¿ÖîûíÛ·ëÏþÞ{¿÷vWÒñîõëÿ|Åè;ávÆÛ^¯sºë¾sèOn†¤®î¶Û¾þÍ«ôo.¦o\sï…Nôõºxx£Ã»¾N·ÑV÷­:à¹ùæ:¤ÛÀøÃéOëê¶:‡Ã¦;Å„‡ÂMÑxx0>ŽÅ£Ñh<…¿»ÃáøÝˬ¡$–W'Qd0æ$yžÜè¹IžqƒHXxÈuC‘Xr“EëDa¡`GQ2?³(CÎŒ ×W茴.ŠBÏŽíB$&ìgYAˆ±èúX ’Xû $BLzŽ‹@awƒˆ˜GH ²±d“{•ái&†hf|plÄrèFB°Án܈®¾Ñ­ Æ $Óä†Ò1Þu:X|x=>8æåQBÙ9„5Eežôâ+)ÏQpY±{¾å¶€Å£ ‡­¿»‘ÅèM  {Û–ÛÍ"×…Ý€x/>‚²‡¿¡)"ž¤ËBÊ{9v£Ñí½òl§ »XÊË0¬c ša‚´ÀÒÞp˜ ªþàè@'Å‚ )_Ay^R¸p%ÞóÇÕt#ÆŠp´°vˆ1giÚ°ÿ‘ 9€V¹L.7&AšÇêm®ïxþ…¾ÿ /¾üf.'ård¬uÇ:ƒ.2 °¬„­–¨5Ø,ó±Bœp«G«˨*…õ_}½w>õÌ3Ï<}òƒìå±îïëí}éÅ—^zñÅ—^~SÞ÷Áɧá°gžzí§VkÍ-F®Å‚ôÈ[h,'i ˜‘„ˆk}JUâÌ•‹¿ºøéÏ~öÚ¯g°r%-ލW.^¼øß¿þäן¼òÊ<Ž÷g³¯¿ñÆkpØEå0ÖjÂjƒ™—þªÁ'ê ¡¦.„¸½ÐCÐ"$D¥a–Œ‘Ó(F@wGâÀ x<žùá[Q PAhMA|Œ‡¯ÆÒUUÌ&SÅ|¬ÿBÔæÛ7ßN¡…êÜ 6Õùl‚ÇãÑ¡x|hy..‹M,Ÿ·Œ¦JS¥\Vi4TªX¸É7…è݇š¢MƒMMƒá&/¿Ÿ@X.o5€·Â±¾¶h¾uþü‡ž/Ö‡øúÊŸ¨ó­5“æ§fãÊxÁѸmÝŠæòf‡0­ ¬l&„½UcIÅBhöVVLesÓS13•ᦦ§a3“m)555=µÔKÌ!,½­fÝ“SkÍV[­ Kr9lNÒÉÑNK9'%’ʤ Çî—t2Å[•“Uo©…?‹•І5357O¿˜V5•šžYÒɬ÷Ø c­²®1èõF½Þlª¨6Á¸¸B°n]C!ÜY[aH„™—c…`Õ¬1êao¬°äç¦+ËjµÛ`ÆeFÏœíŽÚ•5¯¥ãù¼¬Ë?¿ôùç—Þ›ý|nvvö‹¹Ëç!Ûs³±*WÝX~O¼<f˜·ùÁöö/ãå'˜d;ïeÂÞöv~Éoi²J8E/¥ìeaÍž¿té’:˜_¾<;uþ2²PžFoU­®2Mæò¼…O'æ•RS”¿ÄhªzË ÷0´Û­åaI!:€.SÇ¢œÀ‡yÞª2škL5f“¹L¬á@€Å¿+°{7P…´c¡[ ÂRã@7ü¦²°2âð°(ß8~¨¿ÿСa¹5zë‹Ùh¨1[jjËÃÊâÛHÚNÛCãý}}ýgÆ3 §‘±VýX­¨!`a. î‘ÜI§Íå"F·57o- ¼Uc±ÔX¬°¶”‡wFCoHq›zFûwîÜYž·¾}kU î1V• ðÃù±Î¹3gÆÑÃä2¼µf Qk´Xõåb]/ÉX«æ¹i¥`­ª1ñ ØŠÊ…e­™f5¤¡,¬äo¿›œ8pà­÷`ýÖ¿O ó”V¬ëV‰§ $ Ê=ç± z+9¡«jµÊUQÖo/ƒ`5}¹HÓN¤„S½ÁÀO¸Ê‰òÓ!ù-/~L)c#˜Zò‰ToݰÚ`0™Lz£Q_Ö!ĉøu5~ÅÍ 4z'ÔŠUÞÙjѳ- ü)¯—ŽõÙž|â‰'Ÿ|²ëG]wôw𽥝¬0#oÕT›Ì•&£Q+Ö‘u?¼nÝÚµO=‚ô(Ò‘ckÅ"³¹Öj®1›Í„ÅlFo­k4`ýÏaüÒùáµG^»è°Ö=¡ËNx6Ùm´ ‚WCiG=ÒªÅ[`¬ukÞžIûV,+~ßc'¬ôRÑŠÞùX´`=ý—H9yò?ò:ùšV¬UkªL¸ *ˉ[Ÿ=нµvíÑ#‡?zXÑÉ Z±4öÐE÷°ã&õHíÑÃ…¶µö)­XE#N¥¡,ÔQW<ö7HÇprìuÍ¢¤4`]øO¤ >þM‘–ü„òzcÍ}&k©7«_5ÖuÓuÆššýÝÜìÏ‘õù¥ßÍýl}¾°&y¯—ç½¼—™ôºÛ“ ã]úÓš¯k6?ËR- Ýð÷Ç’"E‹E[±X"&§è»Òè›gb }qg$ø –\ÂëD¤„¤©¥c ¬ü½?塇ò¥U5ƒ*XÚäi»t¬ °èÝ»wo‚«¤<®/•g!˜¬¹”T¤ñCý} Þ>Y½ªQœy-õ–¤aé*¥´`MN ›ø´$¥¹îsý~¿¿ Ô¡¤Èêù;©ÚX~œ¢"~”'çÞ?ž)! XÞ~{b2æ6El›Îì¬ß²eëÖ­­¾-8EæEJ®¬–-EÙÍõŠ]ÿí¾3é0:zf|<­`EU¨©ÇF”GÚãý}»î˜§]»ÔI5Ô|5³P¶{¡?ŠÅÓ€%DNï„úhiÍ«ª­äkñ#Û-~”4ãlËf[‹º[ÏþyXZ¢üˆüut‘ pä&ÀÚ²¥µu«ªVt>Ôÿ|-ÍØ@v‹o‹O±¡µmñùäm>Ålîèß/ñ¹¬ðσ£B×Ðph§¿ÅçËSmõµÈòùÚZòjóåÕÚR”­¤­m×+†~­X›¨ÝÎî–»”¼ÂýPîš~¿Òç Å,_ îŽrç­Wº«gOúN¹¬ɡ䈈¿ ÛÝ}º{çUÚ¶íêéà%¼uí@Oëû¡ÏìꟇ¥Í[’ü…fùºclcc£>Ž ÁíHž °ép7:°ÑèØ½Mv&ôŒ¿_ÎCE»÷÷ôìß«žå§(IhÄš7T§þâ¾ûî½÷Þ}÷îÛ×sÎðà¾}ûî½gbu°O mmwìê;ˆ÷„‡-£ËªÇÆÆR©1œŒe¡JØ¥†)9$í‚©²]°Ô}(KÉë;=Vœ/HšŸ ~p6“J§ÇÑàãC¢¢oK ­ÐÜQÐB¯™hCÎS-Ÿ£ò]4(ÊIVÖ¤"!$5Îôù}[åBÖVu´nQÂAk!4¨y²…£I˃©"¤tŸ–¸…~XÌ'Å-5ØOïiVÿþ·rôjÃqaú”LÇ|‡âøÓûG¯'‡Y.@?×@îïþ3¨$¿œàHÕ¡XÔˆåkÃÕ‡{ý(`´Vº¨ê¥4N'ßCu3ˆñññsûwì@!h$Åk‡¼@Äò#¨×]<ðà°<øàý܉5:ÏE‹ÌNsö÷žoMN¦ÐÌ&•Éq«±ÑíÞ°aaÁ ·ËѸÁ/O° êúFÏœAïÉ@Ž"OW%ç["MêHCIMM”ÉfÕ‹Êfrï‚Þÿýwe!krò=eëÝ÷ƒÀ7½½wŽžSÂÇg3‹ öç>œ-ü?ŽvéF>–äGŠ„,²óœ{ÕO{¯-Ã{º»û»{®ýaq ÇÖŸŠÒ)ÐÈ)IäÐö0šFÑ:ÞéeÜN–/Ær‘$éD?§!ɲ0½8–Äq! 0ÞïeX£Xè<ºI{½LF?)ÝŽ2*¯°ÌuW@=gv¹H'E¹œN7étSétQ®ºMwþ?VïzĽÿÚIEND®B`‚nagios-2.6/html/docs/images/cgi-statusmap.png0000664000076500007650000001220007436604446020637 0ustar nagiosnagios‰PNG  IHDR–sMV átIMEÑ 8ƒ>î pHYs ð ðB¬4˜PLTE!!!!!)-%!)+!!!!!!!))!)!)!!1!))%)1)11)%=')F-99)1111919951J9B999B19B9BB99FADF?FJB=XAJRBLJOJRJKaLVTLT`PZ^R–UOZ Z!!Z!!c33d=B^==o==}VV^bg]`eh^`€^^œkkµkkÆkkÎwxu†{|Œ„Œˆ˜li²sr’ŽŒŒŒ‰‡‘””y{­ŽŽžœŒ””¤œ””«–„¥”‘œ‘”œœ”¥””¥œ”µ¥œœŒœœ”œœœœœ¥œ¥œœ­¥§ ©§”¥œ¥±¢œ”œ­œœ­¥œ­œ­­¥¥¥¥©©««©·ª¥ Ÿµª¯µµ©­³³°¨¨Ä¶«Ç¹µµ´·ÆÈwuØtqÚ–”ôš–Æ­­ÆµµÞ­¥î¯­½½­½½µ½½½Æµ½Æ½­Æ½µÖµµæµ·ÆÆ±½Æ½Æ½½ÆÆ½½½Æ½ÆÆÆ½ÆÆÆÆÎ½½ÎƽÎνֽ½ÖεÖν޽½ë½½½µÎ½µÖ½µç½½Î½½Ö½½Þ½½ç½ÆÎÆµÎÆ½ÎÆ½ÖÆÆÎÆÎÎνÆÎ½ÖÎÆÆÎÆÎÎÆÖÎÆÞÎÎÆÎÎÎÎÎÖÎÎÞÎÖÎÖÆÆÖÎÆÖÎÎÖÎÖÖÎÞÖÖÆÞÊÆãÎÌÎÖÖÖÖÎÖÖÖÖÖÞÖÞÎÖÞÖÖÞÞÞÖÎÞÖÖÞÖÞÞÖçÞÞÆÞÞÎÞÞÖÞÞÞÞÞçÞçÞÞçççÖÎçÖÖçÞÖçÞÞççÎççÖççÞçïÞïÖÖóÚÖÿÖÖïÞÞïçÚ÷æÞçÞçççççïçïççïïçï÷ç÷çç÷ïçÿççÿïçççïçïïïçïïïïï÷ï÷ïï÷÷ïÿïïÿ÷ïÿÿïïï÷ï÷÷÷ï÷÷÷÷÷ÿ÷ÿï÷ÿ÷÷ÿÿ÷÷÷ÿ÷ÿÿÿ÷ÿÿÿÿèýWIDATxÚÍ›PW~Çå¤L¯ã1gȱ>ŠÚ°,M†Aß~ÒçãšÚO{á,Æ_ÏÂy4EQè3ûi2~Q~òà…Þtð¶ Œ0p~(dY6y_Ó>0Æç÷Í6ÿì?:ýedŒÿÎ—Æ ‚ ;*ü4IQ$IùŽ<\W€¤)ZÒî–‰¤¿â`=GV’äoe%IuQ†w˜à›-AÖGûšh†ášþ9®ÆR5U…Uô–K©7ïÝX(”ª TÓÁä°>¨4Æ”öxk ÀS·M×Ó ô,›½KÑ Tò@}}=½Pk€OϺ·×P¢—W·JoÒ|‹¬XÁc¸­)wͳnµãEX9Ic ëƒÐ×›˜écêŽú¼Ë(Ù8³Éd0å CžÑ`ÎCXÃwõôp],Ëó ßñðâÁº»yNȈI8Öß9ÒÙÚß;š(’ûûû/\è £=‘ÇX¢ ®ßÃý}ˆ!„ ŒPªÄX%„›ðd¹› <²Òåu„›æùžÏ Kë=Ö¯Û€€ŒçC¶³ó•æÎÎþ®Dc…ʯo`Ø Cðå4¿ \JÆÂËWÇA´…Æ M×§GÝ ±Ø~¨wHèåC¡_ ¼"Ñlˆ ¡zU§Ô4,ÏÉVd"iw‘¡Èl,µ`µHéõ‚¦|^ªŽª$=u°Mú*½d†XC££S£¡/FãŸÊ¢ò†—†ÂSÈ"iX³Ùü- ±˜Ó["‡å±•½èóø.ä]=™VbL·™™Xì¦"d ,Ë:sAAÙl1'Í„ÔÚO¢˜ZG·2uû)ºpz°eì[?èøagçø@s<IÇF: ;Öګıìárºœ„#'¬ Ezè&Éýu°ÅùÛÛý¬ßŸ1R½›íîU’bI¸‘³|hf*Y‰Å7A.‘ïZ7‹A=$ò{9>X­þF_ÆXÔ§zÅ¥BvˆÆ+uJßÃX>°Wbšå!µÀá)/ +/Õ+ç³S‰£àܲ,O%ÅÒäöø)9…•»ñÑM6‡ÝxSçÓŶ¶¶þ à˜@€Óº°ÇóYÀŠMÔÕQ9ì§PC ÇÂSáðLB­å±jm9g6ÖtWkÝîÝêvîÞ½»ngó°ÝÜÕÕ-Ó1080Ð;þþ±Ñ„^‘†úû{;‡-Ѹ黵d½½´Ô¶Áaµ¥°š47€ØÛÚü ü5Ãò@W7ê|2Å¢[[ÙÞÞÞþ«É’áý¾N(éÄ!CW+7ßl)*²X`i±X•ØÓ…:„W:Yx!{ÞlOV*ÆMC¶””Ë3Ü(ŠYi¾e(rXÍfk‘ymñÚ¸Çÿ­\¾Õ»³®ºšªƒ8OÔÿÙøxx|Æñç›ü;iX9›rÙ¶uŽRGÉÝìw©3è5“,Q/éõpéX ÖÚBó:HPךî–tËÅ}ANÃʵJí¥Âi+X"S#ºZ÷[¬k‹×Ùó—Vî¦׺͎’Rk¡ÓYb^*X†•÷XW•ÀËju,¬¥7í†3ˆ‡Ö¬2MF£¥Àh.0æ— ÖƒÐ:œ¶õ%.—Ãå"–ÖwÖ<€2SNq27] X?L ‰>·ÅEÀ@ƒ(]X³<ݘ¿TÔ2ä-3.Á–˜»é;vû‡;gia–ßómS~ÁÚ¥¦ÖƇ]6—ÅëÂ2,_þ€¥° pm%;X éödA-”ûz›9+XD‘; jÝ÷×ÅS¾Å²ÎRš¬rK°r7=º©Ôé(´Ù¬¥–ybI¤GMÑ^2Q&K<ÃË™øfÜ·V[ ‹ŠÖÍËã¡ðE&RÄŒNå9}þNjm|heaÍV¼lBN =ù±T¡r9¦”ZkÖÚJW—ç%¢ 1!MÄаx.2/Ïðy£Žµl–LóTKÖ'K&.EåÈe%2y#[XËŠWšðcל¼ùa!·V5KŠF'¢1X¤c± s|k}±ÕM¸\.·wå|°x²ÍmınLDUN¦a©{ ÇZh%^¬tã©]ÔædU»ÕDQ‘žªôp¼Ûh79bœ€TGýøâ¸ŽõÒ‹/–ý§ˆÅžY¼¿yú¨¹/ȉŽúWðå‰á±nçß-2ÖËe±› e)"¡Á+žC#X K ª¦öºœ‹ŠõjÕ¡C³°PèÔÕ‚-Q ‹á‡¾¨¯N]ëòØ/&–6òÇ}˜º¿5d5R±NÊxâ‡ãÎ.Õ¾ÙŽ5su<¦ÕVIæS×Á­ â"(@(€„iZéhò;‹Š5ûéáÃbi: ,åô8ãQ¤€Mô$Z/Áÿî"µ´GøYǺZv¨ì™ÏÇSgáÁ†‚Ú†±@DMRd ªÛäiWài°1wäZ¸Ë_-{éåªÔ×F‘C!*”*ëXH+$¨…?=qó¾Åªz¦lw’j }CZT4<Úˆc!¹iDVP-*©Ú–™Àðâ`i± ýŽÇ±TéËØ ÎL'ã锞N þ§#X°X¨‹Üñâ™tÕ—&ôžQ ‡?|ýõ£‡}{Õ–:톋Œ!|’¢âl9&M/’Ë#‹jW_zùðñXÔ(JÃ×^«¾ŸQ¯ þðY¨Ûȳ®½ÈǦ¥iô¡0n–‹Õuû¼¬¬ê0VuèU„5¡þúùêÑyèg®í{¾Z½¢My–",q1¢'¨’Ä}‹‹õ⋯ƴØî²²gþ/¦È¡á¾À¹aË·—øî‹Š¢ˆçŽ"Ða£/&}|àwª:æq-RKLªUö3Àúäg‡?ATiB‰jj÷‘#*ÚAMS¹Œ#èY ­oÔãØ§ªá½ÕÝ‹‰¥{ÿ}ÔÕO>Š©zï¤~ùü¾×Ðmq£P´º|ÅÉK @*Ž-ªoi7.éxêµ½©iRõÚ~ü‡ä}ÇÎù` ©)—ð¤¡Á“_Ýù²ÙúÂz­ùù”j$MȳN4nüKºˆé¾áâYÃzïµêé´Ý´Gª«Ó:À¹ÍÝd kð@`êö‡¦'‡§çs©lbir÷×Ý\„y?þÉÞ—Y.M~Ý‘Ëó(ÅÓYÂRÕ¯Í:£sÉGoR+ä[Š_ýAjyMÈî7Ýd²r‹FÑBQ®Ç·c±xYúq|}Y_QfbxÿzúÑ„ÅÐd©"–òÎpl°£ãtúyßìç.ŽñB__Ÿ ¼Ç gÁNŸø€ @™Àóx755ÝÍ’ú(’¬ô$YQ³§¦¢véõxIÞuTçÿß¼~Í)§gIEND®B`‚nagios-2.6/html/docs/images/cgi-statuswml.png0000664000076500007650000002005407436604446020667 0ustar nagiosnagios‰PNG  IHDRF–TΙtIMEÑ /…P») pHYs ð ðB¬4˜PLTE   !!)! ) /- 79#+'%#)))5955'%E DR JERR!R9))B%%B))J!!J!)J)!J))R!!ZZ!Z!R)!Z!!Z)!R!)V!-cc%!c)c!)kk)k)!u)'1"6..,?-951F--R))E42:D6R1!R1)R)1Z++R11R91Z11Z9-c))c1!c1)k))k)1k1!o-)w-)c11o11h9.eD.{1){11s9)w˜B9„BFŒBB†HC„XHF=ŒLD˜J?¥NBˆMPJR”NJ™OP‘`SŒlj„Œ„‚¨UK«XX§gX§yr½oa·„vÌwjφv…”‡Ÿˆ•“Œ©–—™”¤˜¢žž¥ªªŒµ”–µ–œµœ½¤¥½œ¥½¥¥½­¥Æ¥³”ƒ²œ”­¥œ­©¥­½¥­Æ¥¥Æ­¥Î¥À”‚Ιˆ¿£›Ðª™ãŸ‹äª”Û°¡ï¶ Œ­Î”­½œ¥µœ­½œµÆœ½Ö¥­µ¥­½­­­­¹­­Æ­¥Î­³±±­Å²µºº¯½ËÀµ²Á½Á»Ê¾½ÆÎËÄÁÞÄ»ÆÖÊÊÜÌÅÒÜÔÔØÞÒÎ×ÝÚäÞÞáïáçóçåïóï½­÷½­÷Æ­ÿƵïÒÁóÚÒ÷áÛÿéÛïççïçïïïçïïïï÷ï÷ççûëçÿïçïï÷÷ïó÷÷ï÷÷÷÷÷ÿïÿïïÿ÷ïÿÿ÷ÿ÷÷ÿÿÿïïÿ÷ïÿ÷÷ÿ÷ÿÿÿ÷ÿÿÿQu•É¿IDATxÚšTÚgšï­fÑ,UP0VRE&0YevØ;“ CëBX§M ˆ²hT°BŒTÇÖZ$jˆ1bŒÑ WsHÒq¯'iÓöÞ½÷ž5â„”15’¦3§3ÄÌL-Ù­mŒÞçýÆ$³{î#ø}~ßçßû¼€ ѵµµ•/z†¯”ŽŒ ƒ‰›ƒÆ8×ÓS/<=Ôa(£ÑO—éõ:øÑëtJé?ê¤Lv²’B `-Ã\îüÁÐ" ž<1x¢·»Ûžžî¨0È^|ih¯œK¦é¹\1—#r8œB‡AKS²I‰ÞuÌê£ããÃíå 28ØÛÛÛÙUc«Q©”/åØx2™XÌåq¹¬SXÈbì` …Y‰& óˆùC`~x<@Nôžx§»¯«£Ã`0(r\¤3#F‚dšNÈÀñ£ëj~}|dä̇GGΜéí=qâÄ;'˜ŽŽN•A¥PÉeÈ0MpGÛ!å°ðÉ¡8fåòÐÈHïGå· .(0@é0¨T*…B&çrSÄņFr ‚Cd‹Y¤Dÿ:æ,¤¨¼c4Žé-@éì¨0T¨T²2P™ -ÂŽÇÄp8,‘).$%Ä0«úGG‡4ˆüVû[@yaP`@K "PÃ-‚["ä[!‹Lf%VÅ1>>:2ø#ÈÓà[íÝH P ¶ 0P¡ƒ‹0ƒÅåpwÓv( éXŒæNÿèȉŒŸém¯h‡à¾õÎ[† \ 6@áò¢%›‹aà7Q*dâSCfå&¤»·|tx°³â`GpºÁ#ð©Bb2È6ÊuxR‹ *@¸/dÅ€I^Œaރд¿5:r Ф+FAiªP(Je2\yPxâxl±ØÀ”#‹•Æî&³ºröêÈÐGÎtW(öÄÅTT 1ŠÒÒR™J†” /°ˆÄbƒ€b™&d§¡vHˆ®¬œ¾62ôá‘3{yÝÝ_,2+JKÁ+PÄ+‚DAíq‹âa)Äb-㦧 ÙdœSó—þkPÃ#£'Úy¼Š¾n(ßN^ƒ äÈ@MQ’ƒù"Æ‘àA•ŒÃxQÂ&'6c˜?ÿpø$ª[Á+êìí1X€SªÀú€‡ÎÁ8(°œxtdJ!c‡d7 5'8õ»þkÃ=¼Ñá—îîj‹~Â8<¨b UM!óŠËU)Ŭ%€ÑDæfÿµ¡ŽòÑ3yE¨N¬™PÅÈäJ¹RŒLˆ¬P,„µ¦­XÂeð Öön¬þóÞÙkCíí£ƒ OÕ¹¤Ò+Å%LÎÌ/(V#+ÎϦ#c²ÙB Š‘(ÕaYá‹lX*¨Ksúܵ¡òž‘Þ½2™Án7è¡ØÕGïï„––VÀVá]ººsÓ;p´šIg2ÙÂÂB±ê°ŠKf”@‡æè•kCŠ¡‘·`«ÕífW;o†¾ÅŽ[{b l)ts ª€Î,ÔTÜt`RB€yôóFyg‡2Øu—ïüió¡›í›ÍÈ?Ýyï¨T,ÓÈb&º!aéã£ÑÁ¢³%%§oþ Ixúàht»ÂuíÉs« íÏAg…,e’`-ü÷Gû O¿]Y{ aÕÎÏ["‘ff`Aë7Fæè3çXy,®dà”ÿ?é©{^?ý£)sÎ(š‚̹?,hÖ,EŸõtÉ,Œ0¿ü9`Ž®<û‚5£ßÌ7Š<ã"§ÖlZà{R5©Þç1Í’†ûùÇçŸÇxÂoxçš›óãQÏøØX0ð<‡‰°3!6×~>lÌãç@«k«ß¬.¯.£Kt9Šì9Œ“)Aƒ3!‚aή`™@•ÏÕò7ß,?cÑèWO% QÂx SÖÚß¾Œ0Qxé<øìîÝÅÛ‹‹·çoݸuÙõë7nÅlžZ¼ûÙƒÿ"×Öz™râ8Õ\ÿ›¡Ãï­¬F¢ŸÝ¸áóù&'.Àíô³6‹n.Á“¾ ðã»õÐÏ,¡$:‘Sõ¿’¿¿¶öÙß,öºÿ_óÝÌM¦„/!b:þ ³˜K® ×%ÄrÁNîš¾àju·µ\˜†Ü“èÁI÷¥Øs—|‹«kËg1óŸšÖF‹¯uÚÕæžtM·ú¦-Ó®Ö6‹e²uÚÒæjksƒY&\“ØÙfoCp‚l)%Ѻ–p¿êøoúzsmíÖ]_“¥uBäk³´Z,-m-ðJK‹e¢¥Éâj›¶XÚ,î¦FxÊç¶´À+'šæ—×¾ 2c˜pÕñÏû~zs5¸ NµN¶´¶µ45ÀQnpŽ˜°f0.ËD£Ë2m™li´Ì6º|—fæSJc~‹aüw}Ó—ÜÜ—,î¶V×D›» ÅÈ}aÂq™v+n·Ë=íšnk…'Ñc(Uw˜ÖÕü¦œŠÎ,úÖ5½‘±éÿËóFÞQ¦ã"Lˆy`]Íç=\P3¾èÛÈeÓêkÅŽh]g:ûùaùéÇKolÆ\r56÷íÓìÛwlß¾}ÆF#üaíÛgyõ3¥8hͯÌÑ•f£¸\–}Çš›´MÇDûŒF‘UÔÔØØØð,f &†y˜CJÓJôÍ嘟;ÖtìØ¾–ƘMÛ1‘Qôæúr42¶¡æìG‡äÕ+K›0ÓÓ®ÆóƦ󖆦càKñ†Fc[£±é)5Ó³ËÑ%'Ê/†ùX!®þvéü­M­9íÚ·¯aßóöƺ»d#6‡Äþ´ä¹¾q» ÝØ p»Ïòì~÷ÝØ“›ºaö8ef#§VÔì-_?¦K“oälk«ÍRßää¿ø.€]Z_k§¦J²¡æ£Ã\ö¥¹w/n`&',®¨} ­m¾K£¦Í¨>›h[˜°ZºâÉØ7—‚篯ŸæôÌ•tŒNh‹˜µ¹Í²Žµx)”/‘²ñ±„|H&|iáØ­ 5.—»¥&UkËät[ËDkS¬‚pilõ=©äùåÈb¶TÊŽ;…0cß.6Ýš^ÇüWöËD¼ún/G‚tÉœ‚¦ ¯?™SÓ±kìv6¶^ÍÆ7(E¼¸¹I«YZA˜Â£€™›lE ìžpO<¿’n:Ã:æîrxŠ.Ç0H ·°úQ¸i¦Ñ¢™˜˜l‚B™„™œþ+¸M«²ï³å°3[*Žgêò‡?årJÂ!ë¸æ]‘EÓÐÔ`lmhh5¸÷5M_úÏwN¾ÑûÍ̸SQ¤f§äNØy0ÐBM°e˜Q4)jü/¶_³×—„ª ¤%XÂQˆAðfxÆúFƒ±¥qÒÝÐjÚŒ¢VQãN¹4}}9R—lRó*¨ñDšo]Ÿ½xqYìvö¯n§cÍë[ü&r'_"Ž•_tå2¢!Oè.ìVoÃ>öúu´á¼ˆ ¬ø ܸö´·ïžvy-Ì’ŠÅÌu ÄF‡"«ë[ép÷îíy´'¾G_ÄŽ†ýð¿ÃvxùÁW<@{ëÈ ä[Œ©YZ¹r Ô°ª¿ …¢QØ…Ã^<¾ÿþƒËËÏïÓ#Ÿ}§ …#ѵ‡‘ðM¼áÔ•ke»8…’px1t?‚½/x ¨ûðbôêèÃMoÑ¢±·ÂÍR$nfÉåÒÝq§>({%—Å Fb¶ˆ‘è†m`àÐÈÃax,©…b¹|7neêÊeyœ¼çÒâÂ<0ææc†páu:Ƀ˺…ÂÁl±R&gÅÔ¼µlWQ®°:è%œ>1ŒS¸¸‰·¡¿ÓD‘Šeë±yÿƒÃ»òŠXLU+Ò4‚@èC?çÄ,tj3©j"$Š ™BN­|p0yyÒŒÅhdÁÛ,2y›lÎÄ×ðµþà:g1´èÕdšá½ßƒ$&P”Oar…ù‘èò7£¿Iä ÌÍæÄ/‹D#ã™^L0B¾f&üåï…ý¶X,W²qqÌ‘—só8ŒôÞ¯¾~ ^4‹<$!¼‘è|¹šç!a¼÷é+YˆÔ0ã˜+ †“˘W¢ž7¿þ$µcs`³r®DæDäոȕôå½{ÿúú¿~¢fŠÅb™<®æ£+GöäíÊc ™¡è×ÿëµÿùõ×ÑÈRXƒ0^cdq!Øì_XY@NXZŠäÓ×_û·O¼¤„Y1`Pˆór$ÎhôëÿûÚëŸÞƒÓ7#1ÚàB0 HN .„ 'lŽ€´{ÿûµ×þÏ'H7W.“)ã嘗&·¤8òðá׿zíõEˆ§¢ï”ß*pšÕtIuµNÈ¢ÑvcjT*=ïEjþpyè{€áä1È„bu O¢3…B3‹bjvŽ!ŠI3WÑÉŒ]­®’IÂ($þïÏœ|ûí·‡‡Ôšl²N¥‡ØÄ0˜š<áw^Hxa«Åµ5™O¢q"C QªP@­Ñ3¿ó·oÿÌqúgoÛ$jŠD§R•Å1ß^>™ÊËe“H¯½›º55?‹ƒyƒ0àBÉeªĤT:³l¿„I¯Óë†ØÜÜÀðPÙ0I¸D„J~!‘@gsxèk)ômb(€Ñáq)Ôl¾@ ȧP$@Ñ&°ŽAŸºïÚ•ËBH$â·Òtâ"ðqx[ìRZªg‰DRZZZ:KW[ƒáð.ˆZóÛsç~ÀƒÊáA€ô]¡TRYY)ÆšL©’ rt³¾¶®º¶¶®¾®®¦FoPÔàƒHÍ£ËW~Ä“bgzzú‹iiä4rƒõ}ú佈‹´>¡%J§«ÔIŬœœtZNNN.G¦:|ØP›EXˆa®þˆ——à1hØÇîûÙlZúKÈÒÓÑ«a]ääæææì܉=ÂM/Be-×jÉ„Å8æU'‹@Èà«‹³3p8B–´Þf«1¨~&ƒ)ˆ‹Å‘Á¹ †šš:v:%##^y¤–‚>Kÿ S³‡Aך4>555yK2‰˜[ZQa¨ÑëtÖØ•:(pôd !U ÑjµF£VCJÓ×’±äWWSŒ‚-[’ý™ ˜%Ñ_’«**”L!#5…€ÇÜwÈRCG‡¡¤Šâœhµšf i÷“õGž`^Ý#$%nIÈ4™DÖTÀå*ƒJI7«©É[““’’S3B–aHx~@ë÷xç@‘š¤;²yÿ꡽E%PÃ|S³Õ$HH¦(KaAbAÍ&™¬@IN¥ 4êmb¨“z"Áìoòz¬N‘FM®­LFû¶ìý_…fá¨pÖÌí‰øŒh!X2À?³—ß<Öl4 D’Ò`«Ñ׫Ì|0Ôô¬:›­0÷c˜k‡Ð bVê…ÄD 2TüR4Ì4K#Pç—è ªZ"‰/(ÐÉÂz»¡Ã^K¦DVcjÞTì=Xî($³ZÌC•¯‚íXb¢ÓKÕ4m1ý@-*~ÈU=D¡0«ëëíöÃ2öUÎÚʾù*oÏ^TX(”VJó`­B«ƒL&¥("C¥Ð`¤ qN½£Ìf³Û ö#¤üè:æÇ{÷åBÉ¢êMß™óÖ‡ÿ&ãJ%ô ÈvH)Sabô*7Šš“'–©ŽØŽ†ÃüúÚ› *W:úJŠù]1''Þ èÁv›½›ÍâÄúag.WW[[)•H*u:(I[=‘¿Ã|Ø­à1Ò$z>??ƒ€O£IkkëkõÊBƒF#§#ËaqÄÐß6ðEG#â ¤ iqGŽÞ^Ÿ¦ÞÀð¸t­Ùljð©¨n‰ˆC‡A_[-Ý_Àd2 $:]]ÍÞÕi¯cd¤PUU&°*5)Ýv„¤‰c®vïïONJ6R3ÛEIÉôtú"›KN#ÁhÃá ÛЙá±.›®šªqb=¥­ªªâ“ëëˆÚÇqLß^991)yÆo…=€9)‰Nƒ©ÐC3d§$'&'§dd àÌ5]=6) ?çiöÏø½ +µSüè«C{eRhþ”f®Ù¬MÜBцJk8UI[¶˜Ç2¨©ÔíÐ ¢ª5CŠßo¶ 8´J­Ã^O4­b˜ß]|u¯LIÆA ¥&$$&Q¤¶žìŸXÐ ‰^³Àì´fòE-Ießc³éñÅZè ¨H¹Þa·×ÌkqÌB±W¦ccƒ!G’ÖW ïG¿j/sÜÔäµÂ0P3tÙí6{5ž‚¾¥, ë===zBsì~uèÇa¶ÊÊÄ 2‘H®Óï-UT(gKsS&5#Ö‰lV½ýÍVŸžF¦1”±#̶æÕæÊðÁò½ o/O%U'Ž IE©RJFúÔ|:Œ%ö=y‡­ZÁáptõ Ÿ>ý6kLÍŸ¯ —W( 7wíÊÁÖp˜°ôÊT2±ŽEÄã‰iéB=6• Áô2™}Wk°wõt÷èá-†ùË•‘ƒ{÷äå°rÑ–Mø]6ã¥_ziçΰ?å%B ìk`R)ÐyvîÌáˆuúZ´oCd{Oí¶± L¹œA&‘2(Ù¨³„u»AUZ´ëe˜)/‚!èËyE¥ªŽž“Žú”m0WÁH4a=8åYÇŒâ’5ÍÍ&­–ŸA îuvvÿëuÕ•Ð…uõõýÇɾ®‡˜LÉh¨´Øëè·yc˜GWGÉ  ¬sÉÈRR(éÿ„¾£×1Éè¤8†C»ÆÞ×e¯«Vû§0L€ È=~j5޹z°, —”‚œcÔ$Jº­ RK«RgnOE½Éççsí}½=•Ù3sÞ9ï˜×k4U‘+eø©µÕ8¦\!%âƨÞfo³Ñ˜DÑÙ B”¦Ô¤$óXJFRrF¦@«&ºúzꉸ#ô‚ÕêÕVeéúO)ñþ¸SW®•——êÒp)‰Ô„í0–2˜¨4›0¶qc3¯ÉiÒj4U$}WW—CŠãg¢Åœ¬;y²O‰¿k†•«¶—TèYD¶ß"0ëUíb ˜qÈêižÊ¨ÕL{Wo7ÄŸ 5‚~Jþ@üg>LùAØT ³ žI½ê`ÅÁŠ °Zkròöí@)¦9l]ÝÝ]]$‹Â¬ëïë;ÕwJ Û› ØA…L®××Õ9ô2…8¥*½éC“A È: ]ÈlÔ ýýŽ>訾>9loÖ1Ýíå 4ò`ÉÏÝUÄ+Ý‹æ”J¥¬Þ]#¤d쯫3tBغzìö=}€©zwê÷WÎu÷¥½¼â¿èÀhí §Û©W²™LIÃfëDm¹ŽÂtu„›fZÿ¿ß_ííììDzÀ:ÚáxØ–tt¶£¬¯Ñ×À|2ÀF/n=6ÛI‚FæI»ƒ¼ŽYùËû×Ñ?ABýcMðWlhèÌ™þ3g†à]Ð/˜õ—ÀÐ\ûïuÞTx¹ŠðIEND®B`‚nagios-2.6/html/docs/images/cgi-statuswrl.png0000664000076500007650000001111607436604446020673 0ustar nagiosnagios‰PNG  IHDR–sMV átIMEÑ %e…R7 pHYs ð ðB¬4˜PLTE   ! !!%%%!!!!)!))!/)1!)1)))1)11!9!)9)'A,159B1!!9!!1)!9)!BB!!B)!JJ!J!J!!J!)J)!9))B))J))9111!91!11)91)J1)11119)99)B9)1B)9B)RZZZ!!Z!!c9)1))c911B11J1111991911k11{191991B91199999B99J9999BB9B99Z99k99s1B19B1BB11B99B91J11R1JJ11J99J99R9BB9BJ9JB9JJ99BB9JB9ZBBBBBJBBRB5BJFBFJBJJJBBJJJJJJRBBcJJJR9BZBBcBBkBBsBB{JJ„BBŒbc86L]M`\IXYZ^gZ_bi_[nrpx|„}{„„„ssŒx~Œ„{Œ„„ŒŒ11”BB”FF‘WT©JJ¤`]¯]]Á^^Œ„sŒˆŒ„ŒŒŒŒ¥”s­ssÎsk½{{RR”]]™kk­kk½z|¢”ŒŒkkιŒ”Œ””””„ŒœŽŒŸŒ”œŒœ”„¥”—š’”œœœ”œœœœ”¥”””¥”˜­œ”¥”œµœœ¥œœ­œœµœœ½¥œ¥¥¥”΄Œ”¥œ”µ¥œ¥œœ¥¥œ¥­œµ¥œµ­¥¥œ¥¥¥¥¥­¥­¥¥µ¥­ª¢­­­µ­­­µ­œ¥µ©¥µ­­µ¥½µ­µµ­½µµ­µµµ­©¥½ª¯½µµµ½µµ§§È±­Ò·»½²µÏ½µÆ½½µÆÆµ½½½Ã½Ã½Æ½ÆÆ½½ÆÆÆÆÆ½½ÎƽνµÖ½½Ö½½Þ½µç½½çÎÆÆ½ÆÎÆÆÎÎÆÎÎÎÆÆÎÎÎÎÎÎÎÖÎÎÞÖÖÎÎÖÖÖÖÖÞÞÞçÞççççÿÿÿn9OèáIDATxÚÍ› pÛfÇEØÇWâ®AQñFv7nÇÖaMgJáø<ÚCêTVFÒiÇuÞ@ÐrPÀq$MŠ()”}šeÀ° ­iPWu‡´fõÚ³s$Œ²c”ì¸í€ç•eGþJ$ÛÝö4ÕÇ+é}þ?ÞO›8sø»ßÁöðÃöîáï¿|öð#O˜;~âô±ÿð‡ùö¡Cß~Ï9tè _<ô¥w¾»ÌÞõîJ{WÍ+uÎìûž9}øîã‡eâ°ü¹þо}ïÿm·í»mß?ò¾—ÑÞûyõnU¾[S‰ççN?ó÷Ó??{ö©³Ï\xêìØçíÏ>§Ïb»ðì… xë´bÂ…gË/Õoþ¾dÙ,±œxpþÜþØ|fjzvéXìÌÜôôô±MOÏ/íŸúáÒKl¹¼%‰ÅLla!ë0¸ŒwpÝ‘Xsz ?œYúÊ »\úÁGs¹z©JTû秨~Z#žÃXíNÌüèwÖµßy0üg`zë’›;öe)—™›²°¾§ÍçSá³Ll6×'þSÛ\Ó-¬ô‘Ç~óÎd!ÐrO&ŽÍJes§fOئͦfgOÏ2³9ó¨ X餙: ÷dÖ=¹L ñÄeýÿë† ¯zu^­ô¯¦•œË.B‘©£É#8ÕLb S³‰”‰O5ã&\ŸMÃ}f2™ÄÏ@¢íb<9{“ÿËfîÓ‰l*—ûk&.B?™?ʘ©—ÌÌ'Ï<žI9X¡‚HçÎ=½ÞL$“‰D2µ1²Ùó 3iþ÷/•½O>>›ñø‘˜aÄ“€õïtné§ûÁsfê 3•Î>ñì"ø/ÖrÒ<þ8¼@éT:I¥Ò)¨NM#›ššMV˜iÎ>¢9í1³ÔNà¶ÇÊ/z°“æl)@Œ˜…ÚK‹UØLr&Åà/çÿÛf§®œY[ûžx¬)– t¢ª†1D¿\# ‚h-Âø^1X“„ï¿#Y2@vŸN¬óäºW–Aø^\~‘;’ÝùBJ[–ÒËò Æ+ëùR:=–M鋲¹(Å_ð¿"°Œ1cÃ]t aj4A“>D5A­PÃXI’¯&ð®9o"3Èt½c°‹i‹ ‘–QäŠ5†5xÍàà`£X’¦+Š"kÑ•z‚k̉W30ÙXLtBÅ€jMsÜÖF±6vteæo몫F¶mûŒ[.&È0]eòV[ôcÑaYò5±ñÙ¦A;«Ê²<&!Ž«Éfmy¦‹Xy{'I¶6 I²,!YUJ’ÆÆ,»qTS¡ñáØ)šé@-i 'B%ØÅÀËÄ  ò€”ÿ³ÕÊsÑ–×8t+½ÓÑ0Óp<à #Äî§™þ`¨k²ê­V_K+I´¶Z‰VßšD¡þÒÁ~Á¥…h¸¸Xë/µs›D´­l âìæ?Á3,qA†gY–£X1Tñ&^½CST`Šâ¨NÝTìžQ"– ³hœ¼–J ´ƒ‹¾ƒ1{F÷0ýýC 0¹a\7Ü)†%¥J½uÅåíí~¿¿£Íç÷ëz#‘HTb1QŽ8`Ymf;dÈí½ÿþ‰°M1FóøîÄÅmµ3²t …!wqÔ Ëêâ ‰•±ÕjÉŠÌËš-†,ç±ôÅ«¨mjÐq*ˆ“¿ØNÓá-ÝeëbÅ;ÖfEvËöp hW,¢D9(„Xm‚åB:‹?Iµ&ÝV«£½Ã%Ö,°_EÝ4«½‰’&;}8:1*öÁAhËŽŽ½¸ãŒç‡X:Ü÷Þîîž°íHxE†xJUXæ4K½šÁa©u•%VAQh¢r!¶ŒJµ vT‰[‰ûPè­»¬`eì[hp¶°Ûï ïoî»sSOÏu×wGÆ{{ÂÂ^·Ì|¿,¹èæç{WR*@’Ø blUyg"ÓáýðàÐ˱áÍ›nïþÐÀu×G"Æ{o¡L¸Å"ÚÛIΕ@³œ\ÀZµ±×ÆèÜwàÞHïæÍ×Gºo‚( oîéù–'®ö\˜ÝÒçj‡|U“%µÔzŠË÷” ¶ †pP‡{À“¶@͘PµZ7¶û|Ÿ"}d‡Ï¿v¢X4àôô‚<ø¨Cͺf# õ£²È Š ÍVq`®à¨=.ôˆÕµñÊ6è9Z™bßtÍ™P<ÚZÒ”I1Œµ{·¦éš¦RЦhš†\ÇqÉ}MÂ* y_ÀZ%],‹¯òM\sTí¸¸£Fz#X¸:Å£r­Õ–³|‡G›ñùŽÍe¯ ÀxßëÔZiÑPIjS°&Û¢S†I‰* çiÆU9j±~ý•T vâÁ´¬9<×,,kˆ!ÒAM–xGÏÆÍDZõ¨A,âŠõýT ¤BAä k…¡xpkS"¾0I‰ähPfå «è¼J¾f¨ÕÅÐA† BÒã$eNó°`@Ö$E‘iñ>wZ!WÕZ¿±su0‚Ï;Vްö#î°&‰–™/=»¥¯R¥pH«b©4í~õÕ–K„xwL÷•úÒ%ÒªXšŒ\ö Šr1¨²n(ø¹GZËÐ'½.¡£ê‘Ž$„¼¶áµcK–U™q\eù(¿ìµQª­–Û Â1á_Få\Æ÷¨×*XÞ¿žÁÜ%ñŒC¥2Ýš[:'y« °&Ì¿p·V½ì¬vÁqÞ*Ëä‘‘ÕÊvíËÚjy­ Àn[Sw¾¬[“šW'rÈUgÞ/kcɲ7µpi¸_ãêÖµrn¼‚°lë6K&rù}Ó5|Ù$¬âÌÍÈN/ê^Z,ne2ÐKå´Š/›å@n³§ž|-_6ŽåÌøš¹Ú UMÉÅâJ﹪žb°Æ°ÊÃvëU;wÖVöTCXUÃþΖg+û€ `qM›Ÿ±³+U×…å½k·¶­ø²^¬K唬>¬&û¯R²z°jû¯¡ïÈ;ó¯ùõŒÚX—È%`«ª}Í “¬ï˜W3+oJ¯KÅu­ú“¥÷K#µÕRµDÕ_MJFÕ߯zþÃЪÿ¾ÍPÕê9²^~!Y{°o­!y ŠŒÁ²JæªWd J—˹Tÿ¬ÊU dm ðn±4Dã/mTb©T0¦©zEöº*k1]× ­’Y·Œ&+? ¾¦qty1IâÁuëÖmذ.Pfà”x¢šÅt£jzÜ€¡%¶Â¾âÁê9Æ«åhÿʦÏ-ežsþä}ÑþulÊÍ/}ë¶Åå‹/./ÿgqùy°çž_^<¿¼ iË‹‹‹&ñ}öÔ±ýói'V܈“F,3b—ëbúüŸ“çÏÿÖœÍ>ù³¹yü[íìù“'³é\6I˜1Ó|ÜLÕÿÃÕº-Ÿy@/~e*›²¼KÄ'˜IÎÿĉÁõõ£òpIEND®B`‚nagios-2.6/html/docs/images/cgi-summary.png0000664000076500007650000002726607436604464020335 0ustar nagiosnagios‰PNG  IHDR–sõêl„,tEXtCreation TimeTue 19 Feb 2002 21:03:07 -0600Š‹/êtIMEÒ Y%W pHYs  ÒÝ~ügAMA± üa. IDATxÚì\ilW~Ÿ{†÷¡ƒº/ˇìX>â#õÄE²©HÄ-ÐoE[í—‹~i>äK‹v·›EP`£Ù›¤)ºi¶ñÚŽÓMÝØŽcŇ$Ë–)É’(Q¤È!‡Cg8ÓßÌshZ–G¶,'ö¶ôæÝïÿ{ÿëÍÑó÷o]ïŸ<±¾»{»¢Y–N§µãLJëê¼»ww ÆÀ@²T²êë½<ÏîÛwiê-ýøÇmÜH]½zU×uM‹0Ìh__Ž~åßžN&k³ÙP($§tºähš¢iZXÃ09Ž ‡]ɤšÏ‹½Š‡šZ[)'‡„išº.úýL6+s»w¶Ÿ”â,Ë®^½bpp¦MApÕÔÔD£Q†a‚Á@mmmU•XSÓtíÚ5š¦ËåRU?eYöx<­­­£££ÓÓÓ<Ïwuu-öJ"áð+K’„€EpçrÈëõZ–U*•ƒ O¿ß2QDÚBX‘xHàÅ^ÔCGô¡CŸY–&I"yÖi3'ç>7¤1ZQ·¨<åóJåfùmš†ÇÍVöeš¬Q2žž{HEQ½^÷M“€Ò¶J&ÅΨ » Û\~TÕ’V4CA¾œƒTК2%é[ý!ä$§æHzôÚ(ãõJ2ò\dŒ3õ™žT?Ðå |$?YY-o» ßÂ4­©žóWûcÀr±{ÿèÃÿâí÷Êk/ÿìÍsú¶2^\‰9ù¿ŸUrdb`ìÐ}hé7rX–Jg2nGQ åLQ$ZSÔØär¥£Çsüw&›Ê™Éi«··xîüx圲ŠktÒ€)-çhkä×ÿKh˜^9“aò Ã&“Ó•mŒ¤–¨Êj?x tv×nyáOÿº}ÛS¬ÇC=z"“I{<¶f†BŠ¢ÔTWAœšš‚E¤šíéÁ`™ð\Ün7œ0örD{t*dÙ '6‡®[ÇD"IŒk>¯VUU‘†.—a%–1YÖD1±Ä‚¢êS¶¦U°‡`\)[jóE+‹ÁN£¦DƒLxW¥’CP©9~Ø´ÿóãÿw¤gxð,=½k Ç07VžÍfãñ8…ÊþK"‘€¦-‹ˆ9„¹\`À¯SJ ÇsÓ•¦Áñ—›°¸PÈONNÚ»&ëá1ä Ý€ôÒ¥K«««ÉІ²5j‰ô644„ ¡L&³iÓ&@ „Òé4Zaˆµk×’VÒ¬ p(}xti>“ã}AŸD™yÞ2é>:Ì0:¤ e&e5M/>ŸwÖÆ)M ‰âŒÌJøˆî’  ----ç¯Êmµ^CÏî9êÛAE0è…"Å–•_'£m¬3â={ö,2H ¤°±±±¾¾ž“˜ß\:ó'›â“†CH ' ê@:¡`V¢kÐêÕ«!‘}}}DH˜¦iZ¤›šš›W(>|QxIª?›c=S“õuUx„Ú#: š šƒçHwww£ W,jøÇó\Q»,Ä•æV7Ê —€"ðÀ#p`Ù´±Q”ŠZs‹…]YDf{{;t/ШÂ}ÐÜÜìóù°Ð ê`x »Ø¼z@ L÷šBüúìØOµµµ<ÀFØŽíD€ºŽÊô'Ÿ¥é¢x‹z|Dß ²Iâd9K\ÁGô½#H$F£WÉÛ<Ñ9i{D÷™L‡àŽpxï½÷æÝÑ믿þâ‹/.örFB”|äȸyvÞ+ 0M™¥›N:Q(¥ò!Ñ¡,Ëå8ìêÕ«²œ¾ws£;;;áþ,IJϜ9¯®®˳†4|cp®8²gÏžrœzo ,ˆpÔ)'lÁ†uuuÁo‡'NÂOÀÂá´ÃC„]ƒÛ‚|hÇÛ)9øD¯C¸iÓÆ·Þüå?ýóOjkj?>|¸*‰±„’‚ ær ‘Ôû ìÂÓðð0ô$ÄkݺuŸ~ú)V‰DÈ1!TÚ±cÇ   ¬}(MÓÀò‡`P„d«Í¡¢ä¦¦¦èééÙ·oe»šáѱÑWþê¯~õeQ‡"5?ÿì³[{q¦)·ÛÖQ@Ú’¼%…‚Ы˜.v¦c`ç î1?ä üðˆU†Žé2Ì]…7}}}è b cÜ+W®€/è–(ga†µµµ×®]ÃVÃèãããÐEÐl¨‰B^k£º®µµ5ÁAbæ½½ ñ`ó0O?ýtù˜„émß¾ÝF‚ãÀ·öövìiH…ÙÎ-7 D×XÆ|@²È ×~þšý(¹fm‰¥–=ô@D Z,XÚ¹¬˜/Ñ%ª:ašá møE ,Å Ë3å~ʧ • ›78qÌ„—/_†²úâ‹/0·U«VawSÎ{r¼~úôéçž{&¢ ™ôû½^Ÿglt¢¾¡º¸®!”Í(mÉeë袦ON&àï,ö´Ñ ²C¨b|¤WW‡(ç4Ýç÷꺋5ú#I¢ÇãvÙ7Ýu{°È‰ [üôfÃЪɉ¤(òäØ0Ÿ/¬ß°JQòjNmkoºv-Ö{áÊbÏvž„ÐèÀ°ßØ‘ð#¶nÝúî»ï"ê‚-€ãPUU%Ë2ùP¥H·?ßrNg†eÏ›ÁÞêArk†8…™Œ¢í[ ÃäUmò»œ·=h„%¸ï€Ðy‹Ú»w/<êîînd’ãoAà Ë;ôr¤°-`>[z†ÚþuO8H§3P¤¢(EÄï¾õ?‹=É{@‡Êå7ä² úÅžàüé›3Ò·¿ ÑuýËåòÇÂì± ÓwÑVž4C[æÃòÝÐ÷Žl]­>zý‰uv8 ¢O&S¡PÀðʲ²îqKx˲‚!ÿ¾w@ÍåïzÐÙi``(•Z¨Îjl 65Õß}?•ä|D8¢︾ ŸO$–}⪪‚ñø4Ç2FÉ„8:ÄY8ü(ûð)75¥Ï¯íØØiZ~PUQ”x^°,“aØXlÄãñöåGÂt:´¦L³„R—˃Ö5>>œÏ«õõM©T²©©­XÔ†‡¯tv®L§e…ðX®n±›C¡yÞUôû ók8ÙŠMnîi~Cv5<·ÚHU*•ILMû|öÕ gŸ}Ó4<¨ÖO0R³ÙÌøøÀ(• ç¯qø%ÃóüªU_¹Ò[W×ÜÓóûH¤ðP4ð ì³æäîÝÏ_ºt®¡¡up°hår™ÆÆöDbB×í˸—/_ôù¨/Iöw~©ÔT{ûŠyC¸äÜcŒå©ÃÔIªg|,³§mQ¨«¯™ž–Ýn ~x^-ņÆH,6u·Þ;»)ûRšF·¶.éèXŽ4BXÆÖׯ ;;ÚŠ«½}Ù]=ÿüŸÍøÎ»±±µòѹ͜†DÚìÒ®KR>ŸcYŽL`?·!j$f3»ÎX¹qs7\ÐŒœšJºAÑԒΖƒûEGQmdxünG»§щFí;Z‰T*]'I.àºfÍæÖÖ¥ä.ùvõ­5ÛéÓÇ •ܲÆnié<}úsh×êêH4z饗þ‚ˆéý'ç¯dŠÌ%æëLÿ„Œ¦‰Á[±rIj:ýÉ¡ì7ìP’]]ëˆÍ°˜)mWyï›cÇŽQäOäÐ 1ÍÍíÃmÙ²›ãø»dždCÈH,UKu5-Yµz)¤°×S©ªê Àƒ:}ûã“÷éD;£jzªPÐÁó6aŒÇ4L¥T²¿Ùà8û‚•®ƒ¡4Ïz9¡˜ËÙÚ•çÙ›Š8ÇÃÈiH³,SY$ Õ¢àÕô±‚f›ƒú<¡B1ã\á5ÉŸ£#­ÎÇpU-Þ:–Èûi&ÞÐÕŒ"Ÿ»ê‚@H™mЗ¢QLôı3 µ²œEZɪ ËlÛñø©/Ωj>›ùjæG,cEj\¦e‡¤ñD6«Ìâ¿Y”Q]’0Îy="ćú²L‚R0À#GÉiŸ h˜6ë¹D´h£­%q•å<Àà9hDø>fQã …R À×In<æÔâäÔÈ9Ϊ ¸à–ËÙ¼ßç‚-ê†Ï+ŽÃa±ºJ‚裉Ç%HÙ†ƒžÁh.ègë"nÝ(¥e5raz˜†(rJ–ù¼øNZ†ifÍ€ßËr,L`M¤ª¥­‘ç9¯×}æË Õ5á­ÛGŒ±ïï/4„±`ì"7|ýá6áSXm.Š GÆS¬ˆADIȮߣEê›$¥ç)·G°(Þù’‡ã½4[䜶 ãΦúÄs΂_@Q$”åF X C¿öM‡é µ¨_J/Q:¶7í™–©pØoQE|¹ÝÂ7Ÿé*Ų b,¸0•£N澤R$k†ÛÒwqºùââÂÑ©ÈGgKŸ0.JZyÛ:KÏþ{Hi©©­™‘_P­tf’Ü)šAjΜ˜êX2ËKWE¶NYÿÆÿSË ¤U}ó*W|°±³­Åí™Éú|ÎÌ*‰ÚHí­fÒš’K64Îrçe:¾ ^… ¡òð+¤úi4: õâvIŠ¢Â.]Þ624.ˆ¼ÇëNÄSäd9Ÿ..ÄLlb$Š(qÎ÷Ûˆyn÷YùŸŒÏQDósñ³zs°Ž·âJÚ8RY(ÍFÎU`ަ\VGgóÊÇ:¡µaÿ0ït*£ëz`Íò¥ËZa7TÕ6K‚À|ðØÂy7ùÖFߘ·`š^*X8ó›é^Ží®Rjôb6{ ïXMËiîY8îYI#{k‘®sÏúkÿ\Z m© S<}cË"b?ŸŸ:ŸgU«Tg64 F×UíÿÙ»Ò9ŽëÞ÷1ÝÓ=÷^³»³<–ò’+jI/)‰’É`êˆb8€åk†‘ùcŒØH¾8’v`1Y’eꢎ¥I.w¹÷9³sŸ}yÕMí gš+GœYRr‹Ù®®ªžz]ïý^Õ{¯ø€¾ Sj-.(ƒˆ®3Ø–<8ƒQ¯5?þð†ª™¡ùW*VeYÔusmuFÔx¥<ðÍzscïàÆM™"ïxšgšç&{v˜Wg÷ë˜ê{Öv¼vkk‹‡^³¤iÚööêÙ³ÒÙ¶qÏß¹¾œ£(¸¹¤ÃG–±Ùïcÿ“ÛJ$âÑh´«ÖÁAZÅiY,æIÒF49 èA jÔQ-'KFÒÒwçÏó67öÔœùÎ@¥¥ 5tSQµ?¼óÉCw÷™ˆ-˜Ãø=s»7†?œJ #I]×—<óÄyÛ °Ïh†;uz&°Èq)ÂIÍÏ<,ô³)zÆ%ʦYÚÆÆÒ'†û¥«V"1â¸Z`ƒ©TÃÀ"׈—:b!%3ä Å›ÜÍËr$Ül´ümÞO×nF"’a˜ð‚Ãßñ‰ø²»“{èNL…½úÚmÓ[K–Hä žæ¸<‰çMkŠe÷ ƒ°^Á…X4Úç p¦¥(ñD€Î;¢àŒ³˜wÿ¸PT°5uL`ÂÔL,&`ØœÎI¬Ø“‘®Thâ˜O4X8h¤ØWáL­V+—Ë ã=÷§‚†]s«Óõôø0E‘±˜LÑ”mÙ(rßuGÓC4E¥†â«+[¦i ”…0ÿ 0pl›Á ³¡÷EÕl»j»-Û)¦3&ˆeV-þ –*Â±šŠ ª[˜j uhZˆ…`¸[¶˜ªÚ²àIƒŸvÙ­‡††B¡Ðââ"b¡¡iƦööæ½÷íïÃÓ’öÒ«Ü÷žëô\WÀºò¾^x ¼ÛÊØ Âe«ùîm/ËÂ)Šë½~t‘¡“b=#¯¶gw——´˜f½I—¥(&°A ç)<¸/]é³.ôѲçx1*Q—˜ôJ¤\®EoY÷’‚†B($€3ýíøʲäN¾8::â%ÈD‹a4MONNv¦ˆÓU{ùóŸzê|we‡Ü\_ ŽEuÈ÷ß{O’ÂçÏ÷Ôri-ÛÈ¿¿¹¤jއ B$ɪm=ïÅW®ä0ÚéÍdâÚDö`od$³(MlÐÀ$Ìýš)¶Ž&ÄB»nw ‚"ÎΞöv4]œÀY–±mFð8Y(Šò™3g½LH0?Xàˆm·Å IÒSS§;¯øä8D($÷^÷‹¦§g¼øž€Z\H¤“£qÜAèmÉŽ[ †„â8‘í­À$IöŲ¡±±L`´Ýßáòb!ç¨Ëôxadiq tÀ„\S¼!ÑI¶-ƒ=mšhÕŠù2¡· “„F€U¦¯chdÑzA`)õÜýÅY׋|ól01¬Ža|¾¦—º6£Z Ë´-Àz½­©-ç _â&í eŒ ¿åÛr~ÇU2µD2Êq,hF’"BˆŒªêÝÅãNš¦ì®ìTuoŒHÇvNž>9>1®ëj­ž'#]Q«8á6kµx"ÐîÞY¼õâ^$©î9µñü"‹aßøháQæ£! MM^@ßîOI6ϤđT -FÝ7ú¶I‡CF‚m’Ï>óŠÖ´Vw©ÖïøÌ8“–é+ÌåÚ™[7ïz‰Ì1/û¬)<Ç#Ç °Ç0”ét4ý–OúX¬ÿé4¼]û²Ž†ï0Ùá‘$˜ÌµZ#‘Œ"l4ZÉdÔvœãaáÄÄWG´þ?uRÎ0C!êûôlãÌÂg‹d ÃÚÝή.êºé:ÎÄäèèX 0j¡PþæFV|[ÉÛ/Ümð¿ ÿ¸><’¨×š„Gp=ŒŽŒ ÇqãÀ‡a˜‡íðÁtûöZ©ô-矘ˆe2cߎOºpBÆ_Ãç7gA`ž85Ñj*ñDTU5PáÅb%Pž¿üäÞnÎ ü1/?sþão âçÕjZ¥b?d#Íf}}})‘VÕV8,[–ɲ<`NIŠÞ½{s|ü„Ÿ¦¯Ñ¨ ‚è%Gu}×So)Í’$ÙËÁe³;ÑhÜûÉ:EÑM''ûg(™ìªUÄÂÖF•þgööØŠ…’íØ–]©ÔiŠÒtƒ"IIWînÎnµžçÊ¥>&ÛØX¢(fyùOCCixYs¹Ý+W^†íímڶͲœ—9pÏw;†IRج(Ír9<›™¹`šúÆÆ²ç’J„BB©”ï ûKm]h;–­Yëk÷nê/ÁˆcÈ?E®ø¾Ûðç`@àýssÏþùÏÎÎwþë8v±xH ùýBG¿Sx€G˜î±0•JÍ_>¿³UZ*0,VC7Q|¡i=ȉT’¤jµº»»û¨žf ÈLÓ4’ÉŒžÄC ¼çÏ_šš:Óß¾LÓ¼yóz½^!I?Ëq¡©©é……'D£Ix’7ßü Ï·+p[¢“CEúÿéÍ\®04”xïÝOÒéáx<òóŸýÇêJð)pý‘g¼8{ö"|ާ/½/¼ðj×Å'Ó^½öÇáÞñh Ÿ­¬¯fÁlÐ4½R®G¢[‘H˜¦øe¼‡Ã‡É‹úHueE3KšfR$aZv   1Ójø»ÁE´3LeÔÅ–5êMþÁ ÜŽ"\¤iä¹Kè º£ˆ¥,Ö¬0¥P %ö%‡ªV%=w^–¡,t‚ªEâ"EkÈíÇiy¥t× ›"E‚Ô 5hÊ/:ìKàúì ÜÖ…-ÚÐÏVB[TvsßÃfN$Æ¿ûÎc …GJÅEE@Å2J×Ð{›§«üXºÛ@Öwgwõôtô¯U´Ýì¹Ùs½EÍšû}ó7៻*Æ_ìv~ú·WµzýÜ“çº<¡ ¹zS©OˆÐ¯WõݽµÌTÆ?²“è ¬ï·Üÿ©=—Ô)Š‹EÐiwõVj(\<6R"Åó4 Üy°‰cÈPëý‡7¬õÀœ#¡x Žd%c”Óµ!²ÅÛ<÷tÕåxž¤# Ú–“L&Áâ (Œ^ò¼¹ÇÃä+Tr+Úl(`¿Ã_¨»;9Ð"ÅB%=>É¡·½µŸÝlˆèOö”¼AkŽ8㺠蘞ȿGò\M¯;]ÙEÀ6ÓZvÉ ØÕEEš½S;è¦I¿ŽüthÚ40k óviÐuÃÀâq샊AT%ÛìmlÁ’ÜW³©™Í*Ãt{Àê:‹%±>RÎ([uñß#›c{ ®UU¯TjŸ^¿•ç9’"Õj£ÕTÁL ãÚÔÈïWWÃ$¹j4Žg8öD+p£˜ý¢°{éÒ¥Þ Ÿ››Ë.Øõj®]{çÉ'g%)ÝSDÐté‹/n3 𑦉ùk<:…U«ù|anî©®RPBår>ÐwÀ Ä=seæIÀQ°÷×<÷ÃAtßEC£“­tºj÷.ÒPú¥¹9¬G,¹1wá™@Y–ÄÕ—ÿ ’d G1-õô©ðÒ26<25–>P'†G2}$qáâ³쫯Ԇ3ÊfMøeä÷â‡` .‚òó `ÿ€ôƒÝƒ•›þaö¼'E)Ï›f‚¢¶ ã\ˆ_R4æêUŒ{²8S*ï÷œ£‹ÎØ·óêµ…b9×5,Âcª‰>IÓ.T¥¸$õ/U8¨®þr­Y„Ñx…F|pp&4Æ^s_w^*—k•r­T¬žžž,•ªÇó@†¼ú×/€EuíýϽÆMàèåu7&Îá¸ê¸4‰G(ªjÛ ]«– ©’iÁ®`šœÄAÞèÜ" Iä Ó´Ñ@Ó…ùö=’ŸA]yáÁÏ€ÿ‘ûý¢¶.T·›ì/C¿âß‚)HÓ(KÐæÆ.*š¡t/|™aèááÄ1ìQÔ_ý[ö‡?¤<)ÔðÆÁïÒ@þ2¼& ²œë^”·-"* ÷^÷‹d>XdQ>Án½æo„N7ßã“—-/+Ý] $”Ø n3Ni*=¨È&výäf*#HX±ÑP@ÿÞúݵ Ký'r¶¾½³:::Z.—ýƒ»X–Ëd&;sÊíær¹­‰‰ °:ë:ùÉÇ×üTå]¤›Î¿þË/æç/]¼Ø v`ÚkÕìõßX$4Ýmû™á»—×8‰é ;­Ö•J%w2(æÔ´ñÛ·¾ˆÅâã=}õ9̶­ õ=û/÷øæ¼´2 3E1ôîÛ;®ƒäŽú1-ÓÈr|vö» €!îŸÆj‘$C–EtÜ“¼.Ë’e݇ÍOO?ÙuñÞØáôë¯¿á Ø] µ„Hœ›š™÷„¸¹ÐSÌu÷q\ ÉHlHyËêŒ!, M-ßYPsúLæîÒÆg×o ¢ã@²,x÷Ãë)êÞÚIbJ3ÃD‚üƒQà|³Ü2ÏOÁ+Xª=3¯=wÞTUQ‘¡‚c,ÃZ¡“„˜oÖ›…ÌT¦K½>j*"{ ÍB®^©äÎÄâÝËi•~ÕËÜ[Uìß°ßbïvÝqûÖ C?²t*ÇFª¢”k{‚((-¥T,©ªj[öÔɩѱQ]׳ûÙÉÌd× šª ‚ÐÕšeÛ‹·g©Ùx¢÷ð·!RWGi!ËëÍÀÿl6;¸Cw“p74’š…/Òý3ª°ï’x|úä³eÝu¿+° â!æßÓÕáFŸ¿ò£À"ðr_áL[ŽŒŒÌÌfV8,œ:=ùù§·Ã’Ш·¦ÏdÖV·› å‹Ï»*”˜œœ\YYéãMM%‡‡¿å®À²,<|#]to™Ñ2퉉Qÿ BЈ«w7%9Ül*S'Ç·6÷Žç猤¾‘¿(jëÂr¹²½)Þ]Úé,ëܼîݻٻ¿ÿxeÕû‹%ï´˜a.w5ÿ£Æ_Á´«Õ:c9„E£RæDzscï7¿þý1<ÊÂÂr±ø-wÎdâ§NM<|;>µu¡rگŷ(´*JhJ¥ êðî’ùéõ›ãÇê (V«Õ‡¥©õõ¥f³!¢aèÇÓ4ãe /e³YEyoo3Où%zξ\\[»6h:iµ Oâñ!P+þ¿ÐN*5"Ë}8­Ý4Ö×¹—Ú'§U«÷ÁK° ý/ÿ§ãD ‡åV«Y,æH’*—óÑh¶z½<3s!ŸÏjš ÅâEÑ¢öRÿbÑ(Z.€O©”€¥Ïñ…B.Kær»p3ï¾ðo@ô ;“¡“êu´€*I˜%ÕjÆÝÿžLŽø™€{鈄ÌÀ°ÎÇÆ2'ýaFæóû©H‡®ÀðBvÚ»Á{ Ô†3ßPÚßß^_¿£iÊð𸪶àãÿ®³g/ôÝØu;wn|øáÛ0³QÒQ¹ß¹³“X’¢ÛÛko¼ñÇï ìÓãÅBDZܯZÂÀÁ÷î9=ýøô^ÇPˆX%¨5”ÈÛqí£û"Hü¹çÐu}2s²óf¿Ó£ú¶Ìýø¢oèVIÓ-š"ýĺ½÷H"r&Q®?°m–P…rlŽçÍzS#Ð9õà ç|(õ‹hF×u€'ÈéŠ Ó²-ŠH<ÊÐaÓÞ1-”ÚËÔvˆÊ E­²,eË¢qá ÍPŽÅ±œÑjÀ‚ X†ºWD“Ž¢iÍ~Z6<Ûñ,5Ö Þz¼Xh;nDÙ¶ B¾ZSZJÀ V,*ÀèÀ BˆñÌРk* G“Õ ,†R©9Àæfƒ´]-™C³Šb@]ä1Œ|œlc ÝåxF¢Ix©UÕ,UÚ[}ÀÔ¤çš ÐÎË@Œ›¦ÅóL©ä†xF8xxÕ€OÀæVK—%~?k²%34Ôª7Ô°ˆt¤÷¤môy´G]¸9¹” -}Ïså‡\äø4t"žOáä=ñþMŽmq|Çus,æ ²¼ 6|¯þžôÒT_:ûµ‡R}ù€fl´]º5ͦxlô¿í][oU>çxw}Y¯/qâ[×m“¢Tô¦ hÞŠ*ÑÇ‚D_¯<ðoøð„Ä(H¤¶H<%´%¥H ilg×—Øë½ž½1ë”’zIk¡ÎC<Ù=«™=;3g¾™™-Þã¿ûqô57x}ãn/Å­XFÐí5kKµè%†î+Êvãd#ÊÒ†AÓ}ø þÂ×Qj} |åËK‹¥hFISYÞ>½r:zCˆ*77†Çˆ>á‘CgÑJR®X,q¥§Ð˜$àTZ̺Τ8<åsóÑß|6¢ÈdÁUÀ*dK¸ˆb&šÈ«C"ðIÆZ.ÊåÙk!«ÕB(w”ë qÆTøÑ'Õì£U+ðÓ„ØAND¼¸_?ðšb3“ÉÂs¹L×å†C¥P`ø ÀÒG:Õh:=™( T¸&¡“ĶQÐ 5º(u]T.£[ªÙÓmðD"7ŒQj`ÊP¡axA`óAÌÑ&³.Ô:âl³h 5u )MÐß–ãÄ1© |.æ‘×n?!dq¢»¸5ðûÂ#» ,Ynær¹L&e ‚¾±AzˆFc7!¡"OBN[’Òφ]`j:ÍP þŽ3’$†Ùƒ«ŽCh³¥Â…¿ ÀÏW¢ ¹ ™¹pša„@ðç/¾É¾/!g_gWo#óÕâZ‘¾‹jKËʳ."Å2û´zn>ÅqS²fGÝØym¡!?Ñ~ÛÐ!Æ üâó‘ ¸MÇP`›žS›¦W¯¡j’9ä`¨*Lxî!,pgœ{Êèû»²ŠRB^H£‘… •3H_ëI‰Ñ›»5p\³ÂjÀÝnö!&d®åxv(áãá±0ðÙĸ*šç•^÷½ªÀ« Ú)ˆžiƒg%ø¿›K…˜`Ørq%3!š[–ˆ™y¦ýà—ŸÖÖ&%$Öí6Oœ8½-°nßþ¶P(\×Ó$ »×Wï?üæqî/|ðÀõ®d¥ÆÛ[¿ç‹™hý†ízвÓh°Ö \ËŠ"C°[YÌìÐÜ\ä»Ð²Ì¥%²xÆq JÿÞ[“ÕÕ7hä°Ê÷‰$•)eM2ðÉåËWQèmNr!ÞH+â¥õsã’?îÜ vlw\—So¬>ˆTˆqB±XcN2ˆÅø\>é±BÀcr0;ä8Ïv›o˜7Î 0F’ $$iLEn„^>«Û=¢k¶/•1Á–iÁvOÄÃÆÀ‰„»ÓC؆¯ÂXSÝÐ eÆ$ƒ½ž¹+oAòNgöi¶TøRÈ„Ïè‹¢¨kºmÙ†i¸Ž[oÔ‰°Ï—:•üÒdW`Œ“)ö§Ci»Õ.WÊÿjíÿF³èμ ¼Ô\&Ì;ÆÇm-2ãßF»OÀ/ÉgÅ|'„ê=·|/Fb’1dæy™³¯½ ÞÌ®6ÉuéQB=ÏSUµÕjÍ Ïœ©Ôëÿxø!”NY²Â4Í;wîPpnÞ¼©È{¼@0(õÀGÃóZ°m{¿Ì Z­FkÞ_Ñá”L†­ëÁS{¾T#˜VúútŽÔÍ)Š2 †Ã!gYqåAkeý¼jø›íb£Ø:»òM¦@… Ð<läq"Ô©Õj°¯Aµà¬®®¢W4@b²,[–Å oYõ¥už³ÔÖWBÚËÏgå!ÑMbÓz-ŒAóQvñT.'q1ûö·Þ:w¦Z’¤n·‹?ûôó¾²½Ø8 o„®SQŒ¾Œ'€å÷1–ðŸÑ©îíD^ÑÐööö¼°år_–éÂÂb\@†‰”Ž“Ïš’”mÊn!ç§’aÐbf§3,W q7µÝrææ oP¡ëºð*ü 4·QÒõ×/IEND®B`‚nagios-2.6/html/docs/images/cgi-tac.png0000664000076500007650000001137507436604436017400 0ustar nagiosnagios‰PNG  IHDR–sMV átIMEÑ 36– pHYs ð ðB¬4˜PLTE!!)1!!))!)1=!!)1!!!!!!!!)!!1!)9)!!))!1!!))))1)1!)9))9)19)9RZZZ!!Z!!c))c9F9 >!B))=))B1!J))J)11)1111911B19199919B19999B9B99BB9B9BBBB1BJ9BJBBJ99Z55k=B^BBk99sBBs11{b Z w &u#1J56O65^9-s- ˆ –„š!”!+Ž$5{56Œ3§!œ!!¥!!­µµ!½½)œ))¥))¥16Ÿ3!­!/µ/9½99Æ9K1/PRJBZBG`H| j-3 &¡"/WWRRcRTO]MMvZcR[]_c``t^`Yj\ph`gscL•Igc{mkmloqp„t{z„„Œck¢uw{’{Œ™u”œk”˜wUU’lk¸y}˜xxÀŽu„Œ„ŒŒŒ„ŒŒŒ”ŒŒŒ”„„ „ŽœŠŒŒ””Œ”ŒŒœŠ—™œ{„””””œŒ” ”œ{”œƒœœ”””™¥œ˜˜œœœœ”¥œœ±¥‡–¢ ¤®—ŸÌ†ŸG½G`º^°ŒÄŒš³£œÃ™”ΔšÞ˜¥¥¥¥¥­­¥¥¹¥§¥¥µµ©©¹­­¬É«««½¹µ¹½½¹Æµµ±¯Ãƽ½±¯Ë¶²Ø½½ÆÆ½Æ½½Î¿½ÚµÆ½Ãƺ¹Ï½ºèºÆÆÆÆÆÎÆÎÎεµÎ½½Î½ÆÎÆÆÎÆÎÎÎÆÙÂÂÎÎÖÎÎÞ÷ÆÆ÷ÎÎ÷ÎÖÿÎÎÇæÅÊïÎÆ÷ÆÌúÊÖÖÒÎÿÎÚûÎðåËâÞâÚ÷ÖÞ÷ÞÖÿÖççç÷ÖÖÿÖÖÿÿÿÊK[IDATxÚí›p×}Ç7 ®fÕ…bêåŠé­Òä*’6IÛüií†SF#YÚ‰ÒÄ$1!ØÆõÄ“ì¶^ °²½k#Øe7Nj—ä´„Hr^hª]‹¥BEfït»Ò.:¸³Awxè˜0¦ÅâOͨ3éï½½¿q'Óá+í¾·oßî~ö÷~ûÞïíJÔx_ßî¹eôÓ±øÀ@|7µ»ïk?}ôß„dÕs¯¼ò™ÏMÓg?÷~úìïÜ{Â'ú̪cñžý}ÏR=Ï~ýkßxeÕªÏþïXõÀªçø«›¨¿üÆs;ùgwîä©3ñø±7ÇâG=zìÍ£GßÄé±c° ¥°ÌµÞ 2¨·Q$žTzÆœHOõŒÇû@=ý}}cI%ÒU’oÌ¡’žt*ãºnÒ=~ÜunVdO>q“Å…$ƒ“D2¯ì.,œä:”L$¼s毣S)'T‡‡]ÇG\)ytw2‰¯4p4 —I¾ušÔD2ƒ ‰”eÁÙÞ至&= ‡Àî2”LzK_+yRí¢ÞvÀ£{_%X‡¹èè×ãIÈÄú éô\pO$“ãc»½>Ç¿‰Æ?ÚG°"¹“²°¼ßÆúê«üW%꤃ /íÃö;þªåâ}ñÝq|±þL×ÓgcšxÿN‚å>ÅÑÆ÷÷“ƒX¿,B„=€0ž””~ÉÃr4SÏûVÂAýñ¨•HšF4 t°Ž®¥÷ÇãQ< Ærô4;™t©“Ì:E¹P ÏRÄG>öGø ÆÂžLhÊ ^2IÇÒt —šº—Š(jº°a=ÜÔ€sº®85¾OøÍän¸Œ&ôž’wÚA2•´ Äqb-ìáŽ÷@¸¦5WŠšÎØ€cy1i3è œ$:è«­!;üíWô_‡|a-^àYžiiå» ˆðå€$H¢‚ö¢±¡Ò±>_žO õqRv‡ƒ±î]¾ GêÆ¢Ø4 à` „²i.‹<Ä삲 ÉçDÊ*ÂZóI”%q{„d’$y£Ÿ/ CÂ^0‘XÚŽÏ•àm.ì¥Þxñ—Uêò¾\×E“aÁU"rDQ¼1‚Ïh QuQ•$3ƒÈ’Q`ËÌVÈd, )‚wL%Ö¢üUWqÍ€ù%èGX/àÜK¿lƒvÅa¡÷¢XVˆ²œLrLD‰à—ix?‹ *°îNYˆgÄi/!¨E[¦iI¹)ÏZ ç}4P Mßµè‡ÛJ5·X5kºÅŒ’Yë‚O”èî»ͱµ. ­®¨†J'Ó‹-Y²('È.˜ck}§‹ 7HÛÂ–Žˆ J5wTÞãî êB+˜[c ÎZk~I¹‚aš˜‚ß ÿ¹´’䊶ÊÕLg›Ä·>²¢1ÜÐØ¼".¼lþc‰|&âä« åk¦_ ‰µþfqCe«Šwøso`8’ðÚ˒ͬÄâéÛÓöe%Ì‹Z¸¼ža­%}}¡ÞÞ^I…¦DHÞ£¢={ÚU~eYP‘!ñ$ ^\AÎÏ ®dI‚6G8ÏàZ2® “]3·–LUU]e‡7&¢(ED8Ÿà3‰LBQxF±7•Ii0ð™°$SïO¦XYÔÑ%¡ß—(Ápg‰ÎÜZU‹ä³kuñæk¹ÿ™–êOŠJžÁÙg>Õ´áw3^µÝÏÐ÷·µ5g'ã8m£ÛÚò³óp gn­ª–{›·K‚ t©‹‹w-)|¶n¹ké¶i%7l8zßF$X[ñÏÖmd½ukk«·ÞºíFb)ÔïÍËq• ^ú÷½´hÁ]Kï"ZºrK—.¹a¿×²ø×̉Žü‚Ÿ9ðëý¿Ùÿ¯?û¯³gGJ!nèXä½±©©« ÒÁÚ@ ¤øÔŸôgŸþôŸÞHŽ+±|`-˜÷àw[lˇ¯¬õ9$Ê[«f±/ ÉGá?¸Þ,† …˜¦PC’•¡÷Íçæc‰ Ò¶óæÏ¥í]²ÜÿhÃ× „‚PDS5MU½‰áìIœ™µZ ûm’ئ•­Lkk3¶V˜¢x6±¿±²Ì³ø}õcU-_„Ž«®†ª+úàãÏ}°ºö'­ëÖµ‡ Œµ fÕ"ÛÊ ’X8€¶m©¦‰®›ªnZŽmq¶½§WSTSC13æ82‚::®ƒLS…ʶmsøo^½;fêP Žc;œ­"Ã@¦…º¡È´¯ý’H)ùû-a°®Ÿ˜8Ž~±«kŸ*KвK1Nœp…S§4bÔ¬¤=‰„¼ïøÄ>u×.i_·$ï‚æÄ‰pœ ÈŠ®B‰ä²½ûDa×.)LoOt_'V‘îX»öË]]]/v´ý!hx¡H­ß^û·]¥úkï¸b½ø¥µk×l*«jþà`ÇèÄʼn‰ôÄ(üNL]þŸ»·l}ál‘~²cpýë°3ž87zj¿;5Õ18¸v”&ÇMLL]<¿ʆ&††‡‡F‡†÷ý¢|¬/¬{ø±4Ñ(þM_¼„±~ôßýçGzäõô9¯®4yñâú¿xuéqç'|øé—/æ55TÖãë:Ò“éÉs““éô¹sç& Ö–¬—Ÿzè‘ÃiÂ5™†Šøšë7¬[ímÃ’Nã"ÀÚ°c*Ët– °æ?ùxÇáô(hx4=4<:TŒuö¬‡µþ¡Çþ* “ZÃiëÑÕ‡ñvJ†G1ÈäƒëžÚq±H•`=úhÇ$àüùs°À=ž/`½ó›ß¼ãa=øÈáóK´þÉu«'KJë¡¥XUåcm\×ñ:ÜîÞaÐÐ0œÌó-l§³ïœ}'߈ӱ6^‰µz݆Y³Ö†Ç;À.]Ê{D«Ä·&§am¸ŠµÖ|«2,jþÆ C£ØZðPOæ±²Âöòú'§[kªcã†ÕçKËÎëñ˜¥'‘š·þ`ÇũˠKï¾{ùÝËS¸ßÚ¶­¤ßzù[;ãJ—.áe Wÿîc×BÑÑe’^†>pÇål.VÕ_œ¿iÓæÍ›ð '›7±KîÞRÚËÏûðü5›¼½›IºyóGîüÂ|ïÍ^hÞ‡¿ø¥Í¹³ÀÏWÊÇ‚iÚÏË‚EKJ_xU]¥ÒÕ‹®ùìÍë¦ê6Öm¬ÛX·‚ncÝÆºu+èÖýóŒ›pu¬ÛÖú€ `},pTWWG–’"’(ÔÛI'ùÆøÉì“uÆòþ£Ø.ëŸÊgªÌ…Ó  §3g°Nž9“qß:eðÿPެGûw9…Šv3(¢*rDÕÕˆzãÈ2§×Ö\7fIg O:†éººá: W£LÕ0£fÔ0ç\:úU·ŒP¯Aª‚¬T´GV‘fhÊÿþ^úSN~IEND®B`‚nagios-2.6/html/docs/images/cgi-trends.png0000664000076500007650000001402107436604446020120 0ustar nagiosnagios‰PNG  IHDR–tPS;YtIMEÑ ¤äOœ pHYs ð ðB¬4˜PLTE  RZZc  !!Z!Zc!c))!!">.//''42)E07A4@EFFTHXlSSX{qsu}€~{“½]Àc½“$”’Œ‹—Žœ™œ˜˜¨ž”hh²kkÆoo½’”¶¢  ¥¥¥œ¥±¥œ­­œœ­œ¥¥¥­¥¥¹­¥œ­¥¥­¥­¹¡¢Á9ÄVÂO“Ðw¯ÌF¨Í¨²­¯®Ö­¬±¼¸µ»½ºº½µÆµ½Æ²Î·µÖµµæµÊÁÆÅÉ× ÏÖ%ÊÂ@Ì×?Çß}ÊÀ¯Â¿ÀÆÆÆÎµµÒ»»½Î½½Ö½½Þ½½ï½§¦Ó³µÓ®¯â¸¶ê½½Î½ÆÎ¿½Ú½½óÈÈÈÎÆÎÎÎÆÎÎÎÆÆÖÆÆÞÆÆçÆÆïÆÖÆÖÖÆÎÖÎÖÎνÎÖÎÎÖÖÖÎÐÐÜÆâÆÎàÎÊ÷ÈÎÿÎÖÖÖÖÞÖÖÖÞÖÙðÞJämÞƒë{#ì™à¿ãÖéÎ+ë9æŸ?ëÊ5íÉPïÎŒÿƜ޽½ÞÆÆÞÞàÞ+ÞÞ9ðÞ4âÚFÞâNôÖGèãNõâRóóZéáeîú‡Þù¢ôÿ”Þð½ùð­ÞÆÎâÊÊçÆÎçÎÆÞÎÖÞÖÎÞÖÖÚâÒçÎÎçÖÖïÖÖïÞÖ÷ÖÖÿÞÖÿçÆÿçÎÖçÖÖóÖÖÿÎÖÿÖâïÒÞÿÒëóÎïïÖ÷çÖÿçÖÿïÆÿïÎï÷Æó÷ÖÿïÖÿùËÞÖÞÞÞÞçÞÞÞÞçÞÖïÞççâÞëÞÞ÷ççÞçççïÖÞïÞÞïçÞïçç÷ÖÞ÷ÞÞÞïÞçëæÖÿÞäôéïïÞíííç÷ïçÿëï÷ÞïÿÞï÷çïÿçïïïïï÷ï÷ïïüô÷Þç÷çÞ÷ççÿÞâÿçÞÿçç÷çï÷ïÞÿïÞ÷ïçÿïç÷ïïÿïï÷ï÷ÿï÷÷÷Þ÷÷çÿ÷ç÷÷ïÿ÷ï÷÷÷ÿ÷÷÷÷ÿÿ÷ÿ÷ÿÞÿÿç÷ÿïÿÿï÷ÿ÷ÿÿ÷÷ÿÿÿÿÿΫX“¤IDATxÚì[pÕ}—°fZI¥cÁPðU‡ï‡î$ûΊo #•,i­]–°ììÊ!èdavXÓ¦ñ4àòB‚ ˜Å'…aôGöóÃLmÒPXó‹Ñૼ8ueìâ†Øn‡Ú+\d·ŸïÛÓét:ÉvÌ?ùÞî¾÷¾ûv÷³ß÷}ßO«²¶xü†n, ¿ú 鯻—4-^ÒT_VÞXwà uqíâºê@ž§+'*WN´ ª“ú\É÷‚S³§+ÿ¬.ݯ[¯+‹‡‚ABsíµ×ÖqºæÚbº¦Tkj·é¹L×ë"u¡H¤®l}SSzötw:½®;½{º§‡šk»ÓÝk//­[×Ëé¦2}Q}co}}Ûòúx¼7QßÖ_ç´¤7ö^nR8%Ë4™J¹à8;êý%ç§d™"¢¸c‰@¨îlk“P.OÇ©èímkãÕø:75ñKÖ?´œ—R#õYoâ}RIéÒ º/Š–it»¶E‹ˆug£À®KRÑÔTO\žT9·)ÞÆË›âTÜ¥¢·mï£$½“—V0^Œx°ä‡%/jäÃØTŸäòX§G&â¬pq5Æ=X^´5Õsá%⥒Vý’ˆKNp1ÉD(ãKÚDÙ£}}}ýý]kvöuõõõŽÃ2u=˜ª¢Ôb€5¬Dâñh".Bõâ‰h,äM†å:Nþ€âÜ9ÇÉf©æ::åä{ïßùO;wÉÁ:¹óý;wž)àqX,âbX‰E¥pRÇ4ÈÎV`# Á2ì† §`ô’ ?L‚UH°ü AKÞ"Çâ·j©ò†Áí²ˆÌ“flTo¤ÁÍæXV´6Z û£‰X¨*ªŠ„I·„cØà‡„D^ž(M ËP5‰Yº¢A²r¶T… nŠ“ÌÛ>’ˆ²Ve(ªï8®òä”<׎AåÁãr/€œÖùi¤²ÙbÎH–o*Õ„¢ˆž“±D,!&ãqˆ‹võ¢`íØ¹ÿýGvìè?6пp8Gö÷ïßßÀ‡Gwì;“ƒ #ù CÁ YIZðbŠ ÕB:¬üÔ/E'Ž‚N=:ˆýĉàœ&Æ üŒÿ—V  “jÁJÂ'ÀK%шÞôêyñD_ÿô¸ä6¨²B–êŒ7†îþÒG³ ñ‰@°jçMEš‰4v±¤\‰”pª¶ó â©ìôçdÙ²’R!Gåw;QȬòðü€?௜låOä‚UQ”eIäUIÌ[®‹Ð­Á‘‘}ʆIÂåô?ŰæÎóÁªbXâ­7ßzó×èp+o–•’°$Ñåd4"¥D1šŠ¤dX#)'#IYLéQ&LH'{ldijœy‰Rû$~E°B×û}ôóùkƒ>–|kèÖ.*Ä.N¢(–„•74c&3¶}p‚ÌçÑw‰m˜l‡fºúŸxf``CÖÑþ¾×ôõL‚Uvum€æa( aJæ}¢Œàv!É[ Ý‚– ÞTœfaK%Å`ªÈ$‰ ŠY*”ܾ!O:'ÓâI“„«¼¿ÖçÃÆ÷q•ÿX-tÍÅ4­ny¾ïœ{s*[à Tž„§S‚ý=ÇP”à:51S ËŸˆ„"¡pÇpÕ¸øïG§óè"ƒiÙ`º¦›LE!é¶Stæ8ɘ5EZáP(ì†üþp4ëãÞt[:ݽ®)þ›túÁ¦t﻾óÎ;ï>úèß_¬ "Ïn]=Õù|¼>^»¶§§{mŽ=k»×}ï¡ïqzèRc°eIBBX8 €U®%×ãûCÜ…xHøñºîÅ=ÝÝ‹ù(N/N7-njkºä°D Tä"Xes®ðùýµ~e-ÈçTz°zÖÞ)­¥èÁõ9ºïRò¼iO†uEx~8 @V@8oNIZ\X=ž¼cøÞ]>Ýš;ÇOÞðÀJ÷ÜßMJµvíß®í¹¿§;½îAž`\Ž´Öó‰!ò‚Øõ9Xëi1µ;íi¯¦×—ÖܹCŒ"6ªä¢SË´8}lM™1A— V¨#è« Õ@ï¡ü¬S—áá3Ú77D1ÀCÔP$窿rX!RMµ¿Æ7¡ñeöÅßû"aÕÎ ‡Cá` *†5SLþ‡5^mµ¯²2௪˜€EÎÿDÿޝ¤E!D40IZÖà‰çâñ¥aÍ­TB\å•~E,SC4ZÔÁ±ÌíiŠÆ4ÍU]UCT5ÑeÉÐq….èŠjË*“ÝVdMR™õe`j‘j¤d„\ÑÐÌ*ïØŽã|>Œ"ã8#.Z6zRábÿܵ-{„ú õ9/lüƾŒ´ÊÊË'Æ®¢â‚f"âsC3mÝEX»ïèßÑf3Ã"{‹*¸ºáè:›|™CbÛçÐÊÎùa͹ÂÃU ðçƒeêÈËa<ø¥ÂEš¡ÙàšÌÑ)Ç`ànŸ¢¢®ÈRê‘’ŒaQð4¢J¸¢¬sccLJ?"æÛGÃÓ‘M›íUí| –C! ‚nھ;óíïžsÏyy5ÏëÖÜ9Wùjª}PzŸ¯Úwµ?o hllè·‡vï>Äw:üÛÐØ¶‡¡8p`thÈÛÆ [ç2C£¨ÇððÐo‡¼®c6îRpCFÇòT ¶”¬i¸&àaj‰AÌxõµÖæ¥K›ùÎË^»ó®»Z[[W´~óáÖË–µ.[±Œ×Z[¾gãÐ7îYÖz×7ï¹m07~«õáÖ¡Œ;´1/“á8ð­¡¡}÷ðW‡^Ý8”«¬²Ú‡ØÔ﫦5ä÷•‚5|h÷ÒÛo»í6Ú‰n¿½ùš—askóŠKWPmÅRpAÙz`ì.p–kón”Í÷ÞÛ|oó¡Ü±á¼HN>Öñ½¿;ýÁélᚇ5ßKôq, ë“O>Ù»çõi¤õIkË!­mÏ‘´žÝºõ¥·IÒÚ²jUç‹Ïm#iuri>v÷âÑÒÉÓÇ;~ú:~räø±‘⥑òÚ9S¥¾ºª¬‘‘Ó /¦À’¶?¹ùùÍOü¬ãÉ'Ÿhß²­õçŸØüüÓ?ùÕŸÞÜñäæÍOw¾øô¶mÛ«ó¥ßÑšòéÓªÒÂÚ§‰—_džPù@$ DÂQȬ¬vô÷ýÝ”Al_ØÞÞ°i¶M 6-l_ذ ü.5ü Õ ©ÇBÎúñ^wÿÀÎý}<ˆÜ?Ð×ßõá‡kºNvõìZsì™5G'ÚwÝܲX«ª²ÊÊR‚¿ÉèTX›~@˜{ì1*ŸØÔðøcÆ÷‰ë±†ï?ŽÓ(qfÁO>åán^*t×3SVä'`!­ˆ@³¢´Ã2LË0mË2ïn¾Ðpºíö¥K;.ü„ð8m P£á©Ç<ÕðT ~ÔЀsO5pÑ=µ°Ž»Î>ÓzÏ¢Û!Þ1GØ>×°àÙMã„ùÞ$ûMæôº9ˆ jªËKqª®hºª~x÷#»yûnl¯ÿóÛ»vý m¯€¨ö«]»Þ|e×+»Àxùåÿ|ùMª¼òæ+œv¡òò§ƒ®£‹š‚ QS5†b8ªÁq%Žb•ýaøÂHU XäÈ® 1SF e‹ôUäŸh‚¦Q[6Äñ/4Á4UÊÕ]Ä®Ôd³XžæÎ§¼²Ê7NKtEݰ –#* A³$3Edº¨3jK–„£â±\qâ4.ÓE„ÐÆ,aM½é`Ùš£F†>KGÄdèº:©¹˵±)Žš?­¸š×Çd³‚U¾¾Ö üPå °\Óe¦åX¦å:Bã ÍÓäëhÌ6ˆÍÔ'-Ò£:u°g‘hð ynn)X=£n9"c&òב4š++ªŽ]РDº*22"0]“l0U]c²ݬ™*êì`•—_È ºº‹aº‰ Â1i›!jGº¡˜W¶W÷Öš(ñ@q™Á#|Û˜¬òùWû*ˆj*|3ÁñÚÌ@šèZ ¥‡š,éÐjMÐ)#TD“_‘tIQf†‚‰i¥\‘÷IÊì`æhU>â„'‚®)“#¹c¶Ì —禌adÈPHLU˜®H°ºÂ0¼"K92¦ ÕÉ@€ŸÒ5ÕœÅz·4rUYMMeEÍô3Q2 䂦kÂüi†¡ªŒ)º.šÊt“é|S™ìh,0ÃÄL$–ÆÔYÎÄò|u˜¾Èà OKua H¡\‡`0æaÍÕVs°4@¡¿üèàê9XƬa•]5õÏœ•Sѵ]ö“b˜$}&Ì@Ƶ 2ðràf8×5-‹¬‚kf ²+ôåˆ=‹ÕM‚E+ß¡Y.Ö‹d,!-Á…„,˜l×’a½4YTeHË2uøY•t\òH².9˜Ž°²œÒSp÷fRU¤Ù¬¬p( ‡¾#ôùÉ4°HJÞG 㟉вÿ"dœÜñ:¿˜W êÎ,¥&þæ,D XŠ›bº›¢—N)L‚£Sèφ¤[²n*ŒBFņh@TÌB™‰"LB°äYÁ*]ðÕTù}5Õ V¡c…#©† eVatUÐuAÑ%ÉLÁâc“TI°Ue]5U€ú똊5ËA¬­ …Ü•g€e¸NîGNÑð6¨3¹<îóxÈhÐ6ÃÍ1™™aÞÇ?ÎyŠaMPyÅ V^va§\Â¥q3 Fc†hÀ¶šŠnidHŒ:sDœ†-A´‡ËLSAiÏRZçKösÒêŽjj°[ðÀ9hØ(9a¨IZ·4áD™ÉäÜ„A3’‰P:7¥[If©öìtëBa´H–Ê¥†¯¬4ˆ*Œl³ø¨‘Ór5wMØ•ŒÎ/ýCÀº¬ôGX„õÀ¢Œ€ò ×s‡^^ãuÏ>N2’hX¦gØùK\ºYÎ':Sãß`N0]yzX 6QO1úPœ>Ô5E…&UIUC’$E’ESP$É@°¬É”p9BjYDF¢ˆ’(9¢¬˜bFL’S¦ïðaÝpù‰l¤$#¥I¨éÄW“ªlÎ,-îÿi·,^sL †eÛ´‚@уI×âŸÛÔÇâ1…íí6¿”JÄh¶od¨Ÿ·ÛÅoNî!6ï`ñÍ™ƒ$dKBb…hAVCd¶¡h&œ4 ¹®($2]F ¦„ßÐé à€ÈôéÉóØ"ý?‚*+šfŠŠ©(en<b6xy#’QTt@¬+é3ÂâÒpX"e%Y:qÞ o–MÛÂËC^6ÚÄŸÄæ_1Û\Hº}ù]Ì zeH¼¸o;Cþ‚ZÈqqS3øÈk83ëÞJSD.d’u › hpu ^¹d†š W©Y² %£ä¹*|]Òȉ†F™5–ktEäÊ è“ÆtC“ ‰É”¡@…áìÏ3/qÇ«ã3Ƀ"Äê8ãÐŽwÖÈ݈u“w²%$©XtÂÒ¬ŒÛçÂÚmŠˆ¨?ŠŒ™¡§ðågvËV¨È¯Lœ}j§êºII"ShCV†4rÁÆHWæ U“aP¸#›è¯1HȤHê¹1è%æ'Ó§.N\(,Ã[ô`øx®¯ I ÞÐàR0½üŸ¯–“–úÌqé°ÿHâ H°r„Aë /‚Tí¬ATÊ:kÔY£ÎuÖ¨³F5ê¬Áà,A(D)Á;îOÄ ¾}Ã*ò.îÉì#y{¢l!ˆ„nIv£Ö^i¬ ØjÌ·A 3Ø×ÒY )Õ SO5+u7ä÷ -mjj:&@’vÎÊvýG/7“s+7`Ô.ÂKØï’ V:ææÖÖVôÛ€ Vz Ï u=u]==m5mÖÖ3ÑSýù¨üZIEND®B`‚nagios-2.6/html/docs/images/checktiming.png0000664000076500007650000001122507436604450020344 0ustar nagiosnagios‰PNG  IHDRI£©zËtIMEÑ³ç˜ pHYs  ÒÝ~ü¥PLTEÿÿÿïïï÷÷÷ÞÞÞµµµsssccc999BBB„„„½½½çççRRR111{{{­­­ÎÎÎ¥¥¥kkkÖÖÖÆÆÆ!!!ŒŒŒJJJ”””)))ZZZœœœÿççÿœœÿµµÿ÷÷ÿRRÿ„„ÿ!!ÿJJÿÿ11ÿ))ÿ{{ÿkkÿBBÿssÿÖÖÿ½½ÿïïÿZZÿ””ÿ¥¥ÿ99„{{„Ëy/ƒIDATxÚí £ª¸€ãTPDT ÷n·m»{»m·ÿÿ§5!‚‰€œ3ßÞÕCÈ"C2dÈ„AAA¡L½ ’UT‘àù¾«›@r‰jréû@ñ@¤ê È{såW5Û<ÏRqyç\:Ù£&}ybXø$òàd"¼8NÈòAsMz´|Xkä@F?§HÃ<-Ì‚VôÏ„üºOSÈÜHËĸÀ‚}m¼e®ó,›=‹bG!ŽŠBÕ-+×§9½H¦ì]Úßúü@žƒj7N+¡û¼ÏYòèD2¦\ìƒ]J¾ï¤ebÀQ¢Ça{.Z%Dæ] Ê«¾xG°O¦dlk•7yÔ¤qà§ÌJÚ±æbEÛŸ)¿ð3âÐgK¶L3Ø¥<ÁŽîË´LŒ²ýsòÉ-‹¢ dS=¯ú˜S-Ë?2™B´f['Xù“jÒXØžhÀ®s­gv-ónŒ6 ¬sË/ož[eb”5É!2¯È¢„ØvJô¼ê ÀWòÿâ@ëxQ“ÆCè± -©ä…N2?c*£%i™1£<­è°n„2ÉMÞâÀê£*ÿ…¼? WÞˆ4qíæpa›ØçËüšðŠ[Ü{aqßG ÑîòÌžïH¹€:MÂ6iL\€>\ù;8âQ³&äS¾k)LëÂNÒ31»Qö©²(!–z€ÂPj¨IÔNšøh'‡[5ÔºæJì¢óÊí¡âÙm¡eʹãš…¨,\è¿ÿÎG<$Ǔⵞ‰s2ˆ5oIþ©²H¡<Õ•c5‰lôé 5 ±X‡x-=õ!ˆ+}*‚X±;fCŸ‚ ‚ ‚ ‚ ‚ ‚ ‚ ‚ ‚ ‚ ‚ ‚ ‚ œ ›¼ÀÆ@tŸ¥ˆš [‰4`Ç#˜MFÔTتH¤q’Å“1‰š [‰Ô‚ k¢¦ÂVE"õˆØE-JíSøušÔ"NÊW ©ÂýejPå¡{·°Õ9¿®wCMz„0D½Mû*K–jaºo'º¢ûÒi;QÍvn¥ýRÊ)bš‚šô€b u•…(!‡)¹ÌJM·d™˜–»^´8gUäuný£IõXeÙŽ~ùn|Ì“Ä6À4IÂ<}[ ÑúE°«nf,š†ÔrR£sžo „ʨح×-kåè÷Ž%Ém€Åb艧£&µ`y1•LÀôÊzS£s>¸Dr2ž4Ó’8ÿžÈè¾l`"£ýN¾šå?…ìÄh¥NhðÐÈOØØàq,# ª€˜E€ñ"âx94&jR+œ‹c.lS°©èk,na<‰j“än±‚—l“Ì ßT4Þ“©g*l¦ñ†DEæÅJ;é¼aS©}4çvß–šDÓ×_µ]2#6®Þ§àÚ´g†EZÛI¼Æó,_4Œ>£ó@lKíñÝäú•4é÷œÞemŠ5¶*±0xý,üøƒñ³Ñ/üã—?~5”µ5¶*±’ìHöf«s~*¾ýòß?~û·™ìßMe-D …­J¬$L!ïÕ¾:ÿþ!?ï]Ö¦X3a«‘z¾ÿLÛ¥½ËÚk&lUâ+Ø ‹ÿÑqý~üòí_¿Z²6Åš [•ø'\{Û oÈÁj±4®iį?ýöÛ²6Åš [•xËÇ9½¬Cgò1iøý—ÿ9Ôg´Ý­‚Ö/^´áÿüõ§dmŠ5¶*ñgÞíEéªþ‹_@þéo¿|3—ý»©¬M±fåZ•Xfé^Æù°FO¼»‘àoùë²6Åš [•XÂq×c[àœæÝYÞ?ÿyY›bÍ„­JÔø˜¯ÆªH„DÁ¹³c·°,dmŠ5¶*±àOç g_áK™¦Kûƒ0¢»†oßÌ)ldm0*÷™PË_Ðiÿêù[±8½¤‹â8>”ÿݧ4ÿg#kóϬÜ'É-©ǮDÕôð½›eîýžW¾`áç‹^Ó¤nâÞ…¼a’ŸÑ]JóOY›O“rŸ µü gkþõ|zøaËV‰Æ<ÃB+?¼¾ÚTxºñÒŠ¾èíýåu!â,y2.ãÊé䯌Ã1%´ˆzªŽÇ&t9òUr¶ËØÆ>€äJ`™Ñ¿y ÛGá\^ìXÄZÍ´Z÷5©'ØÝ¤^õfy˜xë=íB2u Ë´XÅŒžêiÍæÒðt&ÊLÔôŠ2ª$ÔˆaS„‘»¹¼8Þ‚Mµ©öÔëéÑ5©’ÍAX@UÓÃ÷ ú°åšÅNÐO µ›@LæÊ¤ÆÚ˜¬Wž5ÓÄÔn._ì°Ó¤MÜÓ°*jR%›Xh’˜ž÷6üTJ¯!Ó&f¢NÐDiÈ&ÔFp]:R“41•—Ë«¶šÔS)Ô¤Jd›$-nÞÛ”`9–)ñÖäð<ÑêiA¦‘.ÎodÑdNÕãä¯Wº˜ÜÍå‹Ph£E :5©qG«Iåp›S’y‰\ 6U¾o’ùDYÜ<]ˆñs–,¨z\3Ï×Åän._ìâYÔ»·6 ©äÖÊx I¦ôtWôf'!•ÜÞÑcÔ$l“Þ[+ã…š4P aÿ=þ|ÆoeŒ¿Ÿƒê;zãBá¼½íôàAzþ÷éqB“w‰ i²LÁñ¤.ÓœÂÊHî¼ê%çmcMz¦ 6!V+4 Ç“:³æ(è6hC—5(ó@“V,pfnÃZÜH%ã÷ZÕØIJ“üKÞï”±0~¯Õøkð9¿×jü5ø¨;š=ØÄ÷ĶX?ãfzã.¶ê ƒ¢¬ fIÀýJP§¹ s=p±U× kpd²­M"Ü-7à'“ÄçÝÅœ"11’ôîb«®A× &U¢¬ Ö»¥ÚßüLŽs2?*G—Ð$11Rœo.¶êt jR%z›´‡»‘_Ú’,ÓÂaÁ5©˜Ù³‹­º]ƒšT‰n')_j“6ù_›M*&Föìb«®A× &U¢·I7{w¬-XÌhO5MswZîh#s©^]lÕ5èÔ¤JÊvÒíRÒÖ0LÜîõ¤£MLŒdúu±U× kP“*ÿh ¶I]¦9ŸÔïÖþ(õúˆšT ¶Iò(a]`OxºÑœb†Gîà0mÁ±{­^Sƒ¨~%–›-³WäxÍÒ./8FÛë Toq€lu;M©]°Ò–nŽRŽ“q{ü¢VuR·ËÇÝ–Ár+ Å^´À‹åZ^aeœÁ#Ó»w&Û+µÑ$ón}ü–Þç@ÞÑÁC§kÓ`¥u3õ´Ï„—Ž4“åøà·È Âʵª2,ÒÊ=¬Zë`¥u3¾%+…—Ž4•ùùÐ&ÏpV®I a‘w4< Ð×,Xiìä)|,, eqp=|i+Mê§MÒg»?y™«Ž‡¶hzàl×K}^¼£S½Ci¬´ÎaV¥IêচÔTšíþäe®Û¢e葟EØoCù ö‚¼£Y-C¸]ª¢i°Ò:‡wÜ)WW›< ©ÌŸ;ð _ÝûµIúl÷'/sÕ40ÿX j°ŸŒ×û¼I펾¹·~·¦ÁJëf"»tÅqMÊšÊü¹¯ðÕ½ŸTší®¿ÌÕhâW%Â!4i°'ŸWÕµŸ”f»?y™«¶Æ}jÒ½ÛPO>/Ó¤^ì¤òlw³ë6íÝÒ«=Lߌ4¦—LʳݾÌUËc[´ =òõ.NE«l\ô»½z›to§‰¡¸çµÜå‘§ó)mš&ñ™G7–}v<“>NÅl]dP4;éÁ|·ëÝTŸõÀ¡–ïáãm|JQšÄÈ3MÒ¥ôépí5 í¤·@o“î‡Ä"×'ë]…Cíáé|J›ŒÛ¤ñ¨Rÿ§ÚÃݵ&õh' 0à7š³ÿ“Oß5€—ÑÉAÓõñ?ùŒv<©¸ächèj©¾£ó “åZÞ{ÔàÉ6Tä©ßÕØC3âVUF›úzTwGC:¹½‚õW¸¥&=+ºA ¯Áˆ[U6ü3PŠ}{W%8’FVô!%§/åž²vë¾umrÄmQ㵟€RL7U¿Âï–ÏIâ±É!Jå&ÂSv?Í­jÝ·n¢MŽÖN¿ú'i’Ê~·ûŠ’[ ³PÞAÂS&2•½rO×}ë&Úä¨Û$ëpÞ‡RL7íYB½ °;«’š&qOYËuߺ‰69f;é3±9hÜ;€Å”7Ñ»å×–{ÊZ®ûÖM´IUdPü ºwcëMXnq3‘#[®ûÖM´Éíécè¡|¬Äº$£5üv‹¡Ï Šè~Z\)IÛðga›Ã¼ ᶇK鞉·´?Hw,`Þ )gž=?Ìž/·ñ.,Ý–±»ÞŒMð¦«ÿ㌶–.œjý³x_$g2Xņ͚˜Ó<ìNvx>€Ó:ÉNôÙjL^Àd5ñ~ñƒ& h½-—Ë{šI Øf)µa àï³+U•dS‘k +åJó°¦Šç£ Sªo›58d}XWƒcu6½0Mߺ{¨á¼éO|Èr·p8Ã…¤àP}IÊ´[}8…x 3ÚìE¾+›ð{0^rõª[NÍÌÝ7aá¾éÅhÀ2Ú¤¸Ñy%똸*“âd%s±3ØîòFh*òå}ßÒ˜ÊÙ2 »ÂÅô<úd²ZuDf¼íƒ[ ûlEð]XR-™hIç@ñr­âáx°!D"߉n1'å– üûڱͭá9<Î/ÚÓ†*{ýpTIÑ dp¶“ÚÖì+ŒaÉó±-ÂW¤_É#8ÀHîõzIœ÷4\Ÿ3ÙŒôøÜ,W·®]oáØî\w>’õ!¾'Û-Ît6Í:=üs½ùbù¦ãHa+.¼jƒn??&cëŠAAAAAAd$üªœ·¡å›"7IEND®B`‚nagios-2.6/html/docs/images/distributed.png0000664000076500007650000015154007436604440020405 0ustar nagiosnagios‰PNG  IHDR¿hmÐôtIMEÑ )2Œ¾ŸN pHYsttk$³ÖPLTE!)19!)1c91kk15k91k99k9Bss11s19s1Bs91s99{{19{91{99¬ ½½½½ÆÆ½½!ÆÆÎ½ÆÆ½!½!ÎÎÆ!ÊJWFAuB6u;Dxw~„„Œ~~”ˆ”(å…<å„„”lÅšŒ„”„„œ†ŒŠ…¦—÷÷{÷„ïŒ÷Œÿ{ÿ„ÿŒóüÿŒ÷”ÿ÷ŒÿŒ1ñŒ{s­{{¥{{­„{¥Œ„œ„„¥„­Œ„­{sµ{{µ„{µ{s½{{½„{½{{Æ„{Æ{„µ„„µ{„½„„½„„Æ„œ¹„½œ{½¥Œ„¹Œ„Æ™œŸ©§§„½¥Œ½¥ÖÞÖÖÞÞÞÞçççççïïïïï÷÷÷÷÷Þçï÷ïÞçï÷çïï æŸxëç±ôç²ÖçÖÖçÞÖççÞÞÖÞÞÞÞÞçÞÞïÞçÖÞçÞÞççÞçïçÞÖçÞÞçÞççÞïççÖççÞçççïÞÞïçÞÿÎÎÿÒÒÿÖÖÿÖÞÿÞÖïÞçïççÿççççïïÞïïçï÷çï÷ÿÿÿïÿ÷ÿÿÿïÿ÷ÿÿÿ÷÷!÷ÿ!ÿÿ!ÿÿ)÷ÿ9ï÷BïÿB÷÷B÷ÿBÿ÷BÿÿBï÷JïÿJ÷÷J÷ÿJÿ÷JÿÿJïÿR÷÷R÷ÿRÿ÷RÿÿR÷ÿZó÷çï­ïï­ï÷­÷ï­çïµç÷µïïµï÷µ÷ïµçï½ïï½ï÷½÷ï½ÞïÖÞïÞçïÞïïÞÞïççïçïïçÞïïçïïïïïÿïïÿ÷ïçç÷ïç÷÷÷÷÷ÿ÷ÿÿ÷ÿ÷ÿÿÿÿ½2¼×ÏóIDATxÚì½\Çy'Ö KYHë5©,+Þu9–aÁ:»¤« „€KTl–îHÖù ؃@&ȈŒpÙ56 —ìäZ˜õÌ.gÊeÖŽòJ³ooß(«;>; j‚œ²›ÝpœH¸;bBŠLXQ |<ÂɹT›ïûºûý›73ýfÞÌ{»èØùæÏûÓ¯»ýý鯿f»–,Yò‰å]K–ŠD–,…ÈÂ’¥Y@X²" K–BdaÉRˆ, B ¨ûïΊŸßíBò§¿÷(€ºtσö8íóÇÛ+ÄXÎÆ²ë= ¹h?Ý^!– Xˆï¦½”y!÷uŸÙ×·g(èËê“ÿF}©:¢üÛtÿàQ@$\ÅÛv䮺xø`ÿC¤»É—ß”'þã¢=UØýJATŸÂ]–…z±þ……Þ׈C¥í*»‰×£-"«b!"’ÏÞM¾wÞõ›ª-ò.€¥ö®¶hû,¢øûÝl7òµ>-:Ò‡¥KøðÐ¥Â$Ý2$-ÂÝ<¡±ob?î!ÚcÅÝŸÔ oýÃz¢ÓU:t`³[vêþaýŠ%v¯Ð^+ᄂ$e¤{ïLT™† ˆ¨ª/BíåÛ+´×Ê»/)bC˜‚Eû}ðÕ>¬­Ïûö³„¥)l!Du”ݤÞïÜ ß 퇅¿Ž¹–â?îÚkåÝŸSMl3@°ºջɷL2ª“K¶Û+!,õO!@ìvÂF0)¤’$uød„Èݎ€ˆ»]»rw7d…«ð´×Ê»o)>«7»»уƒÃ_ø}xw7‚šÐ/ ÎÛ¨Š“,‰Â]:Œ©Óì)ÚkåµÔ…þz×Ü{]zÀçÍ»–ŠJ{Uéð©ó.€¥¢RÜ„x0è{\K)èAă„%Ka²€°d)D–,…ÈÂ’¥Y@X²" K–BdaÉRˆ, ,Y ‘„%K!²€°d)D–,…ÈÂ’¥Y@X²" K–BdÑ“˜¥„¨µóînÅ'æ üÇ…åûš»fĠΰÖøçZ¾O9´qíÂ#ø¾[oIü’…³C˜õ:“cŒ¯–1 ¨¾ª;Î]FË÷×í ¯ÝOªÛ¹f£ÃrÕšçÐX"„åû‰ëvltD8ÅN·.š ÌËOB£,.üY¾?¸nWà=aÐ÷zeØ…³=,{@hm“ÓÈÒ€¿5xµ|?pÝ®€v@DÁa¡¡$üÃÅ)kùþáº]Eg@„rZ@ XÕyë¼–gËu»&ÚI¯]r´eƒöÓŸb'w²IBG·_7V?u€°~×€sÑ,ú}ܼHD;š¢ý½ ’ý\‘ËDr\±|¿òFW@ìöˆv%Xé=ÑnÕ§µô³„Ë]I‚ÞqË÷wÕ«H ˆH—m;§mLuæÈïIÚS¬÷wy“§„Ê3aiRZ z“pN@t¸^G@t:>? !Ôx‚#ŠåûKyÁûDû1ñ_Ï )H‹Ÿ| Ë‹ˆÇ ¬€„ªU™ö1õoTQº€p­Q½Ÿy¿Fu‚Gô„Aòv Zž§Û5É+Ô&$@pájÁÛt÷kï¹ï¹â 'êutôÇ@œ*ÖPê=1—Ø Ãˆª ±Ûé #"ÜT½†–F]ýSÚi†üêÕ+` Êk×á¥ÁÉ•­kË–]ú{g@$LÃí1@¸‚B…ݘΙÌ9÷oÇ^ ¤¼nfÜ]çëw]” Ø’½Êc¹)(ISJˆFúnûwÁò„XkʰoéeêÁ Îû8z7üñGŽ@ÙðÆµµf]8WA Õךå±¼'ïhCÄøäÎRe2˜yî’ÝNÇ*öNh9‘Ì]÷½7ê´xý.Œärd¯»õŒ¸p’ˆ»Ò†èUËÍx¯BÉ» ,lï„‹îvú.v诉¥) Ô¢g!ºó+W9üáØÝh6®Êﯨ‘( ~E8Mº"®^7.—å¹0‘m{·Ã½‹v yªâ—n+Gô„<½LB$BÈZR´óz ›Ð¦R>·Wy,7åÝ$D¸;´õ3ïlèMü,ý1Ž’NwÑŸs“i¨.Ø—Ÿþ{§fgOž<3›=úå§r~ G5·žª`–:Oò2YêDÌѺ¦0àœ †€M'Ÿ?¨,•º›¦\–÷â6Q™!1Za(ƒÁ°êzdr2 fŸ>H…ŒËcyW®ëQ¸VBókLøaNG>l €P¥©×9ï]Ë»óPЫ„ùY7„®=9º$óH9qîòÛ±–›q¿]+! )ÈË„=±ÑTy}:p1@8žÌ®eRË»sÝ®®5ªM‰é™+­É×;“ø(T&OKˆ.å°ÜwÊÜg©1¡s®0ñ êT´!ŒC-u lWšˆgÿ¶Ô‰iL2Cp×÷î$óBf2,åÝyHÊZ@˜SýOZ½šp1äyò2¡5á´NÏòXÞwÜÂR'bN=ø°AB¸Ê¢ñÓrYÞƒ[£Ú”˜²¤líŇˆ§îÊfÃ?Ǹ\–÷â†Ä„ZŽHŠ.|Ø€xöéƒ>خ瘖Ëò^ífU&CbZÇT¯½øh%„y¹,ïÁ- ̈9þX¢qÑ…ÏE$„y¹,ïÁ­ÊdJŒäiQ1Dþi¿p S’FµV9óv»" •©wy,ïíví¤2ÅWæ¤_µ=½Ÿ“ Héò2¹.ûòó'ÎÌþ½³³³'gáeöôé3'OŸž=ŸNž9qæô铳ðö|‡œ€cOš}V®(:_ÈuE'gOœ’üì왓ÈgiÅÑɧ"Âé]Kf$† ã ‘&/ÎT??{öÔì™3O}äàS³³ýÈÁçáõà—Ÿ:sòÙÙÓ0Â|ú¹Ù3³úýÙ“Ïž|öôÉÓ³_ø· »Ÿ>‹ÂOŸþèAÒæÔÉgÏÀ¡ˆ,ø;u*"!œ«6xcpJÌË´›1 ÌO,< Ü4y™Ü:û§qÌÇ9åƒOŸ8ñу¿ñô©ÏÃèâyøvö“'a´?ø4zæÄìÙ3Ï|΀€89 8yæÌ€Ò—Ÿ?ƒ„Äi<=y&"!øjÏòXnÈ;‚%LÙ‹ ÞËÓÿ…ÀÇHgñ»„pS”ËòTy™v- :=Jª¼L”d´}ÐfO# >O¯Ocç)ð4Jø{JÈÑŸé÷§>ò‘§%H$U>zæÌ/º@?uc»&y¢,ï+/“îÄQ¥Ç"m^&²!~é  ³'þmÙ…?zð?X8áô D¡L`Dß•¼k—½ËeyʼL»=¡\2mIœX²°i»S4MÒ“ÖŒiò2A÷=©\¤Ø™¨ö`'ÿåÙçÐ~í°»IeBi!%ÄGžB`€á|¾êÌ’¿üÛ6Sm)#ê ÿ”ç;A0tDb×ßíòmû}s„ã¹æ$=üY°¬ΨÎý¬ÿròäÉg5ð“Êyyröäs'48ñpàsšÞÁ¿çðw<Á?Å‚û,eE¼ vc¯q;7ÁÈ툤S{ï7Ô~œm™!XÔcèªLª“Ã8Fô§ä·gÏ‚=ýÜi›ô…SÏá—ôÛYÎYxyîÍXá'~‰&ªOÓ¡§OŸ~ê#a•Éå=Êc¹!ç"% 3D[ß߃€9hzâôìç?ç•¿p‚‚™ 7Ÿ@è¹ØïO|þEb€Æô±Ï䯳*V ~Apå ÎNŸÆx'*'IåšÅ™n»»®Í»1 ùÁ®Æ€P*“·ê‘û¹×™ë¬8Ÿ=yZ ÙS_@;@Æó&„H3š•ÖÚðàã,jZgHu‚_žCK#£Îœ‘‚m*SòXnÈ»©L,Ö#l@¨±Ä1 Ý¿OœÁÁ_`VZgÈ%ÁdÌ? pø ”/œ’*{âŸ?C× ³?*S !pÇ”üCö6×áà%„ž‘ëÐ1<@øÎ9·×€ÀpÖ3$ `l×]ÿl³ÚŠ8#ÿ(*ß~þÄiT—¨ÿ# N`ô÷ì™_"SLB4e.FƒrYÞwv»Z@Ä¡–U™e3í!›…&+ÞiPg@äìeÊÑí*æeßãœvgÀ1¥'·ëP²!œÞå±¼×í*ºHˆ„™¶„ÞoˆÇuD1æ!d­yŽÒ6»óQKˆ^å±¼;×íê&ìÑ 3Õ¦€ètY#@`¦:EÜÞ»Ò „xvx€ˆ.!EØ…g/sÑ%ûw·žËÂÔ©û¶Ç&ŸjˆBÄ2ùÚ&Waà´¿@>j ÑèQË»sÝ®€Î€ØeúºS—îíjˆbD»jÛÕñh±×…]BÄÓÐô(彸nW‘‘AßmÖô$a 7 ’ŒøQ YÕ¹ÛOY"K®ÛÕÝs{Ìå)!Rø]G°?DÄË”»¿r¿p¾'•u’*#-Cª¼Lu‡ý¹]1RÕTuJ±ÅûIí:$Ú#€H´ÃG[‘*/ÓUÏž8ƒ!¬³gÕüt÷¿Y ò“ êuü³g¤Êôƒ]›—)3ê”—©ˆ”¿“)m^&™û0ôûYµÝ}ħW<áY O+!œžå±Üï=@äU„´y™0üÆò“ZÒ HäÞMož%-ët¯ãc¹]¯æ·÷y§¼LŤœá°›2/“뀄8õõ{÷HÏožë}ôÙˆ„°y™†™—ÉR"¥ËËäÞC@œ8õ¬´¨Ÿ“¨xv¶6 Šg{ÍíêzEÈk´×¹ØS"wJ•—Ém®±16\ŠÙyç3Ú/ÜJCJ™uã*-K¬×› å¸èù—ØÕÍþPBX”øò2€˜èš©F°= »vÈNJ÷g%„•#§t" G…ÇüùxH ‰¼ÇÖ}EfÄ(XC…U’W-NïɹkÚµû–©Êcy7nw!5$)!x(ÌQÁ~I\øÜ†6Än "ÒKˆ^å±ÜŒï‘X¦"Ÿ¨LIº ¸ÂËSØ»:ÕIZ á:=Ëc¹7ëðM{äxÒ áHðX8¸ú6m~-Pu^¦°Ö{¢Gž“¢s“|H+#0Ø0ï ­}ÃG?#Öç•zÝÍqbºý‘}«KOå¨<>]9½¿–¢{«á Œ‰ûLÊcyOnˆ`ìß4ž©Vd¡ŸYðeŸðÍ‚a0|§(,Š·Ç•tf\¤q»öýg^Ë{rc@ÄGðL}ÅB?oâ‚E®OŠIˆB"U^¦`=–tRþ¥ò5 ãrYÞk}P •IùȃŽêKˆˆ–ãK •É€ˆÜí"U^&ÍÝþ$D*¥)ÿ¼F{ëv©%DÐm‘»I€Ð–tä—¸ó½€H“—©qÍib¸¸*¦à±F#M:N—ã„oÑamò^åÝò2u3Q™Xw•‰E¯êö,ø®€"®yÞM驦÷â`-ÓÆ;ç‚weæ¾"ä7Ú«\tÉË”Ð|eIË‘1£ZC$nTÇÄÂnDX„ï‚o ­mšäeÒkÒ'9™rÌRÀ=iˆÐ_ûñpkžå°¼ÿ¼Lé»JÞ}u$”2/Óªð²KãPÚ0! =þ;~Ãñ~¡ÏÅÈo´W¹n× fª@ø£H:õ>¼Þö0ãx¸ãû ]éÊcyß»y™r£ty™‚žÃUM{Žþƈ;L·–Òo#¿ûß{®ay,ß?y™Š@83û²Ö\1|ÎFtË5ǽúl´«!1”\Íh= îîÈ\%“Fp¿ž”ïPØõ¦Ä´‹I¹A‡K€7ñÕýtˆ&Q- L‰)áÊG4`»B‹Œê~6éz¶*“1…Œj5Q¬ —*“Ùýx.ë™[ aJ4^£&#ôÖíà C¦ !¡ïXðè}Êýz¶€0#¦ÝŸÒ}=7 î—¿;òAá¦ÄDxiÚ‰¶´§PY¤Fsߕӆ„^¦Qær]¼cþyŠ,ÎmÖ S’‚ÎãÓo"(K}‘ß¶fÄ(Ì8û÷€C\W/Yþý,×ÜÂpÎ=ŠlÔk¢¡L׊ûãfÝ‚«‘{XÜ{y|U.⮾ë(îûàrYÏVB¦ö\‚˜ï±4R²€0#^¼ƒ#‹3TÎÂ‹Šøðï÷ÀsÆÚÂŒ´TèÎ0¹Ç¼UÕ`úu¨÷³\;/, )]^¦ž¼^Ýi6šWÐÙ×ÔòZ©Iœ©É8 áê+ð8‹VTcbw¿qÜgLýæeêˆóu2åÈ×Wwuæ8”8''êÂÁ5Óõú×ëD€ƒ{ÜÏò,ó2YÚM›—©¿‚ï›kM”M±Êyð»WƒºÞt¨+W­ó”åÚ+\¯¸HFŽ#9JȺê¿\¬’'.šƒß×÷su.ŽmÂÑŸç:*Dà Ç}ggk#%@P¼I¨©±ñ0hQJºã\ÚßBpÃòì5º%éöu§¹ö<ï7Ö…ÃWyæ'î¾(Ái!Êtëp?×µáß©¨}9 é©èIÿç[­7ÿlk«•Š–zÝܘš`¢^oÖ©ÏÔßïyj8Õs@4›r¿Jß7× Ýco0²˜Ä2™‡ òuÓ+ɆŽòÛé%Ú`pll"×Ñõî !1‘²\{…c•{/{('êܽ·îâ¬=þ*h~Æõ~Ÿ=ØÑoû©eXfÔ' 9ÙVgc_½Ý‚NVòÆvz±ÕÚjµ¤õ½AºÓÖÎ$ÃÐqE(E®8{î92¼‚¯Š5€Â:M)s‡ŒNå¨D¹Áºh ˆQ*“&vç†T{:ù” ¬jüO¢ Aº9)0Àª.͈}K  ‘zˆD¡ŽMùJÿÈ´®‹¬&«2S¿F51¾Ö“ú1!¶PQÚÞ$;„Љo‚ý§ûðýjTsi,{w¿ÆÎØ$Î]¾ñž pè~Ö¨NIý»]áßäÍíM2Š[ÒWÔ‡!•%_\HL}õ¿i·rí®»ýÄΖ¬‡­ FZø²õž¼ì§}¬Ûµob\¸šDð¶qr˜³w®Hé@ln¤Å„‘>oƒÀÑÚG3 Ó•ÖUÀ/ÕÙ]©‰îÜz3xê.„³úx|špwÝ N×Ĭ­|ݼ VBR_5#9©­5[6ùÝVkp€£Z«Õ—×uS\`CªPp­© ñõæ~°!t@ öÈFƒ©ù)N·¶Z[½kg[5õ1š¦Á¥TÝQü£Œu“vsm^¦4Ä\¡ó2DtÎ^œÂcÆßÚÂQnKŽë&#^’ÒÔj)0µ4Dwù7ÌÊQl~Õ©£ëxMàÜåäMˆ[Ò`2ôClÊCQzî&&FɃÂ×½ßl’“Ö°½, ̈Q€€ô15 8Žz¶Ý„Aç*{gç@²oK9ÑQ{o`ïø&¾lnÞœ¤=$ê´Õ´\Åä*ÀÅcã;*°ÿ£PÝØÞL3€È³·¶wÆ£íQkåFå°6D*Šæe2Ïç­º.Àáöý[r¨ÛêǬ&e©¥N$§këÏÇÇߺ5¾†òÞÏìwwýWÀÖß‘óŸø5ÔÂÈž*²µ¥† 5§¿55Ñ!ËÄfîË”˜CL3À õi %ÄÛÛ­©ñ·w`ÄÃëCBÐô´Âj^;ã“;hT Ñ F@“r“ÿXB v’ð¸Ö’V“‘U½­Ž#³CN~n><^Êîë]a%Db´ÄP͆rólÒÒË´ƒMõŠRJôÌD°À@¨ €ÃMü|“5Üu·.5“ò•×Ý?žüÖÖVKY ²~Ô̼‰‚\wá£ÕëÆ#oã÷ëܸv»õ&v”û‚êþ\¾|ÈÍÈ3«˜ :[o¢-A*ÔÎĵF³Þ4)ƒÍþŠ˜£uM‘‚Ky‚€hIßà@b+P‰7··“‚ÀÊØÔ?Ó9ämŸøê޾À»‚Ao"u¹ŠÆ¹ÃÞ½ÕBe°_á%RK7¡švÆ]Ѩ§(]1gHr ‚ÎÜgžÑÏ`wnmµ£&Vï¼õ¦R{[[ Fc[ǘš¤Û›a¼ì°FÚò“‹Éü4wi`CˆŠoÂ…àjý¯ätè~ÿPFF 3b~ ‘nÛÅ©L0jm¨1_öæ‡&ƒxœw:(R;¡˜ïÝ b#lƒì0Š~©ÊSDþ_0ö.Õ‘‘Å` !¤û¡ÕÚ!Ú»~BA¯fÄBÓ©:VßS†X;׿KaŒFõ¦¯ùl´Z&—JoêÁì¡ñä¤dqlJµiCªµ©Lœ÷(OÑù{LJQœmîwž¦¶pÝÈ$kÖyÏúñÛÕfÝ0¥ /M¹5U^Ÿ®\¹i›8¡Dy‹ t¤Öv«G‡2¡·ÔX×ÚÜl37vHnQ0´IyŠË9»ýÈM:"ú ‘×|ýèÖC_ÅVèqÝ®®5ªM‰ÉP&G)¹=щK A¡w®oJ³XºÙ7õê†M•T#AæËîáw-=jây¾Í^¦:á”§Ð|âæÍIv› ¿5¸ !Ã>ZÛSìÎw§îøy»ÜßfîKKzÓE„ƒyˆŸòäÝÙQ™¦©7µ¬ØB»þ·÷€¨ìÀó¶Ô©[aíP©ÜÑí9$ª»ão!¼i¦Z- hh*t{êÝzýƒ–’³6û·)1@ã׫x{q®$Ä­Hw¨»‡§‘’ÿ¦Ï¤ŠÕÚÜl6Dìç\0² ¾ËÆoµú[1Ò6¤L±wn£M2õç=ËZ“maFLi&Ò’0ß_µ„hëæ”8@ÁDÙ2dS£ûF—”;̰jI749õ€°¹­íVà^€Š!oƒ ‰ÝQÎë;;*ÚÚ~øÝ:ڦ局0$& dW’”Ç$ġڰå}”¬iÓ—¾Ù½)òÍN"%„nÏôå*çãÿÓ7C!*ôø˜hǧñp â2 í½ýÈDhֆവµ%+TÊ›wR´›U™Œ‰iS½šq9«Ý®2ilP‡ù^Hž§7;OW— ç!Ò–«h\Jˆ Z6¶uXŸrBÜœOX†óoܹåWU0÷)W­ã³ùÈW1«®yy, ̈9þX¢qaÌ“êÍp;ÊŒÛ@´Ð§¼—ìêÆåLuå*çr-ÄÖ†\`«”HçôºZ‘ºÛÞÞŽ-NßôC dÝJ=þ¦È†0-U™L‰  NÓàn 6dc¾ù¦ô¨/q6¢ÕŠÎ?±¸ÕmÞvBŽïjPË(óyÛìe,Iëü3Eê`üÐÛ¸%™DÖÄDX5q»õÜ&!¦(Úugâ{×7qÍðöw?ö‡;[2I¥î[·H!h‚öüÈÄÞÜN¤Q] ÷iÿù—ni—[`GE5ÅÍNó›Ú͔ںššøßnÓ™@¼mXC6/S*ê7/×6„ô â0þòñ·¶¶÷Ö#­[lüÖC“ß»ÝþÆC㜱›·1¦gû6ùU<6ñS“¸Ó lƉ&-qóò”·ùá6·Ut“|à ˜ÑÒ*册T9 I ½s3Yišºãˆå±€0¤~ó25„t»êùfjÉ·;Ј;èNœü6¾ûÑñ·oOMüKô(Þ¦¬KÿlÕ«‡H†h_üÖFàs¢5ÕR#¿Rß|<1¸ì¨ë››;lâú”\$õÝ)¨¹woLMü0j†—þ¿nOMÞ¹ÕÚŽÌã6„Y»Ù¼L©¨ß¼L/Óæ¦ÎiÿO'Ùm ;Sãu†ïþr툩‰wn~gBv}û JÃÎ#ã '¾“4Âá©ÊSP>ž8Só]’’bbê@JÉñïÜž˜¸1ž­0Nn=²…€yˆ}g[@F|uJBؼLSy™´„ð½DØT· a\»95þ.@à‚ý·¦&ß¹9E^¥·ÆÇo n·@BL‚$¹Ê&ÿù-íôfبöußbäWê›'HˆM\>A+I@>ܸ–×mÒõõÕ Ô  t¾³³¡VeG'®Q9„•i¨¿¼LZB|G72%ÐÚÂpƒ¿Üæþöcã×áÝ›ÔØyjÌòws|ò¼Np&îì<ŒQ ×•> ÿ&)ï¼Jƒr‘,!Ô ‰íG&'nÜf“;߯œ%­ä/¿µŸñ÷)°»PýüþÍäõØ(!Ò´—„õŸ—IÚ:Ñ"fw•›ÈÌ”~b.Æ–LW©–Ü)›”©oÓƒŽ €û&/S q‹ì)Pœ`@Ùy @q%'ÆÃ’œ%éŠR¸õ ñ¶¡ÎæeJEz¡Ô;਼LC!”¡¼LæåÊŸGwbbãßi©Îå·dÊ´‚:|˜½sãÐþàqçŸ]gþ8Šq¹ú‡7Z-™€!ºíñÔ»J¢›•ËÂÒJˆ0 ‚–îYRÛ­³÷Éɶð"A™‡cÛ˜8_lµÔz ¦”NaôO´h‰NÌ}U¤ª 3bjcð~hbo’ôÛ1÷=?ïwÌØò7Ï"÷‘œ‡Vš&-!ÙðÁ³å¯©ÚŠy™Ò´œ Ý0$’:3CtýO¡ÏÔ ëÆ^丒1 îÇCáŽr¥(†f´¶h©¥È—¹ž·7•(QQ­ziÕ†\.õ3¡ a^.n%„!I@„2ºS€ g¨*“+ó2í1 ‚KÅÕëhW5^9¸íG„oJUi;ÈËAS:”ØL¯-$µ!ÞŽ88z”Ç”´Êä­z¤¢ ÷̸Ó1Uåà€€Þä­¦,O8ªKðõ¯SN&ηÎ% %F :(€IF4ÉŶr;üIn îsҔ˪L†lËk’„¯ UBÔ÷hè†#kt¾µkðqòŸ¢‰|c’ýðÄ ýt$‚AV*2'6(˺f'Áþ¸MËè®1öÖGp{š0 ‚‰9“ö²˜ïœÓYqÍùPmu§~Ê•?Gùð>†VH•iŠÝ¹å‡Â&B+Í5þo 9AÑÞ·“óú·ÈªÞ„k|;ˆw¥­bTëv5&¦BºÓdWÑãŽÌλ4(©¹½[ã¤ï,4Av\ªæè:ã7±kOüs‰ì>¥ÖQO^ßñ“A¿½ƒûQ¿sƒüØÎÖÎàcð·ÙÄn 3~CÏëßÙÙ"ëbêf4,Ÿ] dLL ÉVå´§)ݹp=NY7ò. H°q‡ üÌÊ“7—½OïÉÀô÷õæøÖ֟ㆼ`8¿5>¾scœÝ~hü¿ù¯M|ÿöÔÄU Ó˜doáv3lcÐÆ`®Nà÷ "ݦ §ÿ–M 0”ãö~Kã’å’ù­, ̈ÉZóô˜fÆqgØÆ5h¼hÞ¥ÁÑÐ"%fîƒ6­7ë†å)¿/-’ÍÆ5§‰aõ.†3Þž€1׋`PÆäÄ_L¿ý??2þîÎC¸äÆ-ø» 0ÁØÉ‡ÆßýÖÃã¤Ä-Šwrkkƒb›T°üäui{ƒ ±Ö³\º]]»?„)ùûCp=²˜ìŽC;H¢-ïÒ€JÊšëÜ÷Áo®¯ß+À.@&þ^vé“òÁÕ߯ß¿ŽKk?vg¾ƒQKãìæNÞ¹95þŽìâ;;lâ6©DãÍ1ö¿LM|@!ðHÚ·o- ¨†ñÃc2©Ú˜æç_ÔßëQ.a³§¥`®ÂÀi\%¬©EBþÍ»40èZ¸u» {•§(7²_ø1í£ßa|ßÂ|Ýßß¡Uƒ×¯Ëø¥G‚B³ÃÆI.Œ-…‡(ÊéæøäõÍí“ '¶pU!®/Ä8XvK®·žúêµ+œ÷(—nWÄ)µvÞÝ­øäKôüÓb!¯ çäÕVî—½ñö¼Kƒ«M˜·½ºuY&Ï \ys$²"˜Ú]IÕ“`·q•4óÝÚÚÆqwnà*8PnMMüw7¡‹÷;“·nÑN{¸Æð‘qø›d !È ÿ½Þxˆ½só¡ ¹`>ô6蔽˧ÛÕJCbÁ(b +s=Dã;Iy—ƒÎÎ>ü6î0Çy–:þ¹”$oï ÿûúøuÒ›ŸÜ÷¸e|C4íÂÿ4'Üj\üQáýLró'ÃÚgß¿šiÈLaºÁšk)ÚHX/“)îîëšÙœò_ÔÛ¼GôìžÏ¥@RQÌ:×ßݯ lÙÀ¥Ò›¾³assCïEÞÇ;$ ¶Âæx0Ÿ± Sºr[@Ò`¢9*’!$\×8‘Añ)ŽèVƒõ&ü>ùÖÐó7T¤<Ÿ+ÑR[³oúUÝÿ7d÷÷}T­ µiÊV«õðùöêiŠlaFŒ‚…UH·ïUœxP!5Ù]¿|•¯â3õ×vyÖ×{‹Òjè¾½áO&lR`=‰oeDB˜ü° Æñ0.°ýÆúûzµLËkWÌ’ßx(ÌQÁ~q®Õ(";ÃËàºáB-!áL.Áíx9yMÆ&¾·ƒ}z ­ÐÞŠÛßô5(+c ujQ–¦ ÊÜ$=L­[ÿ*cÍ:Ȇõ{.ÍC–ׯ2™’Ÿ¨,Ø¥Ïñ?÷Í9µ†ç‹×AÛs²º~1¸L&ÀÝŽõ†Rr•­ÿß´1Êõob’25ê«ÎMA %”ƒ[;l‚¡4º·Îiîè}¼·Yy- LIçe aƒOX©\OZDÈ•Œ"»ëçÍÕº4&צÉÕrÉÇÉÀáÖë÷Ö]¹7™Õ-4*Ð ØRC†Gj\H kS¹M‰ îºï¡{»^¯{üÊRØÌËmaFIèO5… Ç~¹¿Î»À0%|xf×/gL)šzDB=\£À˜¦ ¡)pú]ï€ÕÚüæÆÆ†\Nrɪ÷`ˆÓâ‰ë4góªQ¸ç`ª{8ZOS^ 3b:o+'è²áB|s¤‡ÉSyZ²¾O^\¬ ™[ƒ6-ÁgM>Î[õŽõ:Õ3G3›VÒýðÄÇvhAh°žÄßÑû‘ 5{Ywqš’ÖƒBï¾·Ž Ôï)ËmaFýäe2Y/#1Àh Öq彎'‹u@rÔuBkoÓžLã9]æ.Ý>®oó2 LýåeêÅ=5D-žÁõŠÂM.’CÙu¯ŸóiÔö%••᫲… b)’ 䋲y™ÒPy™zq9bà`ãš N2OQþkŸã*c«`aY‘¦^q_Zò;•93DZ‚UÚƒ•׿eJMýåeêÍq%OÓËEÈ›”÷”xà®öÍ¥>_æãx9XzêI LjI®Îþ—My…ÍË”–Òåe2åøN°z_šÎµüó&eÅi Ƀ`ïçÇl—d…¶$(,²AWnàεAË«ÛÕµy™L)]^&cŽÿ÷C üÍsézE—ÓÞ™^‘º`ÂÍ|âÀ$±*“!…Œj’ž¬€¯z ]­™]/'îQÞ%ÚÅáN0g~À ›þ;åU‘ýs½^ËÂŒ(¸Ë Ùõx˜ dÖØ»\›âþZäWÓóµá BèÊr…¹cVÜÕ-kaFLº«µé˜¡›Oì¥tö¸œDCm&ô}Ï…V‚_ã,ìkÂ#0Lž2³ ïy, LIº:B®”¬8Ù^/.ûhR^ ³óƒñ!$ v#€ë;}'_¶åßߢ'1'Èéš%Ê'SŒ%³|K4¦’jx®œ*ËæúúâѪw¤Ñ»êQžØ,ó1Ù¼L}Ó°ò2ÁXÛd´U-\u-ï|J½¸À‰¸& Õ˜yI.ºÖÈðúk>_S­ïÃÑÍŽ³âº]]›—É”²Íˤó/©u¤#{«”C¢y•:–=1‰‡—åfìÒÝš]}¸«¤×‡³n5'%ÄêpòVévµ†“—ÉŸ RzxÞ6‚Æì!\_2¹¼‚»Âóm™©é~Ö÷µy™RSæy™”—C‡”)6o¿ª”)¯ §yF"£úÓ~ÂQÒ)ÿæ¿ÎóÙ¼L¦ŒŠä‰çWÈKêЉÿ¨9迯ï.õµ&n ¿†>ÿ†Ìü8@y¢<<š²\4É” ý×Sonƒû ‰¹~jLúÐu õ¬Ó^5~4ï“{/ËàÁ~ÏG~÷»œó{_£•Án¦>'ä*åÚ¦™z4²¸n¿Ü“šë®ïº6ü;E÷˜«S@M½Ž;@]™ÌÔÒØ§ç€Óž/Ä•«NsM4ͦ Sφ ñ¥tˆêú£&gè멬„0$æ±Lܭ˾X§­_øÉSIúáD­tñ>Îwëuô–Ü]¿»o±L¾…2LJֹS=µD”쇌®Ÿ>\~˲:Œë«eGf¨éØéøÕUî|ÀŠFÏ®ú«âsõ/ÃX`\¦ßY@äJñmyë0<ƒd¸ê¾çN?ñJ¥<ÕÊåR¹Rî÷2µåW*•J­V­|eé·—ýI¦ ¿¥»3p g¶ò¡¿Ò yýˆU™ )bTÃk½Îÿâ?ÿz]Ì-ײ¡Å~O,—«Kµ ¾«–Ë?þ_­Õ326¹ÌÇGBGHIáx®—›Q-ݾ®5ªó§˜ÛU¬5]ÎÿøÊÕ+WëÓGjeúWýqèÒµZ©6Ðù‹µ2ˆ‰Rµ|èODvnH!ƒ¼ï;±_rr»úfµu»æLŒ)§1·(Wà `cúHVbªT$¯V«‡þ´ïìØÝ 6NWÛ$·¹R½Ó 62ô=óEóós†´0wñ<°‹¦Ç+:OwÁ—scŽý°™û"¦Æ Ó›Pr¢¸B¤ç •1 l4P"„ C,Z3ýdìc Äáá¥4Ã<@bþâ\¿Rââ¹1ZN‘T.a%Db<YÛÅô2õ—ýšæp'7Ê´„ëÒòÿw8bÕ‹'Š‘ò>˜uþsçæ.ÌÍýsóit¦9ÄDj %ÐyºÏ‹c/‹z÷lìôHyw·âS’·Eå‹ÞG^&=+÷ÑG7©›îÄ9{f~áWÏk•é¼)-@Ï ÈøxE¾rvn ì—äàG›ý;1Gëš"ÌQnL/Œ„(+ú+jPú“{E­¶•Ûç:>É—,ˆÚj?ž¶õA¤+‡¢»œç6õˆìi‚X s`CxŽŽÐJ*¯]1gH,å)”óõ=_eÊ4ïÀPû‘wÌø8R_&g+cþwÑã„R§D" tÞ$ãL9Œj|®×ƒÇŸOX•É”˜_cB¸ÊCâ·@Fu¹ ˆ84½»«!!tFÀ°êððj¸Ðr¸ûñãBA¡á Bµã$^¿#9 äHNÓ‰‘Åöç³€èI~Ö ¡kFD§XnW|©D$šhƒÑkã:½–z.~œÿÜÚ‚ˆJ½štýN|ÔBƒ‚$„ó¾[!»íÏg³n˜R— ‘Ñ mBtÅ6‹äv-ãë¡™]_BÜ炚*QœÓ3¼#Szí¾rBÆŽÓÏ­áëý‚Úi„êe­'µ„ð¥Ä¹±:öz\å(®9÷ãÏçZ£Ú”üž:;†¯‚ Q©æ߆(ÕJQB¯Iõõä0'ýÙQ¦´#³ã¹dvÆŽ×ÏÍËnhâv¾OÏD 2 ÷>N±:´0þ|VB˜’Þt½õbñÜ®ŒÙ~ØZG«eñŽ„}G\’RIŒåæŽì¬žj­u~€êf×i{>›ýÛ˜ä.*Ü™»ÁhçÊíZ‹¹]©Ô¸¡Ià‹rOxËìGr¹(o;>ø±©C€Ð›!vºOìz9¯›ÝöçãÖËdJŒÆÙö¼V®¨Ï«âÎ*PùÐôác8Lš~ôèÍ T*‹+‹À//ÖJGgfŽWqUÛï/ývµZÂw•ÊJ¹|©R:>-ÕòŸ>^*—ËÕåWËø\kqÞ]B^­Vq•iO«-ÃË„ä¥Êå ~¿²R ÛÁ&9š×j„†ààq¢×™pvYrÛÜÀï—0=¸ˆÑà äe êf×MhO+! ‰9Iˆ ýÓW™ ›>]~¹¶X{lúðÑZmi©V‚^ ÿ¡ÓÖ+Ǧ§Õp tmyñ2 É-Ö8ðzLbæ@¤V¹|‰ VÔ¬ÀQ+Ë˸N´¶‚‡V—^].Õ–^]ª¢d€KÕ¥Úï"VÀ‚(¿–Ú‰6ôsá*4 ÜÆl‘2£©y¾›È6¡~íÈñß<ON€ˆIÞéù, zSzx0=€¬ˆéãU³a„®šaìðÑjõ±é?±ø[+µÒÊeå«ÐwËÔ{/ã¸^B ,KEÏ*`JÇJÕòq8ÿÑ#e+• ¢ j`®§•K¯—–©|e P)‘œ¸ ÒF/BJ5ò96?îõ"Ô¬grN.wгT:DvúñÏ ªú4vøø‘›À%\ì§Žƒ¨X>¹R; ç~â1:ó'ŽÈó¯‘ä!0Ésiëðqy—éc‹((PP•#^&éC çuH6è1ÑIx®Îý•I€Pé8Œ¯“' B^&/¡|fÄ+Úõñà{™(9šÀÍüôãÍ@—žù™cå¥êòã33GP>`Ç9Rà(}: Ÿ@‚L0Tù‡—@e*ë.r „–H¥||zŒ=ùéC"2ÆÿÓŸFÙñSŸùÌÌô±ãÓ3ƒæªÕc?öSŸ­,¿ŠpXY.:V‰J•€ë’£Ý ¼—}48žÎè?Wgþ¾££}"uãïLezÂHˆx¹¬ÊdJŒäi´¹«æ!Єf/z—~á³G§94ý$(RØùgŽ?13 ¼þ›G§§Ÿø|*_:úq9þEs¢º$?1T¸`ŒòñW*`U]Â×ãø¶ÂòrUÉ­Ž­–QvLÿÜ%0Q@[ZY\Œ…nø“NR1B4p_dh1aÞ‘ Fñõ:¨ÅÛc€Hxn SbLmTS²°jí±™'?‰ùÐôO;23ó8ŒäGÑ:¨ÕðâÈgÑx®IZuëc—.U¨ã×*Ró;âJ”è™:‚W¨,ÖV–•öø²òJ=úz´vè|%O-X»¾Zà UNµ-Ú/^«QòSo7©ÿÜÒ³ ì‹Nôí5·kÄ´±*“)uÏË$½L5Ðßgž<†Z<)I3ãSCWF³÷Ž ês|fúø±¥@=VÕ£Ÿ>Šù 4–)õX g°H‰zdÍôñ£Ó3ÇV@úþüG;ïø|óñO_.!ئ?õj¾ë!þ_ÙäL*3­yÆØ½E(¼¦Zô‘—© ÂI(™„uÏË„yUѺ„ªÒÒo;ýãISúH¥*c²Ž,ÇöÏ–™Qÿ\eéUP™PŽTÈwŠž&0Vä‘?ñ TÅÆàJÕ×H.ŒM?¡§ñ~áSò.3O”hzµ/%!È-*¤£U¥,ÓØ;~Ö>/P £:R$›—)uÏË„€@D,?6óè߬T°Ûþôqr¯‚,øÉO>ÝùçÙôQR}Jø+Xå2I’éO þz¹rd-†ÚòR­¶xhæ_?R.UI-ÂXÚ%r®Â¹KU×ÚKRQ*×ìQ°X–H>TTèÍÈ- ™ ìVi3úÉ×ç¨c È ÖÚ¥¼N$„ÍËÔuÏË$õwšg^W–)ïjµ¶´¼²_‚Zó8fp]D#ay¥V-WqR®\}ó±JÇ­ H*áuVV@£ú0ò_ÂŽŽZνádüvùòJ¥LŠZ¥RBÿVµVzËPRÁ}LI&·9Bô‘§©#oˆkkáŒ)Ï/„ aó2 @]ó2ɤô("`¯–*Ð3 !å•Úòrõ¨Ê8N} €=ùÕ¥åeŒUZZBˆ@®–0ŠƒœjµK2"ãw–oñò++¸ -ŽÊåÊW^‡3ª=…x"PQjü®A^&YA¡b⮺‘rÆi1è*_Õuú:…Iõa%„!õÌËTUùEèà—¨ã“Kµ,m'?ùêÒïP\ÞRY¦î®`HÇò"Z'” ¥ èò5²ÊR2T—$>j¥?À %ÀÞë%\ÿP+•K+‹ø®ŒÊΖk@0 ÿVyˆT¾>ó5ÅøZ“j Ù ©)EFªë†h4m^¦¾©k^¦Š 뿵Œæ5ˆåßZA}§¤ÔšåštÍ¢vƒ¨))5«\[\AŒ”–^y…õ0šo”"ô6•d\9|I‘³+‹ÎTtÔP˜€‘±Dyà¨WV0ö»ùJíÐ_ÉL¥¶¤øë‘0}¾¦8ÇEEXþ²\F›:ÿS!$„HÈ'e%„!uÍËTÕ~­ôû´¡ä*T–¡{òZ©¼†Ÿ W1hK”¥4AIP‘žÔ2EÌÖðRKÒÁàqz¥½…*t,‚ [Ae‰­K¥i©rhš…%Dx.kê{G¡BHˆh¹m^¦TÄ|]3ØyFKˆ¶B8Ò/aTjFŒ*õòZíò%TóË‹5ÚØ#˜>hWk—éc•Πþ½ˆ`Z¢èØreII ŒEƒ|yy…–F ‘R%{^Úã%÷¤Éáj‡|vüé¸Äý_˜a~an~û,~‰¯çqñÐ…yÙ™çæ.àas /\˜Ã„2óssç_:ñ"|w~8ÿÎ?¿pN˜“ÇŸ7•:È5(Ÿ„!ur¸7’ÒÐY¬†ìòkE´À6@%¿ŠË¡_ƒY}ù2ÿr†Kµ¬$ü¼R“~+ 'àüÖŠìüU´4jJ(PBKHk%ÜG*h4ïç¹'\w q!07÷¡Ïœ{áÀψŸ9·°ðá Ó!/|xìÀü¯,ÌŸ¿0¦~™£Np¹8÷Â……… sç-†‹ðPua¾³„øõ°„H,™„1GkáQ¯:èÑÓGã‰Ê Û–V*¸òíòÊÊ2uuäB+ ŒJ|CŽS\iW[–û÷À¨¼&Mór®AjQ¥²–w•´/2^¯U^Ák—QÒǤfG4sŸÐ™ê EÊû⇘?76vîÃcÏœ»06ö¹1vîÜçæç?ß‚T˜qlìÀÎùÕÿ%Bƒìè /GÈk½„ß",æ;â‹c™ÂÛݵ€0 &ÕLþ"BÁ/‰Ihy'þáœóâòqÆv@‰Oøsm õ£ZeyY[ÛG¦g'¸”¨/‘Uñ;KÿÙµOMσK¯,ãj#\¤úo]!áãçeªÔâkªy,„¯\BøsØí>|@Ê}îtöïšÇïPÕ9ð~ÿ €†±ÏÁÑŒ8ßΘ€ô¹/}iŒ¾hÉ3’ñBÄíšP.+! I‚ëÕf:^2 `,§N~öüyœ¥~uY*<•*•|)‘”¨âšˆ'jÕ¥ê2Î*|¤Ã"ªVpÁK¯ƒqMA‚`5ƒõP¡`ÁπଠER™"Y7îëpׂ‘–˜Û~þ⇠v>ÇÆÎ}ˆ:ûÜ<¨P :. Æ^ü!ö¹ /Ÿ‡nÀùûÜ—^ÄN?öÌ€‡HºèotÄ…hp_[°«„)i•I§‡Gþ^'•‰lК° //~rfúñZõ?ÆØÇŸXô£|àçÿ•±¿ËPB Ìý»°5 tùw"øÛ¹î€I_g e•²€0#æ; uVÜ.n׿.VMþd­ŠvZÔ¥Z©"W1`|¬š½>Nk£V ¨ѺŠjYýŽ T¬,†ªO3Ÿ¥l¬ˆcš›¨úy™^¯Tjméðy¬ÜùóX^&ô2ñzNçÁ˜F[¾§n?vaáüøT)T‰Î!8PBÌ¿„@«ìø†i™qÁXBø:“.—u»SšfµÊÎOlú'AqÒ }~•¦Š\XZ®-Ö@=ú¹ ©PHŽ¡„˜žþ4¥¢ò÷Ѻ:W¨·Ô*SÖÀÝPnW?ëF¸Üys÷˜ÃI4š7˜¿xqná%ÇÜüÜK/5s jnaá"M<ÿʯ|..à,MÂá,œžo¸ðïÈ~Oóx”©„Píés»?„)ùûC¨ôhA —)yZ_½H -«èe:R«bLM3sß=zŒVÅU?53s#ý(¼»òÄÌ}R.«þ,*Jpô4åìxôˆÊ½q„ SEÉó:Z(Ç—uˆm°¥V-šuƒô£]}FÊQB\¤ qrnwÚÅP‹/\˜;mmêëç/bXÇK8Û67¯Ž>?ÓôÅüE‰'èìæ6çðÐÍˤ5J›ý;ûCp®ö‡@ ±ÜfR—ªKäeú©£å?Iå•Úѵ2¢ü¨M¯c™hàñE8ëoª($\¥-Mé¯(ózúGÑ[Uþq¹Š®\ª=6ý ˜ãoù•e_e"§S,û·+ôŽGk:x;wΕ„¸H&õýù èýµ”g²p^ï0=‡x ÷ä…}^öñù9µEïŹ î´pñâü‚¡„p]_VܳÂ| A©*øªÜu‡Ë%¤móÔ=KÿPÚ•™bæÑc‹‹2ôTèð?IÊhEL¥ÙÚ‘½”h±ö8yŸÐ^>&Ý®d?T0UÙ®½«T~C›jr-Ÿý»—Êf„Ò:^q¸²!æh^:1ôü—~àñ«/ÉÀ¼9ŒÍ ž=wá…‹~´ªVçåìóç.hÐ}óxÜÓ}>aãÞŽ^&Õž!naF,EBº°N2Ð>©Œ)…Œ e]¬U+¯•Õ&p4[ð»¸Â­¶T¥,Æe<¨Zª]¾L`*Á¸Oi+‹+¯PØÇq¯†s8aWC«~Áµ¤a£º©&7Xñlée¢@&óz(>ç/â‰Úÿ„P€ÁåÃ<…³b—G¤¼¤º½oFÀ±óÿJbÄÔ†¬iÕÒJCb¢Í憎é£ñ „äz†ÚhýSp÷"fð.ãš7œŸXÂ>Z-гÒ‘0 %ÓUZ-Z£¬áÒ‹¹9à.åß—‘¨Už˜žùÍwHÄ^¦ˆ„à~Y‹áoeÿ&<\Ä®]Ÿ:÷iû=yNjFJI’q{sÁ¾÷MÏ]T!å&"ÉïjaFÝó2µnT—~{YfXzòXeéwRn¹¥ö€¨b¨RUe†}ôØÊ"­²“hX•«†hU¶¿Ç\9¶O5ç¼Ñ®RÁt¹N©Y”sq²€0¤îy™âBÎÃa½ü{‹ÚàMA4ÿL‹¬Ëå×¾R½ 7P©-k¼à‰Ë¨r½²r¹RÅ2µ©L\è€Ä\cù”+B¿ˆB®˜³y™RQ÷¼L1QÑVöb™²Í¤F„<$Ú ¯WeœŸZs*VâJŠÚJM}¸]Kq•ÉÑA&YäcŒ«íÝbeî³y™ú¢îy™:i>¯—iï ´{ÐUi{.ŠizíòÊ2Îqã"jLL¢c™2nàâkR­0™MÅw»Öjµn×|ƒú‚LN6/Óž§®y™Ú$„¿â¿ºüÊÒ«ÕÔ*“"0>ª%ŠøÖ±P„|·´\Y¤…ä¥òsœÑþvmnW'«|LýsZ͘Ü¸Âæe€zæeŠ ñ~Ž&ÿMZ¥ ϼDºj`èªwdÔJ•<²Z­…$Dya‰¯÷Õ~•'â|¾ó¢ý¹l,“)ù‰Ê‚]ΉÊòD)nCÐjW?ˆgÆÕâKÙá}=(غ]¼Á2CZ¸'á@G„À¬L¹J·½^, LIçej7ª‹¤2Qlx̨~ß7x³›hC…‰Ö„È1_}§UJ¤{_ó¾v×½'?} •)<šËúèpú\.^¦h*K‹1äF·*“!Fu0Õß1/Sn€Àiˆxè†Î ®”7×$š°1í„rü×°±½vÍQ*Ó‹ó£7ªç"™ûx(/“_r 3b:or+Šàs‘Ý®´-¯çDË=8'Á௪ ËLOå"‘ëâÂÙ˜èlúݶ(!.Á¨VÂ/¡„Åó2ÉP¿ºpÞ_Ÿ9¶¼X[¬•èOæŸÁ­iÓ¬q¹~¢¶Œ2–2÷™®ÛqÔxé*¥ß ­Ö¼EÌ…Aó2å=1gó2õM±¼L8.®ƒÈuë¿éMS{üÐÌ4&u}cJ”f$¬5×>h6IÝ—Žìþ˜ñ±P7z iÀ- Ì(dT»z…•f£±Å)¤„‚//÷·Ÿ‡‡ÂÑšV»QˆÞËzò,ú|Yó{«|U•ƒgúÌÌüXÏi3n¬„0% îãzšKˆ¸CR…çè–ê}·­¼zµ› \ÕßÒ÷3 ïÀëõ5Qo ø·Öt³•щÉî"h7Ÿ[@ ¯¬Ò+æÚ܉÷ws‡@’„hw/· åÉyhZu-Go Z”xCM‡Ïqzß­zÏTBH<˜›ÐަÄDx©ˆqߟ?¢” ¤A¬¼\ÙÐ\ávÚ Ëž/kîß÷}øÔ¥„ˆçeŠOCX@s‚œ®{cÞ ×QKwÈË$s_ä^.²"2†35«ã9o韄I ÁE’ǦøËDÓ y’®E)/2”~t£Éñº,\„ÚÖÂŒ˜ ~‹gÿÞ+ÜçÆ =tw½(ÇçÑYþ2—†f5抱rY@î!w„È7‹v\í„p„ƒ¸&ÔO¹—kíÚZ¦"„Éñ¤rY@˜QtY>_|.ó z/ËýÂsÆÜÕO5Êò÷õ²”,„ÐÏ-åƒg%DÂyÜ|õîAH§hã.eìYK5‘X ˆÞÄB¹Me"•½ÄæU%î©…ÜUOYzæz”å f¬]õ2èÌeÝó”®’¸÷;OÏ¿ê†ÊåGX@˜Sk„ë7ß^⌻k«_¤A)ôëHËãß×ñœûŽ ðÔ·ýpùŸ®éi§äóíPðË¥T9 CŠçe*&—“^NèŸ^ýà¸åÇݺúo'ÜgL±¼Læ%÷©i—ªGºRx]t1Ê9,.·féã<›—)-Eó2 º¦xX\‡G4Ô‘¸Í¡Ü@8œs5ÿrõùYúól^¦ÔÏË4h^¢áp6&á\eYÂø WgY¢ŒÝ)çðž%Dúó„ÍË”–¢y™Lóœ7×h‘.ñ‘qÝR>l¸ÖÈ¿|Cæk¸Ñ.KžnW›—ɘ¢y™ÎK4,îê],h Îw'RÈFÊ7ôçÇð<ÑÇùº]­„0¤x^¦bèÌIy•Hfѽò/ןŸ¥^›—)5Åó2”«Epžïqâ®Ü—Á·ŠQΡqÎà|›—É”‚ §Ã\8“–ã\P:æ{Yò/ßè9¼cƒœoƒû ‰é@W§Sæ@ò’p5Á˜ S¸Ü¨Ÿóµ7ÎJCŠï1W äƒCÉ‚„.9l³­„0$æ±Lù‡sûaÝ*&‡“ ¶ƒCÙçr/W^\Jˆþž_-“²€0£bߪw®\%ÍI‰Ê»\ûžŠ©2^%mU¦þɪL†TP£š¶”ÒÆG®Ãb”ÏÕû–Šév•¬„ 9 R>ëvݧÄ\ÚáV%ÅÏ“ôRÕÈ”ù¨P$·¯úPyhlè†)ÉìߢCöï‘‘#ü 9úx¿¨ë¤ó"G…§%ýÛ†nsß—u†~ ‘_~%oÕ[Õ¡Ëh;PßjþyŸŠÁé•¥Ï3Åývµ˜?ŽPÍ J=ZÞ¸ï4×õÿˆ\ÊQTN¡î,ýyA»Z@’¯™`½ñ ãÝh9½®jé p‚÷ò*OÑ8MS2/}½* amc SåÈGBøs Z:X ¯§ ´«„!å³'š¥ÑµvÞÝÍRb¶½ºQµc+x/‘m­îdñ@‘½ÈâA"ÛT=ÉâÁ!+ ÈâA! #²€x@ȶ’Y@<dŃ)Y@<d›È˜, ö?Yñ‚, ö=ÙöICûœ¬xHGûš,RRõeë¼°d›&-Y@ìc²â!=Y@ì_²íÒY@ìW²â¡/²€Ø§d¥?²€Ø—dÅC¿d±É¡²€ØdÛc²€ØodÅÃ@d±ÏÈ6Æ`d±¿È¶Å€d±ŸÈªKƒR&h[¡ db`²€ØGdÛap²€Ø?d›!²€Ø7d[! ²€Ø'dÍélÈbm‚ŒÈb_m¬Èb?m€ÌÈb­ÿìÈbÏ“5§³$ ˆ½N¶ò³¤ljÓ¶I~dë>S²€Øãd«>[²€ØÛdk>c²€ØËdÍéÌÉb“­öìÉbï’­õ!Äž%[éà ˆ½J¶Î‡AÕªmœQ“5§‡C{“l…‰, ö$ÙúY@ìE²Õ=4²€Øƒdk{xd±÷ÈVöð(«ºµm4:²u=D²€Øsd«z˜”) ˜¢]õ!z ¿gíýõn'ÿzppøK/êð;ëéÂ=FŸÕÁü»g=_`x¹Û¢sÙ÷j[]g(€Ð·ïøä]e׬ßFˆt¦þªÃÄ`™peãضÐWÐ&× z>ùÀB¼k]öYƒƒ¶BdPÊÆ³má_Áǃ þú½Mâ…˜?(ú÷Ö£¸ü ÇÂèú¢­ŽC&5BøÍ.ëv©„»³ä;Äž¦íìN?FÛpàÁm€ö²mÑÞy"F¿(m," Ûk.Ô—bý*^µ‘«„¼ýRIwg‰wˆt¬„³w“ïÝÞÙªL).eÛ"Öí—°† .”Øa®t¿UÂÆÈaþÅ££Kè*n>`7áàøb5ØvönB±#-§þ²µ!Ò\ɶE¬-•’M÷¾Pò¨.K0ÐtyšŽOÚ¡:]¥Ã¥ºÞ2Ü Ég‡dz±#2Dª Ù¶ho‹Üñ#Ñ1!¦š6‚®‡!40µ$ÖñÕi¥TUl~t l[´Å°%DÐ {«‡µÕ3Ó6[r#0ú>3@¤½Œm‹¶¶%:z™bS4B´e£\ÓY5Bûa‘.iwÛßfˆÔy Úâ¯SµE.€ˆõ„ä n!Ö±æÚ ¹ÝØYŒum„èIdÈ%·•þ}w7ùGù}Ö*Súkضˆ·…IKŒÁÓ0ÖÖÁ±ÑãvƒßÂÇ%4Ân쎱öaí$Yá;D>·½oŽ6AÆC6€èã¶-bm¿pVÝíJ‘{†ŸOÿØV ¡ƒÃÖÑ®_ƒúèx Dë´Ã ¿T§FˆÝ!\êD)ò®}øÉý\Á¶E¬-òÄž¦L†òá”,ïŒþ‰sj‹ ﺗ­]Њ Z¬!=l®ma!Ën"Ló+]ÞíÓ"ýH^ma¡ oñPʵ-, O¶^GIE'[­#% ˆ‚“­Õ‘R–Õm›nd+u´dQl²u:b²€(4Ù*5Y@™lŽš2­qÛ|“­Ð‘“DÉÖçèÉ¢Àdësä”m•ÛÌ”luŽž, ŠK¶6s ˆÂ’­Ì<È¢¨dë2ʸÖCër-åDáæ°”/ GGpáÂ?îºþ!YnÂ=¨<¬7Á™µØÇù@8y?ÏÞážãrÎÃ~ë¹ýö_}üAKJ@ˆ.¼o4¢a¹!w -@g„ŠÔç»"ˆÜŸgqúc²ßò~û¯>Ó¸¦$½wè€Æƒ4vYnÀ=ª7O@-R{¤¾KˆbÖ¨NË¥LŒ“1ÍU‰¾Ú¡£Q] wZq8ÓI­;ŒéÖí:Z·+Vþðp ÜÞ.\M"xû§I/Âxàˆ´ú¾EǰAï%Ú$„%34-i#èÝò—¾®‡šáà>KHÒŽæR~FåA‡ºŒ%qùÐ?Y¢_b‰µ‘oK›œÚÚ¿¢ö2I-9ªS=˜œKùàÄñ€õô¾#"Ç{¾u1À}$Dê¡ØœSèKh#Oõåô× ÙkMš:¬öAæ®Ç¹ Oj_L…vvøx9!7è}Û¿ Q{'ìG!El3Íu°µ%&æœhè÷qøàq² <ÈeT!‰¬ã$2¨¯/Sê¡Ø\ΰ„Ú诵ŒZõú¸nHB4ü‘N<ðœÂW1H&¨ë`¿ÌH= ¶¶–Å}“$DþõPtÞk,¹HB4ͯP#ð2ù³±<@àƒÉ1 Øs}<¯ þq Árá~¿D ‘= §Sɱ>ýufª- ]èTvÈˤB¾'ëeꇜXÅEôÚTWâ!«Z ¤u)a¹Ši Lê° A:“£ôW—»^÷Kœ©Î¿ŠÎyh"ÞF[Ößu}£:oråJá–c—gˆT6¨—r-®Ë¸Ë•‹oÀûFÁyAꡨ\÷Óð@k#'VMÓŸ@ÿþ…óÀr¹&4âÏ‹ ?Z¶Fó ÷MR™ò¯‡¢rÝO¹×¹À¸ãýô熟†Fº…ðCb=eh<œû&DÜ`£5Ïx” ˆôVùÀ÷‹K[ÿݹê§ÂŸ„Hh#îª>nПõïRiR€p|ä9”­Fˆµ–s9ù½¸ÁÖhhƒøµÆÀ÷‹Kˆ¼Ÿ¿è\÷ShƒŽm$R÷gåNo‚ Gu„–K<\¸Ko7ââ–cê¥ ƒŽiUo÷‹©Ly?ѹꧬkynšþìÆmåzr… ñSV„$³×äLd·Ž×º]Ó‘î§,¨¸Ä6Jן¹:4ÈËä*‡#w}Ô<˜\å½j Óu º'ÓaÁÄþï×îv-F=œsÔkÛˆÆ*/uæªÕ•—Iæz²™ûtNÏh7 uW²/œLëË.Jµ0Ès¥ç~›ÄvBøY7ô²HGÐþ3Šc0Ç*û‰ãµJ­Z­Öò§r¥v|fÕ}ã½7ÄÚ{®/oŒÃ¸² ’ö™sóó £ y›ùù óðîÜ5Ñ£|ÑíNQBt=½R?V[ƶ¨./C£äLËý©ë~M¸õ7î­ß[½Êžœg¾¸0QÖÒüÐ[E^þܹÇÖ>p0_{r¹ä´«Ÿ¹Ï¡I@½D5ÌI¿ºÆ)— Õ|©|©\.—>3ó/¿þÿQéš ‘\nÍךèB@Pœ›2-œ?/âüKç.~iLmzݹ|nâÒ®Ç>òZ¹\«U`„*c«äÚåCâ5š_o6®AÙšXÛÝË¿~}îKsPMHsÃnŽùù9 ¼Õüü¦\æÐ©|hQD÷‡à1áÝU<ç."çð±²*9SµºT­›Æ8O(oœÃë áX- ª%†Hª‘/žiaá‹cNïÝkâó=žç û…#—T;ÔÊ圛£V=ô_»u^ÿøŠÌ§Úëy?XCi}áÂÑÚã<ááü cu¾~Ͻס\‘Ð ­Mq…Ê›¯¸ƒìU„zþœ%4bñ30ò^¢¹ÖVÞF[ùë¨þâ¹ù9ÄðÇ$52‘ k6z”/.!z#1ûéÏ,//RE,ƒÒ”7úÑøc›êâªÓ«üø¼_4Œ¬=@}¥~/ô®)UTBÈÜCJ…ÕÊsª?æÝXŠãÓ”á¬ÞVÞ­„ ûܹ†?[â"@mˆåq Ñãø»_c£VÐct¾T=ô'ÐCî¾q÷k=žÓçìo_˜ÿFÕ º5 ­Ñ‹•‡«YŽHø·²ªÛmˆk {>®Æ¢œE4ªÌ¥òÓM!½õ^:«ó£F¥)FÔósÁd9ÐÓ&à)m§É>~¼¶¼ˆÆC¥ rè×ë÷atm¢ôZëÝ÷Ùß qÁ¹GˆÍ55ß\¾°—©‹ß°³~lˆ#U¬ûüÝLhNÖŽÏ\‘ž€{nO?ù°/Óüܰ‰…‹çÎèÔÛÉr»vÏ~øxIÏù·G lNÙÐßsï­óžíá½,Ôðw~è¡Ü~Ðî:_O(WèŸA^&&4Úá#å"À†E0ªµ €_$R½^ã½LóÒ×0ì±hNÚ)ÐÐ (¦]íªèTΔy™êˆ£UUµj9ïæ(úSšê®~Îî$¸”Ö£’ ècBã}^NËi˜— º\‹â»AùØŒÿlzÚ½ Äè1wU¦1¿lŽ á&¡„iƒûŠˆÚ¡,óJº\O”t§÷ša¬îDz‹ dî#/‰Dî.&E¥òñir¹ŽœÐ÷ümUÝ6N“§nâüÂI,›£·cO(gʼLõ‚¢|èO…? ­ŒnåwG ˆy}¯ cî®2Ë2ª»åeR9/+ *øïøt“â ÛúÕ%x‹Òœ FÑ  çɳåh¿Ç½}z•Ô€P Xxa ]L÷¯```C4ÃY7Ræe¢évš˜+ `T:2³K)Ðé«°ìx¹y !œÑî†*Sïr¦ÌËT8 ñØ_…žQ8=ó>mñƒär†$D÷¼LJBäíðV„¢|dÚo‚Ý]57×±üÚ†XX±„@CΠœió2 •Cá¶à½ËŸ# "m’šŒò2 cy‘}àøthTÂbjÄ'ä=ª“÷à™QMÌ…±‘R:š—©h€¨ŠHˆzÏòçˆárªÅÁýäe’ZØÀ¨¡Ý`Yg€@O_tTêTνîeê£-r—ár¶çer]*)SM>^Áy J¥\¡.Y®–j+‹ôÆìJ¥RÂ)³2†?VdKU«5ü‡£á§Je±V‚¤#———JU<»L׬Ԗª2P O¨T0œs©VªàÑ‹5œŸ.áüC©Fóå刄´Ùy§ò×õ¨4b@ Gk>.!Ê™>s{òÖÔ%Ô Öÿ"¾R]— –aШ.—àK¨ùJYÅÿ©úÄÏ5¨ìj‰â–k²å ©.]¦‹RûÀWKúÛ³FwÂóðäKÔ–òLléÒ¡$ÂDBŒ.Ÿnm G{]ƒ~n˜—‰ËEc5 (ÚXzµJ8Xúmª– ÖV¡³–*‹‹‹+ôŽâÐ…—W*ìðµÒÊ" H·|ÄßW 1—Õà¿—¯Ö°¹àÍÊ+R î(b£DXi“†Óu•6DN€Ê)¥r6‚°PA{jãûñÿ”Wd8´öf@V–¡?×üú¬Ô^…±¥B²ÕÚbeÛzúëµå xÕªPYyQà"p 8½¶´üª (\\¤tC31ÝÜTBŒ½Êé{™änÏUI\Ñ5ý"½Le á¨áª™pT_\º-ÿ~¹B²*&¬<øíòe8n©†UÝy†§ÚåÊ%Ä¡ \§_ª,Va䪑¢8ÿ2^žÀ…í¹‚ÐXY©´KåYŽ–;T~‡¼L9"2*‰„r¶åeJ~ÿy0j€¢˜ þ—°Ûb~ 듆 ªÎÚÊÿßÞÛõVr$‰¡É^i÷a| ð¬ÇêéYw·­µ4t죵Z°³vö7\µ¬ö’£¾íçaî 1}8ç£ÏñXmž1f 틸%À²^} þ$?T|ٵ錈̪¬ª¬¯S_yΩšIÖGVdFFFFdDäo—Ò¯c bv‚Búg|¸Bœ3A<{‹´@N3΂œqê[,ˆ;H2øu„·¡¸÷ÿGháæàïÚ!!pTCòŽ¿˜„P,êÔº äæ,™Ä<óÎrF]ø–ˆYæX}7™¼ÆeÏx< A;"½$&X È9ƒÁ?^¼\ô!(f2—Vô ¤gLBÐÎcþ ìèÀãø%åõüùKöt¸@°À…äü»ß,f¿{ kÔñd:‚œNþ Á Ó…ìGõOò³ vòJŠñ3×r:7`15‚ñ?‚/.7Äo‚ã¦o—g£±\†á܇?F%D.þ1ÄaŒaÿ+¼¸:÷ysŸr.SóCŒ¿ßÛÝB¿ »{Ð3cXMf¨WÀtroðá#\û,—¤aœ¢N!B“ɽ]ˆmLÄóè,ø÷‚‡P²ˆµé™ åo&´J…YIV¬FßONßÌ€ToÄóqRB8¸g‚× ¡íC8¤íDñ3ܮߖ C<Ø£$==ì~½ûÑîîÁD¬—N—‹Ùô{1èÅ8Ÿ.{zop÷#!|AĪþ„YJ0Ò|ôPÒâtA¢i)Ê·° z Âù ´`£ùÛ)¬ &(+Ë7°öZ ±ˆY™:ðÔÒ ¡á©æQ!?¡T‡±%Ódòñ€‰¿¦³áîîg§§B9ž Ñ ƒõ¬±ô†ó)¬6§¨mŒiq-b6ù‘ ÂØ‡ÌòR6 L±ðf1z+ë÷3ÐÿD•‚Ѧb}ÕêÑäÍo K&×óŠþ–,™8Šˆœ9ž»1÷k¡ç±è‡öᾘœÄ$%f–ï& Ð2GtØtñp÷éP2@PÈþÄ-Б&'Æî€B†Ž3æb]*H*žË`‹‘ ãk  —Ì‘sÆÒ¯m>Ž*Õù¾tÅ_Þ‰8d¦3¿„R­¶*ô},È)îŠùjo±xŒ2h<9À9LöP\²ÞÙ•„µ<Já.p˜Ï“Jµ:T=%žÆ Ý¿ƒ9Ú8w£ÃgÛv(þ†ðóœ¾y©èuˆÑÑXôâPøPÉñÑaœfW#žeó2‰%LJDåxo°û³{ƒ§CA‹=ÕKwžHZ<¦×a.'ª¡+˜HHˆñswW>”BþÐ4ö`8úîÇ0á=Y(íèö#¤øö &ãØÆ\>Üïì>ùl0x<ê÷ýÏî þbš Pÿ V¿ ­ 9F$„ïäæerÙ_é;ÕÇ8Ó À°?Æ‚ ¢g_о<†ºcr†9ƵP#ˆ@="B”•¾ï…ó2ÅÜ¿'“O„Ïÿr±?@Mçó?Þ½;„9p_ü»{0šB·âl?¿Æ=Š1„ø{òV¶0‡¿ï‰'ƒˆ§ö$Ó<=@áüd1%)r÷ɯ)f×ôXY×àþi1PN ptüìÌGpý› weW¢è8ÂÇ^A,°ø¿>^)!!<¹f­–—é¿ýwXþÀV¿ LL A 1p!€ë5ôïç@=±$ÍEBмr ñ?$Æ!þõþ:z…|óêÕ3 Ù1) #¾_^B$Æ{Á¼L®Ô!”„:„`±Jýw¢ƒ¦¿{(öÃÁOq¡4} K¢{»Ÿï qüo?{¸{÷É™`÷3tá‹ ±‚=ýû9¬gw÷ß‚ÞðÁ¿9ñô‰`Ÿ}ðèø»|GÈŒñf1ñ®Ò&†°q‘´2IûXJ£˜ûw"×Àñ ºÔmÇ-èrœìÙÃH¯ ½ø»$ŠHˆ*y™þ‡Ë>ÜWŽ-NEÿ;0sL÷vÿ9hgg8É `ªzSL“ëb"zS(æ X¢þôS˜´ž FúÉ_‰ž~ó™”"ÿ e¹`‰Ïf3ZKß6±v‹Y™ ä¡â8”‡rµ$¤¯øbÌË> P$ˆðä›oŽe’Ÿ>‡x·CD¬L±ñ^8/“• A„ÁÁë1¬7{û»ƒ½uá`wæ“búà@­L…Æ Ô.T¿Á‚Dókjà ±ƒ!(Ñw÷`~:À¥Öàã%ì '¯Ï@mühf¬‡BhƒÇŽAB\fäJ貓ĺôVJG’ŽŽ^‘ú Æòñ¡¶d:Da"Ká’ ‰v|”»dŠJˆdÿ–ÌËäý€¿×˜~d¾'–LËñg¨sí eôî'0…|F1U K3…€=!Kæ£oß ªA‚% UrØ ëH€Ÿ|"äÉ,]a¶æÀn>Z<ë nZÀô7Ck8h‰1 ‘?I1š_Áh?:|ù«ÃWtàÄNS ž_=;þæW@RŽ^>:T¶pš:4L`Ù Ç{ɼLÒŽJÑñO– ØoØ"u_t$¦°EËÆÿIÊ6tßC¥¨ v8“Pž½ÿ tî÷“ñZD-”0u}ø™T”Â~wOSª£›,nFÞ#¹A ñB1Í>ÇJSk!½ß¼$MÒîÉŽ|‰r8BˆŽWšhÖYÅ%Ú.ªåe:ć“ål N4B‡x¶n1èUúC¡…‘â ¥Tï~¼XPî~ò_þž–ºŸÿ g¸©˜œ>ž.ç´üë¹Pª„’¹T¦?ÊÖ¾¢E*¶‘Ÿ—)®C ”†^ÃYþ—/…³>÷ã£_‘¾|PA©Hù#¤DI Œ÷Òy™P©Ö$ÄdˆëUPÁûd4‹§OÁd·û)qöß΀î³Ç»dï/Çì£+ŒèòÁc± } ïí°§ÅZéíC”ß/>Bá|:’ÂyH¤ 'gËñÜ$!^€Ï%zùÁ&õúÏçðTšJÉ1¹óOÀVWGèº Þ—BUœƒ&%ñ[ûXy…Ïi—ÈäÜǹ—nç‹ëØ“‚^¾xÿÎÏŸß¹óüùŽH;_|}ôâ}!ä¾xõâè½çÔ›âÛÁ§ÞÛùëWÑŽþS“)=CB˜ñ,™—‰ÿÀ~2‡¾ÅÙîË >8¡žNÆÔx#˜ä§ûè½:Bÿáñ„\/¤GxÁÌa„ÔÃmÕ ÈptÿžÑ ¦0Ü|C§þÓ%êñ#R©Ç × ¯€Ý5jv…µªX½·´€žÆûų/Þ»Ãĵ£ç²sç¹XÎ IM´´yG&¯æ·?-)!t<y™6â¡Ùýq&AnÒ‘ü7Y.Ð5 dÑl1J¼o¤C¤Â•/”2öêðȯCˆŽþú æè>’‚0ðÛ+8ëá«öõ{;ÿ^\e‚`ïß òê}1—9è ê€g*EÌQ|ʘ†-øg¼……éeså·ùüœ5È6Ò½D‘ø4ƒëë„äÅ£LÉT² "s˜_OÐâ+¢ÅÏáî1 ~ÜÀâ÷W½{GHè£o»¼z§)¶ó‹/ßÿ“/ûê= Å—‡¨ŠÕ!_&9n4 áh— )ÍdLµ™!ÄÐÉåÏDQ)&è³4û^u,ÙFSÁ.`^ú)9Å¿iZ2ц´d®3„L¡($„6bhCײŸãBéož ]A ÿ1ô¿xö«_ŠÓ—búÕ\6Iòì}QÂL%t”Ø"ÍZ2y†ÌˆeÏ©ŽeÝPn^é>Fw{ˆXYŽ–§BÐ<=/9en Ðë×8ô%•äEø#ZÀ†Ü+dƒŸã1{H3¢Å—Çhºzu”Á aRrœÐ¹+ÇeÄTeŽRÎÂóù[òŸ-rð˜ýî`ÓxM¡šDÁü2ãÅÑ-ál2'§òä ‚0OºóRqÝPT€…÷îüDîWà#e€ È7/ÞÇYjçèå‘X<}}tôw¨Uˆ» „ÿúÅ/ßßù¿¤Ð>,cvuRð+çþ×! æd¡­£?Ž¥eƒ?g³ß'û¦.±0ô0…·CP6…/Ê3Æ|=9%eÎ8âþíæãŸÔ!þ#ê ì`ŽvA‹¯6Ðï£ôÞùúÕs tÎÈè¿Ýù0¸ ]ã¯M:²:¥1ijxÖ 72nt¥ZhJ˜ý¸ã;~†„Óü²6ŒÀxZ$UÍéoÿëD®„ô.YG`k‚<‹ù ¼c ìeVªyº¹Œ;N”!°£„„¸óÅxO*ÐÐÍâß—_#1¾øZˆê¯Ÿ½÷ïü-Êøùþö7RLå2D.žæˆ¹ÌtøQ+ Ùå)†N-ß@¬fL"pïAþ¹|’óÄîOof b©³³ÙŒ"§‹³³7#HQ¥šç⟢TßùâË÷w~q$iñüË;ÏÞ¿óÅÑØüŽÿî›?½#˜æÎß0©Ï %§©¯PB$Í™Jµ¡ŸýPBè¤^¬¤;fWðŠ„Eò“Éc tç{ ƒ]­Õ:€ëæIý‰r%ä)Óݽã툚]ƒ­ˆ—`UúJîC0²l€å^ÇíC|%mßxÿHákPÀß¿ó×ɳMÓ%á™ÄÏ´1çe”Qb!SÅà*O`³t"ýŽžœÍ+“|-S÷÷‡ñ›h¸:ƒšÑÿ „Ãý†â·Ä v1ŠH'ÿCÀ±|ážS´ ‹LH0 ÉÅÔ×H ”íðœ Õ¯ÉæôsÜeM×!^íðÔÝ¿¡ ¬Léytây™âü58‰M&Á>ÄÞ\.CÅüÿzLêòˆ¢Ù'côg“×ò5Z¼Çh—vqð¸¼;ÄÈéÉÙ„‚Xò%DàœeÎË$Í®A÷4 ÙV&¿jæ¾¼‚¬RBL(¼ù÷îÿŒ‚³Ðá6æ^Ofod¾+PŽQ]•Ñ¿?›N‰¡€2±ÖË‚Ž3d¶1Òc}£  ´y™>zÈ«feò¤Žm4 ð"Y7â3ÄRtÔ#ÑyƒûÚ³ûd† RPøbÐ:]ãÚ‡rmÌ Œæ¡SŒX_HRAj‡ dæ˜.F´ÊFK¹‚fŸ´`i‡sš„@©œÄ±¤•)Êb6‡¹gà1\‚ëÝÇ˸oà®2ìNLvúd¹À}è·3æà<9[⺠ NÇäðÝëÿr†Rz$—I°üô3ȵ—7÷â´(jeê6/p9r(C%…úÙ¿s$øº|®}ìîpôý†‘ìQ”Õh8Øý Ȳx —˜‰ãí =%s±>Ï)dq(] ÊWÌqŸ ¦`Ò!Ñï‘ü<.!ôàvk$„£²¬WÊþeJ)vˆ7KA‹Ÿ|‚¡WÀû¢"†»lüЇƒÁ#¬ǧ´1§ÉIðÀŒ‚ É |°SÑC §@‹Ï÷G³Ç»ƒGÓ¼}ϵ6É€ycNëoW?B¯à%KN:D*C öÇÓá._¿J×Ï}*wL?"¿'ªì»1¡×ª YŸþ¬Ã‡ƒ»LA£É'»ƒbâ2®tˆŽB—¤CTÌþg\÷£ný31è¡WEþÄîQ`Ÿ¼>¯;´G1Ùâ iÙN”§ë¢Š˜æö ’bOE?€;æÐ SÏ:DÑìß]Jµ/ÅïÂt>×B®ƒ2]BÅ÷¯&d ôyÀ;ÿîžtßùË{Ÿ²;óÎ>f這ÃG?ŠYëãÏ(uð!ÎLà?¡àù< ¡œ«}“þö$h8n¿D¢2SÿëÏÇ–L F ÓÝäìôC>øs1‰P&ÖÅ#ð9³ýà¯``?}<-cowð8ÆÌPmž@šÑ9„Q. iŽÿÁž Ã“‡âùO&§8éÍû±ó!x.þÝ1Ä?F¬a’#Th u>ÄUznÔDš˜„óÑÃIÏÀ„7Z,?†EÒàSJe¦ÔŸüA\ׂ<éÁÆK¨Oî þ• ÌwòäÆRßÂâxж"â&<3Ò !ºÒ7áYI‡ M3кÆÓG0}ÀäôHpÈS ê|‚ùQ0 ~1ßLjƒOÀù]À‡à áBO‡‚R> .ãZA¨öaËtŽa^Ó¤!|¾¶¹]“Z§–ÛUåÞ¤Clce¶!†,æzú³?Œv?]?øh¤xôH¬V—§°jÝòzð1ðÃäõwïPjiPþf‚Aî ò@ˆùé@ý ³3<È—B@8.OÃß&+9ÇÏ !œ:Ðó1+XIÑR:ËžÁpV;ÄD4}ú’Ì Í „u  ²gL‘–û¾¿þn‚!¦¿ˆñ,HúøáŸCLüÓÏÄêk¹ø‚~Ç gµèN5wsñïŠ!ží$ð¤ðµ“qîS¢XÎTî XíB>“}ØxH;˜áï w} ¶aú-(Ü{´P`²|ïéG™-®b‘ Ò:é|cˆ ¼Ui…RÍcã=v`J‰¼Lq8ø§»ÃÙx²xìC¨|ì)"<–ù€0UÄXíXÜÿH*ÕÃÙdˆª(Õ¢€þ‚M¡BK¦ry™Úfˆºó2áÆÜX߇€Ÿ“Å)ÆÏÁuÄC -@oØ=­aOö9äÈO~¬28="³ÆîÞ\ ü²C©‚hb¢àÝ9Ø©Èÿ2ªCTÌËÔ&C4“—) fa[ˆÎÌ&§¿,æúÁ>ég§KA:HwõtæO¢½Cü-³ÀÁNÔPzæé™ÚæñBˆéûE–Leò2µÍuçeòðÌpÕsˆIÄhÃ1äIM@¬E1‘ñ.¦€ÔàÑÛÓ'ƒÁÇ”d3%Š^=½Á4ÄøgB§€ë?‚ó‡P«Å²õ§CLF#i4žO÷&¢b^¦¢‰¼L 8}ˆü¸¯3–yYò 4I€W8èÓ³3Œç½Ø’'rÌ)‚qy5î$žŸâÙ*B/‰º??( T—ÏËÔCÔ— ³n`d¹” Î)ú÷Þà_>ËÆˆ‚E1ÀmN§å‚w<™ÓÉM”ç#Áuÿt¹ÄÔà`Âýãõ¹S"ø)V4º7¸{ä8Ö¢Z^¦6¢‘¼Lq˜P‚±9æ*YbrèÉk<á vÿÇ8¸Ï‘XRFé9¥¡!òœÂéB¯QÈïÜÙÙˬ1œÂ2y½?ÿvG ˜]Kåej›!êÎË„:ê¶A<¥éžÎ–Ø9§ÿÀN4Æ–,f§Ò?|LÔÂ÷) †b ¼{ØpRÐ|öûÙ2Xp=!—ü1l¨¢þtxºLº[VÍËÔ"C4“—)¨Ê‰^?áIX`\ÎhóTPéÛÑïG²8½)‚ψ٠Æ= ”‰ ‹L[ó^„b u:Y€ý;±f5Iˆ2y™ÚfˆFò2QÂRªqΆx…ù².í/𬭘”æ”ÃâÓǧäaöÏÄÃj¦£å¢§Ï`ØOá¸2¨ì[™cWènÀ&‚_¾ƒ ßS°1Ɔx—ªy™ÚdˆFò2%×Ib¤>ø£³%ÏqöZÆL/Gß'ò`¬ù³Ñ£È`8•àõkôÿ~üvJ†Œ)úBÍçÉTƒ„(“—©[ QC^&²2»Ïÿ™ÈSjhf¢#Jñ|ùØëïÁl$Ÿžã 5£Ùt<†éT•?âK#Ü“¦ èÐKZ- ;Õ5äej‰!ÉËŸíùÛåLÐb„n—³Ñøà¦'dÆâ;ͧoþóìw§ eˆÒ©ô£Úào(DüÊp®ƒC&þGý'ã"¢\^¦v¢î¼LJÍuOϘ/–§“ñkt3žá?#<¤t‰Ó• KX:Èf!Ùd>CgYI– HnTž1rä5³ˆ;G£ñ$¹Q9/Sk ÑH^¦Ä 1Ãpt1™œžÊð4fLо"ÂÇßAL.øeNhM Ç(ŽðÜK¤à‰rÉ#Ç©K¦Uó2µÍuçeJÆTC?ã >Ã^qüÒòu8Ö#}0_x"Cž2:\y4ŸNen§S)³™šçF¨OPPÏ_ÿa2[˜Ã!+æej“! çeò+M²tótˆ–![B$ñÿÁÂÕf¤?^-@¨óƒÛç÷â{BÙøÛ±áÉ=R®áJÍý•»º¸îÜgCD­L^oYþKCÓås½;Ò¿÷oT{¸u ‘<¸=p¶Hˆ -!@H97]&}±²wª[‡t ‘êMf‰„ÐÓ8è°Jšp§ºkzDnçùèw¸dŠâé&è¡1—tKÜuÉ9Î:†ˆùÏäáo„Pû wè¸s_¶û´‡çÅ-ìaˆ¨•©¸ûwû ‘ R>Lʳ©gˆž!ªÂ2D¿dj!ú%Ó.™z¥º9†è•êµUª{³k Ñ›]×ÏìÊÔÔÉìÔ˜ÙˆƒCnžuæ¼L©9³øáÁRBÀ m›!âëë8$ó2e¶1Ä8!!²ÁÂ1aúS³RÚê Žàž} QT‡@†ðºcˆx€P=:„ê‰îb^1ûw› u1‘èH‡]B¸žÌ;àt\­Äµ0„UK¦h6×€7•¨C¸VHtåIài<£=?XÇI ‘…¿k‘„0Œó[™—IH\&ʼ¡¶!)!®W—©øÓ`‡A"ŽŸ)/SV{ìbˆqB‡ÈÁ¿#†ˆ©¥ãë •™É—)%ó`ˆ…U •&¼y(!lÙ‡@ Q1sŸe ±X9s_» aÎíçA^¦ „Î3”RBIuß%„oU*BuO» ¡Ïž”¨bæ>Ëbn”ø[¡C\^™vÝ.C+“âl5ƒiÙšÕs–1DtVJÏ: Ø[’†Æñ x–ÌþíÚÇÉ}ˆbÙ¿Ûgˆl< ;Õf«ÍJ¶1Dñj9+uÄQ<7ÏÊ”<¸}½¬L^$ŸLT¦ÖRž¡¤€"f$|™,Å?Ч—ÄÓ3îTgÐÃíºëMLè–âŸÐ!’øJuèÞdÌôàªÜG°¹§w€ö/òÁ´Ež)ûOÏ22UÁ¿qœA¹ç<_âXÞ¬ŒøïDü;¾›ÀÕ0HÛ¤…纕ðo gnïZÖ 7pt2»¨Çœ‚úÂÅÈPˆTåþé›ïΪø·€3:²úÉc MK¦ôö87òïkçêÒKÒ àˆNháúðogÊNïñ¬žr¤vebyÌWsŽé`ÏÕÌå;iìPˆ ÅHUꟴæÅð.…& ¯|<½Ðèªá“^J;TéŸËÄÔ'@ÓXß—mÒr쮌‹´Ðõ$\-¾Š¶Æ-Š+™GçJå5¢9öÒ»¼Ä¿y*;A·Y‰²2ù€ÊãŸ7lŠ ¯Ü”çÁKà•qüã%ÎeºBn“„pí+‹´‰×ƒñ.·®B ÁeÖ O—àyá“ÄsuRÇj{VÒ$€,Tÿ"³R-CÇÃŽãø²Û¡Jy4Ÿù'™´èDBÚWÿÖhá‡YZÝðÐÎØ¡‹@œ¤‹_üP 7}V*$¬s9¼t“QøÜlÓÌÿجTËÐÁ-¿ò¡‹žqW6àÚ¡ZíVÿEZDÇ{ôÐE\1ÑÆ¬r×èÜüCÁsñ5¸AD¬Žªln)Áˆù98Þ…ñ/4+ÕAÀ#‰gÒìjn‡›mi•[IB4ðÏs*áß-œøxçúÆœ«å)Ë ð0XiJ-š²†: ÇF –@íȯ€‹Ö$¨ Ϫ·«vRVÅDß–R«›‘«ãß.-’ç h·gœ˜’È—†feµZÁ…ü~1¼SñooVJÉÄeˆ¢íÀ|íÉ>ìV­öªâß- x‚†œ D«ke›Í*3%DtbÍù‡ÈýGäö"xgà_hVªN•i:ŽW\BkG;H½´¨þ¯ø8JÁ¿%Zx|Љ•Âãž:ÛŒç–i3lQaÆÒ¯Ç9¢·WÅ?mÈÔ6‹R:†ABiÎliC»"-Vocq:Dño›f<`•¡t<·t]\ B–|—¸‹3¡™0!g¸àxOÒ‡÷£%þãá}îºÑýZ]‘ȨG•žäíÕñ7— I3ww4šý^:žJ³â“8…´`;ÐLâÓ ®Ï0ß¼ç´dhÍrÞÑü—Ò>X±0ÌS¿R{ åhž_ÿõ£¥”¹üËK½ow*ž\·2EÆUV ú+íþbíœþb¤­» i™sß¡ßôRp¡á}A7¤" øAc1Óê ß÷èô£ñO­ÿ\…Õº8n\i—ÈÃ'Ÿ*Ïéí>q Q¸p̯¡h»rhï÷wîËÒð‚žc…ÛQ „]j§,þÅë§¶‰æVÃ3˜± ø„§òâÊ 'OÇ—Ëb?Š9‚q©@L}çýsCDµk–Ÿç§yàÌOÏûTJæeÒzMæyb ©áߥl½9­¢Z˜Œ”tõ÷e°w`ªà ¶¿T_‰Ö6X{±¼Lirl8‹’k¯Î“¦÷¦ßÇ9Ý×™ >cv¬@X•êWlo(o£ø9¬H-ò-æÅßwIä:‰ùY:ƒ'ÖµÁ y™Ì¥:ÌLLî9ÌSà®åŸ‹»Ü=ñ3Þ÷6Çzhe˜Æùy~.¹lbcß)™—)Z¢4>÷#×Áääç¾ïK 2×uýØ}TYÏßôARñ“âã¢ÁŽGdÍÕ¯éYy™ÒJôà½ô8ÍzW—Œ‘ûõw .Ì^Æ{bV»v®Ôß` Œ Š„„(‡WÝåŵhwyÝÜwVk/d£ý}EŽÕ‘þÔ²bào×@#qGù•ÉÙó2ö\»¥Ì Ä꯿t^&s©ž„Ù„Ÿ01Ó “õ‰ëþÜ9OO|‹ùáßÐÆŒ ÁTv„||š*}Ô!üNɼL!^`fõiz?÷µû¢w#§•R207¡ 4…sß‘døG¤ˆk\\‰4÷MBdçe2—Šo1ìæŠf6g« 1CyWéï;W,ò·™&£ Q¯ÚK˜D¯.®šûŽIBxï»a(!Äüv}¹/®]çÓïâÚÀ¦SA\¿Œú X@£W¨CÔ]…ò2¥æ×Aëƒv)?ÊÉÌwÜÔ÷ÈÅ´ëE$D>>M•mü6WɼLá{î9C Œ¶ßÂû>óÜ||Q¶s´x»Üõ´ë¸…}Fû0¼;:ÈÃÕYsßÑ$ÄjÚ‹öÞ›,+Shÿê‰Í“VÙ˜ê7lÄë_µÅ,z0º‚¨/ œ„e_ÖÆì#EtG¨NHæe ÖRY'¿$KX~b‰‘®\‡¡VSì^„#dÝ22„c:(æDXÊ=u÷i¹Üs¡µrxÆPùv²ß+Všó2e÷»Êpä™ñbn)|Á-Ú¿F¿2-²½\ÜqB×°>!ø”Ü‚öÐiÿK:Q¬ÒŸ8ƒçžPT­¬(!ô7¡ÃÔ\ådïCx^B¶xñU«â‡ÄûᎴ «±ô=yç |þ´ç²qÊoe“;«Hˆè~¼Ârø:ºs8^úì*~ˆ:Z +Žƒõb|Gþ#T ùœû‡†¯‚‡VíK%ÍšéÜ—µ¯œ> ,¹ŒK{6Úœ2ßR &Ëð:ûG?$*£õ1ziü‡¾ç.•`/ |] æ…Ó*í”–ú󕺨$•åàs’ý„¿Ân.‹´/Õ¯,"¾¤“ò¸ò6òYj‘"ŒháÜ ô²àk;XÍ×$—‹h¼DV©9ñ Æå¨š;è[Í}–ó>n=x^°Èq%{FW­®.‹´÷Á“±t-PtcÌÁæ¡€R ëŽ0 â‹·O–búF–x¯piȺ‘ù<ö¼ï0Éð†úB·¾bx8œEèšâWæi #xîG€Ž¤*½ÂØ Nµ¸“AS˜ÛhP Þ’ýt£Ü"jïíoGc}» ÜxŽÜúãE–2ù¢µiò-ÝÖtC‹¡ø{´üôp© ®µ _Èšç1|Š­SÁèRqi©%Í’…ڔ̕­-ù^Ñ2¡Tg?ïÓ–Ó²àÅî«eiq:ªe!õoª×.{Â÷¥‚í¼s‰7¬-8Ѽl?qÙêÆè€æëر¼å¶ÒÑ­!\ȓŠ”Ë`żU. ä‡UmÎ5lÁDÂŒ¼ÄûjYNcTÐ&^r)ï¢â°¸© [× ])%óvìþǼøÒÖjH/Å ÿ+ÉP§¯ò ŠçoÒÊ)BŠ-¼`ã¶Hÿh™yYýº§_èfW .á…KZÃâ|„¥nórêS®v³ÐêIÏ Ÿ³P[(ÌÒ™êËo'­Ô²ï-!¤yÏ»®4'{Á•È}1Wð2ß'£53âs´”z˜zŸ4„L!m¢Li~éþ„ÿYý–šÙU†kÄ üæRU•3\ÿˆæÝ t¶Øûaè2hòÌÐD^ŽZàY$ëŽ#ÿ s£—ËvS´ŒÜ^½^—•ÁWÑC¹‘;ž«krú@öƒ·|W{®$)$-Ôæm™qÇ¥*)rÉäΕY9¥¤:\¦¶¼(Mwy>.béõ`°4Üznúw= ùz¤ây%g£(!À(‹3Ó;—»yíüÄ7Y¸µ—ýüªeÔM$Döó®ã±,|çɤ¸ßPEBHZHGv~NØÎìçW/ãûÙÏ£,>ÉÂ;û~æ{Ð3)bXêRÚÞO ´päÜ_¿ | :D\7ÔjŠKNÁ|þi%äÓ¿¤ çšì0È[x÷âZ='䆿Tlªž…ø<3à"í¹`/¥¤3+MÏ»ÈÀ‹fW ºTAø×—í¨VÆ%Dþ{¡mÎ|´œÒx\ -œk°¬B¬!ƒ=iQ?–I·UKÞ !·ØÉ8­Ä•5)ý2ëÈ9£žhÏ£nÇøû<°¦cX £èå´ïR†©ê½¯ˆ€ÎIûžÂ׌’'øúeå2.!rž—Z[z¡žñ®ð÷U{9Ét×7»3_9Ã8uÒÂËmoÐn\Ù×ßÿ<ؽñÜÈsJÑ!¿®káš/j2ÔãyZ"”´56î"ÖF¥EY[²‚ÏU)yY"PãÒûu5¼C«_$éƒÄ+<‘­Š2m¦EüØM8jš¡ö@Ûµ¸Ýr$ªU–LŽ…6›ÐGEÞ1Ô£,ˤá‡~4ißåœW_¯jTp x&ðƒ¿XØ¢âýSÚÞgÈíšñ<óRûKpòe¼Á®²ú: ¿²€ºÜ­•…í®¸Oîñ&ì®Ú+äeBÇŒÝ[‘ªU›rásh®,W ]’ÜHL¯^;¡^+8-渎oˆ7—*?g>¦Šl6OQá¼LŽŠ€Î¥S$/“á=Pð•!܉ø•¹aD[7CëO­ÝžCf.W9lâR®J¬š— Ä—áj,{‘£þ/á–Yܺ'%Ü\åÛe¢¡h&ófãyŠJ9÷å>XWñ,éPD³nˆklR;-T¿¦ô§£b3Õx ó/§?¼j15äeâJ¯“£Sʉ|îÜϬG/¥ÓVäýð{÷Ê9j™˜‚ePü{þ9*Ý籬¼þÍST0/ýc¹õù,œmËá#ûž©ˆ07QdIh(Çj¦…Úç~&~¾Ön_©¨ ç5G^­šR]./åTÒóáß Ì”Îuè4†¹} 8qyW°µ¹./Cþ#Çwj°ð%ˆ ]™Íù.¯.ÿ‰ã]_¶‘§¨˜sŸ2æ:ëA—¯€Ç…wA¦ô4ýÂ¥ëK07E4Š{µÓâòR™’ÍΈÞ…æÔ'h!0¿q´<_­çe7\ ëR×É™K‡dí9× ²k¸%™üüAÿ^í$À‰$ÇQ<ÿO˜Ñ.€&óÎËäâFg^}ÇxR$/S¢Ýçr¶T™šÐÈJÒž« ¬há»a–óø`ÚßœÇôîž+§÷jôÐ$Ä*y™´l>ÁöŠ“¼ŸŸGçœ<`þU§yGïgê, –SSùæG£MïÑÒÑ5á…™ÅW¡†óÍË$¦Êë‹Ü|K~Yñ¶!ù‘h=e¢‚>P›µi¹Qª‘ž¸¸Ò3$Åñ»`^¤= ˜Ü®\µÿõ/¯—I¬cO¼€³¤Û¶#C‹"×=WÎ/™õy' $×Ç^â¾ïdAî—Ê_ÔïE6R1 Cïây˜¸ãŸ0Wå“h:OQñ¼LÊr”W/h?^i<äÑ+Ø~÷Ü‘™2:J˜Vï,½;W'…¸Ÿ‘GŠã*CKždJ•îµ³¼LñçÃoéWLOD·¢À³ù!ú)s…;¬|ÌV"‡é6%§áñ ƒY‹å}rå~Ža>XIp§½§²3°ÊÇÏ”›§¨Ù¼L´C“Ž_ßs®òÉíÐÊù‹(3 ošž TSc)N¹_eòvuÜÔñÛX^&ü™®+½ š—)žI·nç­é4‡.–ìÎòTHy#æ,—Öî¼¢‘¬BHy°Ã—åW®’…€|À‰³YÆûe|&bL¿ŽÇ‘f9]ÏKdݨ râ!œ”~O­NÉ4¯Ì[露Ø0-¡)@ã"<‹°bb¦`ÜkÂÑ.…¡q0ÞôX¸tc^j5•T¾pß]‰Át”C™1°øh†e¬ rÏ©.÷-ÎT´J©¾N¯/ðsn–žœ,‹P‚cšl9ãV£70„y™èÒ"ßäâhÂ2ß.# —–èʹBÇbsR‘"Rd<7Û=9äâ"õ^ÞP¶˜±[ó¶¿M!‚tÅÝ4Éè`#¨ ^^ÌA¼šÛw1÷ï¨A»x½q7öÕK¥²z¼9ZÜàwÔ%»]Žºp—×UÚ§+ÕdWŽ•)æ)Nf"ó}Uc–Y•¢ÃrÝ5yp<¯Ð!(ò´‘-RiÚÏ5ËøœÓ\B‘ç~x½ªYÓ1§õ›tå,î¶I›‰nà]Õì*ñtsß`jÜy<×Lì‡FrG;‚¡øq¦©¥J=‚ÔK/™é:Ê=ií¦¾ïH3”—ÿøŠ°ŸX)úN.n€¿>³ä¿W¼4mÌEî—¬/è¶ZðŒÌgMÒBΦyøÄ·zC¨Ö>iÐUV¦ùk•í4–ÏF†q¨óÈ-/™Hføa”ç§X~!™7¯GüÀU jÆ·æò2¡Œ‘3CáüBNpNTV¸Ÿ –M‰ëŽéັÌ})YÓb3Ž ÂyÉ ¤ˆIçÏ](Émâú—³P]Ë Õ ÍÊ$gD:º¸xr¼ŽìLÙØÖG‹zívå@Ž})1„ÔÏÌþí¹a h2ëµwògæ(C;˜:ëF¹{Ï+ËGZ2‚”ÒñyíGPЮã;%ðhªLÍþ&^pKôay®ló5ã[7-0G r®+’D¡©Òuµó!ÂO3²C{ËÞ-×½×¾â\Ññ¼ò?^ý¶‹BY¬U‰¹ê% êa¤»×–Å»Þìßxøñ5Üà];…뻤ƒŽ¯¡—Æñ­¢‘Õ²w×W^˜Î‡à’S¹Æ±*U‹t.ŽÝƒ(ó=¾§žóO(ã„Ö$¿“Vº¼þU÷puÅ¢x4U&•Y=£r­¬üF1#»§ô¶zñ­›n˜)ØoßüRíwãúFžqUÄ…ÄsÌÚÇB+Œ“]ü¼)çdÃ¥£”2y×B„Àža˜uˆ´=…<hqã$²ÔÖn½´¸º¼ò‚3„º-·«šßiÐË`Ç”©»è}ÚÃö]jzШlzŽþÂYKeÌsLß‹—*èºj:}CpÏÃÜÖEðhª4HÙï$½ =Ž_¦¿$•0 ùõã X£[]=´pÕ @ÑñÒ^ìX»šs_àä¤6:‚2Xº°@„Gî{ÚÛ)ñÄ–"Úó '8oØT_¬t¹ªIfªN†.dúFb<+MsÔb6‡U¶¢âõqíPÖÞ8l^‹2AÙ=Ç8^Z,£ ‘›— @m¥mTšÚvyã[e»s½UâWªP| ¢Ñeumä®Z¦åe’ÛÓ¬l}AënI5T˜jÆ—d•‚hÑ}ÿ‡tÀQžŸ—‰Þ‚ÜžtàŽåµqèH--¿ ËÊ¿¤ü{}\:Q2`â^-‹E™ï6U¦åeò¹\¶( ?çÊ×ÿ¤lÝxû'Õ6L¬+äQª»,œ— æ/ÈùjÊËDù^õ¿ñ×”\^ q­j[_êCȯH™ºJ’" …ë)‡Ánû_µG7»* á˜òÚ¨õ¶2îË\*“‹Déy„ruO¾§hàJ—Ê®Ûmg(Õ¡{S<#EMs7-cAh”gÖÀl¨/GËË*‹>·AeâXÞ 3‰œNÊÖKYOÌtôµ4ù–´ßš2dˆ ‚ÎóÌÇ.†:N¢Äߘg¸{&åý°Ä ›üç6­4-™iæ(Òo±~¿qÈŽî¤Þ—tòEÝï07Gçí·£¤¬ªanW•G‡JõŸù>õ=R’sÃsDW¢ôyN=ÊÚ¥2êšñÙ¬Ò|Æœê÷ÒõyïÃRûùÆ R 3tÞ~›J'؇P’€J\ñ´ûj›lU®ñ}דÄw¼Œz\<‘Vw~:>›U&­L‘~[¡>\ §öŸã©u­·Rý›\rÝÊ$)À¥’,i÷åüÎÔN†é9u‡¿MõpJYnïœÔç6­ŒKˆ¢ýžÞJÖ¦Ó8†’ •¯SKš·¥Á3„É„lú}ÇUbÄáÆz\K‘”Éx’ˆäzÐyuÍpò­2–#,©r© ƒÇ"£ªSTçí·¥Œ0„¦B”5»/©E—é~0-Ñ9å)õD¡ÕCC`áÈÛX–èb å˜ˆ"o*GØ.­ioŸÛHC޲ޮ2üK Mˆº9œaA¸tv-¹]½)”0´ŒšNx) ¯5ñ&zràQ³¬—άks&ŸâMÒ…à‡.2:Yí*ÜÔ÷c¨•ÃÍF°ó ]¨f7Y …Ô'‚Øn©Ÿî·ºšXãSàWŒ#Ö¶ÿ£-½ WŠ™&~ÙbÜênjO5‚_Q±¦ýÅ¿àÚK­ˆO›qk¤­µ=V?zkÞ‹74V–x­µð-qk¬±õ<¶òó©õl GTrÎìê×nBCØÖTmò°lÚ¯WßGP_ýM–=wÉy¸Y¶ŸéPÒ¿V}¯·±2â qDøÙ¶âZ«-Þjm©^Oéàf؉ªÍ¶øº›j]Eë[S`—•©{÷ZñH}¸ÚêÕ,nU ±¢½;aÉØ¼þo¹*ûqk ǧµÐ«Ú»×Î’ah³]UÙ[cÐC´ò†þîZjص¢œá`d/n¶Asx¶Ê ƒ÷š n_Ô:¿Òn¶Aƒh–Óê°wGjXÔͶuŠˆ¶p³ ì@³.{·%Í)Óêzk,yÝÜ,+ÐlξgEóouXe]ãØfÜš…æ”êúqX¥*‹©Ð fõ4ØfÜš…F¢ƒMVàŠÐ`BŒÆ­ah4+˜ a+ØbÎX7܆F¢‹¼€æ9ÈB2´:èVˆíY¿f¯~0DJ}öÉêv]¹¯õ Ñ%­0„ -m¶Ù9--ó¹¶q³ ºF°¾ïºI#Yµn›qk:F°‰Ï7`lqà ´íqkŠ#ØHSZ·w[B T·µÄ­y(_.b]Ø»­ ˆÍƒÎfÜš‡ eë;¾ýQ×ñZ ¥Ú[E¯~ŽèŒ!:§J£°WíÀÍè¿î$DçºDûš«"¢ó~ï°í>Þ¥½{c§‚ÛªÛõ]àf t‰ößôw«EãÚ‹[óÐ víïÛ~¸¯Í“°Í¸5e3¾ÔøKŒ›ÇoÌY.Ê"¸rk:ð@µÆ›­ýV݃颣æXÅíRª£¦wâ}Üfímã·F ÑFf5K›^QDô ±‰¯>ãÛÅ®5UÞ9CØÎkv]‘%ôüûk;0z¥zl?úEO¦ÊF9¢Á-I‹e£í6×FŸû! Däý†9¢¡êë¨ÔfÜš†òÑç«öU»Q•n[8éÑæAg3nBY†¨s”XÌEŒ·°ýy^ãf”µÖoC¬!GäUÚ%GlCÔ Žè²Ùëˆ[S°Â>D—ßo¨ÖZŒ_YdÛ‚6áÖ9¬0t:ý~#µjêB™—ê•–Õk($Xnbk·®¡|Ø@e§ˆŠÔß*¶Ò[5+Ú•T³’óxY]°Mܺ†ò¨ÚÎå P…ÅD%,JÍSå…íáÖ9”ìGUTÐ%šæˆòï vdV£˜XÙb±ŠûMÉOµ„›Páíò k90¾ã…Ó ¦óUÆwÏx¿»|wjz]Æ×<7”š¥J£¿"C´‚[÷qKvù:íÝ¥µ|°þŠŠöÄŠC®’„h·ÎÁŒsÃvyC¬P}¶ˆ|¯æšX‘E«öÕ=ZÁ­k`©›´Ë³R—KaÑ…€hl8ëv%‰Ze•Û4nÝ˸֠]ž•¸Z´ÊÒBÆb†ˆ­Á™ví¶–åHUv 0ˆ¡¶¶K¥ m¯®®ZOWkIISb…%+khH6F`Kˬ6GP[¯-¸âÝÒ¡]~u‹Uë;Œ W§U5ôU?d´žý$jë-dMìÜ.ßCÔM¼õ -Åy¬/D{£M»<˾^nÇpc|åF®Ðæî í8µ–úGmµ–}f{w;»®9UZ<š:ˆóXW`)¿×Wkù‡Z°w7äunÛhê4Îc=¡†¨¥ªíÝ +À¶@ãûI3Dƒ¶ø nÑXja?ió€­¡Þ:¹«v[üv1ÄJ¯n«˜hŠ!**Ö‰ëµÅ÷ ‘ófqëš® »|7}Þéñm5±óý¤õ„Úö?Sk®ã©.0³¯îXXç±FPr¬LÍÖ.B›\0YÑfûâ<Öšcˆ[[†GJ“ײö–Q° 1mCÃá6²DÏkÕš–¡ñø¦üª[ïôM爞!*·¸[3dÛ½Þè÷ºBÖî'­ØÀ›Ä  ­tk¯·¹[`—o§®Yb;㺕é¸u°¥ÍÞ`)ÿÇWL9n€Û[Úìm€ˆºê—¾|7Àmƒ-mv=˜¡gˆzР †0¸Ä3ÃoéÏDë¡!h›!êú^†0ßí¢‡,h`P(~èÏDëaý  †èÏDëam¡9 u‹IüÒŸ‰ÖƒÐ8Cè[¡ý™h=Øõ†@…¸ Û¨HÝl¨¦/¦Œ[¯[y&ZõBs ÑŸ‰ÖÖùgÛ [76)eJõC?zèAƒž!zèAƒž!zèAƒF¬LÚ®ZüRâ›HìS¤´$öf|ŒÅßê¡ ™]³~­Â¹‡æVÝ3DYPó€høL´È¶r&ZõC½ã ?­‡5‡Z‚îoþ™ð°¸»ã?-±ÜJ:-\Ÿz¿ŠBC ¡MôQ—¦äh”¯:Mý™h=453D³g¢VL©K¯ÞÁ¯‡U vB°`5¯ëÔÏDÓ…J&ZMÀ…:Pf™ö°½°~C¡Œ{¿Ò  =ô AÏ=ô AÏ=ô Õ Á2þꡇ&ÀêQÖ3DmƒM£¬?­‡ÎÁ¢1döð‹íYçºöÐC°gi^K ?¤¨{j&Z=£(⬤{e÷g¢õÐØ3ŒXÊÿñSŽ`=T‹†Q&ZÝC?ŒzèAƒž!zèAƒž!zèAƒž!zèAƒÿ på´ÂötIEND®B`‚nagios-2.6/html/docs/images/host-dependencies.png0000664000076500007650000002154007436604450021461 0ustar nagiosnagios‰PNG  IHDRË2“©9tIMEÑ 1(r pHYsttk$³ÖPLTE)11)1119BBJJc÷ï÷÷÷÷÷ï÷÷÷ÿÿÿÿÿïïïïï÷ïÿ÷÷÷÷÷ï÷÷÷ÿÿÿÿÿïÿ÷ÿÿïïï÷ïÿ÷÷÷÷ï÷÷÷ÿÿÿÿÿ÷ÿÿ!÷ÿ)Þ))Þ1)ç11Þ)1Þ11Þ91ç)1ç11ç91çÞ1çç1ïç9Þ)9Þ19Þ99ÞÞ9Þç9ç19çÞ9çç9çï9ïçBçÞBççBçïBïçBïïkµss­ss­{sµs{­s{µs{µ{{µ„„ƽŒ½½ŒÆ½ŒÆÆŒÆÎ”œ””œœœ””œ”œœœœµ­µµµ­µµµµµ½ÎÿÿÖÿÿÞçÞÞççÞÿÞÞÿçÞÿÿççÞçççççïçï­çïµçïççÿÞçÿÿïç­ïçµïççïçïïï­ïïµïï½ï÷µ÷çµ÷ïµ÷÷B÷÷J÷÷R÷÷÷÷÷ÿ÷ÿ÷ÿ÷ÿ÷ÿ!÷ÿB÷ÿJ÷ÿR÷ÿZ÷ÿ÷÷ÿÿÿ÷Jÿ÷Rÿ÷Zÿÿÿÿÿÿÿÿ!ÿÿ)ÿÿBÿÿJÿÿRÿÿÆÿÿÎÿÿÖÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿZ¿/«óIDATxÚííÇ}ÇçX æÑèIUq"ó"ΛB¾‡âx¤ª¼°H‹Wp‹JHädWèÔIê&0êq¦©cÄ/ì. óÆ ©G¸i n¹ÿ`gf8ûD.—û0;ü~m‘ËÙ™Ùùý>;;»;GŒdDÊŠ/²AZ*oÆ‚I—þ4R>E6Í\µów–^ËT³mÛ”K(oÅfIÝPþJ²Í& ¦ÛX€LXñYr„IÊËõ+ÆÁ‰K)¾áÒ/áúEÚ,µŸ¥w8ëü¦©²óÒ\wxL=ßa‡÷²X™Ž.OVŽ •8ËHΧVô€ì<0©;?ŸÇÍMè¾¥¿¥¢¯•.Ètº$^†Jže ¨ÿ—U‹½ÙEjgiHÆìwÔzìÉ=rºuˆe 7–+,°Ob\/åm»•èµ\·¤^®+_3œSͨ^úí6V°¤F´Š¹,(,†kضF:CÔßµ›•ÒbI|õÊ ¨Ñ…+}°<¿ƒ«)On¶Ï,7O$Ã{Jˆ4deæ¾tvùý…£‹ èbo-ûn:,M³eoxûÀ¨,=±¥üí@—wÃ"ùÊá-lÔtr¬ Ì€Ú$³¦™ Ë€áK–Îoš:øDª,á‘òŠ–Î°{€ ‚/ K¿é?ù¨ƒ g)Qovž C6Vì£qÒ¹Ëêɉš ¬sRX¦dÑ«¦ÅÒEƒÊ–ÛvEf)x—œ1"ÅLWs…ŦòdH&¤Xò¯š!8#Œ¥|vÛÞª¹.¾¡Œá¾è±â{"EIç.+q÷Ø!–e¢4XÖÌÑë2ÛhêÚãÍÎùAC0C ŒT#«’­ŸÎ]6©.¶¥&*S¥0ö‘­ó_BÒ-0Týu"-g¹V:oá c¥øEféí­šéóÓ–Ô…©ìîìYš|–±ô]æ™e̓žk®Õ,IÌzYsG¢QYFJç-k Ëk®B²$KbÈçîj–AíJAC:U‡¼œåZé¼e ç•9Ì„XÊw>|§§¹áM²’% ÷$ñù;3–a—+ö}hl&JcÞG •š-«ÌÒ]ƒnŽ…ÔŸ›u–îbWy"¤3\'§U(_Ëû‘•Ë 1«ßò°‰ü½kKŠHC3dâ‹/]-xÞgqñT¦"ÌûÔê%5Bp¸B‚º“`”Þð €°HÞr†)k¥3ªjhéŠ}Mâ¶Æ0¼ÖfjÈ¿‚Y®¨5we2<± oÊ€úµ8ÍBX¬LgXþÓÃu›¨ sxþ_ÒýI{°iÕÃå,ÏñØ»j‡¥÷Îëøš´*w6Çul¯mùLýÄ?œï¥HçÞ:'hhÖÔݶK±è’´4,Ϩéèªâ=ô•ák6›Ÿ:1Šº±uAç< ý±Faò{>Ïd?œH©3o¿Š bº,ƒTL—€eŠé° \¢ÀR¥>K}–ú,õXê#°ÔG`©ÀR¥>K}–ú,õXê#°ÔG`©ÀR¥>K}–ú,õXê#°ÔG`©ÀR¥>K}D®ù§ø˜Ï'“ì p}=Ÿ‹ƒÏùGvǽÎÁÜë‰i(MÜZ2ŸSf’™ïÆòcÏm»uxîmìµcZÆ'Ò<‡cšÇO„Í™Ì*i{4S™UdbÍ·ü¼¥cŽœ\__gn°á4€ ·ƒdBÙ'ùéö~úôÜ$…G'Âî}²“½Å;Ö1ç× Ÿ¹ÄØŒ^ GãÑh<ÆãÑ4SGÿËkˆ3þÉ„&ÿª^™µ£ŒíNGâ¨ÂîÄY–®¾f™GBâ8Ùêà›Lû,ÇÕÁl63¶v6›ñZÃ|“´i„Ù4θYS~„ÌYNÅù™é„u—Õ;xöörÇÌÛf{”4KÖ̘‡àçLæb6å"~çÄQ|¾š¸Ý` –` –` –` –` –` –` –` –` –` –` –` –` –` –` –` –` –` –` –` –` –` –` –` –` –` –` –`™K±O¼ >4Ë0ÍFcûÔÙlÈ‚g£Åþµ_NUž%ÓX¼7>s'àv¦Cæ6þž<3|8Œ`Ž,ÍÂñ‚¾˜²‚mºÎî¯gæþ å0Ι®6Ë1wŠqê:WM_MÅl×ÌÚ³òTηµ 9þzl¾ ?šù?!Ǫ©½_3–¦¦|Þ ¥$3¾Íü0ãvÏF¥¼ûKÞxŒDK"V60[UÊþ güc*Lµ«—¼GáçíŒO§39Üü˜½`ö¿Î"®ö'Kû\óº7ã¿Æ¬­ýƒ8E¥ä ÿgFЊåt4µŠ]f‹pñÙV%%Q¿¿E‹&Etfˆz:ÍÌx:Œ5V%?Q‡¢O´ðI{fb—áx<«½ð3\a–6µ±ÙÖ°­¡IÖÞ' «€ub),³}1›- ´ìŠ–UœÒ3y·’,í³p8ܹs5ÜùÏ´›%¹/FsÃÑ}±_7–£é ÊãÞ¯~2G> »î܈õ—¢ Œsûˆê7M¯˜M£áAõ³èçÍÎrøÇRu`6A¥ê³µQ*Î’ ®ö¹]ÕO¯ÌñÎTÔÅA©úsÞ¯V¯¬ÕØTg)æXËÏÏ«ÑøÕÒçƒWK¥ÏÏJ„Tÿûµ*!Ÿ<Í¥Òà úù`µ9EbÉÆ,^­~~õjuŸ|:¸bW™­ÌîÁtÆÏðƒêðóYñ6ÖûðY«j‰Ÿ÷K¿g– „Ÿ>;¨þ¾TzÆkèójõ9 ÑŽåxÌh]MYíû˜T¯¹Ò˜íßÞð.è™°û³§;U–%ßšÕÛwîìÂY^U÷ÙYÊê)okþÈà)«—_¼*lÒ‰%3žµGæÚ¤Î9\bly+õŒÏt‰öˆÑyǹʱ‰ö•Ÿo¼ô¼­9(ýÛŸ”˜M¥çÞÆ¾bÖñîóÒ·Ÿ”>ÑŽ¥°ûj6c5q¿ú«…ϼ½z^b¡¦ÝW‚¥Þ+=‡gvê|¼Ê{Ö/¾¶ÏÚÆ‘¯óø?û;;¿%|õÎÙŒ÷›äöÝXòñ{©ô|4>(1KÿëŠÛ=}^"ü×€_OT÷÷ïì‹Õh£\_çÛÆ²ãÎÆ_³+a1Ž|ûcRbãžêà>ëï—~»c®ª{Ÿµ¯&a­X²¾…Û=}q`ö—¬}}˜Ý¼^N_ ï—>yÆí3j·±cѼYÇ ®³FìÊã“+>†ûì+ÞÖ0{X«û‡gCfëgWú±äg2ïyýûô+sÌnÙ=æ-ëxÆ>Ÿ_™×e#ÅÛØÔ¥6ËÄ–` –` –` –` –` –` –` –` –` –` –` –` –` –` –` –` –` –` –` –` –` –` –` –` –` –` –` –` –` –` –` –` –` –` –ÛÂòJ°Z‹oG-ÓpfþEsµõÕëM…æsðÍd2Éá|nüxÆr£Ô›Ú=³Všev ÛMŒ¯—b17küˆeâ+‹•»yñâWhv~~)\<ç^Î ¨aÕËõOÄn¾jð·;Q›y½4×NŸM_D[™Ø.ùß”Ÿ›4Îß̶i%F!¾ÆÝ‹éúOÎî¤M#óê³ÙÌ^R,ŸYöªòõ²cÞ_fX%OQ/ŸMÇÑ»”¤ìž‰?—À]}ðIÛM&D¨FrÒþ>ë» ãËy¦µ“Ó<üí¼ì&d>gvÓ$YZU¬xH¬ç©µg‘ÎÙo½8å¤W_ê•2ézÉ”ýaØDJ'ï'NúH½R¦ÃR„Ñ –d‘lQ=ù65À2÷Ù9Pë‘0±0BT³ 5÷X1Ý,0ñþ2—¹r Ô®YÔü jbŦÕmZûk"°f×Ì"H½b&ÍÒpˆ¹šØšËÊý¢«;¥R°‚NJÉsê•(ˆåâu~o½t[‡%•ØÿÐÆæR¢Õ9PéÓ%¦ŠÚ–ÅÀ‘¼Ý/‘œÃ ´[ e>·¾n•'h·›¥ÓÒÅ/uY%gwqJ´Vt;ºFhÎÒŸ¥½¼†|Á(¦ì v;Ž5kW#5~)*í0¯Kj‹KšØª{ŠyN½‘À_öÅ£ï*Ó™’bù.7‰aÃWwA¹%ÉÒšÚ¡&"ÍóXõ’Ö ×<ž<³·¨ÉÎìlºîº¨æ=µJ“L‰üm¬ãž3wÍy2Vn|ƒgÚ©šs´ê)…9ì‚e~Œ#]_ÚõÍÔŠ ù-;IW̾۫ïƒen%½踞 O¾º·?oöÜkôe\ÏùB¬Ùqg’œ8Óª`©´Bîy‘űow€¥â fi³M­A²D –xÎ-iZÜ™·^ÊKÅ…O¶s³`ßsª ,ã{N5e|Ï©&°Œï9Õ–ñ=§šÀ2¾çTXÆ÷œjËøžSM`ßsª ,ã{N5e|Ï©&°Œï9Õ–ñ=§šÀ2¾çTXÆ÷œjËøžSM`ßsª ,ã{N5e|Ï©&°Œï9Õ–ñ=§šÀ2¾çTXÆ÷œjËøžSM`ßsª ,ã{N5e|Ï©&°Œï9Õ–ñ=§šÀ2¾çTXÆ÷œjËøžSM`ßsª ,ã{N5kyÚ•· b{N5‰¿¿ —II=Ãɦë#’Ä ù- ßð¼ x‰ŠÛFn*õ쎺Æ~hzóÏåmFR’e\Q*ýé”ÍTÄsA]–1½™ÔH´€0•eË—Ô(öUÅfRÏêÍJTðKÄÍlϻɖhq¹_À6rSéÊR=»Ò—z6oR"±–ÊhãQõlÊFêÙ½y‰6žÑ-¨ôb)ÒDæc (½XªjS6RÏn°ÔÇn°ÔÇn°ÔÇn°ÔÇn°ÔÇn°ÔÇn°ÔÇn°ÔÇn°ÔÇn°ÔÇn°ÔÇn°ÔÇn°ÔÇn°ÔÇn°ÔÇn°ÔÇn°ÔÇn°ÔÇn°ÔÇn°ÔÇn°ÔÇn°ÔÇn°ÔÇn°ÔÇîtXògÙy¸õÚùú¡ö†±X³B|Š7Œ\ ”ôUÒžS¯D,97”a¾¨@í{µ—æ Fü_ÍÞM6_C}Ï©W"OÂÿ& “†”ØäÌ*(oZû¨‰Š¾JÚsꕈ&êwfJiXRb¸ã(*õÊ—K¹E]TKCÞ0;J±†…k?µÒ«-õ ˜KWwé  v[Kĉ$(ÂÐGÁfÏÒPg?ËœKÎÒ ò•‡»Ñ%DfæI–9•(f4$LéëìVºDA9DB—ħҗª€·…¥]H­ †IEzí.p‰–æ@7"ÑðV7zp¦Ú–1]MC“«À.‚Ý…/Qð|ìb@êÀš;í¥g‰ÝýåŸi§†bkH«T–¤JDÂÃh0K9̉p‰â„i·2UtËX’€ K?Ë ›'A3í$üxÅôœz% kcKÏĬܔ2K÷Ô‚½íÌ´+ÕÄn K»™“;ÔW-­-*Ç&îŠJ\á6E•ÖkÛ2–Òÿ4€¥)¹S¥v€sãÚ ¯yåí·-c)±³j¨¿Öè"Ì‚lnó"“ÊãVyvV«sKX.•3'GWD2VEÊWÛÇrÙ¬«ZrëÚ]Ì­ ý±"®ZÚ–i¹_5¬ÛÀR’jîOT[Æ2p¶<è^eX³«òɰm,­ eõ —æ z»X®Ê{õ½-â %Ö¥Œ^T£É–È—uï¡«/'CïBWâÊ7o©QŠdK<·nˆg–IrâL«:ÏÈ:æ«'5;+þÓ¾3âº;bOûCž*°çÔ+Qè=/²øÿ9§·¿Ì¿&%݈¶›­Qg ÐLÈßQ¨)ðw§ò>~% ci£²jår”òÍIyJ^þrÏÍç.% ‘p‰sð<õ!MË÷0]ψ™wçá9¾óF‘3¯@µÜ–.Qo¼ŽT¸îÜ6–AÏ)¯Ÿ‹rïì|dx>ŸLµlûXsfùI¯Õo6û«Ùo·›ÍF¯·÷‘‘,Êíc)8rœå'ÍæÙñYÖ,ÍF³Ù~ýøÆGsë¬JJÛÈRT‡Iù²ßgÕ£‹ѽßðr$Y5·Ž¥£òåQÿ˜ý—u­l2”­V¯õ§É¢ÜV–sãúå·[½~ë­ìÛØ^¯Á:ÍþÞ¿Æ—‰µu,.j÷’A޳¯—ý~»Ç¾{¿¹¾F¹©&~]R~ʼÚμVr–¢Ç¼ñQÒvm#KSå îÚìaÚâml²K°L2‡|–iäÀ2òX¦‘C>Ë4rÈG`™Fù,ÓÈ!e9ä#°L#‡|–iäÀ2òX¦‘C>Ë4rÈG`™Fù,ÓÈ!e9ä#°L#‡|–iäÀ2òX¦‘C>Ë4rÈG`™Fù,ÓÈ!e9ä#°L#‡|–iäÀ2òX¦‘C>Ë4rÈG`™Fù,ÓÈ!EdÙèõ›ÇíV«Ü>ëõØûÙëßmô[ív¿ÑèõÅbý×_¿Ûl6À2EdÙl6û­·Ú|% ÉI¾Å·Z½ÞÑÙññYûìˆñd¿z}±* Xf¯ˆ,"¾ZÄwŽYÔãþq³y·Ýj÷ïÞ½Ûdûý£>ÿ×ñš}°ÌEÑX¶žË2_ èFùý ¾^Û눱kþÙ¯´ý£»„üü kcÛë¬ã–É)jÙ8{§\~»ßØ+ÿâǯ³úwÔg-+k_á·ySû´\¾¸(ï^4ÅÊ=‘Q‚e‚ŠX/Ûoµß)¿tÙïíí¾ÿöÞË„¼qÁêaùb¯Ì¶/Û}~qÔj‰µAš¨—¹(êØ§Ñx»Ì×AÜ+H^zò¤¼{¹W~ÿòFùWû,‡£gù´'¢öX桨õ²Õ»,ïˆeB?¼½ûcÖÞ>ÝclE/zÁ.Kx}å«>±´×^§‘U’eAU¾àknµV¹¼}ÆúË—Dù«òÅÓ—Ê—ï°ÖµüÊQ㻬–¾Ó>+0­µ‚©Š,•ùC±kªüN»yt´Úçm6ºÙ½h·÷^þ0Ž»å'ýþ;¬ÇüõÎîÅ» ac¢KÞº6Ö¤©"Ëb’4שìE˜÷é]îî>íÝ(ÿš±¼`µqïåŸ?aµ”°ÑmO´µO.vw/ÅLAÁYT׌D?Bùúëý'/¿ô¤ÄÚÒ'|ìú‹'O_ÚgTÛm~ÅÙoô›7vwvÞç½o³¹Æü®’, Z1ËíþQ”yŸ^¯ÕnµÏx÷z|ÖêßmöZ|†‡aìÿåY㈯!Úë·œU~‹Ì² âãØ,Ye;î·ͳ6ë9[ F³ÝfX{|ØÄW,=ã³=l8ÛoÞ½[øëKSÅ«œlÛì¯û0Ø Î¨!âò_üVÃÚ6kmÛ j›³>­•ãbõY¥ñš¤×ê‰ö”S㵯'Æ«|Ø£'êu‹_4Ïúí^/2I…YP¸­ÀR¥>K}–ú,õXê#°ÔG`©ÀR¥>K}–ú,õXê#°ÔG`©ÀR¥>K}–ú,õXê#°ÔG`©ÀR¥>K}–ú,õXê#°ÔG`©ÀR¥>K}–ú,õXê#°ÔGy¯_›¼ç·—e! [ªÿ¹ÒOÉB¯YOIEND®B`‚nagios-2.6/html/docs/images/indirecthostcheck.png0000664000076500007650000011134607436604442021562 0ustar nagiosnagios‰PNG  IHDRìrånItIMEÑ 0ðì pHYsttk$³ÖPLTE!!)1ks{œ¥µ)1k11s119s19BBBB J JBBRKR”œ¥¥­­­­µµµµµ½½½ÖÞÞççïï÷÷o9-o95s99k9BBkB9N?m@w=<™—˜s­sƒ©{uµmx²xsµ„µ-Þ%)Ö1)â-)ç11ç)1Þ11ç1)ç91Þ91ç99Þ)9Þ19Þ99ç)9ç1BÞ9û÷÷÷ïûÿÿï÷÷ÿÿ÷÷ÿ÷ÿï÷÷ÿÿÿ!÷ÿ÷ÿ÷!#÷#9ç99çBÞÞçççïïï÷÷½ÆÎÞÞçççïïï÷÷÷µ!½½½!ÆÆÎÞÈçççïïï÷½ÆÎ½!Æ!Î!Æ!ÞooÿÎÆÿÎÎÿÎÖÿÖÎÿÖÖÿÖÞÖÞÖÞÞÖçÞÖÖÞÞÞÞÞçÞÞïÞÞÞÞççÞçïÞç½û¹½ÿ½Æ÷½ÆÿµÆÿ½½ÿÆÆ÷ÆÆÿÆÖçÖÖïÖÖÿÖÖçÞÖïÞÖÿÞÖççÖïçÞçÎÞçÖÞçÞÞççÞïÖÞïÞÞïçÞÿÞÞÿçççÖççÞççççïÖçïÞçÿÞïçÞçïçç÷ççÿçïççïïçÿïçÿ÷çÞÞïÞçïÞïïçÞïççïçïïïÞïïçïïïïÿïïÿ÷ïçç÷ïç÷ïï÷÷÷÷÷ÿ÷ÿï÷ÿ÷÷ÿÿ÷ÞÞÿÞçÿ÷ÿÿÿïÿÿ÷ÿÿÿÿÔ9½yIDATxÚì½oŒGv'ížF·LùzX†‡×·ûV#yMÍ™v§É–†–5:ëløLAcþ ÜÁ½Ä7§n ¥Ö``ªí·fÕ6qXp0jˆæu/yÄŒ T™Ù[µãŠހqÌž1•nc¾Ü‡lO ïEDfdfdUfVÖŸîz?²+³òOdÖË_¾|ñ‹‘Ì#flÒ'@ Œ DvÂÌ€ÈN˜Ù 3";af@d'Ì ˆì„™‘=#Ü)/ "{V f§›r»%ºñM²ßYÏçÄ‚È>2ä`—›¼»›´b”çsÂ0ÃdÑÅÏ]¬›bÝ7ÐŒc†É>Š%›¼"âω¸CáD‘qdØ*Ýæ çX„y²4Wÿ–œL+:\¨:K7W¹yÏç$bfÉîAvQŠ¡X7ôm¨âÔ êtÏQî°û(œ( ŒË³‹}ûn¼þlÜ×Ôd̹ ß;ÆŸOpL7²dFâ"»a‡tÜ黨Ùa%§­”[Ï4à -a±†Üû‰ú¡ƒÉîzC‘=˜ÍvIòßžEŠs%9Cßûý´dw Ìv=Ó#ædãDýÎF¸þ$´Õà jx‰±¹Ô´È ×s;é<‹‡1‘[Œ%ü4ã¾ú™èljƒž 3Åöõ3Ó0ÂÍBöpШÆÄ¾±HÉòô¢»ÄšÊÚÕMúiIw¢Z§oìzÚYÕ¡Šõ3“ÉžBg/Öì`Íû ;"»£ì’¶ºdØ2ù\úœ°>M¾qO(NÔÏ@vM ñ›EÉî¯÷âûÆvð<Ã"ó.†SIJ¢Œã±£9”ºI\}cm7Dû“Žõ3“Éîzæ$8·ø–æ]#ბì¡ã–˜g.-!roè&èìêl˜tÂò|JÑßT:Q$èƒõ;ûxv­YeÙ½0S"¹a®¶¤”Ü#~Üð9Eèm${Ò†ý!«Ò}ž†;xÒ×m\8Q?´/Ù}B $»ÉÓ†—¸Zày¦2âLfƒË7ÿ"ŸÁÉ?-¾Ç˜žÝfü­3FõFöLÈ;<]ÖÖÆœãe-ÃͱÛìE3CdO}UÇtùµ»`ˆ¿RüŠ¢sœ|²çºÔn®dëÖtMè5š‰èn–å®ißtvî…“Ov#¦òOåI$Ì(Ù ³";af@d'Ì ˆì„™‘03 ²fDvÂÌ€ÈN˜ÙÓ EsO4;%m µ$Dö¾P únŒ•©ùïö[mÃE’ AÈž ißüÛg6q¡äÓç ‘½/XÂìÔÁ ²Ø¶²«‡H/k\/”šù¤ 3Mû"6`L@vø¢ìóæšÈS×ßC.`òKP }zŒ‘W/Dö¾úô¸Âë~˜)±à'ó]¸Z({;{¡gË ¡¼è1JŒ/Dö¾0{^×';“‹˜¶:˜ñ‡hñt?.÷w½È’gB Ba ²÷E¨ß& ñÈÃ÷ðŠûnPŠNö \}ì„BA6í ݳ{>%E`‹<4Ï&¬˜wUgpO…ûZ­ÔS‘=‘}t ›&ÃÕˆ«Å)nPÝÔØ’Ú¨¤¢òh£>àø_Ý’f\"û¨@6í ô ¹^ËøM¸‚ªèï/tU¸R ó×eAÙÁë5éÑ×5)j/DöaAL~p¦NÔ„!@dO ã,žÚÅ•à™–ôÍ( "û0ÈÂEbôÄAdO7ÕJ-m,CyIÝEƒÈ>,²8G˜ˆì„™‘03 ²fDvÂÌ€ÈN˜Ù 3";af@d'Ì ˆì„™‘03 ²fDvÂÌ€ÈN˜Ù 3";af@d'Ì ˆì„™‘03 ²fDvÂÌ€ÈN˜Ù 3";af@d'Ì ˆì„™‘03 ²fDvÂÌ€ÈN˜Ù 3";af@d'Ì ˆìÃÞ.pŒ@dOEX7akíµbnbY#¾!ú½q ƒÈ^ rQnÐNƒ_©GH "û4€?ÙóÀøRÔ¡7Í*„T ²gÅØEŽ}< ²OˆícÁÌ“qô_Ÿ°Wtÿ¤‚\ó„ 8O;@¶“$D0³VN’ID—ûð×¹æÅ1²»¦’pKIv7ò-Lv7E 3fÛJ,Nöø†¥®Nö’tÛr™dc\ŽïOjÃA<ý±€ÓIÈž³m%æóT~ógäBy+ˆ?m“°ggÂÿ&–âφo ±ÔõݾþA¿Yäî®:9W•Lý Ì.Ù]ÝgŠÏ™ÆPµ†i3²ŽȾ¡R¼H%mæé%‡v”çc › x8fÚF!Šh.[#tÈ÷‡¶Ðv {hý© Ö»á¢J®¾é ££à¡Û†ÅÎ/9š'è ²‡¿„iéêKƒ*m„ìn$ÑîE/ƒ½Îku„HþÂψÐýá—àÝÈ.á&2Jß°„ÉZê?ó¹\R ù_á±5ö{#»«Rbz8Fè™¶R(fOCv=ÄÖÊÈîšwöìÉîyÆ•Zô>iS ̶•ôˆ\cLó¢Ä5,+Ù §NèƒY¶’íü ÀíÇ<7-ÙCHÙØª b 7¦³÷­ a¶­äêh 6R T¢·¶u"ÙKÁ@;$_&yöˆô&»Izôµ~BÌ6Ù=QË f5úá7Óù¦Z˜ÂT4ÒQ²»žNROß¡&»v„˜g×vôuW»5É !£\mÞˬá ëS#ù4ª½tÌgqòAdˆ”$J³™›f§…%[OY‚3KvW÷æÑDC3mÜÌÝŽr±/²'•ãªó$ЧÅÌ’}Šã:¡M% ñHƒDö¡A`ÜÄ-†ZšeBÁ ²›àÆf2î7â“£û$ˆìIÈàÚ‡:ÀPEë³€ÈÀM±dØóoUìž3 "{ZdUù’n"èÄ@d#œNè&¬õ¿ªïn¢VNr 5ôçJâ Ò(&+ˆì!„s˜y­é{gã‰f¡ÅÃr3ƒìB8Ÿ0Ì&WeúöºÅ,%9†–'Ÿ‰›ðÈžd¯"éˆáLÝPFm$È\:B2Œ±–lÈ’osy©È®ïêG2¦z‚GdÏ 2—ލ‡ ùìÁT©#…Žãy&²‡jDöAæòÖ7ˆ½Ã´Az ó™…()HeǘÉî†ögº 9& «F„t séˆÆ)®b >® …:ÛÍD4 …ÞÌü¡:Tán¢g—¤ÖâüÐíˆ<{.¹B0Ñgè„sã›g¶-é³ q=#È^!ÎWbpŽ{›ÞGŸHŽ=+È^!øÊxHöË9{­šÎ•d¯T’x_Þeî„‘wt·_×=—¸žd°BáæZEˆì>“> Âè@d×qp,¹Þ›ô ÙPâžcÇ“¶á”ƒì£ÀDz¬®eÓŽåÐÅì²ãl±%kóÇk Ÿt1ûƒì£ÀЯ+ÞØÇnj“g²ó9s<§ü©TÞ 'Dv^ÝÜ9Fÿlðíò¼éböÙGÙÂ?Wð³§‹Ùd¨è2ÇiJjL*}X´ã‹F·É¨y©/ˆì b_îÛè+Û­ã5µÈ³ÙGA¨1€¦ô•ÇkÚpȳ‘]AÄìzvî/[ÇiÊ={‹<û@}˜£bv¹¯©E-¨ƒ@öQ€TNë8B<“ˆì@öQ ýăì£@:û‰ÙGtö"»éì'dÒÙO<ˆì ¤³Ÿx}Hg?ñ û(Î~âAöQHÐÙŸ6l«c=mÚÓ‚GÝ¿~úøÉðåOŸjËIg²‚YgßoþÃ~»Ó±ºûÎÄ«ÝnÙÍî~°Ï'-ÒÙSƒì£ ³·`<–åÓ§a²pzÒÃpÌqV7;øóæIèDIg"»‚YgouwëÕíZ¥ÊQ¯V>­NõS?è6ÿûžòók‘Ξd…ýéÒZ iöimÒDTNýÕ£Îß=iðZ?[ŒÚIgO "»B‚ÎÞ^Ú»µ]­Þ­nooOšè€ú©v›û6Ô!«‘;éìiAöQ0ëìOŸ.ÞÙ®ÖëŸW«@öz}Òdÿüù¿´:âÜžÈs$=%È> f½ÕZzPݪU*“&¹BåÔ:޳¿¯ôuÒÙÓ죔Ͼ´;i~GÈþC«ÓèâmÙmjgL:û@}òÙ§ìÕçÿÊr0âr‚qÁHgO²BR>û´‘ýÔ_Ù–x5º ͳ“Î>Dv…„|öé#ûa yôè ÄΞd…¤|ö)#{åÔ_Yv“ûô¦ޤ³§‘]!AgŸ6²sÏ.òa¸7‡ÌÊgO²BR>û”‘½vê¿h½v€‘W“töô û($ä³OÙ«Ï/yâ²ñ¿6F뤳§ÙG!Ag²dßúüóz¥"š–êõjå³Ï`vû³ŠjmªÃR7ýæ¨mî•ù×›7«u>ÖXX›ìèÙ%ÝU-ƒtöT û(˜uvhAݬý´R­ßBš"m}ìl FWjæl‚úöög@úO1cr{g§zw˜”²Sšg'=È> I:;÷ìèwªÛõj­¶U»É©^㮾ê'†wë;Û;‘»@¬“KðŽá÷ÂÍ›°àîV~²'xvÒÙ‚È®4nÌÒƒúdqÇÍ?*"ü¨Þ ²e¶Ð"%rÇÄN™-¹µÅ·ÚªÝƧF5ù’ÊžݲHgO ²B¢Îþ=Ys^ÝA:óXýIáPÚoßè¤^½%xὌú‡õìÝà iòÙw9a%Ù±’ZÃj§¨¸V«"jß‘¼ôÚ7y¨³¶ $}ãN­rjÔm¸=À»oñõ·°À—Õäö|f«.î’n»USaO¥Z!=7È> I㳇ɾ´÷_T«·ö8ewêà«@Ð~Š“ÿÔÒë{ÏsBWwN-α߻S«í--€'ß•$]zkw«Î ]þwH_©>¿ÄN¿ñn”S‹ì‹_ß½WÙ[ÏŽ½%6ÇØ[{p“°9JAðC:{n}Ò䳃G?µøõÝÝÅ¥@KÀ[{{KbD—7rïÍ×ÁüÒ÷*[¿Œ[,>D]²u—î?Xâá Bìâúç¾·]û¼õ½Û@¶ôÉÏCü%,{ÊÞKŽÙIgO "»B‚Îõì»ùß÷Í·?¹] ¿Îé¿tÿ>'å[€Ð§p=[~ }=÷ǵ LP1ûi·Ãòéò€Gñωý¾~ÿÔâ[|néÁ} r LþŒx ž%hpOÄGUÒÙ‡ÙG!M>;§§à¯Tøôþçu 18yŸ_ú'»÷jÜ«ßçèÝkU ëó"¯ßµ¦ò¼ðøÜCï"¥+Ø<ÀXþÁó‹¯ß©ðø|ï9¬Äž~cïÔÒò2:2œ¹ˆò¤³ç‘]!!Ÿ=êÙï×oZúýÒÒne›zWÐû­½ÊMPb„gÃñÉé½[ݺ[ÛúßÇd±½¥çøºÊ] lêPq=õÜ[A½ßÅà…±×Þü÷½S«>Xœc"z'}H}Ì:»õìwnÞÝ]Z`‹ÿöß..î ÈØ¥çî<|ŽW,yµó ^I…P‡{ü;ÛŸìÔy`ò]Jìû³×ë;õOnòˆÿ>V5yä¿€±þëwøÒ½|ß÷ðŸÝúþçÕϾ÷܆2[wÅ­#ÄÒÙsƒì£4>{4f¯V·+œÐ¼ê¸Œ5Ô·vˆ ê2.oí>„peai÷.úõe>z ¨(¿û½í›5ÎePc*ÕÊ.Fñ eb•õ4÷Þ<b ¼Ì_^\æÅƒrƒ®žñ§B}›töá@öQHÐÙ/î툼óÏ>CÏÎgyÈÂcï ù÷!*ß~¥Ç7„ô(#ùJiÏ~—S¸zôðΠ—ó˜ý¾ÐÍ!Žë{Ÿñ{Ô—7ø ²·ÈžÛ­ÕáZ^þúOù±–QÛ¯ÊLbÒÙsƒì£`ÖÙÛmÌg©ê7kÕ:|» ßj7oËÆ~#T0JßÂdß-™À‹žøÖÎ-$¶ßËc–W¶«÷*Õ{· š©mmÝý³*Ü_dÜ|²½ ƒLòOhV«¤³²B‚ÎþdqªŽõ»ŸW±6ñßêÑÇ÷NI|ômÙ’Zƒt_5¯†í˜€t¿¹%©­®÷D:'òöööm,ݮޅhw¯ÃgE4®Šô1ÒÙsƒÈ®`ÖÙ÷÷—¾‡90rXÓ{ÕÊÝ»@ÎÊö¿®ÔëÄJK»dc“zû/€–woí@BŒ‹ZÝÞ¹Ô®Wáɰsk‡w·Ž)bèÿ·?û÷*¢ ô¾Ëçïçw Õ2)7†tö û($éì‹ €øô&2í/ } úap:rBÖnd±ÿ¯8²µLkS»Í#–ÏùC`«vÊàä¯U?½¹u·VåÏŠÊm(2` »}Kè-ØáéæM™{K w”cHgÏ"»B‚ξ¿ôÝjí®O7è›´UÃ0»ŽMFÛØ?uKøoД;ÿŠpÒµÊ=IÖJ­†ÝòDÊ$Þ8w¡¼{¸LÏø­á ³½]Ûâ+·kxämÒÙ‡ÙG!!Ÿ]Œ. ùy é^ƒÔu¤r½Âcø[;|¦¾]8»r{xUm”‡4;Û·D°ñ=VO…†(b“Ïü|I5SÖïTebäÎ6|ݪûéÀ¤³çÙGÁ¬³ó˜}¯…Lé_Ž]K?…:ä½­À3×k2Ç,^™±XÕE¹PGà×·å3„G/ `ä+0y˜töÜ û(dŸHŽJIå31"Ì-ôÔJ¯Q|®Ü¼-8}³&Ø UÒŸÛàŒyÙq±Œ}¢ =7È> ©Çgzn#51•«^ýULÕ}cÞ¦]í*aתèê·«~³»´ø]©lùClì|Ÿ¯ý P^öDë,¯ÜòÚdS>4÷È&=7È> Çg¿W½wkÒj•‡(=¾~§z¯.°­³rÔDTã?Ùþ¤ò½%Ñ C¹~™oA¿í|Nð[a÷ne‡\Ú‚ô°½ÛŸV ¯·!=7ˆì éÇg¯m >?„î×ÛÐcaa-=”=KkU9z@EŒpW©Þq<æLÖ ÿäôµÞæZå¶HEÀ´¯ê§8ö`)iŒIÒÙsƒì£i|voÞá„ÜÚÚ]„-ö—Ù×ïß¼Wá•Ê{• :õêMQŤVù <û'ò+„ð;ÛÛŸàíŸÕ»5¾ùÿ¶M¦ü ž ý=;éìY@dWÈ2>;dªlö<øbLƒe¿Âkª;·N--°×÷ Ký÷¿¸<÷ÆHèz}·öy½zo îä·oñèdOdºß«nCê××çwï/=ǃœ;‹sÐÁã.$Ž}}÷îÝø±IgÏ ²B¦ñÙ1PÇÛPIÝ»½µ…ML0AwQdDòØæõ‡²û8èÊwÞ„]ïB–ãcË_ß… Jˆø¡G*éÔ"[^Ú'ÏKÿ®iˆ<ÒÙsƒì£z|ö Ö0ëÕÏ §Rýû§_ø ‰Ýô éÃ.÷«5Eà׿ËC“êÞsÏ=BûŒ*½U÷p$šÿ]äÇ/ñçÀŽ'ðv ykÏp›‘Ξd…Œ:ûMì–wåÇïâ¸.;0HÒ¿Z«ÉÌöûõêÈ8ÿ]åæVýÁ"¯Ðòf«Ÿ• ùïãípó»¢7t¸þUŒß···N-¾e<2éì¹AöQH©³ûMF÷ªþàw …óW*µ*êî·ž_zëW9U÷¶A”<}4ø]¨‡â yÐúÿ}Nvîë9ùÁŸß¯ãh2»Ïáˆ2{XUý´r[øwC•tö¼ û(¤ÖÙ·¶D¾/vרA¨²W­=\\^~ã'þÃ;rP×ïTÞ÷*Ø'£¶u÷>ª7|þæwy¨óöVýÕŹ1üÆÅÅ;aÜ*¨÷Õ­_^ü½ïÖ2xvÒÙ‚È®é=¨õzm«†žýóû‹ì4æ³?¨nÁèË8‡ÃdÔ«wO-Ф՛ªñ Aªü›çŸ[flGClpÿ°"Ç#¸WÁçÆmS•tö¼ û(d|êö­:ŒÿR¯Ý¬î.Í1î©ï×y4þ¼k¢ÇiµýP—vE^×v«†2*Ð×TØb‰-üŸÇè}ûßÁX3÷¡ü+7Ío+ =7ˆì YtvÌrÄl^O­ï@nMgZ۪ס}ˆ+Ø+IUgq ê[÷D:XM¾oì¼v%Ë¥ÝÚÝ­{"ña,->¨Ê8¥ò줳ÙG!ã{P9{¡:èÕDBÀ6Ææ<œÇ&Ph/Â>¤UÑ…2$?«ð»à³Oä Éj•ZmKŒûÈ–¡bê÷ê¨×w@„ÜþÄ”÷H:{n}2½9¹³ýüÒë<êÞR/ ~¸¤:B¦ªèV 1ª÷nÉ®{Û;Õm™9ƒ1ûÂ[·Tmt{»ò)ÔönÝÝÚŠ7¡’Ξd…Œ:ûÄ@:{n}Rç³Ošì¤³çÙG!c>ûäÈN:{^Ù2éì“$;éìyAöQȨ³OŽì¤³ç‘]!‹Î>Q²“Ξd…Œ:ûäÈN:{^}2éì“$;éìyAöQ ýăì£@:û‰ÙGtö"»éì'dÒÙO<ˆì ¤³Ÿx}Hg?ñ û(Î~âAöQHÐÙŸ@Ð*¼®–n*‡®ïˆQ“ û¦• zöoÙ;8`VçéìéAöQHÐÙ­¥ûÕíêÝ»µJåvE’îžì”4h À™Oîáô“êN¦ý ÓïsÏÞë-xxé::¤³§ÙG!IgŸc lÞ»Ž#̱¡0äî~ª=vD:{VÙtöÖÏZÇâ>´Ùc^P=ø×ƒ©¤èÌ÷ÒïÛïïÀÙmÒÙ3€ì£ ³w|iï߰=7-C™@süãAÌá!;äóÒÙ3€È®`ÖÙ­Ç?á~½ÝFÿÙ>JOI7Bw˜/‚ê=þt8<\óÎþ~‹töÔ û(˜uv`ÄÃV·ñô©íe¦§æ×‘íÃÓ½§æ¹wç‘éìéAöQHÐٛξµï´œÙ[Ù©8v¯¨@fùðð€õŽà)Óæ÷'éì©AöQHÊg÷ÕÎ'/=K2ˆñ<·˜@Fû£|öL û($éì¶ô›ðMPÖóÒLÃŒšO¿šò-‡òÙ3€ì£¤³ë¾½×Ëàyµ*ª¿¬0E&îÙIg"»B‚Î.=|沨1žWò$½EõÔ-”æâŸY‹töÔ û($å³:¶eHÏîzi§Js {öôûǧ=õ½÷g“töô ²+$ä³ ÏÞj·EÌ~”U }/¦Šê‹½àÙC:{ }’òÙÕ´œê‚žÝ”5ÂS¸sðâß¡&ÉѵYúýûO9ŽÐHgO ²BR>»®ÆH噕bÊÉ.Ô(Ö¶á^bYöï;íÚNC²žtöt û( ÒÙ³£i7˜®ƒ7ù?s]˯ÒÙ‚죤³çŸò?æèËy,Ãdß"§ÀãΞd…Á:{64ø ï6œÆ\ã' ¹¶XÎ>Dv…¤|ö¼Sødº^/2'Á×;m_þ8¤³§ÙGaΞuÚàÿXø{—ÏÏ5qM³°ãΞDv…=÷¼9“\ùß–ÕfNýüÐåëSÒÙSì£0HgÏ<…ú©¦ƒË8aÄZ^Ì”tö û($èìC@DèþŒ¬¶/9ÎÅ@:{*}ŠÖÙèk…žÉ£tKªƒÅJùHg²BQ:»jqEµÞ&æÈ-„«wü¤³d…¢uv»ÙèZLiê »ÉàÙ1'½>éì‘]¡ ÝϪ ´˜:í6üÇní–ºI›tö €ì£P¼ÎÚ7“~ÝÏ>Ç»´Ÿ’Î>fÙ ÒÙ-™ÿÞúQkw–ň3ʳ³ÓØ~Ú&} û(­³7,ŒŠÖùGÓV£é4 <éì©AöQ(Hg÷óßEž£%¢vøŒf©qÕIg+È> Eë쳎屦 ¾Ü§ºŸS,Hg²BñùìŽÛ¹#‡>EŠëÆN:û˜AöQ(\g·íŸ¨¬ö¦cKÏnI½xÏN:û@Ù ÎgýEe±/3Kˆ1¨Á8˜ýH:ûøAöQ…ÎÞT½’x…€1‘‰KºÅ‡töÔ ²+œÏ®žܳƒ—G Æ‘‘6,#}ü û(­³[àkm«7m« tïJ5ÆrŠ;éì©AöQ(:Ÿ}¸ÔÔã<‘21)éìÙG!¯Î.õtKŒ\d٢ݔ1É>W–î w‡•r#xÈ‘dC(ý¤³ÙG!¯ÎÞÅ·_à7-Ýî:lÊc±Ú Æ£ÀfVÝž?ÏtöT û( ¡³K=½)5§ñ–¨ØÜŸóí8®Èƒ¦e•tö ²+äÔÙ嘥¨§ŸÆrlͦîàÃB̃㿷[Péì£ÙG!¯Îîëé]Ö;èõ4‡žDõÐâc½wïNÓ.Ïtö ²+äÔÙ•WuÚβ¡Tw w?âÿÈ6m™ O:û¨@öQÈ«³+==PþÂq=¶€{vñâÎ×Fæã“Ξd…¼:;ÄùÐXä ïXY^ýtöT û(äÔÙáiàÈ×â sx<>sÄ(3y΄tö û(äÏgWò gë5D`»j]%}$ û(äÕÙ‹äs@io8yôvÒÙ‚È®Wg‡èÁ¯sÖÕ“áʼ™6fÓÎ^<È> yuv^;-ê\féÏÒÙ ‘]!·ÎÎÜ¡zø$¸oo[™õvÒÙSì£Sg·ìbMÈ‚s ½`}rêì 8¢c?*Æ¿³`dÒÙ ÙG!«ÎŽŠ_\[7¶f¸ PkÇ1Ä,'Ë‘Î>d…´:{ðÆëX¥¾ë/Œ³=‘ÿbİ®åØz†;éì€ì£Ug‡vN%¨îH&k2Ù])ÄîØžÈ’Qĺv†3"} ˆì )uvË ¦ñ& ð?Vò¿ µ»6ar•œW›KˆÇ/FVJ­û“Ξd…¬:;÷ì¬']©bzÀ`}â²Ð]¡“\Û.&`$ÓÄ3"½ ÙRêìVuîèþ@}–»ŠÐßj<§¾FvžrQ.ó#qÒÙ ÙG!«ÎÎ=©Ã4Ïî!Ã¥ƒga²ëž=¸›GO‡W…å‘Î^È> )uv;PcŸ¢>¯ýø%´0Lv/FvóÙØ]ô²BFݱÌNšÄ·LŒÙ=è™j‰ˆ=}ö#éìAöQÈ¢³‹7iè;‡„³㊘=äÙԆʳHg/d…¬:;h1b|˜\-¥žˆß“WZ]ÔSŸéìAdWȨ³·Úr0”ÇZh‰…%nízs"b'½@}²êìMvžý@î3#­›7oDzÏéì…È®EgçÓv›×”é¾k™}:81Õº âéì…ì£UgçÜ:ˆö°6æÀ„ç̲½¤Æ÷%½@}²èìFfÛe©¤š¶•O ÆPgO—×N:{*}2êìÝfN®§¼Xð&Õtêéìƒ@öQJg× ‘9œÊîúiƒNEòü†rRŽcC:{*}2êì|SÖëôÑ?\Lñ ¾©Ï4®]¼›ÃVúPÎ>Dv…Œ:{ýh‚Oð3dVdòy¨|ön—tö‚AöQȨ³C7¥ƒƒžÙ—2Øþœ>x6ðv&Êg/Dv…Œ:»ÅEv7ìË£œ÷“F}ÏýPIg/ d…¬:;CýÀXVi(²cýÔiˆzpêó!} È> ™uö>¦Ö³‹˜ŠòÙ ÙG!«ÎÔ2ÄÈrøŒP}4<éOv̶aJM>¤³ÙG!ûøìÆît¢,¿#jÌ­Ë/ýôG|ßL†ó =%È> ™óÙ» »a·5+óÜ4 (Ì5„5³!ÌÎþ>TÒÙ‚ì£mÜlñqFàÛY Ã¨jHg/d…ÜïA&<ÈyØH&–ý |ÿNd²Bþ÷ ú£Ä`9ýƒå8>éì)AöQÈûTŒÞÙ³»0ÜÀ°zH~ÏN:û@Ùò¾ÕiÁgÛ²Úr´®ÝU,«¾N:{}r¾ÚQ!CѶ1ÁJÊÈ`ä² ù뤳g‘]!ï{P[ É´hR]fƒ’Iä¯[ø2¥lï?%=È> 9߃*txÜ)sòM‘é»ëÝÉ–¿N:{f}r¾ÕêúŠNþ6U&T˜”ÃÄΞd…œ:{þû ät€þ.Gµ¶³ç¯GA:û@}òëì¡i[ÈíL Ùó»xè¡•ÇêŽãdË_'=È> ùuö0š6ôé°» ÍˆÑ≫ Ϭ.8å†Óq˜ã“Î>Dv…œ:»!ß½åˆvU(t™%Ä12~=ñ/ïñHgO²BN=6…ÏÆO k|Ó ñþ;Q¼ ê·"Ã1{þ:éì™AdWÈ©³G§ŽÈ…tÚ- õw«Ë‚×,±ïØ—î«/j6}þ:éì¹@öQFg×§Ò¿Ë÷fà[Ù±k¶…LÇû à‹á­I´¿s<ÒÙSƒì£Wg‰þkÂ{ îø½‹ïò…—jÀœ»T|OŸ¿N:{.} ÒÙc°×Ù°JúÀãÐÅì²BA:»aj ®w™%¢¢Ë'=%È> Eéì1+ý:Úy˜>:ÏN:û@Ù ÒÙãº;›Sd·ÔÛï ,Ÿtöô û(¥³G§’êŒ98æzáå“ΞDv…‚töè”p˜jc-°|ÒÙÓƒì£P”ΙÂÛ3,?ŽqšE—o“Ξd…¢tö¸în9àÓ•gHgO²Âuv›u›8º#}’ û(ŒJgÇ H SÖ-5* éìÙGaT:;ŽõkÛMÈ€™³C—–xÒÙÈ®02½å´ÿs ¡1÷¸0¤³²Â¨tö¦ÝÀa¾ »±97|Þ:éì¹AdW‘ÎŽm¨-«ÝßÛ>Ý*T_'=È> #ÒÙáÝKÌ–-§Ë?. éìCƒì£0*]¨ìþˆ¿¤³Od‰fcýt>†{eF0½äÑ<ç(Â3"{#`<ëó­`ÙûÈ`D®=Jö‘=A@daD£g'ôÙ~ä`ñ¯äÜ'"û¨Á|'Œ dúQƒE9Y|b ÓäÙ§dúQƒÈ>5 Ólà¸@¦1XŠ%„ñ€,?bÈžé=©„â@d1ȳO²XÞ5Î&læ’÷òð=ír€ÈÞnlZÒXÞM½šxyö4QÜ -*0æËfù,‡%ÂXÂ"²Ž£5Ë`²»}¾¥\6»{EÑn”†§ƒÈžnhbø2^Êï÷•®ïWú-O0Àtñú)‘=‚ñQ+í^Œiu‡ÂŒëŸùöx€îÙÃð™ëFÂÝlnhó‘“=t,ѹ—!ŸÅ¬¶j¸3:)—Ç`w¶íC"µ¼¢©•¶‚ê»iyXµ¯<<Ã?ýÄfì*ü3¬ši»Ä%;ÎJŸP,µÒ{öðåªÛN|åÿ\yšŒÈ.€t7Ú`Æ ‚£–£κÃS+m£SÁ§8–XT,Ô‰[Ñs‰ì,ÃÒYEij‹9E­R„Zîbv5§Sñ/ôœq‰ìDö40Q«ä¯4QkdwÕLIÝ~þ‡yá'‘ú›u9&n^×#²‡¡‘Ý <û@jå9Rö3 ¾ˆG„Xòä(fW(—’atŒZ©ö2µk%uo®ƒÂ˜tè›õ5îD07ãr‚‘=FN&²ûHAdŸ&ÝG "û4ì>J0󓙌>ÝG –i1aÄ »Dö©Ù}” ²OÈ}ª@v%ˆìS…˜Ý{òUš‡Ú&ôz‡‡lU«Û{ÌÀ a{‡}+³ÙŸ=¬îl×w*Õ‘}$‘ºDÙ¢E£÷Ó½êÿDZûÌbÂŒIy¶[Uئ0fg$¡ŸÝ¯V·nÖj‚îàë½dWTߩֶ*·o= ²"ûÈq éÜûéCpÎÛÒKóØ=¾-ÝùÏk°R½^¯ïT·«)QùÁOyeàHhœüïà§÷ë[5¹®bؾVÁ½à& Χ÷l/©|¾yEýˆÄn½·v«ýÁ÷ÿ!îu苯ÏÔÁ.¸ºž¸ãŠFQÆ<ÏÑ¢¤†ÎéOI3nV¸ÁøÓœÚ®ÂO÷ª)€Ç¾ ½Xª½²^¯j•¯¼¯~•¬ýe¸^:çø&Û{Øëõ8îÍÚ»òi¥²û,VIeG‚tÑzøj58aþ<xbˆ¿üGY%ÆxywêõàBù5ˆÄ½êuqµ»üçþà§Q²¿1ðoGÈ/Ô Ö¶¸ ~ðìuXu‰ù^•Á. t,—yFRèœú7;üú¿K\ág{•GÂc…ê_W®ë§‹aA($Èt½zêxiÎ0Çõâdå×KžìÍÜw¿ÿý­ÏŽ~&û¡ô (­¿ñ`»R©Ü®îìܪãSн"½­o ^+VbÛHŽ-~3U´$›¯ü ƒÏ‚Ûá½Ù›o‹ï…?úHù—4¤€ßu:ÃûÉg(M^ÍáÙk7oú´=’gÈ=;·ÜV5éù*ñŸ…CÒg»ÊEx½¶ª•Ϥ&×Ó­‘öz…î!g|½¶wÄïª"_%eùÉU¶¹9Ð-ÄÔâ÷óž(˜ß™[[j‡Á¸ —÷((°÷ì~½.ooóþP‡€·ÚkÍ‚‰7W½~w‹W#~¨Gb¨h cjø¿‹ƒ~ž¡tHøÇ¦[µ~lâ¿«ñì3“½V ÊÙ]\^†¾ôücnŽ¡9à*$[B^šzý/Ñ~Û8ÿ]UöëÅòVý :{™¯—rG©ÜLîëõƒÊg!Âòs†³ û‰C$õPaß݆ŸÈos¸Ïª1PœÙödnB䙯!\ {½sS€zê™ruRhx=é$zÚùj÷YÒÏÂß„ ‡Ü<½££>Ç1­K“³ ©Pe`;Iò‰ù¿äçÁOôD >Я×Q‚™Ò^/˜å‡ëa›f?ó{{™¯÷ü¦­ÞÅÛïvåæÝÝgè¼ÃI2¾y½#ÿ”q&’ý~5F‹C„ì¥Î$t•D’O†µsPfS&”H¾¾~4D¬|IqƒÉÎËå.™¾€Ã¡h=8èWv/’¬—þ3^¯Cí÷zú¤ß¹Å®WºóË~½d Ο5ŸU0l¨~~ÿwM‡±³dêwÕz¨¨n‹'T} ÙõsÀÚýASô‚Ð ´ •ŸÊwþô¢¾!+Rxvîd–9J0HØKó+㛤ãzÖë¬<<Ôj¶©¯—ÈDÌr†Ùp(mÈÉ^ãµM­v± þsX© †ÏÓ¿Ah«¤ cÄæøÔ /J´`tM CòøñBN*‚H|u¤ï•ýZ &;Ä•rÏ…ÐÖ}vª9öKm¥L×+îÿSà0^Jê“Ë~½¤Z†5z%9öâÇLlÞ8x¶[ß®PºÀpH™ÐîZKȬápÏ.DÒd;oŠ`æyDéC!!¡=¶X²=6ôåÐ ‚_‘ÿénµ2€­ÉÞn—¼OéCÁ<ŠoÙ= 6/AV|Ǿ±3者„ÆX!<‰H3"˜ \ŽðMtÏŠb“i…ZBýO À`²«@% 9Ñ= ²Ð41f‡'ÂAý #ýX:ʼnîp(ÚE<š®úm'»öé¥ló"$!‰ìý*¢Á+¬é b˜£££áHb#@!ûpHéÙ ¢ Ñ=üL‰T%“Žà YMï¤*Dö‘b¸ñÙÉ» 2çÈPÄK™I¸!ä‘}´ú ×äÝ‹™rDpû ‡”ÍèŠî䨇‘}´Žì’ß”#V ÈŠ£Ež]ìûoDöÑ‚¥\–¢$rï 8b°T‹R–¥ñÝÕ> é@d1Š$»§×V5ž»ÄùT ²†W¡gs grƒ 7btÃü6OTgȵ§‘}Ä(8ŒñË  —d³ ìÆåA¨ÆJtñ²ì5j°Kr—Í(52ˆì£Æ(É.úy0F|O"û¨Á.(à‘*«û®a¦Ll>S–ãÄÃ;ðÃÁÿ‘"ËùŠG¬¿x“Ëñ ü>Ÿïû4pÅØ6©ÉîšÉ¼~¸Dö‡Q{ö¨iáM½þü :[éäå¬)à&cúšÐvž|…1y#ÿy¾TÄS¥39 ”Ç"«cFd5âd/ôòÆÒ’†Ò‹(B~ãó£ ¯äé|ö¼ÐWm;¦mÜ/,¶+~qc…h%»Þ¸êØDö‘cüoUoõYïúþjÿܘb¾©]yŽzÔÐÜ';ó©oµsý£2ý8juÖ1}‹±°È>r°hûé¨.¬¹\ftõ: 5]ÂíKZÈ.w-idgA ¢ÊRë\O«‚Š`ÈcZð£VËû¹ce ‘}ä`}¿7Õ²ã5Çîj!8‹Džk°ðvÁ]Â4Zk»Ê=\S zÉ“»„â1r²kpS.E1ÒE+ëŽ8ê—õUŒEI®Ÿz~}4T­ÕW9«È>z„’ЧÓà…DVÆŸæF¦“ÄtÚ~Â(X.‰ÊÍ`<rc371³oGw|÷‘}ôé SfðlDs3¾ï&ìÞ§Ìö'&Ï^\Ùï7¨@7íÖ™Îl\÷‘ÝvLPŠ&nòö+$˜q×NÜ«ˆì¸Ìr üg19åÌ)¬T(­È­©‰ Äô[ ô&¥`>£¨Ï<Ç&Ôõ„Èn³KðÏæÿºø™ojñ?Ö´m,ͱY×ê6!ÊSSÇî6íû˜ÏHýÓ8”ƨmä²à!²{Z2^7žŽDvX»Ýj£ïv ®<º-ÅBôÏmþ—·\éáÛ¹={8ÆÐIXÒâ.–æêž[þwEŠoI÷íáÄ/Ò‘›àÆìˆcÊøžÝ²›Ê‡3Œg–’ÆåÚÆ°åÚ Pc2xv?‹t¿»ßµ»-”•Y,å±CG¶ÿÛ2ç%Íuö¦Œcx<“v¿äòºOùYt:ì|¹1fhtf¡%,˜ÍùãÅh×v {g,ŸÉ uks,´¤"m„§!²»r¥”¤‘Ý —³û:{«ÕáLE–?Ï.3ºx,‘rÚéðO~Ÿ¨x=ëþ‘)jôÖ~³›Wg#êšÁ&ñÝ–¾ÆÈœ0Ñ0m@&z!¯®>J®ö=¢ GJ*…ž ú‡zbª0† ˆÙc:{Ónp^qÎÚMéÙ›¸&í”—ÐìÚöcv¦ýËkB ¢ùô±Ý(ijkm¨Áð]¾™´&Sí"í°Ê×xZªXê.[µ$EŒ›|ã>^Äy{²­Á÷Ï*ÖöÝth6‰ìÚÊÀûë¤fþXknÏÎ?Û|Ú’óÙâ‘;ÄÊYþaf/Ú-fÁ—V¶½Må9N3¿În"@дã7E“\ü‘Ôêhëhx…ȹ‰ç‚i­«‘ðh<äïá<;_¼·¦3XçêwIhçÐ&j…çEÉ(ŽiÕTN~¼° ²¼¼Ì&9&5vË~:¼gwµ ¡§°}4´•俈˜'Òü´a¥j&e±ÑƒÇJ¾qOw¾}Én˜’=Tb°(üày:$ž¥/kwžœ=¿ººraå"âÂ…‹W.Š/i§/®®¬¬^\Yåÿ`QÖýCÓÕ /þ–¹1EHLûô4û ÁŠxf£ÏrfØH^œhÎXè€cÆdÔ˜8ëR‘]ly‹ó£ `ýRß3‘]¶Ïœº^T'»ßŠ:ÄÕ j£Æÿ‘TÝx^—›¸Su\à~ð®—;nLHzŒpÛ5’=Tå EîºôXŠl]òw"ŒÑòѧì/ý¢c‰^ƒÝBbv½×ZŠ®iËkŠÔC™¼np¥´Ë©Â¥Ð¡&€IÝÕ];‹Ñ<"Kº~˜Šb":;®*ÒcIí 6†» ²§±|ö)#ûÊ‹¿x"k3f=Æà&ÌÚ6¶4úâËÉpy &äÙCl–CïøÆ}•|¶kûyaÇžMgŸ6²¯¾ô ˆØÛû…éìq¸C­ ¾ÆìÇ b’÷ ¹]®Ïf^–ÆíÈ’´vŽéìSFvô좯ScXÏ®Ëí³nÐhHi:úŽ9™×ŒÉ?pòÑ7åv9_ töìÙÝKò–5½t&Dv7ýº ^¹y2àõ|ö)#ûÅáçÜ %=Ž”ÓIþÉ{ö|l½aì«å³OÙ_ú#F¡™îK0m»¹òPœ;ŽÉ·Ùt«1vWfOv««šއ¹Ü”k‹r6S¬³¯ŠTgòžýøa cöQ—~4Ùi×Ù/¾t¨õçÿ•;ΘUsõ§üTëìg<½}žã7WV§ž¶*ZÐÃbÚuö‹/‘gωɚkLòWùÝ€)ÖÙ/ Ï~Ä)ßãWïh"×í˜büd×Ò\dޏAbQb‰,Ø.” lše$•8½:ûꋇ®ïÙŽŸü7IŒìzN×à$•`—þ뙹hã­:;xö#ïRÙ)fφqš+6X¤_]ßÙd÷¢d*àyF²'íÓ¬³¿Hž=/&³‡Ã>ŒvãßKú€¦n)ˆR‚=Xt8$}Þe˜éÕÙ#-¨´gÀøÈîpt`/ȳݲKÑ¢õ­"_’^å<Å:»RcȳgÅ=»Áͧ&{´‚êiduàö·J_AMVc` "´hufù²•U>ÏÿVqÉWa%Ì®\\½pá"Œ¯]„ï+°¶» VWÅݳŠ/ñ¿  ´Q_¼ßá«Á±Ig!»[Ò{ÿ«ºªbª;ˆìáßI¢dgC½ÎÎIøÚE 0ò}EŽúÅyüÕ ð« *®”{qÖñ_ûÞ'+«A@m¸MÔç…ØîNô×^[•Á£]¼øµ¯]$}Œì![«›jžºg¢äú;heFÚŽXxEö’6†¤vZèìà•W¿zA0•Só5AQÉïÕ×^W,ò…UNN-ô³°-zhØûk¯‰gÊñ|øšpç+òfúš˜Ãi…töܘD jQ…JÊ–%‡˜I\¨³¯¾†„Qˆäùk*ü€‘ ¬xÀ! ܫ迹k‡=VVÅÍß.ˆVV¿úÕ‹"´YõC™ ü!Áï^Îk_»è?<øM@:û0w5Dö4ŽÄ¹±H$Õ ñŒÛ ÒÙW^<óÂo¡_<óås/ž¡}—Ùo¾¼rñ·Î“ã̹ՋçÎÀÜcËÿì<ìsîKâ©ò›_A’cèr‘ßœøœñüók¯]¬âóàÂEu?øŽ~E‘ž¤³çÆÍ¥Ë1C½S'²Ç‘f¨ŒAY}tö—Μ}|6'='»8“³çVW^úõÓÈñúÊù³§å¾ð*ÐõU¸ p¼ë^FGQüE¶ÈŠç*Æó<®YGøpX.ØÎï 2Z%=?Æk.ÑГ°"¼@ë~¤QXÌ &™@@tµÛœú…1}tö—ΰ¹ß|¦/œéì ¯€7æÓs/ù Nåß:sæ•óüOúeTcΟá7Ÿý­3/¼ŒâÌ!³|ê+ ÁFD<ÜãË¡­WD䳪d‡.¬ÎžSêÜ4«Ò÷¢ÎR> Yg_]}é쯱ß|uõ5Nö—¹w?ƒ¯Ùùüï\\}õÌ™W9ÙÏÆˆÜå“s_:ó2þÜÙ³çñfáO(ꥳgÏ]XùÊ™3ç_â·Ç¹3ss/ð›â<|éÜê…WÏœåËÙÿÙ+P3X yvÒÙsÌeB?ý¥3¿6Ç=÷…¿„žý·Áó)ŸSüENÝs2¸Y^æžœ{fNþ¯€”xþìÙ—!~?Í£œßüíW0ÆáßZ¾Ñcáôû¿$–Ÿ?ÏKgÎ_”¯B@ýtöü s™ÐOgéì—¹Ç}áw^:ó›çy¥cñ3³Ÿ]~—þ«W_•dg§_ø hﯜ=û øøsg ,ÐcD¼ÿåóÿâ쯿ò ¬ò%gÏCøóʸ„§_˜û/ÏŸ?ËÉoüÀF©ÒÙ‡‘=‚ùì@ÔW8á_<ó_¿¬*¨/€§?ƒ´ç¾œÓ÷œx5Í**ˆüûyhJ:aÌÊWy óE$ô›;Ã=üÙWWx©¿ñÊË|»ùëg_Yá!Ì™ó¯à­Á?_ÝòkB³—jŒG:{ÙM裳_€XèûÒ¯˜Wy¬Íx¸²ú"TV±Ùè+gÏþŠå²5‰Çìç_ãÕNðì+°?Ä÷/¿xÔÉ3/¿ ·j;°žÿñ§Ì½ìÏ]¸pA$!\Ä *©1yAæŠ …Îþås+XÍä¡ ¯˜®\äá'3'ñ+ø‚± ÿüÌ—~ ”ôUh_Åð…WHWæ_† å·!Æÿò«|ûY1œÎçWypQúÙs¯À­Ão"Ôðêë ¯®r²K•}•töá@æ2¡Î¾ ’ãêêW0¶æÄu•‡- @P¾\èÿ⬨oò¥çVÑ£s.tös¼Úyúô2›û§çÎÑ>¿ÎCÌdÿÒ9“ØFp ñ§„>"‘lE…Qyö| s™¬³CÀñå—/\øŠ¬Hr:ík¯½„òá—Ï EtŸ{ZP¹§GmfŽWW_{ ÈÌ~ ª´«P¥Á È¿qþ_òÀen ¾ö cþ›ÕUˆÜW„Ò.ÕvÒÙsƒÈnÂÀ|v^c| ^d3>ó0£qeõ‚lé-£1!à"æÆ€ãǨ“1ÑF4%a‚ïÊŠJ¸(óo j øÚ .„ÔÒÙ3ƒÌeÂ.@:{~¹L qcN$ˆìи1'Dvhܘ 2W4nÌÉ™Ë7æD‚Ìes"Ad7Æ9‘ s™0Åj éìùAæ2tö "{¤³Ÿ\ÙM ýD‚Ìéì'd.Hg?‘ s™@:û‰‘ÝÒÙO$È\&L±C:{~¹L ýD‚Èéì'DvHg?‘ sE@:ûÉ™ËÒÙO$È\&Î~"Ad7tö 2— !5æ•‹øf x_Ækø0ñN˜ŒS9žXæýbSåÙ{³g™Ë„@g·›8¦úÊŠxïŠ|iŽ?ÿí§9÷—¯½t¦‡—­Gž=+È\Äuöó8Ö:xV1Ž».ëT ؘ}¿ÈteåÅÃ멘ýpÒæ:V ²›èìûÆÀ;ë.®¼†c5âhºâŧY¦Šñy÷÷Ëyé,¿!e³]½L sE×ÙÏ‹—ôÂ[^¤w•/£Î4]UoqϹ¿_ÎK‡‡HõŸ“Ξd.Ý~ræ·äÛWáåíåø»9¦’ê¹÷—£û¾xÆ;ô–…w§«— d.ÝêŠwU/³iÁ2?½ÈΞ Dv4½ÕyÒ±œf—ûù®4çdþ¯äοð· ª§GËtõ2‚Ìe‚®Æ°l¯——¢¬HºS>{>¹LÐòÙ-ÿ‰ïyié j"Ф;]½L sEÓÙšœó¹<» gžu“gŸÈ\&:{[zø¶Ã?ÛC1ž§U2ɳOd®b:»-¦f·a÷¤ ’åÏÕ(¯à@u—<{V¹LtvéÙ[í6|æ6Bž=Oæ?ºz™@æ2AÏgWSˆÙ½!‚Ïõ×)fŸ È\&èùìE¨1øWâ#yö‰Ìe3ªì6ÆìÐ÷3̓Í?L~ïyŠë¸.m9ýʧ«— d.t]Mácˆ &6?ìßyö¬ sEÐGgGQcw»›f*¶fì KNŠà…7ºV†rÂÓ†<xÖ€‹'¤‘ÝMg÷õvÐcÚ¬pÚÜÍšò6h8Ì/Pê9|©Å Ä´åÄʵÄó¦Ê?]½L sE¤³ã§øk §4[6æÒÛr©í°n#C9IÓ/e3€Èn‚¦³kz;¶¢ÊVÕàÃ[N›GÿàÑÛø|p,QÃeéÊ1üá?,•®^&¹L0éì<â¶DìÜ€lßS‹GèV“ñ¹ª—"ŠG“Ù?I_NÂÔjòOºz™@æ2AÓÙ5ˆx9í?Œ­þŽþâø"þY³g™Ës>{64m`d¼$îç™å?5†eÓÕË2— &=íTµ¸âæ¶ãd·œ¡Ë‡otõ2ÌA¢ÎžÃóvsF^HñÍ.éìAd7Á ³§ªüw«…ž=¶ÔzÖBÅ}¸òɳg™+‚D=ó"fÅ–7ºàÚùËõËi’gÏ"» =íTå¿‹?æD×Z¬å _>yö¬ s™`ÒÙ³NAAÇÕë»*h®|ÐÜéêe™Ë³Îž *ÿ5yæÔzXn9ÙKŽåדΞd.ŠKByŒ/‡LHÒÙ'2— Eèìʃ›¶KZN:ûHA抠8Ýit™Ñ7í¹Š'=3ˆì& ³·„ÎÞ2èì 9¼ŽOž=3È\§³Ã;j :;€ S.éìyAd7¡½Å¿Y§ãÛ9V‹{vÒÙ'2— Eèà6d=bnLLgg¶Óº|ÒÙ3ƒÌeB:»ðÀ¡{*‘Î> ¹L(Bã0Ùµ©-·XCû>Ìèêe™Ë„atöð”ióA>{ø;éìc™+‚Âtö†l+ó¸Og|E†@:{fÙMBgôpGzö¶Ó ô“6Œ3ÀÚ¤³Od® ÓÙøÇÿòÇ‘Áµ~¿TÒÙÇ "» CèìÞÂ)å´‚üõ6´ŸòÍHg?È\&¡³7ÄøàÚ-[Žƒ~™5‡*—töÜ s™0„ÎVÔ¥Ê_g¹5vÒÙ‡™Ë„btö†ÓÄñ¿,ÆÄH1NÃÊ;3¹L(Bg•øß¼pÃA ãֹ줳d® 7¦!DuÆØS5öPIgÏ "» …èì-iW¾!¯ K»NÇk[m7f sEP˜ÎÞÄvSÿ}r\S&×Ó¸1‘Ý„töúßeŸì¶ƒ:$häJ盧d.ŠÑÙQ% â˜ïÂÈêb´vÒÙÇ2— EèìZ棬¡v¾E@ÓkHg+È\&äScç7ð]xBI‡ÈLB¶û~]¾ÃVÿ9uwòìAæ2!Îîg­wTÔ¡ –u‘ó<Ža–Œ@„üŽÛÈOÒÙÇ2Wyuö®Ò_üÏnSÆìspïØØ²¤¢wËV,Ç'A³›]x'=3ˆì&äÐÙQ#q ‹½ÝvZ"ç± ñ –Ç|/5¸bfu»6Æ3]Ï º;éìùAæŠ ·Î.ü¹\ÆIÎç,¯)u¡Xaç΢·,Ymmúý˜Hg1ˆì&äÐÙ­ŸY0øº¯žFwÎXûtòåòÑK·HgÈ\&äÑÙ-áйGgâµÓ=a[×/ÕÕàÏïÏ&}Ä s™SgÎÚŠ’¼ÿ¡ ÖšAw'=?È\&dQc„Ø~öÈËlRˆg˜Ð»ÙôvòìAæ2!‹ÎŽmb¦ºÜ;¥O×ç`«–B:ûÈ@æŠ ³ÎÞ,ä,ÍoKY£uDûjÊã’ΞDv2èì¢eÒóûYù(è1ËV%’Î>¹"Ȭ³óè£;ç¡|ž#€ C¼k‰töÈnB"m6,Éñ.q¡®00Ïtöü s™Egç1 r=/áCê»c¥?.éìYAæ2!‹ÎnH¹ïG%=?È\&¤Pcë G·²¡›àâ]ãwןŠãÊ\aPZHg/d.úéìʳª¾H¯%öB{›£7:ã[úë˜>ªŒ-Çš!½ ¹"È ³c#Á8ÉVán¿(>äÏCwKÛŠJ:{fÙM裳k:7ÎËŒu‰”µÔ>›á¸2Þb‘Î^È\¤ÕÙ» èoÇÂI_Ñiôkß{A¬<`Ø'uð¸2¤³g‘Ý„>:»¦s·£ Êɇ‚vÍóÁ3ÛÝÅíYËj…=;éì…€ÌeB ûÕER¿˜¾e%›8áApÀæ¬Áz;éì™Aæ2¥Ò¹5ÇÎ0tç2¥K›¨?µ¡l)·Âi˜ð,¬ûÎ^È\&¤Qcô(Âç/ ³Y'µÚ’ù åÄeçÏŸí~ïÕ#Ïžd.éìRa_ÆÎÜ) ¶º1–cYLnÂw@0‰ 7Gk*•töB@æŠ ­ÎÞm@¢€lOòy­< È^b,äÙ=áÌû’Ýåq»jW"½0ÙMH£³·ÇwÙÙ]Ý¥«‰æÚCžÝMôìk8rü<ÒÙ ™+‚Ôùì Æzè×!Œá¥°³Ö‚W¯ ²ÙM™ðø^ŒÚIg/ Dvéì8ÕEõ°ð¿”<“ã‚õpVnWÂ(¦k©¶ZÒÙ‹™Ë„4ùì–æVûg „R_Jž–ãŠAÂs£›C¶oS I:{Q s™0HgÇœÇl¦ó_Á¡¸Ú Óö˜=ŒcB’Î^È\&˜Ô=C»©Ôaà¯ÞðÇJ:8¦·ÃñŒ£ü’gÏ2— É:»c£ª'ØNö'M½Ü´8GUNmíéì9@抠¯ÎÞPo¿+±„è# 3çS0ž…`[?‰{vÒÙ3ƒÈn‚Ag‡1ÔA]÷™Žd?Pkþ–…î§að$ÿ|,ÒÙóƒÌAßšøÛ’‘ênâ—ÄEfjvIg/DvL:;¼¾Ô÷“ïÒPLx×Kùû ,‹1~#žtö< s™`ÒÙ›˜…ÕìʘWÚ.·c{Z¡7Áÿ$>~;éì™Aæ2Á¤³+¿ ü›Ã7=öÙ?¡4–ñ›X-x|ïH:{~¹LÐÕ˜†?þ"°Œ3Oñ¯/ÙubGò×Ó±v/Yøî%™†mª éÝéêe™Ë„Îî#¹0|G5Ž¥.¸žPÝŒf­»¡n²ËV#1޵OƲåÙäÙ³ÌALgo¨¿Ÿ0Öàs]Áõ¾DKJä Ø?è4Äx¾DL¨©7xìÞÄQò¬àÍ|¤Æd‘Ý]gwZ-ËiC–£ôî<º°Á¹–úìŸÐ)9=€h@u0jâOuÜ6'~[ž“jY%Ïž d®b:»ô¤ss"rg2’Hrí®)#T ORxv¬tñ½3à¿ölÈÑÂòiÓ Ïž Dv4|ªÓæìã“VËa˜‰ètÁµ'§ h±yØ­—Ü1;êŽððhvm¬1ðÀ½ïÌæ3üŒZAbÒ†:^ s™ ëì/ƒ_垔Ў|§Œ$ÉîÃÁu|ÀŒÄË\³¦³cö#ö 5R¬‘ÚФ u¼@æ2!¬³ûJxܦa×Aþ &»Z’¾…ÉUl‡Ç‡òá¾>~¿kc Ež=È\1ô¸UºØ†#ß †ñ;Œ% µbÚ²}¢æÂçŸ5Åhð˜yÉŸ2Vxdø¡_t3 ²›À´öRK©íLËj÷[TÞ†«s@öfõGiç¯ëÚ? Ž^È‘gDö°g(‘9´åH݃ûSжµCMÔD¬¢+㎻۰ºñdzfK-Ææµˆ9<:]O©“"» P´yuUmÌul/;¨‡8~~;,oñi‘ÕħmEó×Û-ðç0º/ í-ÙŠ;(¡ž Èn€+²0Jî M›Im»©å•ãíÅùvÅØIãÄð' œ>Qð\¸wÇ‘k(„I "» Ld£Ø¶ôª<^o£/Žƒ‘µ?fïðvU?k'ÔOÊÏ_?mA›.wíð\i3FŽ= ˆì&0ÑcBåÓbèÞø‰z†Ê'ÇDÐÀ„íKC Ò³7uŒX>=?"î Pùá»SÈ 6; c^]xW|çÓÔ'”ß®ÆÕ-¬=Ó¿Çੵþ ûH0=R·êÍ÷¯ShÕylÜè¦yƒhÏì%è#ƒŒ,C¡Áï?µ„Ú/”IæõTÖ8®âqÏÄÑ,$PèFŸ.FDBMÛ ëë ã¥'ýì‹q7ÖXTÇ7L¹;÷·‘É crîÇŸ#j4ñc€qÄSý„Ð2Ôµíæ@ÏÞì6[;ϔ܀'æYZvÿ÷lh‚;ƒçN#7Æø.§¢írlÐïÚ2GÅ¢º§š¦‘ÖÂÑ^RœÌY]âfȪÆi;)Þ‹*¶É|žGüªæmG©=†ãøÇû£-wÿƽq ý¸kGÚu§ñ_²w-ÇVœêNé”[º”þÂ俢ȯ'FmÚlÎBm½‘⽤6f¹7¹³õó%“ƒkÌõzsªgTXÇO—5vxWA^r0ZӨܴ©àCò´oŸOöÀ?1rìtNûõù,èz£¨£ã0§Çna6ùà÷¢:ív"(‚•ÒfóB®<îߺAÒqü©Pþ㎽­3|Älg¢«÷±æ ;ÀqI”gŸÞ©3jÝHï>5Eh5>ƒûu™A®ëÞñ©m5Ä™²#mÜ-WvÓ¬›†?VF¿ã`´ÎÿÁˆLo?­sgÂoNœÃðd6[¤íàýlSòÏ?¯Q{.O3Ã1¶Hñ^Ty¾rDëþͪL¤7 UE<ÅÓxüóa±úÁ(M$5 î¤ù0ð_¿˜=͛ᦣõ[á^¡LeѦÐד€ã`ØMßøL >{ü6ÖJ‡+?2Xê;óoî)Gÿ ª¦ÅLãÔ÷”£äº~ö1+\ËqÞŽô ÂëŘƒŸ¨§C/ԡ졞$%Årí®õÜlç5‘xHn{ŒkÚ—ì,…†< `½ÞA¯àümñ~€¨?„%âkáy l‡•Q<¥ò˜Õ¡ïä/¿áÀ¸“^Oç4z÷ÑÔm˜Òö¦ý=»ÈÒ¤ïNj*ïØv{4žÝ5Eº8Üœõ±Ø{HÓNÛ˜ˆ-±þ(vÂÿ´Ûþg«åäµ–aIo4± êðÞ‘)áEÒt°gWÓöOGáÙ£Ôšµ‡d­(¹Ï·)z5<)÷ïð¬=GSé÷IS«á€¨oh±Û™Œž&΃<éó¸go÷Õu'Ý´`¥YX¤Mü‘^ä8_jÞaì‘üÔ¾"Ód'}l(†ì&·_X„Mš8*ÑzHÅ€·Þ#j˜/¬ip”"†oòo6ÿè"~‡6ƒ&ä´A¯]èqåðeñhî™$6éì!5:nƒ,äü-샤¿ÁÔ[½Ï84uöÄßãøYÉ×Ùå9ñšˆýø??ét:V×vZ?kØ]̶hu¬ÎßuÆÍÒÙÕ5Þaf¦³«7ÚÁHên «39jä°ˆêìÚÏb¥È‚T™˜Î.Þ Ûxòüºý¨Ûè⻈;¬Vç‘ÓákŸN„Y3¯³#—Ý”nÝ+Dg·ðý©ø¾ŽÐ¸î-X‹/^gׯ)rH²Gtö¶ÈýYëg-»À˜«Íý}GôwyÚíîCF¿Ñ éì9¦C{ötU·uvôì,h1•úø´ªo]g×y½‰ƒ^äCÑÝ ³ãïzÊë%|s~™;ü¦ì“huPw·¬Žýä±ýxÀ=>¿Ê<*>‹r‚:{»ý¼¶Âj­ÿ?él;±ÅguÙœÐ6ö²ßßoîóø®ÓÙïþ5ÿhÚ `4ìÖÏ„?Ñ ¹áóqÝ$¤÷Ý¡À¡(ŒµâqŒtTT]5dˆ~Fn†y–‡ØdŸ{jÆÞ¾r“»ËÞ¾Ræ<_Û,—7?øö:~}c–”ËÿCyý½/8Üï—7ËëoÎóHXÐÜw:V›_ëŸv[à÷ ÏŸ¨ÎþÔê6Ÿ>튱ÇñùÛ†fµG'OøM¿¼laî¬;Í–±^ÑWtän·ùŸ?m:: ›æ¹äº ׯm)²M1dcÆÅe+§8ÙØ82ÙB™Þ(Tp­X§ÙÓy}ýÆõ7¿½ùç9ÿ²¹þÏ_¿~­¼É±± ÖÞ”ôçaÎ88íè’üúB,Ïðâ1I½Ývøç¾ƒíoÜmë[š|†[ï¯n–ß›ÿ"çñÛß¼<ß{çyÔ÷·r®–óˆOŽËïÿýÿïròÁèÖ“Iâ¦%Q΃'/ ‘{ÆxóΕòÚÕyfÍ_ådæä¾Æø:'õ‡ëœîë•¿>S{ƒ» Ö>žÃüû<Šï´–ƧNÆmA{ë~»¸~Ó¡³7Z-Ð"øSŒGßPw‡·¾-Ï_†çÞ&¿ë/ÏÏ¿ËM·ñ&>¹AÙŽ÷É7]`?n‚‡o=y 9döþu´QÆ‘QÚõE‘}àé'©Ù|{¯7ÿ§eŒÌ/CLŽà~üÆúŸol”7×Ëk]»^^Θ69ݯ¯•Á»û×qîÆ›_xçÊ•y¨•=âA-¾Ãjk¨ÖœÝ‚þô]Цš]Æ‚_ÿpùÚ n¼Íµÿ|c“[¨| ÝÁ‡è6>ؼô#Æ}Éú:lÛåϽv Dö@f@´>êà9á…í©ÊHŠÛÒ‡2Þáü»ïsÒBT²þÑ5NÞMÎõuÄ\ç—n³ ^|}sms Üú5túÜýC´Î¯qyMx{¾†_Mˆ†: Jà;f[í¶hg=):ûÓÇö¹³^øqÙçš×>â¡Ë;Wù£pSÜûÕqG±Á­³Žbcsóýwçß¾,"ëó-Ì>ju–½Ì// InpÙ#yëfÆŒ¸~ZT“é4cƤ}s\1/kÜ% ×´ù>ÿC×´©Ø|ýúupò@ÎúMd7Ìn\ƒ(ç:†ö—æy0T¾òKŒ?ç;6è1GÀ» êì71ž·¶±yýw`$[û­–µ¬uvÇ‚¬ˆÎã§ ’?êtž|á=þ[¹ ‡xïÚzvð˜þ2÷ ü£^† Ý5<»'Ï0qj“yQoÔæ³îõÄCtaþOÖ7¯Î 7ÁæfŽ+Æ/¯ùãf§e7¸wR,ûÒxöâtÎýý®µÚ¹Õnv±ÆÍ ÅŸp›è 63‹ï¹ÆcŸkoÎϱåå,aÌäݺ7Mž=ÔIÅ×E£˜¯Î_æa‹pÉè×ËÊ—çj•ë—þ¶ÝrZÎþØ?Þ:û“'v·óȱ°©ÉkÛÜ`×®½61Š+g¶ÏÇk›Wæç¯Â#ôÒ¼~±ÒÐ,£Žùŵ 5щ½‚=rÛîð쇘ûÉcõï@X¾þ1T;1ÝÜÌ~ý „óG¹Oo8ÆîÙ ÕÙ!€ßeû<kC“1ãž;f¶­m”ù4»g@Wðñº±Ö/ý} ÂÆÇ~›ˆ[Ofõ¤\{¬“©šzä©Ú{ç=ŽC•ª âJyX·.À믗þ#÷ì]çQ§øöñêì–ýôéÿiw¶üÎåÍ2÷À`îñ˜/‡[ÀJêÜ& ¬q²§º¦†¯xù4‘]™@»ï¹‡(ñBsÄÞùÓkÿ3¯zò—¬ŒŠ(d¯¾¶¹öáú›ÿÉÆŒ({¿0ÞMDg±S‡½syýÆûþ!þD°ÖfU«ÌÆÚØÜøÖ‡ Êƒ€ûñ{)™h«¡#Ø0md—G½>5b“ÖM!ˆ9ÀvÓëׯ­c«ŒWoØ(koïÍŸÆ|Hèãt¬uöG˜ñdîí+è“yè±¶ùñûñ§×ÆŸÿyvë|°"$Ü*`òËóY9&_„7¿>­dÓ½9Þþ&žnâÚáTçnl7oµ÷»v§Uï& ³·:-è©øhþÊ&Z©¼¾ÉxÔwMÜØ]ƒ|nЬ‹rùýwS]﨡:#MˆT—ûÌ ) (=ò ¦×ƒì¥÷6ñ â5þ}H¶£g_¿ve¾Ëëul_?¾:ûÓfÁÌ_æñÇЖ‰ãÊ<\ ^ƒBÒ$¼‡ÒÓ@©ôËÇyjÌ4‹Žb¯k~õ|ºsÂ_ú³?ïöîpœùì6f,ÛóWGAu4Ò¼PÛyêÈøƒ<óUœ£2.ïÉit÷çŽŽŽ ÿˆýáe‘›^øEäÏxñ¬¾4Ï:v“G2MÛúYK½qvhÝ}¼:»ÍŸOͧܳC­´p®ƒõßü?A3èF`—Ãg“mù¸O/öæ"˜£ÞÁÜÛ—?†ýý£pX“~ÈCRèÅ úô)÷ñÁ¿?­g/6ŸúÙü!x¥,ª5E{^¸ô÷2|1Ä0êšM¡¦œìÝ5=“ÞCÇõɸ«ë××en“?§¦³ßnýìï:O:ÐsõXéìÿWƒWlÞ¹Œ þ×T.P¦ZÛ¼•TT‚½Ÿ'’¨4|šz²‰¡ªÆŠU"„BjyíÛE´˜Fu9ê¾½¹ÚÌ¥¿mØ¡§öaž‡cÕÙç¯\/‹ÎY2Ù­PÜ•–1cF˜¯›Þƒ79*…Qh·¼!!ô*¿mU×Ï篮¡gÙ,@lŒû«2~ kߨܼô†½ØÚܯçOg2:;`n¼ÿ‘Ìo,½ ûÅ{!ôʦëKóžÖsÉUŠúD•õ˜yÓ/äi2ñÉ0[Àc¿þñµõÍo¯C-@¥”7¯ÌÃøΣΛûõÎðùí#ÕÙyõ¹%î«.ŒôbAsYô*—A ôÕZ+ËþkÐ_éÆÚ¦jCÝ{xAª×µkeSJ¯án<°¶¹öæßá Ó¯Û´`úÉ< qŒè’WOÅ5]«Eã '©æ¼Dç$þüÆŠÙºjwâ˯aÒ»q6ûFAelµQŽ<ñ¤ˆÈêìØ‹z‰;ËiÿËœÙCEtÒýPeö~¼öÑuáí7Ö ‹¢¬§l"ýeGEÙRÊ¿9vñ‡(„0˜”„‰§2-Œù"¦‹êÇìÁI©a—ØÛ—Ëk2âšL7¯Î/sÌ_¾‰ìåuìdz¹qy¾óØnv÷÷ÿº»ß~<÷Ñêì–ƒcÔþ Fûbìí?Ÿ°yMÏ+cŽoYu¿…Ø"vHI‰uÜŸ¯áÚ7  ûÇh‡õXÌ^F_Ïm»¶YVAŒ|ú²)cúññìxNÛçÿä\Eì¡ÏPt8×.C7œÍ7%Ù¿ÁøôOÞDjƒ÷Þø_¾ áL¢yX»\â‘ÿõ>d‡a ðÚ^úQ×·/A~LgÊuö'öS¨]t›Oþ¥–M]Ãà ú^mü `(ëÁ¨`@ØáÏÀP›P/*Ë€Žoýö{ߎuY ¬0dôIå×§ `¦‚íhß”Ë&‡ˆ© aúô;—±£Æ5‘“6ÿö{óÐËrþ*W®åÙzî«Ø­Œ£@ðkù&:®wÞƒòï\æ7Ã{}ª§¨Æàh¿]N¤§Íý}|CìÔêìûûèÝ;ŽÝm·ç/_÷c<üÛÙ ñõuô Ü`åæÊ¥_ÝfG¬äpß1TYû< .Ë©Tbð¹Á«ß™êUÓ‰é'{¤}¯wÀÉ 5¦ „D9á²Pƒ?¥çß}ý78®?¸Œ×–?€aù:zv¼òßëßNöì뢷Ã{óˆ`Ú<:(b™‘êìCoHt|ú¸ƒñ€¦‰ 0ÔFc9î xÕeYx…Íò5ÐqùýýK<œÓá6PÃç^á¯l„º.”åëëb@µ©${Ÿ—©Oݹê8òØÛWUXíí\2¯#éÿX†/à´þÂè}tU†1o×ðJ¿0f ª¨eX/ý§Ž †c¸ÇÆ4ž}ˆqbøÙÞo?…ØyÔ¾#4†+”Ò³_.Cåfyþ=ï]¾ôxÌA¥gý¯Ì¼{㘼ÿÂÂ{e«+ñ€}csSU›xöÍ¿ŽË?5ñK`àØyM5ÙaLo~k‡'ÜvO×ïÀµâ—“üÏ€Äï}A<­á•üI{ã!Œùv–!; žÎï\ƧA²gþm^ú‘ƒõ>È{<:ûÚ›ö|ܳðmLÝ‚¾/—¿0÷=TGÚà% ª kÜ@Ë_dËï-/ƒçxûJÙØ\­±Ä„°iŸi\ôë¦GˆÃoþJ9¨©«X^+_Ç,ÖòÇë×>⤿öþÞ(ÅÈû¶ùhò-£ºö?ÞHæ:ö÷ƒ›ÂràÍõØ>}¤:;¾) úâÛ>—c’×?ZÿcrþãDëÛÛÐ(ñÍKóx…/ÿÀ¡ûßàãu~¼¾“H þ8¤Þ¤¹1Yßú1y°·¹gÞXß(Ëî²l ,£·ßüÀÄÊ;âCìq²u7pDve^+¯÷OðÞÄÐþ*´ îã2À§ýýýéÖÙ»ÍÿõŸB?Bgþ>ŠñÕ B $¾*µW 3]þôOÅcZç.Ã]·Á7ææÿjöIñÞ†h°‚w<\ÿhð82G4/mʹþóyay †éÑ[¯Ë"æ(˾Kßú¶J{Ô5ù¼…™Í2'þû "®}"ÙQyãîÏršœ=06Øã*{S¬³·@íÀ”»÷ùX•R< 9±¯@Ÿò?÷Ãl Xfï¼¹üœìïnðÈ~yÈÏmso_IkcÓPž|b€Lû­CdŸ®€=¡Š:åd÷ ºVÚ®7Űwb0nè‘d¹ü‘œ¢r³¶îåY^ÛXïŸà]ŠÝÆØA¿ ŒZÿÏ´ëìO0÷ÑzÒp,fòÆ»ç¡ÕÚã´}R…šµaéÂ@›ÁUº‰­Ù¦À^Øži“`³–½ú7ò@¼®Ôêæ¾âm˜>û¸=î#mÏC¿ÓxQ"ó *˜°ÓA’4±ÇBšjDMÐLS„‡7dê™»vÔ°qÂp·„LöÇç¯çʳ{–ÅyÈQÇ Ši¸ð6Ê‚Î<Œiq*E3å_G+7¼^—Ų,€ö››áðZW¥öwæHü®ª ¯*tBç±Äz®<{Â>µC[¼æ>QÈŠþQÓ/£ÔŒ¼<¢¾†!+P‡…÷쌛›ÝшY)‚úX•µ€¡ºÌ°ü=32V3áîa8ìêÊ acý ¨4I>P¯)<×Ûì>¨ŽsÕ ¸§5n¢‰½Ö2¤î‘”>{´©e団÷Џ¾)|3ŽÌKÃ!p¾û¢ô‚Y帥:kQ hJí²ŽUŽ´±´ªÃ’Ü V_¤ÄýÞR±œ £’·Y<{ÒÏïz;­yŽtPžAöÑɆ˜Ak¥ò¯â…:Wîð¾È`™æfw(v!#45âºõ±]³ˆ&¢wV SŽáÑ/¢ÉlDY5 Î ò-Pt§§û;óö²ÅÞ=<{¦úì¶mCATez'´‘Z(½»Ô5ÍÌD90’Ð ·~»<û#‚ ɯˠæúñWq‘Îo˜¼ñð•ï¸îW7.A®²nF,E#«“$ò6‰gOlÛwü¶§žÇ¶LèÏ輂ZþUª÷žeGsu)*½( 9£ — ùÎa‘};ÜúøÐH?ߎvŽ0KB¾úÊ\¤åHr„Ú²¯+ôs× Ú^¯#•b6ˆgŸÝÚ×ó­Ð÷d%©ŠsU]S÷´GÚyv¸ §À!/Œcv£óÄ”‡=JkRÃõ7žIP4s=`mÔH¥ˆUÁ®É *×ÉWÏ/•Dˆèä‡Ý¨WËñì³ÛnWvÉA,#~'zŸv¾7d—HÍÈ p‡È±ä£¢ƒùÆ]A®ýöö…%É?rCÝ ´ŠgìCÜnù꼕/|ÿ½ö±ÀNXó½>yuòÃ]dõf…;/ž}ÎhŽm»nèø_µŽrdL¢µÇûõHá‘§}£Q±ƒvn¸ƒN!Ï®Gâå!\Ô4mÿ×Ñæ…½Zåð®£ß†CáÙ®8X¹]d¼¼(õáÊ?û¼ÒΡ®m}o£û Î™R1¢: .ˈÕ}ë Z˜ ÆAÞISÆœDÉ“ˆªÆEY)È’LÌ*^_O`!æÒÉ™‹ç5”"ªæY’(WÞ‡º1 ÷í"¬¹}QŠ–˜nFŸcxÅi‡£ù}°t·–½² £q¬|ó†¢Mê±K7f¢`ãŸU™ Fý.õÄUÚë‰~:˳j’w·BŠ÷´–Úˆº$ë芤q™c=¥ÙBž:û¢Zï¢ÝT¬˜‚+Ž'œd·Ü‡˜0±Â5„ŽÝ®ÅH¡ *ÕÌ3]‹°p]ÉW<4ožª¼|§(wÔ_ÝçqP#À›(ï±*t¤ìŠ—GRäDëF«yr~^7ù)¿Œ5–3g¹Ž:S:u„× §ÁÙzxö¤ž×æ…ÃWµ3S¯³—‡[7Mõ­ùt‚5 š*צã C†CªÒÍÿv/#'ŠD~øs´6úYyÃÕÉ÷WÓtéÒþÔ[ê‰Ì{FM'íÏ9±ƒcƒPa¾;Tn®ãÄ(ºln8Â)L”FžÝí÷ÿlÉt¯ÓÙycpÇôJÅY‚P§T¡Ö#Y[ìá7<¥mÊB¾túŸÖìÙ³íƒ:¯+ãÿÝ¿rþíÅËܵzÁÕÖš~z©§¤sR#a Î¬.¬¥ÿø£F·þ¸‡{ñlˆ…õ–Yƒ??Ò5)Bzc¼aËUhº€‹«õ±Áª•å¿bþJŠr8£|8*BH/ï(8 ] Ì8çûù¾(ISÙï–—V ÕM&°xN;þžO‚˜ÿ¶¹wµM³¹§ÂÙZxöĶthÓÛ¸ç™ê¾ÎÒ#Üõ.·e¨F’×Pšù–ÅÔBqS¼õRyƒ¹AŽUÖÊÓ´I1îP,T—)Ü--Z4×ô¸¹Ô…l…|:9X?Àä AFdëÞÅØžµÁ)Šlúé„]D&m{h-•:qBÂ…¦QþÉâl :ÿ^7 ½ž‡5Ó§ÁÙd›kÔ„®Lϧù¶ë†žR…·.³x5Ÿ5•v?C«Æk³)î3A7¯'®%°& [»aXºUŽ¡W—þ,/Á*¸ø›¹tåè±`¨\-®™äïêQG»Édtt~'J¥Ñ1Í (0‡! î ûºcaE¨ë;ÿp®BŸð  !úžºŽoAÞð½âZ=Ü (rÜBþ­˜>Þrîƒ:»Åœ¡ýç¶ßõ:` 0FóH:·gfjZºàÑÓûÚ‰J³}³ü±C~Í¥JÓK1Aû(šXÊ ˜Fy¦7YûC°–j pÁ]ê<ºSÕ1e3ëjS¿ ôû~ºè¦ÿq^YöïįßD‘•€’gÀ ꟼüøotf:è†DWè•ãsãaCH(èXÞ3!Ï@WÆßº¨yèu;ê‹—=Î&Û\yö9Þ=:®ëÒѤ.$³Ï¶?¨¤PﲘÉâwˆ‚Éøï‰Æ¢(†:|q£TôXg²fÈ©A±ú¡!ç¨/ Î¾ß4ÆYR´Ï n°ƒdÑBIúÝŒÙ(¨s½A½çEì4_lÛýcˆ¾½Î•åI­FßÁ‡|¿ÒéÌ–ú>¢ §µõòì ë·C\öt‰…J Ý5¹D‹Yhžð y•y¤`ýáÞ„—-¿{Û!&n¥ÒËCÍ”­³duåc3€è3ô2x'Èé÷K‹}b¾hy€­‘gŸÏwwèÚ§«ß#O@‘"Uî©U,:ЫDi÷å·û<ëªëø2,Ž…¬‚€]®øD T¾;çF82[?µIñªfšõ£"Ö× ŽH,/'œl&Ïž´>¾­çµ%çú‚WÕÂvÈì-ü~¿Cû¯NöþÔ{Sˆb I "Ow8,½ªÕ!YyÁž¥èc3"NÀO£oZ÷ÎN™`¯“à ècm<{2ߟű ËèÖa# ´PóÚ¶så†>ž #–>®muÝÂxvY§ ~p÷åqC–Ë\¹–Ay ¤ž_+ŸÇ_T¼ œ¥Pæ;倓äÙç¶4ïxÝ5¯Óù Üëtê·ýö_ÚøËk‡^ÏëþâC‰füþ‚xvi\P‹M€‰Õ?›ë†›CM¹)ÞT\zv+ûüó/ˆgŸÛRÔÊ{¡RPî{¾ÿw'´ÿËuÿçŠü7вc cà1"¤ä“‡o×ʳÏñîèz‰{{móS¨ŠñUàs]"ªXC©Dù2å¹0`GÊòtn°ÄõÁN#ÿþø¸…âÚa‚ùŽÌÓÏ3·Bñì¶‚€é¼(¢bI\xò"«Kõùò¿G¼¯§$]缊¼åÙóØ®ƒgKl—%1вÎ-jT/´ˆ¹¯).V›0þþ1í€õЬ žŸÞ–gÿyv>*îâ||åȬÇá ´½˜m'g\U ¤RV¾Ê1¤újŠrxH½¦ßߪÐIPŽUS??§Ÿ-0és`ªž /ƒBÅÃÌ,š+a×÷®rs÷ì[ž=ÇmÞžÝJ‡¯Ț—áÉÀ…khvh0Økö#ü 0£ÎÚÔÎß½†x·ZQJäß/êðø_±¯O›¡BV ì#b£òŸÚ!óB53ž6ùüÜ=û–gÿyvwÑxlŠ^V8½Q®¡òcEê¦|õl§"¡¬íCâÎDû4Õ¨쬚@¯))Õ*_ ßÍç4xÛhôFù'Š×ÛòÞÄw:'ϾåÙsÜæÏÆ¤Ž#è …Î%¦¡fa£ÐšÁyö*~Ò¶0Ëv Ú; ij†]ŠY«û)a Û»w§h/­ª‡Šåu±j ‹h ÑÙ ¶<ûŠ8Ùòì‹Îlº9ŽkSlMCUC®Uª°µrHS€½$8v§‰êœ;*¯õú¾"JPÌ¡­xUÙãШ!…Ÿ¥ö‚囎„ q¢1“ë1ùRxöˆÛ‹b²äŠa!¶V®^lÏþɯ ÿeJÒp»Cý¦Ú +€@}H»Z–¬ÌwäÑ+ààX§¬|]%&Á~縜êÙ!é§:—?©êþŸìß:^Ïû…æ þÌPr÷ìA;((>¦¶8& ¦väÙôÔ–3 ¹/…Úzò7¯ <»ã(o<.MÒMûáùé9@ÿOe ö*.€*bù&³1l‚ÿÇì•7E™@ºiÆÓ^ˆçiæå¿*²šËE'ÂqÞ@þ<»Ôï-,NÆÛåa sJíuñ®mð,…Ç;yv倇0ëªzrüüùX­<þžÀ^¸!ãGáÊ‘)Øcü,Q¨Ã t‡øNYÀÆhÜ΢©ªMõ{¥ã:tCé'8îÜyvËÛ¬/É=ã’—g¢ð–Ûy]γœ,`Ê5Έ‚Ô&Z\‰J }÷ŽäÓ'Ì«˜:9~V¬†¨µ.µ{SB^T2ϘΤc…å\ÉZu˳ÖųoŒ-Ù‡!´vÏîÑô=&Æá†![šqO!‹Êq 7`1e<.Q7 @÷@´'HK#“W ýÏ<;rcXÙµÃ1LÏŸðÜ9óìÅÑM~¸‰ Ú‘ü†¹˜gwK¯ªÐ?7c ^Öa×´Æ[‰]ç5¹/­bT3ô(³Ë¤HŒ¡Éo£Ñªõs]«ì@Ì`A~ÿÖ³¯nÛÕ°;yv/èÿÖ ”J]CëÓ¬={¼zÊl”?.ÎÏ™gÿl ö4[³»n„[zU1ÎO›™í í[*aþBÃôt.|½<ûfÛöp¥ÙžÝë2ÃÝ-½¬F©¸ƒ]Ǫ«¾¯¼DKµ%}C·<ûʶ=\i¶,ÇÕB¾"«]3ϲ—¿SÁ´›å%Áê5Éòõòì›ms‡ë©—  ÿ,yUζŒg—Ú-H°UÑLí­Ô‡‘ÒÆõÚ±¥ªÈ ÓT™Î~ÝòË^2’ByöÁ‚s6HþÞ'8K$Ü}¸R08¸×‹>;Xá-ë±Å<;Åìˆ €ö|{Kûç*׋RüqÒ\ç2ë€.•K֎䬲ò‡€»I{EäÙéÞ‹ÁÂOxÐ×®ni‡kjðƒ%;3H{ðÁc/ æïâÙû}Tƒ†yøÎîî.Š/ÊŠrH^¹aè—ÚéÈ:»w-ê_þù¿ç÷`ÅàÙó?Uƒ;¸—Ýϳ–=™åŽò‹yv—³±¢¾ÛŽÓB<ó %„ªªñY_vì—¦Ù7RÕkÊ•ãsXÇ)2ÏþØÓ5X°Íèã“69\ÓÉïi¤}¹sFñgLé)ï›|"þb ‡ñþ­lwòìQî!yøN¿´{=Ëöɳ# ’â˜úêÑ: 8Ló¤‰vÙQI=Þi{ߖ룬‰gOÂd¹ â7Mý9˜|ÿo¼oü”„Éø­ûü^,üœ4¬§½XÜ9¤égã½È½ iñQY¬cÅÒŽãøŽ†¨ü·mW©Zó-äWfgâò$FêeåyÍÔ¡(@w;¤ªãŒg_“%@üâAê£÷ƒÉ4Ø “4°/þ äÎ<ìSŽ=z°h_ƳK†»ÈÞFwŰPWú8C&|}ÿƒ'À8r*¯oõûS}` ³'`²Ä¹¦ß“zwŸ†É`Ñû¦½üäûôv¼;؈ˆ“/Ãob/þeæë}ÒØu‹äC“ÃW°/dÙÑÑ´å„Ðþ‡ŒàÉÿ†ÜCï÷ÕðîQÙ6$ïÊ?[^Ð!îûÝ0¨öŒgOĨ÷‚‰È&ÉYeì ¾[ÌŽl/ùHrTbæ“‹?Iþ²—Ü‹Álœ¿N[A³žbwøaTÎÙàf@>rž,6Šº.šŠÚÔ†©Ðd´{Ä©²jU«*è°ßÛÖåÙ§¶ó'wî‘Ñ`LFwÁdìò™}z/&°ñ„q4s¹N~öÃÓ?G£xç¦ö0ñî„ÿžº?ëKõÙù휗èCե߯j˜¥R8ÂùîQ«štšœ¢^¿Ðñ¤ Zx*ú–±þÃóç5CÛW„;î…g-׫_#ÏžrŸçA|¢÷î“Ñ}a’ c²û(¹ ¸ß^Œf.›ÑhÓbzð{wF‚OmwêÆ$­Çî½ï;iï| Ùhø^Ä¥Ó²0[6 PÕkæ™Ñ¬´nêçšvv¤t„(9ŒäÞ½¿wM<û]e‘|C…Ò£®¿æîí>º5IÇ~?òõñìç›LF)0‰Ãèi˜ì‰¼¬ –1ا¼ô`æÒ¹o#?ej/i/™>23‡«8TÌhÏžÜ:Vh»6"ö í‡NØ®ïw-òÑ´3a€Š&¯)J…;W«<5M];R®,ÞïNº.b¿çYö]úçàÙG a2Hkæ`2^L-xI3(Ÿ½fV{b/c{o4 ÆÍ<ÓŸ”6ÌOP'aLa°~Ï>½íBÄí^]È?÷-¬;uÀÅû]¡T–‰û[2ÙœBU*ÿ jÝ{þÂwÃV_'{-U”ûì}î Û÷|öêóÒŪš? ¾äª¨ —ä¶×FìüÞ~â¯öÙ{Ñõº1–|%Q5Y#¾[Šj£Äž8²¬ÐmoŒÞ®”ûìÝî Ûù|ö¼²Ÿ¯ãK| q¤&MñO¬üÔâ’¿±šw1$j}önå®óê²áB}nñFÓ?¾pJÿèØyƒrŸ½Ï}a~ÝÿÜ÷¢eËmH„+—ÇXG[›dņò.®.°ûzîÌgߢ÷IŠ6Å›ŠJ]^‡ÿO­ªNzO¾eÇ÷†íí³Âeq7fg×9„ËŸ}H—Ÿ}\»>û.>û¸ v |ö!!\øìCB¸,ðÙ‡„pYÁÁg¯†pYà³ áRà³ b·ÀgÂ¥ÀgÄnÏ>$„ËŸ}H—>û.‹#¸1øìÕ. |ö!!\ |öqAìøìCB¸øìã‚Ø-ðÙ‡„pYà³ á²ÀgÂeq7Ÿ½ÂeÏ>$„KÏ>.ˆÝŸ}H—Ÿ}\»>û. |ö!!\øìCB¸,¦Åã{jkoå×]í?¼{U®-rÙ¯9Âýçû^þì¯ü¾ŽÇ¿¼{U.Åýö9ÓWo-gËÛÌþýç_ïp Än1…Þ:„ëÈ }·ö v8 ˆNb‡Ó€Øá4 v8 ˆNb‡Ó€Øá4 v8 ˆNb‡Ó€Øw¼¸j@ìÈRˆµ½¼‡àU^èȽ ˆýÄ’_·¼*N1Û"õV öOR¨Säü; öéEâÍŲ*Ö¬}ëCžåÒÄ:´“õŽÉí·3Ú€ØSä—‰ÕÆîi.#‰JØîVí!x$5ƒ8¦H.€“Í“¹M0Ñ{[](i³Ýübþ™bê!Œ)”DÕߊiâ#/™÷MÁ“\O²Ô÷†”^fŠØAS„B!³þ¤E«>r=EÄ´…7!Œ)Œ ֛ϽÍÓÅŸë]øhõäÕ#Y™Ó·|vÀûÇzòv^-zƒÿTž.1±»`ظ¥·¥¶ïßð&µ8¦ÐÙÄF­ûíñâç11±?v¬¦äƒË:±;Ò˜fÆÁä«Õ*Stf¿òÚÓÜÆ»„ÎoKÎÞ˜b¥] 9ÆDt¿éɪ"^®/sܘO@S<hæìÛÔ{Òºw›™]×vêa©ýLc{Kc /qaxÑ‚VfâßQŸÁ¸ ûœ–vÊËÉA.ïASøßMú§’š½Ã/²ëÙô´­ )'žØ1cZB ˆ_J¶ZYgµí ˆ=†¨ÒEφÉõP0N$×4±G˜—a$—cør–Ôþ̯_±¿@±BY¼±+ûkHP”TÍ~:Tîƒj{œ„J+r‰W)]p m@ìï"(ò( v8 ˆNÃSÀÇþã#`IEND®B`‚nagios-2.6/html/docs/images/indirectsvccheck.png0000664000076500007650000014307607436604443021406 0ustar nagiosnagios‰PNG  IHDRìl79 ¢tIMEÑ ´N_2 pHYsttk$³ÖPLTE!)19B!!)1kk11k19k91ss11{œŒs9) EJRRRJJR”œ¥­­­­µ½µµ µ½½ÖÞÞççïï÷÷÷s91k99s99k9BBkB5kBB7Š9†ki—¡s­o„ª‚sµs{·qw±„}·} æ$1Þ)1ç!1ç))â91Þ11Þ91ç19Þ)9ç)9Þ19ç11ç96á?Bç19ç=ù÷ÿ÷ÿïï÷÷ÿÿï÷÷ÿÿ÷ÿï÷÷÷!ÿÿï÷ÿ!÷÷ÿ÷(ó/»µ!½!ÆÆÎÞÓ ÞÞÞçççççïïïïççççïïï÷÷÷÷÷çÆÆ!Î!½ÆÎ½!Æ!Î!½!Æ!Æ!!ÿÅÁÿÎÎÿÖÎÖÞÖÞÞÖçÞÖÿÎÖÿÖÖÖÞÞÞÞÞçÞÞïÞÞÿÖÞÖÞçÞÞççÞçïÞçÞÞïÖÖÿµÿ½½÷Á½ÿ½½ÿÆÆ÷½Æ÷ÆÆÿ½ÆÿÆÆÿÎÎçÖÖçÎÖçÖÞçÎÞçÖÞïÖççÖÖçÞÖïÞÖÿÞÞçÞÞïÞÞÿÞÖççÞççÞïçÞÿçÞçïÞïïçÞïÖÞÿÞÞÿÞçÿççÞçççççïçïÖçïÞçïççïïçï÷çÿÞçÿçïÞïïçÞïççïçïïïÞïïçïïïïï÷÷÷÷÷÷ÿ÷ÿ÷÷ÿÿÿïçÿïïÿï÷ÿïÿÿ÷çÿ÷ïÿ÷÷ÿ÷ÿÿÿ÷ÿÿÿUã:pÂÑIDATxÚì½]ŒWv&x MVÃe2˜* vkaÝR‹ò ÅqW±D`Z4ÝÀxÛ-ôåÕÆ !‹(Ø`tÕÊ,MIh ‚Q¥¦3G5©¬>,Ú@Õ äv挜9Ø»‹}hL [Àb`D4 7ÏK(ÙôC3cï9÷Þˆÿ?ùSÌó‘•‘¿7n|qâÄwÏ=—¹ÂŒ€Mº¸@d'Ì ˆì„™‘03 ²fDvÂÌ€ÈN˜Ù Âáÿ§3Bö :lŸxN)fƒìNhútàé:›1`6ÈŽ†NÂ÷Sw"3!ûPüpgN‚vDõÒ8…d‡«Í8ÜÌ /Ör¼Õ³·ˆ=\\±cþ^Ë ôÖò|Ô¹¨²õø´à’‹‹)ÞZCÑ2fS¦a˜S(G²˜ƒ—-Èp÷ëiÃ)=Õ1’=fSÆ*`{éMãŽNdÏu¶“.@ÉbÇ]$'×Z %Ùð>ÔÃ?‰ìÉÆ:w²ç³$²;±«§•ܘS€É¢—×ÉAvGŸÄ_ñ˜}„H–t'¼C'ú-VåI¥žFqÍq#?wɲŸ¨‹ËñðZ×Þ‰]Eµ%=î{”»Î†>þÄý3÷~•}H$ûSiëO9Ùå4d`•É«E}vü6Í,¼ëÐâ˜5¼›«¡¢<ÿ«9¾¤ !kGIxðEo%Ͳ{¿¤„D¤àS"¦ž*œÒs =ÀH_˜cq/¨ú|Góõk³ÉÎâË$àèǪÁºÚ!~F|+H8qïgè´âÏ%áì‚õÈâWyŠpJÏ(BÆ8k¼‚¡…âGÍÿ­[Xe¢d²Ç{òI…0Ùõ29,²it_£>FV=øsjþÙņÈ>}’ݳ…Þ,ßÀ‹Õkë­?ä=ïFw¢)|tNʦ’Ïš€)SBɃ{GJâ K9…g—fêŸ"œÒй&`°¼EAþ… Wh'‰.8+tøùómn Ùã$ÿ”ÂE >o… óžr.0­ä—5¾œ“½Â£À)=¥*Fˆ’È'7òÕÛ6ºVðø!Ç£Ú™~Û¥q\òÎQub 9ï¤úH¬‡ÐS!î&õON陥½æ{µ…ÈÎâ®´“J/íq„ lªn†x ìw]K"_!²×²ÎN{——§‹wDíiåû)=­ª,{ÐB騳…½ð›r-z8qÅKô“œhÁ"ç.L|=$]°ÙMÃ?_(ùÓ"{"Ù#„¡ÈR‹ÝYز{ÅK>…Ä‚›ÍbO«ÐÙL»/Ù<…æý”žQ•d¯eÒAÿíÄ/¯E¸Þ”)Ç9ùB‹’Ý‘¿=Ó¬Œ²æzä!»‘xG=•l?¥'”‹ìþ+Y"ÙqµÈ^ãŽ;'Øv™pš˜’Èî¤2¸Ìo`¹ê!ñ|Õ¢Ì~:Ù~Jϧ Ë^ _Íd½"²Vœ{’pŸ8ÚO7¦pÁ»ÓuSÉ®\kÈ"{Яw"gØ\¬áÙ§Éd»–FöT£à‹—åX/ø3Žì©:{ü™ë:~Ù‹>eÉoæ§§ô|2È® $npµ0Ùƒz ‹ì$‘ìwXÛB6–:nÙ;ž¾l v£wãžZ9ÎÎa)ë<=8¥ç“LvÇ!C<ÙcÖ ÎÐB²"G¯§fÖ‚;‹l9×eµP)âN!á葹);‰?»@í¥øÔ㔞PŠeW×´–õˆw9Ò·Õf8a.ÒUI/SÂ-¦­9…¸ƒî7,1iÂÎâ äÄ(ø-º éì“EàeKMãBf³^PµU™¶s=(Ð_%RoqÖ/@¬ØcÕbÉ÷ü|ޝ}õ@}„:-%í6ðŠ.ÎSjÖÝÓHöê×o˜Ž¢9Örâ–ù-º6UÔÝ)ÿÊO—A÷ðô’Ý)~Å*¹Æeo'ùKÉbæ>|½_O?ž^²g^¹W6¶'¶“s½´C&÷ÅNØKIêOŠ!HO žb²ªóJÆWÞÉ•gšjbxÊÉN ø ²fDvÂÌ€ÈN˜Ù 3";af@d'Ì ˆì„™‘=r7¶º á/CíšPˆì©PÄ9y‚b7Nâ …ðtŽa9- ²—B0˜ìÀ—èm¤¢ˆó•‚Èž –0‡…GÑcqxù½èúš¿$šìTÿ¤ 3P¦"’hÅ';|ø^vëqâÈSÇÛBÎ`ò‡¿7øtËŽ¤GH‘=~çÇÑÓÈ&iË?™gÂÕLaÛ%Õ³Àa1¢¼èGŒ¯DöTÄ[^Ç#;“³˜¶Øÿ¢LÐŽËí74'`Ù}ˆPˆì©tÐdAÇ#êyx^qßñ÷¢“Ý߯>#†ì„JAuš ݲ»%…cñ<4Ë$¬øî¨.â®r÷µ·RWyöDöÑê4ŽF\ÍOqü×MÝ©©•jÊ+»1zÆïÃûéÔ„3ãÙGªÓTx99€„¾/ã96ÁTEo¦ã§Arõºv˜¿o?£&=zº&yí‚È> èƒÉý¨‡M"@È "{N8Þ‡‰ lâDöàÆÍ©zlB<ˆìà‰Ñ‘=œ\ µ°±ûKrpè¨Döa1¢ t„êAd'Ì ˆì„™‘03 ²fDvÂÌ€ÈN˜Ù 3";af@d'Ì ˆì„™‘03 ²fDvÂÌ€ÈN˜Ù 3";af@d'Ì ˆì„™‘03 ²fDvÂÌ€ÈN˜Ù 3";af@d'Ì ˆì„™‘03 ²fDvÂÌ€ÈN˜Ù 3";af@d4ºÀ)‘=a„µµaÅœÄ}ø†Hq ƒÈ^!JQ.k£ì!õ9AdŸáÇ"{ÄŠ:ôªå‹BÈ"{QŒ€]dØÇ"û4€Ø>Ì<ÙGúò„­ÂÛ'íÈñVO8PF\íÅ IafkII&žïÁ[æÄώ݉Û.b9Éî„~ÉîäØ!³]K,Jöè1sì5i¶å<ÉÆ¨ŸNꘃ¸úc§ ’:‘=f»–˜ÇSùËû"gÊ[Aüi«-;ö7q/Þ×àm!æ:žÙ×Á#è7‹ÜÜQ…sԞɡÏÂì’ÝÑm¦ø Бi UK˜öEîFq/´m`/nh5mæê{l(ËtcbVËx8fºŽÑL¶Fè€í¬¡m´ÐúSA,w‚»ª9ú q‡dèùGÜ6,R¾dož ƒÈü¤¥£Ïõ_iCdwBîˆÎp7Äxé”è;á¼VGíÂ;Bð¸?¼=¸D÷,Ù%œDFé+Ö|7YÛ‡úÏ<.×Ã#öWXlýnÆ!#dw´Ô˜îŽÒ1ÓµðÙó]w±µ}ødwâ7ì*hÙ3É 5ï}ÒUy*0Ûµ¤{äc’˜&n̼±’=¦è„Ìr-)ÑÎs œ4æ9yÉxŒ#{p…¸×±†ÑÙS_P Y˜íZòu¬ ïkè-P‰ÞÚÚ‰dOÜ :Úù2ɲ‡¤Ç Ùã¤GOë'¤c¶É<ÿ«F?ßýf:ßT SŠ1Žt˜ìŽ«“ÔÕ7¨É®!bÙµÍ}}ÝÑn B2¨ŽQŽöÝ-¬á kSCñ4ª½tÌ¥xúAdÏDNåYÍɳQ‚ÂR¬§,!3KvG·æá@ÃxÚ8…»•b_ÈeOÚ£ÊIÏ‹™%û#ÂuB5 :•¨Ä>N ‘!?ˆì>I`œÄ5†š[dBÅ ²ÇÁ‰|)¸Ýˆ G÷I)Ù“PÀ´u€¡vI¬/"»'Çœa÷X~­j·œIÙó¢¨Ê—tëA'"{ÁpB'a©÷SývµÂ`K ¡¿T—~@á0EAd Æâ—ÆýNàl4Ð,0{²S¬caP}Œ' ²ÉQ‘¾©©[œÐÜHc`~rIœ„ßDöò ú ŽŒÔ DÔFƒ-ÇÀ îHgwø‘ öÌQàº={%©¯“®®Sª/:ÇܱjŠ®a¤ 1ìN}É {0Ö=."^[’+FHU—/îÜÿ™ÙÑλö®ÇAÇÝ‘ú¶Ô57´W7àê†sˆìC€ªKó»æÉŸñd·ü‰½Gó]ÏÊ´gAlS"{)Pué‘(žì~/¸˜å?†©ÞF9È®Ïö½xþ¿ÔrˆìåAÕ¥#Ù…—îF͹OV/¡’Þ‘vœÈ¢ vãÿ—ïDö!AÕ¥# Ãľ%ú+²ä›!~¹È®oêy2qï .‘½0¨ºt„-lÀfg¿ Æ‘:´£Àq\7Žì7"{… êòHëëûÞAG:Fz ò™(Ú‘ŠŽ‰'»Øžé2hè˜,¨òªKGØOqõ¼(êló5Ñ(!˜y©:ÔÎDË.I­ùùÛÏ?YöR ê Ž>CœÇŽ<“°ndNÊ&Äõ‚ ú À7¾Ù1î #½> ‘ {QP}à)ãU Ù.—ìµWVB~P} ‚ÄSyW¸FÙì.NZ×=‡¸^Ta•Â)µˆ0Ù= û“.at ²ëèŸJ®&]€Ó"»JÜóìTcÒu8å úQ`¶m†e˜§ôŸmØt1ÓAõ£À8[LÉäüéšÂ']ÌtPý(0´ëŠ7æ©›šdÙ³@õ£À<ΜÎ)*Õ†¯…§DvVÝÜ9EÿL°í²Üt1ÓAõ£ÀLaO+xééb¦ƒêGùª†ºÌiš’“ T? Ìmãô¢mu5/¥‚È®ÀÀ÷åö±‡¶²×=]Sƒ,{6¨~„èH[yº¦m›,{ˆì Âg7вs{Ù=MSnÙ»dÙ3Aõ£Àlå³+ÏýtM jAÍÕ´ rÚ§â™DdÏÕéìO=¨~HgêAõ£@:ûS"»éìO=¨~HgêAdW ý©ÕéìO=¨~HgêAõ£ ³·MãÄ8î˜Ó‚Öÿqü³‡Á–kóIgÏÕB¼Î~ÔùÇ£ÞɉaqœœLÜðw{½®Ù±Žz€#>é’ΞT? :{ò±Ì?“sç'†cž³ºsò€?o J:{&ˆì ñ:{÷dñ ÙØmÕÍFý“ƄѼðS«óØ÷”—¯K:{Pý($èìÇK´ZH³OZ“&: ~ᯜü¿Ûü-‚—½vÒÙs‚È® ³÷–oï6{ÝÝÝI€–ýÈ„wÛ8Ïtö¼ úQˆ×Ù´Ûh6?j4€ìÍæ¤Éþѳmœˆ²=”e$='¨~âuönwé^c§U¯Ošä õ ?=10_ÌÑ‘Ò×IgϪ…¤xö¥ƒIó;Lvã¤mámiu´“Ξ ª…„xöi#{ãÙ¿2lô¸l?/éì¹@õ£Ï>md¿ðW¦!žAm«­YvÒÙ3AdWHˆgŸ>²ÿÉ£E%†töü úQHŠgŸ2²×/ü•av¸Mïxe$='ˆì :û´‘[ví9DÆP<{~Pý($ųOÙ[ó‹6è³>z^ÒÙóƒêG!!ž}ÚÈÞxvÉ—ÿõÐ['='¨~tö‡‹÷9Ãv>ú¨Y¯‹¦¥f³Qÿøcøºûq]µ65an7½æ¨]n•ùÏííF“O 5–';ZvIwõ–A:{.Pý(ÄëìЂº/XûI½Ñ¼4EÚzØßŒ®·â£ š»»é?ÁˆÉÝýýÆÞ0!e4ËN:{!Pý($éì‹Âþî7v›Vk§µÍ©Þ⦾á†w›û»û¡»@,“sðŽá÷Âö6ÌØÛ)OöËN:{&ˆì Iyc–î5w ŒnþQîGcÏ–ÙB‹Èý8vÊhɾÖNë>%Ы)T´ì†A:{nPý($êìJÏšÛóÆ>Ò™ûê?–„ý¦z'ÍÆmÁ{tï¥×?¬e·ür’Ξ "»B¼În˜üµ‰à ­ïï7›Ý–Z;;‚¶Â_çßn£iO±Ö?iîð=üÇz½…{+‹ËN:{6¨~uöCáwìpgå`ié€Ûïî.-îîï~âuÒ«×wZ;Ýg;,T‚1çL³ñì";ÇØâݽmîõï#Ý÷ËP>곓ΞT? :û‘ÔÙñõóîâ»Ê雊ÊHöFó6_ãÂÒoEUy 5_ïÂôÜž;wõ^ã> ZR}ŸÂj éì¹Aõ£'žý€vQ’_R[øÚ)^\ áµïO^Zímîêo·v¤WZõ ‹ îìÂíÖ}‡/¿ï|^K®Ï¿ì4Å]ÒÂuwZÊí©7ꤳ—ÕBR~ö Ù—­Ñ¸}È)»ß[½ø8í8ù/,½zø,'tcÿÂâ<ûíZ­Ã¥s`É$Iù²&w€øßœô÷ëg—Øù«÷áF¹°È¾üêÁ~ýpI<;—Ø’Ÿ»øK¸ïy&hŸä³“ΞDv…=lÙîó¿Ã¥¥ïüøN(ü*§ÿÒÝ»œ”W?B_ÀålîÛ÷/,}ëÛãV4…Ï~ž}ëþýŹóWïq/þ±_sñÛüÛÒgw¹½‡gÀ·ø3âžz–@ Ážð¤³ª…<ñìœzœ‚¿VçÓ»5ÑÅàN8/{-Nô»üï>úæ +Xi.÷A­©?+,>·Ðè·×Á±¹‡¾ü½g_ýQûç‡ÏàKìù«‡–ææêÊ9ðEyÒÙKƒÈ®Ï¶ìw›·/,}»¶tPß}íø·Ày9¬oƒ#,»pW^=7ß~g¯µô¿‹Ábû‡KÏðeõ=\“[üo}xᙫŸ‚z€Î cßútûÜöƒVãÞbÈ!½,¨~âuv#lÙ?ØÞ;X:ÇÿôOAP|•Ûòg>üôþbÉ_;¯ò—Ô¥ƒOÁâÿh÷ÇûMpL •Ø>úìÍæ~óÇÛÜã¿‹¯š‹‹Ÿñ—Xéë,.ÞãÛ¶¸…ÿøöO>j|üá3KèÊììc£ÄÒÙKƒêG!)?{Øgo4vëœÐüÕqßP¯|&^PçÀq¹zð)¸+ç–öЮÏño ×€Šò?}¸»Ýâ\5¦Þد !ÄøÊÊ—w†Ø9Nÿûÿ|qŽï”4õŒ?𻤳ª…ýg‹‡û"îüãѲó¯Üeá¾wÈümÐÝwŸEéñª¥'_—Ë¿ànlƒ¾Ž èå÷ï Ýüø«~ÌïP_^å7Èá";÷ÌAëÏïÁ2÷[|Â5‡Ú~CF“Î^T? ñ:{¯‡ñì"T}»ÅÝøµ ¿ZÛwdã¿êØh´ƒÁ¾;2€-ñíýÛHl¯—Ç.̯ï6ö¸q¿ ÞLkggï#Œ¨×q{qóãÝ]H2É?1Ñ$Îl4HgT? :ûÃÅûðêØÜû¨8°‰|èÀãý Rgÿ·ÑwdKj Â}!k^ #Ú1<é¾½#©­®{"œ€yww÷Žr–î4öÀÛÁÍ›ðY«"|ŒtöÒ ²+ÄëìGGKb ŒLkº×¨ïí9ë»ÿ±ÞlþW4*-ݯ#[œÔ»´Ü»½µ±»šsž û·÷ùîöš"†ö÷ãOàá±W/¡@oø¾œß‡PˤØÒÙ €êG!Ig_¼Ä'ÛÈ´?ƒð-è‡ÁéÈ Ùºó±Åþ¿cfk˜¶ ,¦u‡{,ñ‡ÀNköÁÉßj|²½³×jðgEýì"` º}Gè-Øái{[ÆžÁè¥ÄÒÙ˃Ȯ ³-ÝC³Šm˜’Ø»ÜÏn¡›Í-õÈ3Ð?uGØoДÿº0Ò­úž$k½ÕÂny"doØoŽf ëR çíî¶vÀeoá‘wIg T? ñì¥ôL¼toAè:R¹Yç>üí}þ¥¹[?»~gxÕÛ(wiöwo gý{|=¢ðM>öâ%Õ—&°~¿!#÷wáçNÓ &½4¨~âuvî³6Â!½`˱ké'ð¹¿ã[æfKúâÅ+#º(#gêðíú®|†p漏ŒÒ ƒ‡Ig/ ª…œùÙ[Ò*s›~{÷Ù¥o}Dð‚úêÁ'§.) J f†ù2 à,èß$Ü–ß©oïììµÞÞ–oŸ1ƒçÏý¼7-;éì9Aõ£P ?;P“ø.¶§þÅijÌÍÁ÷æN‹“ºVC'>´éÜËùûÂFq«ì¡¹‹y“øS:ê5î--}Æ}z¾ý>ßò³Å¥C¾iLnÒÙKƒêG¡H~vî¶pæpiéþöÎg‹Be_º/RÄ4áýµ±÷ÑGû»2u’²Ï‹˜]ì“ímþXØÙ«·öÀâÞ9~ˆ¤¼¿Ój¶„v¾¹—mƒtöÒ ²+ËϾËIú)öD=|æ™{ÍÖ}èat·!_âÆº%^8ÅK«hQ­BÌ俲¹ÿç"]ž|U½}çãï4öà-µŽºeëƒÅ¥O1áF†e'½¨~ŠægßÙÁ™tÖáý×všûØUoþÕû|Ùâ·çæØ«‡÷0NfB¸ýrÎþ&·ê¶ô£:7lþÛsKŸþhé™{û»ÐícñŒn\‚›g;ݲ“Î^Dv…ÜùÙwT®#èRþ‹O[¨¥ìî,ÎÏÏ{æríž;QèŸtO¤»»AÁ"T¢Õϳ¹Wï6°#tꕸþµþÙÅWïÝŽÉ/C:{iPý(ÉÏÞD_åÂÒ«Ÿ5>†N"𫡿س"Ô—÷±{õíú³‹ß:~8îkgïLJhï¡?êø¶1ðK÷ïc'<è劖ýGq)ÆHg/ ª…‚ùÙwÀ&_=ØáÔäîF£Ž9|±ïÑ¬Ï.þö}‘zCļÃÓm7¾«‚ò‚¿á%÷“úá3K Õë.žx+Õ£™eHg/ ª…œ:»§|·¶Uw¼¥CxüµítÔûQ-3Þ{R©á–úöþ6é{üwƒnÌÝ}ü‰ṅÏòVÜî±wcøôϱÿj ܘ¿ø÷qd'½,¨~rëìâõ}ö«Ííû¢“44*5øké9ÌûòìÒÿx¡-pΫŸ¶¶[Û÷¥S³ôÁ' èùâAý[ûvdíô~ºúi\^`ÒÙKƒÈ®Wgßù„;2Ÿ@'ê» %rî‹xö«‡»»ßyv‰A0H¬q¯¹Óª,~y³†ÕÍ»ü¶8?7wnép¿/'¿{“ýÛóK÷?…—ÓÝ{"§ÀÎ^ã×° v?ò“Î^T? tvÈyt{oûƒ¥%):6÷»??~‡;Û0  ñ¨Ñª"Äò}‘Ïû.áÃAÌæ¿›;R§]a°osûSì§ÚÚ&½BÙòê윧Ÿ´šÍýÛûÍò±ˆ|l6÷¶ëæ‹­«Ø*B}12¦.âÕwë»?9K…‚Þ:ÀlçE’<À6†Ü}¶ËmÙIgÏÕB¡qPwE|#æôú³;u Á…±–~òÑG{M Hç¶_˜éÛMìLú“&ÄÀìc§ÔO GÇmLÏ^¿€ŠÍ«w›»°þO¶ùÛï>÷ÛŸògBÌÐK¤³—ÕB!}pˆU‡n.ûVÔ1}uKŒI£4J F%~wO†víãHLØ=ûtˆ„Õ­}ÑcU<âÇç ½4¨~rêìéì¥Aõ£P ž}²d'½,¨~ŠÄ³O”줳—‘]¡X<ûÉN:{YPý(gŸÙIg/ "»BîxöI“tö² úQ(¤³O’줳—ÕBÁxöÉ‘tö² úQ ý©ÕéìO=¨~HgêAdW ý©ÕéìO=ˆì ¤³?õ úQ ý©ÕéìO=¨~tö‡‹w‘c0’Œ‡V¾)öàh©Žþe§õ:Zö¾;çöûÌ8y@:{~Pý($èìÆÒ]óh¯U¯ß©KÒíËô»YS~ùñ>N,»”æÝ>fºÿnÙƒs.^º“'¤³çÕB’Î>Ïαyw}nî<ÃoC`Èͼ¨ýþ€=!½(ˆì :{÷ç]€mpÚ°¾ë¿fþ `*)z¾òo›ö×÷|v“tö úQHÐÙ­6ŸÛ6Áê·M÷‹b´ dVÍñ;1±Güû›tö ²+ÄëìÆÏ>çv½×CûÙ{’Ÿ’Nˆîð½ ªøÓáÑ£9ñÝ>:ê’ΞT? ñ:;0 üaÃj›nazjvÙ><Ýê;·îܳ"=?¨~töŽ}dÙ]»Ë}önqjú†Ý­Ê‘™{ô¨ÏOà)Óã÷'éì¹Aõ£ÏOn zÖ¤ãºN5ŽŒöGñì…@õ£¤³›ÒnÂ/AY×Í3 :2ê{þíóìß°)ž½¨~’tvݶ,¯öŠêÍ«L‘‰ZvÒÙ3AdWHÐÙ¥…ïÁ·"jŒëÖ\IoñzêTJsñÇKÖ%=7¨~’âÙ}Û0ûÒ²;nÞ©Òƒ–=ÿöÑé@ýÀýÙ!=?ˆì ñì²w{=á³?)ªÆ~WóŠê‰ÿÙC:{Pý($ų«i8ežÝ‘o„S¸sðâ¿áM’Ã2YþíÓ§m[èG¤³çÕBR<»®ÆH噕cÊÉ.ÔØ­i½ĊlŸ:µL»-YO:{>Pý(déìÅÑ1ÛL×Á;üƒo–á½TÒÙ3Aõ£¤³—Ÿò?fëó¹/Ãdß"»ÂãΞT? Ù:{1´ù þ¶Úv{¾ýy[.­¤³g‚È®Ï^v ŸL×ëEä$Øz»çéãÇtöÜ úQÈÒÙ‹NÛü þ¶ø÷ù.éTvÒÙsƒÈ® ³—ž‚5gÒ‚+ûÛ5zÌî¡zÿú”tö\ úQÈÒÙ OáýTÓÁ¥ŸÎÐã̯fJ:{&¨~tö! ,ø<˜ÿ½×…]‘Î>:Pý(”ÕÙ==Ýbƒþ` ô$ªf ¸y·;æpqg‚È®PRgWVÕîÙs1{u2­ûþŸlÓ“‘𤳠T? euv¥§ûÊ_à®GfpË..à|m>>éì¹Aõ£PVg?‹ìá ++«¿“Ξ T? %uvxØrX¼aï€Åg¶È2S¦$¤³g‚êG¡|<»’_8[‡xC¶«ÖUÒÙGª…²:{•c6(ím»ŒÞN:{&ˆì euvð¼wÎl]=ŽŒ›éa4<éìÕƒêG¡¬ÎÎßN«*‚à ýÙB:{Å ²+”ÖÙ™3”A‚ÛöžQXo'=¨~Jêì†Ym2¿ ¤³W ª…’:;(ŽhØŸTcß™Ÿ™€töŠAõ£PTgGÅ/ª­Ç¶¸ ú¨µc1Ã.R"ÒÙ3Aõ£Wg÷G¼Ž8Éaê;ÞÌ(Ûù/2†Y†mêWª…¢:;´s*ùCuGŠ«M&»+Ø™á¡ïŠ(È"f™JD:{&ˆì 9uvÃö§~å1 à¬æýògjw¬Âä"ù]­.!|ïY)·îO:{Pý(ÕÙ¹egiJÓ}ë‡î äÚz>0p=™–ˆtöŠ@dWÈ©³~Ô¹­ÛklõXî(Bûv[¨ñœúÙ]xÈY8ÌóÄIg¯ T? EuvnIm¦Yv. < ’]·ìþ\=\þ*,KD:{E úQÈ©³›¾c{õxíù/™A²»²Ç—ƴк“Î^¨~ êì¶Oá¤ItÍDŸÝ…ž©†ðØóG?’Ξ ª…":»ICß8 ¼Ä«1ŽðÙ–=Aq UžA:{Å úQ(ª³ƒ#òÔj)u…ÿž¼Ð°P{Ì]ÒÙ3AdW(¨³w{2™@N‚ã[hg%®í¸óÂc'½BPý(ÕÙ;¬–½/7æÌÈkæã×cmÙçtöÊ@dW(¢³ói¯Çß¿Èاó[‹HéàÄ «µâéì•êG¡¨ÎιÕ÷°Ž ~‹'x˜í5•ß—tö Aõ£PDg7Ðȯ»"/©që>‘Åa¨³ç‹k'=¨~ êìV§$×sÞ }椚O"= T? Céì42CÙ/¬ «(Bç7”3 éì¹@õ£PPg竲Á Ÿ¢8âåÿRŸyL»›ÃTúPΞ "»BA½‡vôI¾"Á^d€ŒŠL.‡Šg·,ÒÙ+ÕBAº)õûƒx[Êtb{ßôIfi`t&Šg¯Dv…‚:»Áž$íÉ Úò0çÝl²CÖG°ìЕtöÊ@õ£PTgg¨±÷c÷UŠìø~j·Å{pîòΞ ª…Â:{JÕ kÙ…OEñìƒêG¡¨ÎÔŠñ‘eúŒÀûhp’NvŒ¶aJÍ_ÒÙ³Aõ£P¦ÚŒÈ>ài$|Iâ †F¹-s:sü‚:»ìysýÕ[„\(ÞÄ­GS} Ì=WjÅãµöDv…’:{L¼{×íª°Ó9–àÇHÿ¶Ä¿²Ç+«³×ubW`ÚRV‚+ñDÞ0ÉEˆì %uöÈ>ÛŸCÔ"øŽpâýþJ ƃ÷[áX<~}8yæªÁxö`|‹>zˆ“wÃâKG"»BE:{xêq¢`ÔHî¿°Îî¤Í¨„Å?í‰ì Uéì‘©aHËâc§úý—ÑÙãG~¸ñã?eñ8~y2—Œå_â1gúQ•ΑÀ…Ød0á]WŠâÙ³dï€DèâDvÀÜHHŒëoþô`t:;“=L…bìË4¡xv‘ mF$ÁQJî˜6NÒúc»Ä8ætbTñìmsÞô3tXÇRÙ*>N¶Îž£¢Eâ:™ëe!+f ²+ŒHgïÚ¬ZIOf•‘™b†ÍSm~öÊø—6á\xDv…‘éìLf…Öµ½\1Õ§²xöP$W²1graü†© Î“ÅÈtv¦õOâs@›éöªÕÛséìy“5²€‹ÎÒ¶düš)‘]aTñì~¡cµM8Â<ä”)1Îé°:{#µ6T?}—ú¢7™j¼ßŠS=ªYܾUë“˜ÖÆ‹ÙF¥³«ˆGõÏo:{ô´câµÜpk¬‰ôr‚0Ñ0Î;6 âÙ%úÌ‚ÈsåW&ÇÂöãHÁÓL™6X_¬½ÚLµ„jYð¼õÂÑáÈ€@¬€ÝjŸÕïäìÁ£‘]'Ю>¯ ³u»Ž–ÞÖ9õÚ¨Â>{T‰³¦Lû 2Ø‹gwUXK2Ùµø.쎈 v™ŠÇ™íˆì L0½rË>:ŒfÙ­j5vC´€#Ãn²¢z {èÍÑœ”¤•˜£}FWreœ™£Íñ-|͈ì Ê—®XggbœTOWïñ9½^…ñòŠíIjŒL>št¡õwHÇw®]ÝÛТCÁ^Úklh%W}qü'„ß-Š,ûdÁdÞ]ŒJ¦¬*ŒT_p>3¬àHÃMe[˜§Æx]ñb.s¬RP!‰ ¤qSÅùI‚È® -»Ð¯¥å¬`*Æ|ìyûÅÞJÚïa§š¶±ìÊUa‘Y¡¯q[¥®mõç0ƲBi&u‰']€©HîRc§µ„¨Â´´ú O™e ;o2_I—xÒ˜2T~iXŽ9#Dq={ø|¤…=ke”«†ì±0§ê–žbÜèÑ=^W?}¶Ì‰L«ãQžÚÈŸ½’xË9oxÄõ–˜ôÙ.|l”qel*VEK„Œì‘£œªû-i²kÄIùEÈBœæ7ZfèêS‡\£ÃWC»QÖ Ýã¶ìiºú©@žìÂå‘·®Ô·òÖcþ5ŸrÄ“}Df FW?µònÅ‚b©ÂŒã•ˆl{,ÙGZ-J=|ua#"ì;ÕGNöÀ±üì:þPkQ4ɲ ÄÕÁ(öøp¯©F"µÜª©•÷ÕÎXÿx±n®JMÌô‚Ù¬ÀÜ*w«ýHúw X®^-„FHv©DgžZŒ¼ð§ü8åHèúY¦Òc˜@MÔAd%X¡Ù§d¤KWTc£D…dRý4K“ÕÙ(Q©eœ¶`õéUÛ(Q9ÙqkÕ˜M("û(ó8\¥ûVè^DöQ")WÙZ'W}(På¬àüÔ}=]¢ú$©v•âû‘öPÓÝï9és™ZI9[Ÿ ÜGàÛ`0èǯ™P‡ÁóLJ'}.§¹ÈÓÕ1´61=øác`»‡¨©ŽVã×í÷ñÖx|¿Þ ²ƒdwÂs#‚:sÉcIÆ@}<¾×¨ú‹Á.ò÷Qœg½}°ê|ÝÇ "û0(âÆD}r2é90@pÂ>þl¯ÑØÿ‹_H§$ΩÍ_þ’{>?ÜÝÝm6Dö!P€ì,DvÇt2ð  =>¨7vÝ¿gæ ÷OúZñ—ãñ§ýÝæ~½Ñ"²ƒüd÷:búÑŒN4ð•ÈžˆÁ/ûüÇÁcω :2qjŒp`»äÆ ƒÜdg>Ù}çe”¡ÝO$¡ßm4v¶[-Aw°õn&ÙÕ÷­úÛ÷ˆìC /Ù£ è ˆÜYèK:~qŒó®´Ò‡¿ˆqÚè.Èþë"Õ›Íæ~c·‘õŸþ‚¿ <'ÿëÿâns§%—ÕcÖoÕq+¸‰üò &ퟯ^W'ñÓÈ­wõ ‘¾½Øê‘'¾>¾×„zÁÅÍÄ ùyá{½jwË‘†f\ Ùã¬òq[taqŽs|~nnŽ x~qØÈQ‡X>´b¹¶*z½ ¾ð®:+ùöWàzéœã%L®ïa¯×_Âq·[;pìú'õúÁãÈK*{"Hý.žB«æÏƒÌ‚!þúŸä+±¨ 7ëòî7›þ…òÞ ·j6E1Z{üt‘€A²g^àÝ0™líð:øéã'¨ÃªKÌ·ªg›€Ù3Ëw¸tî<ýœfÕÖ3„Ç ¼ežW©ëB· àº^u¼<%,q½8Y[õ¿”…ÝnÁ-±÷“ŸìÜ{üä—Á«ñHÚ”Ö¯ÞÛ­×ëwûû·ëÀøt¯Ë¢yUÁߊ•…Ø%Ç¿™êÚ Éæ«»»ÁgÁàVy-;?ß Oú‰²/yHQר$Jx7¹„²Êù-{ËûraIº/óœî¢ƒ[v^s;¤ç«Üø§ƒ.éãƒV# E¯×N£þ±Ôäzmä½^{$×íXôzíâ[)’½éQ–®¾ËŸb}½†˜zX ~9;æwæÎŽÚ {PyOôûðn³)oïøíá¢ùSϧÂÚwoâÍÕlîíð׈Ÿêž˜“‹ì-pH¼ çŬsÃJƒ„üaºÓJc?¯V.²ïíÔ€r¢Ï°:à*$ׄ¼4Íæ_cmxmãƒ_|–yVů?åæ=åt>z4(|½”Éx"ýê]¯¿¬ ,/3”6p5Ô—/¸“4@…ý`N‘ßæpŸgª1°;ϳÈØ„Ð3/ˆGp¼õõý¸ 4‹ý=‰‹ÕÉñ7Fb •W»Ï’N ÏÅwñê¿i{xûÝ©oïv¨•AU›ª2A‰äë뽓ˆU.(.Gïºó‰í ý~Ê®ÝA(X/ ^¯GÚù?rõIZÙ"×+_ùŠ_/éˆógÍÇutÝ}ÌÇ£H)™:リ~[?>ÜO¨f&Ùõ2àÛ}?½*}ß5lŸp2ýç²]U?ݰm(Š(Ù…g„{Äï1Ç{yÎ2ºJ>®½^þÂG´7ÛÜ×KD")a1ྡ´øÛ&¸Vø þK|†Ö Úÿ¡­žÇ«ãS+8+±ÃKòTÁ0$/`¤BùWOô­Š_«ì¼14OA¶sëI?#Ï>¬¥B×+jÿsàQt/¹ WüzIµ ßè•ä8ˆ31Ò¨ÿø ¹[§p²P)_ã@á]Õßpßo ‘4±7ðÞzäþ÷‚(\ 4’Ó!Ù«ƒ÷"ÿ‹ƒF=ƒ­Éõ·Ë?Ý¥p¡@d¬røøQº#Çâ7UQÂý1¾>eHéYMd¯b†¸zj õ?‘}ô(BÓDŸžýúA‚,ûxðH´‹ôû®#Ãè%»öéæló"$‚åžI( áÃE z-ˆìSª÷Ñ‚È>E z-XÎy„1€*~Ä`¹fƪøƒÈ>= Š1ˆìÓªøƒÈ>= Š1ˆìÓªøƒÈ>= Š5"cÛQ•O Tó£ËœA¨æG "ûÔ€j~Ôˆ!»Céy'"û¨Ï‘j|b ª5XÆoÂØp:«žf£!ûiñ#—¶a&þ3øwø5­S›õº6~ïâ'–ݶ'^®S25Ùp “È~zÀ€å¯ >5Mñ9­ÓS¥4Í6ÿÅ¿ÙmþmÒå:%SƒU×éß'ûi±ëÐG–[GSÙõ^ÿõ¦uj3»Û3z`Ù{ÜV±.~·'^®S2.Ëî¸ån”´íÒö7:³8ÏmeÙ…œÞé¼ÙáÿÚøiÎóo–X2ér†)wcª3ÃÙåK½Ä®ÍÂ#flÇ8bøO7óḛ̀LðcÀ“á1ÿ–`*§à´¶ÿ=ø.Zö©(ß´OÍ‘¸1!²çg»ÃÊ‘=´ü`Lp=íà˜/Ô?5§Ü6É)Ú)þ4êÀ}:éb#Rc‚dÏ’d.‘\Žk»¥n+§ÿ3 ¥¾0ïýË÷o´d×§ó«¹â;ÓVñÙ¥i`O޶P­Ï³òßhlÒö¦ˆi2;óR3²Û6èHü#äÃÈÉî¸:µo,2'L^Ü“›¸§X²×䂬R{Öqê§x½Dk€!-»þoâå›öéˆÉÎt+¶²à§üYM#jxOµÐÖ±nŒã² ŸsiŸ&ËÊãïÓ¨È°ŽœG–=/ÆBv¿N”Ð1_kNÙƒ·ëߎúžC¿Qûïü©Ÿ ¿>»=ÛfvÏèÚ #Oº\§e:²ùêæ"»ZÙ‘úaòæQÕEÜP› že÷ýÞéž ËÞ“nsÖ›¦Rܧ¤|Ó>µÏưÕÉ${²²ëo¶au?ä %–ZZFlc›îi›ò·ìpnsì|»¡=aç§£|Ó>ý j”u‚˜!†‡y/©+ŠC·&ŽìbÿN‚Ëãä!;ÞóJ«žî)¶0Ã;AÓVíÓQ¾iŸŽ^zLóZò¿ úÓðÚ‘TOfwsYvãôÀ"Œv?ûq}„LŒ‡ìÁ0ú©¯•$=:±kûD¹žÛ²Ÿ –´ì }QjAÍ‹‘‘ÝÑí1|©‰©ƒJšïâøËB·Fø¶‰4Oiúz,ÙÍ!J,µ1qý7ïÔ†Øu[ã:éìS£³‡à„:;ñ+ÂpAl§NgCÞ6™¥ìzÛ†™íI—êÔ`|dÏÁU'eYæœÔ¥É¥>=:uOè.Ü©±ó®ƒ3ñr–é¨ÉžL·¼Fy„AN¥ÎÞ6ÛhÖÛŸ·5›>å›öé,{\׊ü.DöwÆ)ÒÙÑ>u{öÈ0¢ú¢v']®Ó2Œãäœ^0 +ºtö¶eØ`Ù;¶øÍç[“/×i™NÔgŠÜ§Kgÿ˜§2Î^SAv'ÄN§´ wR~%•Ú¬s_††þ96%˜Ÿ?1¬Ž9ù~ZøÄ2Dt¾añ7Cå{€ØÛܶ:²U¡|I§@Ióé3ùê„×*zŸŒOgïžœ}ñòêòêÊê ÇåË—W'Œo¾ð¼p]Û°º'†êw>)\|b¿C´'–ÚÑ>YÓ¬³»¥ÕÁì=–ÛËØuö3WW/_á4_Y}åþuÂX}ḵ<>F[y<Æz£cùQù2[‚ÕþÜ™Ú%ô+ŒÝ²HJ,½Ûqêìg/._¾¼Ìqyìú¤É¾òüáö® jŽÕýoÝÉéà"V_DpÚó¬Ÿ=â<{=\©ø•êvmå9m:»£…¹äìtX/⢨ ?D2/þ“‰bÜ:ûñ™K««@õ)Á•þág惓ó­ûñ¨Ï?qÚ1U·¾Ð†íÄŒ™›gÌPÖÜðÖ›F=ÈH®Ïk—¡^‰^¼£Ñ9°kÑ […Øø ²ƒ|Ç©³Ÿ½$œõË++“ö×+ÏÿXP£ƒ9sŒ#cRíh¯Á ««;×ÃËh³/ø;thSÀU{ÊRO›Îbd ÛäNœÅ|:û»®‰¤Hº5|O/5ÞóãÐy¿ôÒ2¼•r¶¯N…}ç/¨hÏù[áIwlõBl[-¯ÊO'ÕA_.#ä°âV~ÞË’3}:{ *]cž÷Uc.‹[äø Èîºn ÛG0ºÝñJ‘Rê±É¼]nÙ9×—W%á' °ìÜ _˜³¾MòŠÚÉŠ/ÃKÍØ0­ c驤~9nŒYŽ| úâ!?¼^è> _/Fr©ÍñáÌEàØeõ1i,?ÿh)A›³Æ¡´‹^³ ›£Êˆ×Ò°½•YÜBÛ‡¢!Ôxî‹ÛE²+Œ¥[^€ËÚÛ¥Fn¦ÁßžÕWû”NKt×±ß3ÉnŒ/žzÊȾúüálAÞÙØ·oôõ`~¾tùXΙ§KÝÏo™VÇVíž&?é¼1n,ñâ<šh»ðWìÌåtô{:Ù' ³OÙ¹e?±;Њj ¶m|†ÜrÇ£Mné˜_M¸f6°½m¶ ©îc#{pVô«"»“Hv· {Òm¸ùÉ.ö86½;md_Ý2mm-·ì#¯¡–›_äk/3Føw»Ó ³‡ô ²ç·ìÇ]Ûµ~丌=ž}ÊÈ~ù…/à¢õ¡~Î Û>êzß:vÇ(‘eÔkw‘¤à‰v¡ãé•ùO‡·ì®Nö€Žãèke’],›Î>u–ýòóg¾—ÿ)Ë>êx|PôçØ\××^òåZumŒèŸÝ'¡cæƒïªn²e¼ †Èº!µ<¯ƒ÷üxôä©#ûŠê.F¿Î­§s½ƒo¦Á„ú…}±AŸa|d'÷ñÇ%=†d’¼nLŒôØ›òÖýt®[ìãÓ“§ìg\ß²sï}ôU T˜2ÜŽ»vBÉ[ÿ£ {À™ÐÞM5K›ìÑF%ØuÈg/hÙǃ)#ûrÀ²AA…½:Æ æ ÌTŸûø#oA Þy#Ôƒ¿u<}å˜ù9ZPgTgGËþijì¥ãÄsO± a•Œ³ý½ORgG׹悺’ßDûnüþômúª¦öY×Ùƒ>»=úóï@¤êÆgä>»ˆ†œË®k© TO4ùï;ÛéÏ –eÙgWg_~!à³£ÖÙM»mWI8„}OƒÎD+–ê(ÆH‡¹žµ‹ð//nì-1ë:û*Xö'î#aÙ­‘Ÿ?ú®ßôñ]#ïõ ÙóäÅHš•åéäîž\/ñ~¦uvW³ì#×ÙMÛ°rvâɹޤuöhè¼NGa8¹%¬9Ë:û 5fäqë•^ü>øíÊ=R7¦ªºrîg†uöÕ3r½b«.®Ë}§ìcÆÕȪ±|y./¯b'lµ¾‰ÎLW®Èn«^ïÕåŠn•å e)¯?®‡˜ŠQWU¦ÍÛ–¾<汸“~)œs—™ùâñ‰ì#Ô•3tvAtü.ºê]^Y^–sØÐMtyeeå›+—¯¬Â蹊ø6<åW•Ï>Àؘ¨^‚íG¥Ë¡õ’Î_~ì)(Ÿ"žJ™ñø3MöIëì+«2£ÿ¿¼"í6v…f^eÛv]p_ù*ºöù-¨Ð‡"Ö2†U • “°^p»„åÊ6Ëd¥žœÎÄ]AÚ.¯^áÎ Ÿ›¹Gƒ¹e^‘w‚PþpjÄÏ+—‡ÏɱúüY¨€Gx麦£³÷¤šÑs{üŸÒµ…Â-uîž§zÄœ¿üe³Êå ~¯šú‘&¢³O9¦Cgç<³V—½ÄIØ'{U¤ÝÀœJœâ¯\¹ ‰8<ŽW`Ù_@]úìV\<»êáÙVy ˆE‰úèj½¤¼ò¢¥ÓÕKD> -ºëäˆÇŸe²‹RONg‡—ÒåUßsYUÞ»wÍ9¯9ÍWp1²üŠd9 KuHçûì_t­“°ÎÞÃïÚTæ`T–’Ï7plV¹<ñüáÓèÚUkìúU´!a*ó³O&©³¿pö¹ßò¾ð¥ç^|áÌ—±“á¯_Z]yá dú=sqõòÅ3¢ yŽ=÷¸=ê÷s—DÒÈ!Ýé³sÖ„3îª6eQ˜A5&þ¼1.±,Õóåb6ò´ÙG-.k:oì«+ÏŸ9û"˜îÎí![È-o…ol| Äó%Èíb šsÅãÙ'§³¯¾pöŸq÷d…[Øç^~áìW.È"¬üsWÿ5'ö¥—Ïœ}ù²ÇÙË@ö—€Ø/9{éîgg Ëÿvö_½rå"¿^à·Çoð›è¹—¯\yù̹¹³/.¯\äkó§Å—ý%$¾8þ+¯ Ã<Ënjõ•ÂçéeZ—û1!w²Ð0Ó-»«È® ¼÷Ë»2‚[-ïiC:{&¬³ƒûò?Ìår?ö+ÁQ‘ÄÿMp2Î|ƒ»-r¤N~+¼Ìé ›O_ºxæœXòâ‹gù·sÏ}ý¥3ÂÅœ¹Ï±å¥3çø _æ.Òê+¯\V„_¾üÂ|3ÍÿM¥c å¤\¿%}T¿Žþ„°rZvèú$“|* $Yö´ROLgçöøÌ×þ¸/Âu97$½¸¼‚$››ûÊËœ¦lùÎÉ~y…Ûè3—®\¹²zéì™QÉy…oÏ­ö×.Á>÷â ·×g_| ] ƾré…³g^z‰ïå¹—_æK—eÔj@ËòÝæ®a);PW œgȒڶѱµ§E2?bÉ2õW}&ÒÙ“1a}uùù³¿~ñ¥3@ȯp²½Ï³¯~ý2·È`Ÿ¿tqÜ•‹ÂŽø%´ì8½„z :,/œÅÛäëàä\¾üõ3ÏqzŸ¹ë®|“ïáÿ’ß++¿þ¾L¿ n‚—Uù{}vñš ÞÇ¥³ø¾:[¼,¾ƒ7޾÷™—Á‚_¹üÂÙ¯]zŸà“Ÿ;÷Õ—¾þ%þ¸ŒÊ¿Q–UXèìO¼¨GÈ÷¯Ú‰ •∨ï¶Ç÷ÔþxÙ#{Ë.òbÆI:{F©Íñ!jÙ¿ú+@öùç^k¾Œ/g^—f4ó•‹œüçØ¹¹¹ù_‡ÔhA=ÇøúÁ÷æî˹ÆI¾zùëüéÀmýٳ߸¼úõ³_/¯[s‚/s²_ú×—¿qæì‹««+* +œ7Ç,ÒÚ‰Ð&âHv†öOoYíèS¿JŽbj¨½Y¨GäR¦óâ{hï2HÉ.õätvé;cÄ 6¡ÅGÅýª›bŒ®\ l›#¢eD“Ò\uEÄNB\ÃÃm]Œ£„a•à­¬Æä1ŸæQ;r>ÑàÀ¦âŸ×òšC,×/ Ëá¨{{cúIgäãÙý]¯+vX’¡êËHÓe?”WÞ^Ü»hEÞâ&²ÏÓe)Â)WÕ ‚„÷ö…®L\Þ˜È8Ò1g>Jmo”R5 =ÿn‰±5LKŽz'•*K³)ž=O©'Ï.T–ËË ÞÎÃFŸeL]‘=”.ãmpYôUÂÍ.£Á‡@à+¯\Áˆ€åäÜêËÛc"…å´Š]D^ý VÂycTL¸划 |öÑŽZÔc *²‹k‰u! ´®ÍD´;ã¯#¼ŠØVK:{2&Ïô]^îx«¾mGŸD(ƒËè™@é²ûé‹”_†pÕ3oyE°Zlƒw'ûÊ7¿¹"Mþ*tù»äwÓ+^§¿pÞ˜ÎçþhÒB™éH[ß–cPûËýõô)ÚxË‹Zî¬nJj*ò®È¬ŽA:{v©'˜7F½*zÍ<+ž²Œ,]Ý“T£§ÖuUšj¾dEîbUºC«j‡ËòPx)¿©+œ7Fú¶¼F`¤in±±_ØiüV7z"R½§¦FÐs6zªeµ #V ‡“ð=qUfx-¨¤³§•ZÚs Ó°ƒ¨—Wý7ÒUïûªlë¬aæ+¶¯ˆ>L«"ÖQn±‚+. W;8­hÀ’ÝØíOÍFw)œ7l²cÒÁVP¡«t,=f&~ŠÙ×Õ˜xÞ<áÇdZ‘DCêŽ&éìÙ¥ž Î®¬µ×Ã{¥®,_Vý­=¢­ôÄ“nŒ×o[*è+Ë+zçUìµâÏÀÛH¶àÕSûËóO©6j*ôyønŬÍr),ˆB]UQâ^éìÙ¥Î|‡¯S–$iüùÙ«Ìô¨]B¼·rŸÈ>Q}²s~vˆóÑ5„¬7Væñg™ì“ÖÙ'Žqçg·ªMX­ÐŸçÞS›z*å(5ågW~vc–]„Îð;Õ2HgOäuöIcÜùÙÍv™ÑÃR#ñ÷^» wªE:{v©)?û¸ò³võ‰|¹Qçþ:Ž:Iyc²K÷<åg7ÆŸ½S¹ãe÷°:Ïž£Ô“ÔÙ'‹±çgGžå°³ÈÕ»Mñì9JmŽSFö±ëì õËÜ’Ñ2ˆ ì÷ûL³Þ9Ž[!m&ËÚ²¥®L:{h*bô a£~µ–Õ¸x^”ý$ÇA= }Ì:»„ÐÄ™µhk5d(Žƒ OVnx²ì~©Ig›ÎnËß]Ììn{#‡ÏÚÎ Sõ€Êýfšì¤³Yg×ó˨º35v¹SŒòÌîØFÇ”±˜y;Ëd¥&}Œ:;öwÂøwˆ“7MÙÊTÔ´‹¬½`Ô {Òã ž&Î>>ÝË×.²XZºÓœäa"UgxGÅÙ8.‘}<;ê¼SFöqë즮ƨ¨w¡·çUÝ!ÿ “[û£ãå=>‘ݦŒìÓÙü<5HDPg’´w(cÀ2F\Í‘}„º2éìYSün‹5 %ª÷Õèeá~)ËÔÿ,“töÉèìtÌŽ!ríÍc.^52°—ÏëR-2”µ‡8Ö,“]”štöqéìñ㣢žÂÿÙ=Tg eÃñ}t¥¾ðg@·×æ¯!=HgŸ˜Î.³Ìˆ¼2楱ۖzçY‘á&æ[ï£rËvéãÍ2ÙE©Ig—ΞÏÝö]äóÆ/³ &Æ“8:S×.¢«“Î)5Þó¤³Sg÷õvÌScË\c†²ê2`¾c™àÏÃ(OhÛùú–ÊDSæxDö‹ËºÎ;ed{<{¤B¤Znâ@Ð4òPÛf@S·"ÂzøpDvslˆÉñv]) `«ú}E3Ç£°ã2ž75Æ‚ÛÆ¬'n&o)'DõàþÜ)±ìP;^îwˆg´ØPºz³LvQê±éì=ie Ìgo­óXve¶ÕDË.§áÛ"L{¥³«Òê§×3æ¸m?óz]ƒ¡_Ñþgšìc×Ù9>W*q¿?𜠎šëQ8ŽšN€Æ.ó'a=Ý'ÞBNäö-¨ãÕÙcãÜŒÚö¤qù£ªýÏ2ÙE©Ç¦³ëùË»]wÎõ¨®Ñ“}ùðÔÕ©ŒŽOÒzŸ½&{IxÛGŸʲQgÔ7ãà§÷ø_·gè¬=fÛ•íŸÈ>N½#¼vÈqb4§Ä•ŽLX!‰ûcúº)¯ ¬Æ‚OŠŒ×Uc:{hjcxŒl„ÿmœË†ÐÕIg—zŒº²³¢º¤ošÅvµ•ݤõân‡˜õ]Ͳ—°««Ë`òÍÆ”J «®\Döqê즧¨Í¯# µ«[q–Ó²»•ÓÖÑv˜K´œ5Ç^²<ýÅE†AS—7âêp ²ãÓ‘-¿%Ðv"´ÎrLð §Ä¿-œü·ƒ£¶×þp„ë'hÙ{c«‡ä©°äª­ç±à‘tör»Îh‹Œ ñÖ8‡㠊ɯ±Ò¦G–ë–¡>/Ç ßgUXÎ 0¯ëꨡÌãôó*ôöY&»(õuv´1(3Ì_ Ýn?"*º¡[` M=1­7lëÔ‘õú¬¯ö3èëûÁuÝ÷Úqâ•MùÓuu^Q½.¨3=ÒÙ‡Å$tvl;èÈŒÜ)ÞÃ,ÙW^ô°Ä쟦œ˜Ú¸Æ»¢Gd1¹ûêGÖ·Ðk²ì[ÍÞ¯s!ï-ŽDêÕzò:»²ì*Ÿ;¶©z£g“Î>l©Ç¨³ ïÑïI ñª0®´ÕˆCà®mûñ}Vt:¯¼~È[ËïS×Î[ÏDý†øXXnâ«_Îð6ñ½à.ÚΉëìÜŒš®.>m<HC:ûÐ¥Æ{~\z2XuÌœ/X†v¸#Þž,fYh•µ™2+³¦ˆ¾<áõ„ýæû² =RÛ^”C‡N¥qøã–NXgçw#“OYïŽå%5*h ²SH6ѯšrP+€?ßN›ºrãý“vÚôÆ*e¶÷Oê¨eu MÙ`Áõ'¯²Þú¿EI ­üÃÔ>‘Ý=|[œOÜÀÖ”Äí;ù¶ÖÐ÷ËRõç¶¥Ö0PÒöÏœgT¨c‹vüù0aÓIg¾ÔÆètc?–ÊInò‰«åȱõAýºò°È|Ý'ÝÎf¡¹Z¾Æó‡Ö±+˜Æž –’tö2›ÎŽ1f›Í'Gg³´$„Ñfþ/oÉ|;¥'OÛâËXÇÛƒT`XÛî-¦{èzb ÀDë&Zúr˜e²‹RNg—ôb8 ôŽ×–£•í%ëÜ|I »ÝëúzüëvÏWƒÁ6½žíÏ—{å{ãgoT¦c;ía-Dãê”¶;üuši²MgGÛÊ-,Äz´còžt¤â¦Ï·ÑŠ›áù,í¸Â"FuêŽoÇXöªtì¡ÇIe±ùÖçÛ6Œ¯1|\û,“]”zt:»áÙqèÓ埚 ,ï‚…MÝOüÙŸ˜ÛÜ_Îma7ùøx4nµçp½àq{øÏ6æ¼ñ+&ÏÎ+)P?jʤÝ'}èRã=?Ú8mHdÊØÐŽÕ‹;,}{Ù’hùÙ°”fn²4}¼-Ôi¾Øom¾È×"çT§c­³3~®V'<Ÿ‰¶TÒÙ‡/õèdc/¹auðò¬˜m± o/• ;u;_ŸÎ¯XǪ$a(ÅlHÙG¨Æ(6›Œ‰VÊèr¡…ßâv„¼ŽÌZKf^CiíIËçMɤ ëí,¡”̬Be'Ë>Úxv¡ª3ÃëÜ¢ÝÒoåŒ×‘ƒ#U°¸ã°¸íÂS#!¯¹Ü?„ë„­ýhê#cŠ×¶sÏ'=?F­³Ûmi—’Tâ¶Õö–·S”äŽÇ’d sÙ43M©†që¤Ö1Q½‰·šÜó ï†É.J=B½gw5«³´Ö³uµ$F§ê:3â–÷X޼*]Þ3zvÒþ!Þ÷IëíÜ‚÷ þ2ï|ÒÙ ` :»ŠÆV#1Çé領êiyÇEéì…K--§Yý$nm’ݱÚ1:¶ÔÉ ?†;Ag‡\ü,nû6Ä g–ÇÀL[‰Ë¡—‡Í÷4q½]– ÷|ÒÙ‹–z”º±T9—Û±:²§Ã+5<éÙå–;uÿS ·³‚ó ‚È> 5sÃ@ïP†ãE–2ŽÜLŠo¬oÈÌXÑý°ÛK°vÀÚŬ`ŠøI™jd u~€ŽTŠ(ž}øR£Ò¥ÝNÔ‡m;þq#!ÞÝȈƒëÕÇnœÑá§‘ãûm éìCad:»Ô„Á’Zqú0ª¶ˆGTQ+ÙV/²æ·/¢?³¶ÌŸ€ùjâÆË¢Ã/FÇ÷¨âÏG3£ÜyO†É.J]½Înü>…«‹øÇÄøuíì|-sn°è~]–?ßK÷’7Ÿ¾|ä:»ˆg×âý»](ÊéìÃ`d:{[ô’ö(N?×ãÌóèäJ¯‡Ùùõç¶Åä÷ÄõXÛ,?ÎèÐõ6/ÎJ?¿¶W“Ãï–É.J]½ÎV»+|é®Ý‹ÑÁE%Œa{©?c §wØK7wùlÊ"Y¯6ºùtûÑÅÿsË®•O¶@€Ïþßõx|ÒÙK—ïùä‡Á¬Dm™Õ*gn‹ÑöçÁøôdÜ0ãtvh•-R~_ÕIZ¯cóÙåÕÔ`ª®¼z´E~„¶}?Ìþ‰ì#QŒ£ùZK` cæÞ ÕÇ>2?5ž=º¾Š±L9Ë¿¿QÕš~ÞvLIÙ«Tc eMå¡zÛ¨¼Žy¡2AFæc<{ý˜27 0Ç4’–‹<òÖØuÃÏæ×§aÎWv"»Q¥^¬Z;“õl‘$FJÇûÓ[8ýèÉÀñrųûSŒå‹”¿ª<-E§6¶•†õt›Uµÿ™&{å:»Ô…¥ögÁƒïtÊŒîkÙ­`>ó|eìtæçD}_õœjOFqg=Ý*{e;Ÿa²‹RW§³+]Ø`Áü0øó^מ“ó²÷çM®ÍbtvÔ s_êÙê®ðƒctx±ÖyÃïÍ?VsÄxÇiƈ9oÒÙK r]êÂÒÉŒÓÅU>C³È~-¡Q°˜å"ßWîü5^?$•Ï ~9ôX“ÑÛù“ÊòÛDmVWŽY&»(uu:»¦ qú:Fe3Ìë…Ù^òÄ¡Ø ëÛ,ª³w{ ³ç/Ÿgé g’»–qÓîYþñêí=c.pÜ^¯BÝŸÈ^­Î.uaKdˆÑ¹Ym¦Èã’©?£zÂb–³\Û‡óÅ´aä8ÝÞË'ÃbóÛŒ\g7ƒíÙí¤³+u•:±!taõ=º<¨,déÂ5&&ªÛFñ=¿þìåu×Ê-¿z:_oGþ¦qP«$»9<$ƒ„ ÒT‘-Æ0UO$‘­±´ºÀÂy]0š½|ü9Œ¾ÙÊL•Á];<Zz{ø^ýùë±-ó—á˜P&r½Âøz"»Q^¿ õôAcdôð@Æ–Ož>•Ù݃ñßCìOØo*.îV/Ÿ||^÷‘NM1Žª%hŒ0X…ÇŸi²W¦³ƒýÙÚ‘<.*»-„“χЯ-†*¸¿½ÈØ^^‡nËñ¤ÃYkT4¾m8.t°•BŒàÇ8ÛÍB-ÍY˜e²‹R—×Ù•ºáE¥ [©­×3dì:è&Ùn /fNßÞ€¾ÃìOFCþø.„DªóÁXM†gÕKÉÿ>ÎóÐw.Ž[Ü­PïŸi²Wª³‹1E¹­ý\×…ýÌ㬂<èÌ êß~Kg¹ý¡"[ÌòòÔØZXµï±éì²gDyÎs®ÏsŸ¦]Y;È,“]”º¼Î.-ö’z8óFÆÐtí^a›j׋9Äñz µ|Ogg†=LÞr(©ÝåúÉŠþPâ|ÐÖCãl×ÖÏgäñìøæ bêmã<çúü‘Î^]©…%S­Ô´cÜa´£ÝÑtaP:B!7Ú6Ž?j‘gÜòGP’º±Žÿ.6mc†e:Ú(×&>¥@WêÀi|yd,¡^A_€Žm¢Ãæç«ì8Dö!t[MÁ+ŽÇ–Jqd´Òò:4CMG‚ ¿?Os‡}™º#æ2V¡Î£îàØßLȤ&Ž~Ž—¦{òPµSœæþ×þû¿çÛ>‘ÝV¿5=Ë.¸a›Z;eÁxóø©²µ– ;ß½-Çr¯.îÜ`ÌÐ5mC³¬£Ó×Mþ®¹Žà†¿"¯­£££sGGà®ã!–‚VtrËì¿ùÿŒn÷äAárÍ4Ù+ÐÙ=ß—ù許ØÍöü|%ùNLÌ#í:’,"FOZU(árèã8¤–v>£‹k?éžp»~ÜþûŽeYr´m´Ð‹Õ ‹åCóa›/„gÀÇœßm‹¿]tŽM³Ôóf–É.J=t<»Ú0;¯¸Î-»)­=Ä¡çÈŸž­?ƒò{¯y¶–¡¶Óí¿ÐîEvvÆ0"³kô|¶¿ÿ„)˜iüÆý”“˜sbภÀ|~–'æ œ!¯Kø4,ëÈ>âo®ÆÉÉI@™'=†Ö٠ϲwÌyùЯiw˜xf´ÛÅ÷Ÿ‡†Íkž…‰*‰—=køýKÿ_”ÞÄÑæ Ã(]?YÓÿ•ÛuûÁCœpßÝ´@m´Ì‡'FTGãH¼¡ÂÕ}`¶aMûÁI÷øgÿõa‰ö…Y&»(õ°ñìžrÁM{ m®‰^iˆ5ì!÷ú3Ž‘-ß jBÝQùSÆOÍ;퉞±RggJ=šC™\éÑèêG8>,¶?@ó­ecì;××·®-œïöØïÞ¸±ptî;×76®-œöÑ÷ -~K˜ð?…zü@:{ÑRKm–˜z–Ý–ïsžb'ÚýôˆÇ2û÷ò§cì¡aÙ¾egÒ·5†Ø¯é¿sÀ3BŒÀ}¢æ™Åý ŽÕ¡ÎÏ&ôüŽŽ¸}X¸±¹¾¾É±ö½……ë›koo^ÛØàŸ779ýÁzH…†ûò]¾åÃâÇ#²/ß*†3‘8@é–®m ­@ÛžÝË‹ãàV¶ÿ ª#£YùÁ´zŒ½öúú;×zláõ­Íõ­õÍ­õõ­­õ7×·68Í79ÿ××onÝܼ±Ào‡×76×7¯/°£^—¿Ý>‘ÝÌ´ÑÆj`¸Ð» [I™P¦½˜_è‹dÈ1͢㋊x¶)ò»+Ý6N×óMÃðrù,) ï¼lC—Ý™o[à°–:NgˆózxòJx ¯Ì<þÙ1R}}}cýÿØXOÂ&þ¿¶Æ×˿Ήoò=·ñòmãaޏw"»Q@Æ«îkߨ“qã¿MiÓMÛRÚ£ˆ¶ŸæÑÕñŸ%û¶§†›à]@ ´¨ël[=[ÌüçžÚ*[ Ü?øLB3æ%¸Qgc¥Ï«‡O;¡k~çúîwŸÿëëo¾Ç-÷Öæz nnÁç–º6®/ 5x£ŽÕûy· eîd–c¦É^Xgo«–´¾†Ð¾1óèB¾ðú-q›Ó‘1áEƵd¿zÿÓ}‰@ûÎ"”pK¶­ÊûJ–7ß{ô¼:fGhì6ŽÕ„¯ †ôš˜Œ‘éXrܺRç…O»ãùùïÜ@üïÞØ\{wskkKp8…î[Þ7Xë½Íkÿ7/Ñññßóýñ§…Ð,³K2Ëd¥Î¯³""½×ý9Ä| ŸvÞð}0N?á=JX|5ì‚ã‹ …l' ŠxsÔb°¼ú± Ÿ"†|?€-âñßê¼ðU‘>ÑcIû\ú¼ºÐæyÔc¯Ý6úÆÂw____C.oÝz3ٸ㢭M¸-¸É¿qmáµëÜwç奯BÍ+ó¼gšì…uvaÍ *CF,8ã¾vî’! cÁÊkڋı {îµkB ŒÁÁzö%í¯ah­µEuvq^;)•¦ýí·ñÞX[[ƒdëÚH±FçXöö%=«Ôùuvë vÏ}¯}/ù„™-Mãùžô‹Œ/jüÜ€ yÂÍq?üXç]$Ÿ‚s,Œn7º%t|ÿ¼p7#:/PÊ{''`ÙoÝz{m¬ô-NsàüæzŠaç˸_ÿÞ:˜ö ðÝ·Ö7ßÚ\ÿþ¯^_ߨºumÁ2 ò>Sw'²ÐÙ-áŸ3ɵÀù:¡½ÂïÁ ßgâ]¯Øø¢†0èÜ¢K{>`Ñãxß¼eZv°b:~Êy7èÏ÷ñYƈ†m>¯ðÎÁ¾sãÖ­÷nnÞZã¼}çòt뇉/©›Ê“ÁÉüÁ›œáo¿ ò Ü#·¶6¯ý?Æ‘ˆÌ'=½ÔùuZaÔ<Ã÷$×îmƒ•_4p,Åk'DZJèâ¡óÊWmÅÏëˆ-ü¯k›×¾sÝgõ¸ë[Hçõ4ÓŽÿD““¤ýÖ,¬¿‰Šåµ¿åïô½ÞéìY¥6“áçC„Vô4Ñ*óçþ@EÌ´-}ޏã %/Ë“âU >9>,#õ8C—,/ vìñŽ!:þ ‡¿p}½z ÷__0½ki ²§è²J»*téóë3 …I±ß”ñË;–Sø`àVƒïä·à&ç‘7­¡ÎK û®ðrÛáãu±W.D(r»Ûý9{­b² 3ÏŸÍ׺¶ß¢L:{2uv•o½mjE™šo~¸ÃN'YîxqCK¶¯¦WÇœUœ—aÆï˜[ö‡'†yüð¡Ý³®oÏïPÁy ZTó´/Ì2ÙE©{)ú³È·Ñê¬WÆ 3SQ~iyS°%½¼µ•Gäž“™ïíå‘·Ë+|^hÝ#ÇëõþæÄÀ~F†Å~çµQx0(X^_°z?pB:{ 2uv•Í‹ úýyVêütZ ˜™4.ªÔ¡íŽ5] BôM=/ ŽÂ†?/—*‚G?·ì´mò{Àê°×^ßšÞa²‹×X×À0HÒÙÓKÝKÑŸ¥ýË'¼ä8–ð“×±Ù°$G:x¬ìóú`óŠèÜ'Àõc‹Í:÷Úõ­¡éraP 1òë70’tö¬RkúDÌÔW+%àxŸýyÌßÞ6“õuÁõ²Ô·KÏ÷‚y䇫8ÿ¼ø±ðí0rœc‘ã"{Øw¾_1××Õ+êæÆÖú„›¤³g•:E˜öjøóR$ô3ã&Á^Ž´|+ã9/èËzdt ‘浿¡n®¯A»”ˆ—ùþBv¾{"{òË»!¸+;¯*P§mO½0d†wÃÀh›²ÐyÉXáN4Î{„çÕÑ£E¶‹ŸÍ³áÂü`}óÖÖ¹÷!½÷¬CÃÿ&4ýóykkk[7·6Ö·nýÑæ›ë›o¯¯¯½„†ø^¾µCûÓÍ-ŒøÝ\Ã@xÑÆ´µuó…Îñ1Äÿ‹*5Žº¤ÆDJ¬Ë˜¿ÊÓ’ù­¸'cY†Ÿ]*ßx5ª¡º:–ú§Zö½øõ‘œW0ÊÝ€LÝž½pã–ð9 ¨eýï@pÀæ½½¹õþûœ®7¹‚a^›¢‹ÆúÚ»ëëï®·¶¶66þxVyks »-ýá®m®ÿ gý-¾ÕFAŠá­×ÎÏý7ÐõMëßÌH|ÿL“=Sgç¦¶Š§½@^ImÛ†5Ðâˆ}Œ, m¬à¥Qî"1·y{PT~^¦È| O•ì;7Þ‡`¯õw±Ä~½wóæ{ÜxCì"ÄxaG¼u@›¿±!Œ?šlnâ7ß~{]„ŒñÇ›ï¬m¾ùÇ£nõõ?\ÛØØ|›ïíÚ;ÁÌ›¨E3†Í2ÙE©ÓtvŒÇªöpØ¿ÈÔ{øô”B Ǫ̰㱄î¢òÛxçgC^áÊÏËÙãµqLÿ3žÕw_ç®Ëú’óÚd,øÎ÷Þ]ßøß^_X¸Î™ÎYÏéüö[[ØñN¼rÞ|ÿ&_úo×ßY»ÿæú{xlÝ|wsó}>½¾°ð{ë[/üèº ¾Í{ Ê<À¬bœñ¤³ëÈÔÙŠµdø}J½qN-ö‰ Ÿ} û#://_¼ ûÂÜÁ¬·øûæµ…ßý·Ë¯_[ø.'î[¸ý8­7€ò ¿ÇiüÆ÷¸…ß;ÿûüÕôÝk ¯½ŽË~(~m²Èð_oxJ;xù·Ðÿ_Ǿ{o^û;ƒtö„RgÄyW4¹ ÅXüîA;A}\¿QŸW@oççÇßù *¸ëÜYgMô+ŽÓ7¸¯o`;þí:øñ¿Çɾ¹y>·À¢÷û¸Ö è“·µ‰kÎÁóbk½ÌL€Ú t[‚Îz‡=°»]ÒÙ#¥Ža¤î]ð„ŠØdfëJIƱœÐ¾ƒ}92ËÄýd¶G}^q^~ôá̾ðÚuxÍä¶ýæ:RipßýÐi|ý÷‘þ`¯¿Ç—ÏÍýÊõõ›à—s¿smák½þ&÷QøšßÔߌÏF°¹¹vío 3~LB"{ žÜ³´¶´¶±WÚ‰|‰Y˜Êæåü—ñåsî% ïä â`Χ#zXضÅ=¦ÁˆÎ뉬Mñ6rdqªÿÎ~ú#°Ë¯]ßä/š0…UNÜ9 üwÿÚ¯ü›ó¿ò:*4 ´¯¿ö}ý&ôl7Â÷ËùM"œš×cz6êÎ}}ˆ¢÷£HIgHÔÙÛŸ£´2Î(§e¯,­Õ‚£±r>tæÑ·Ïd»’ݱÛucTçÕ‡êT:;d[ꊈE7‹u°èÀKiÙ¿÷·ä¿sÝ'4Øs|5Ýâ´ÿÞæm¾Í— zÃÍkþž²ìqØØ¸öwDzYöh©{Áxr9íñiqá1w—ÞºÙƒ\,éÇrr΋?–ÌMŠ=‰ =kdçÅ-{×?¯#~¤ï~C%l\[㯨`Ñßã–è-ˆÍØw_‡Ï94æþù¯2ö»ßÛädŸ›ã/°¸Œ“ ú׸åçkž²ß܈z0 ¹óõ;~tdÎî#Ugïä§„SÜ b–\_FÝ;nÇn‚-ü~  6ªó PÙº>fráþúÍ÷nâkäûüò]Nøõ›[[[ïßä†~íîÇCLÀŸ¼‰ÑëïAûêú;àß„v(Èí¸¶öŽpƒÖÞùC –¦Ô7ßܨЏ1››oýɯmnýþ‚a>´ÿŒtöH©{Zœ·Ð½{bìÒ”m0Kºì–\ó ~þS§)·ì{éq &™Kæaõøo#Åa—Çrø–~@G«7—È¿;ºóô¡; åµSð·ƒ…ë*“#pöÆ€Aà"}mÝ~r{ÝÜ{ÏÛkï®Éˆw±½è‡?ÜÂ|aBhÏ® Ý>.­Ò†„©Ø7ÒÙÃ¥ÖÃÉ}5&ÝÚú¤P†Ðû¥q%õ°Jg72ú–­¢UÒ|¦!Ï«?`ÌÔtöãcöhBBäÖMéŽÈP쥴.“­õ¼D}ó]tjnmI­eI}kkóæ{2é÷l°ÿ‡ðl ~CÄÈKé‘ßI?ܼöÆç]›e²‹RÇëì©­êL¶­ØP„ì^Î]˜~,éÎÄËÉy¬¶?2ÇèÏKe;ádüÜù…ëè}ÿÁ¼ùÖ¿ûÿÛ{·ÞÆ‘lM”zq#i;•^ÊíLÃè-92}†¶ÕDåNÉ’E­ß$` hj¦jwÏ`ÆG(cX]ÚgÐbb70ô¼¨œO§Ò>ë[+HQ7ëFÝœŠ¬2mêÂX+V¬øâ[+løäì†ÈkgWæZ´Õ4ÊÌL7”:m[׋ +ŸôIdà2²úšâ½³ŸoUhÉú6ýgç¾oùì±2gçÜèã|ÛÇA§vâé¾óø µcyV´û‡Î“Ïê u 'Tv^5VÃlc‹“ëþáþþ^S-( ±)´ûÆàm~† 8ð× ˆÈoᨶ¯=ɦßb. ³!IáNáï¨uißÀkÑ,;`ˆ•LûÜâ·–ÛäñÉÊ.µÄÙ=>íbŒR„‹Ç~ó7¹tCË.döÏ£ŸõØ}Vä^LîGó³üpgi“„\bOëõ€,û;Z˜Bд÷jGÔÄN)Øë¯@óÚÛc–ú¾¦¿5ÎÒ/öµƒÓSºË©P­üYÈtÇɬ§ò> Àž¡×R‡HÀTÈi™é?·=ÏkÔÛõ¸[œ½¿ÖCpvYÕŒ–§ÓsQ²w^NÞš !¿Ü­Á¿Ô*Rý=žô¨st»ˆÌ‚劵ã¦gqpïW{LóÊ’oq_ÏÒ+§]æ ©éîÁ‰¼Bä$Ã!»YÇ­à˜éÀ‡¹ô‹#˜<ö |š=Ù“eá²›¶ÊCk®Ÿóól•}œ}Ø×LÔ)ëS¯äÏü¬‰¶z„-à»*³ôâå qv×]+ˤ^¦q½;f*—~b€­ÎÜupe˜ùxŠ4^‘…ÆàÈ2kæu6Æ%)sà-LIÓVı·¼ãĨ}¬G>;¨oqöþZÃÙã;É—NŸ}‘Ïz”¬Ñ~âbåºï‘«©çóD×OXµµÔ ‰O"å}‘Å=Ê„,F>¦ ‚Á±÷â4£ðQîêàá’ÃëÙùΪe—¡„ÐZÝ:|¸ØÝ³Ç·hLo­‡òÙ“ öÔvtR¯Ò¿Ä£B»Ï Ÿ$šslø³º8»ç©×dw_äŠ6;§L (žè©ÙròÞÁgWÊ~rYí×µ7ƒmÿ ¹)6“¡Úö•é ó>*;9@4œS°Þê”M°)RF÷¼V“c•¶8{¬ŒÂÙÛÈr;#¿|ÂÂÙc¨‹|˜žÄÍg/P.°ƒj˜Á€&HW;x‹XR‡ƒªõãc¶åÊ6ŸHXÞÙî==k‚þ+.Ê1{óRä÷e“‡‰ å{•1¯É Êžª¿ä{èµãâU˜/£×}¿å¶kõúÖ²ÔzξHq8ËJÄgo ²ûó,»Ê:ê†;¨K«áuåª#·©â; ²L…Ü”½>Öqÿ(û~—£•4ý]ÞÌì¦RzÆàxTZŠÚ8‰î¼Å0ØKÁƒ?b(’ÃøÈÍÑv‰ 4æuÆœi²[ã¶ëm>«g›7&^žÀÙɺ#aQâ‰4¤€á[ ºùU\ 5Yܳ"]o+ÄbäzÀ³ªAÈgwëu¯µs 1EØE*JZ–:•ݲ‹Â•ñÁ¶¾µ8­Lx0Xž|zÜ›=ÚårÙæ\*7êyѶmäÎp,ÉždcÊ0ßëZ»Ióò]‹þÅús‹³‡µ‚³3öÝP{ç‰kF¸D¼o9/}í§©3¾Úa¼«ø‹“«ÑˆËåñ÷4Ä"!e©ÅªZÀÖœ™áTLp•Ö«\)S!×Ûº4kÉ>A <`g òàd¨Hq…äIæ…ƒ)ºG3ÉÚúè1—¾éoqöZÇÙÕ:uþ³z‹8.Ÿ¿WÊ™N]>ÅÄ‹²šªêBåâ9$Ä·Iªf³IÚ§å •‹ýœsy™—ÿœÇž(­*ÿï⹆c¾³9$’b ³¯I–¿`©ód°sD*ÏC¤R1ûkYÄ;‘Î#?^QJ~í§ïùD§-ÎÞ_ëQ8{È#YÀ”Ï[/Ýü* 3XDûu í~\׃0›Æbä Ü.ŸYèê4Oj™«³0JäD>ß×&gä )ºWXê’oÝb›oÙß3«1*B„11"ÊŽ|K8ÃËÓ¶Ä x0î[œ½¿ÖþSY's¦C·ü^ãUB,o ÿ¯Ý/ M×½Öv-W÷Y=ï®é3"¢ñv>ùåðÜ­0÷®•ÀK¢ÿùK$¶QÄY×A­'Fi‹ÆÄk=:?;»‰ªÄgE1 Üxó®e¶e?K·B‹Xˆ½ùÙ0‹ “ËkÔœe@_ÄãèìauS•0âæ 2ØkÕªþM€LnËÝžƒ/có³Ót¼ZÛfý‡û{z8߮ۓ±J8à1 LÆÅÀ³ÚU!á Èuÿ˜\ü¬@Ó¢ÓUiýâ7q†][Ïœï$‚TÂ¥YK9=Ï2ÿ™Y1vú_=ªÁíím;bîo-û@­ŸÈÏÞž>WÜøÇ©|cns(†çÎtÒêÈÒ‘g5‚F˜—=´p1¬öÙäråª×]ɺøQ;?;ü?m2rá$ÏÛÛålˆ@£ã|ëªD_'eÛÅ‹ñGÊç%'×£Òõ>¹šÍÚO|Ò r«ñ9¨W;(è è¹xGHI`¦¼¥Gþ?MÔ§¸íæg¨õùÙÛœoES¡™IȇŒYðä¡|¿Á¶(Águøœ£ ²ç^”ûY»/Y¹ä»Î¥ægoµÈÎÖ@º‡t¦8I¤^ëËœßgW_@nÑ7tIÿÀkgﱂâãÆY%“@aºEjêª_ýûDÏÂZ!F ›2Ñøütw¼aäªâY÷ýu+×ýÃÃf!­ê×& l•&?‹Ïâ0”~ÓÏkøžÂƒ·8G×|’‡wwú²µìO×z4ÎçŠêtð ã!–MÅs»8ô๫Ý+ß›©Eå´é ýœžç‹o4f’ëqB¹¢vüß®‡È²àBòèuçÜÌ“¿ ‹Æ©àO|ÊIÿP§µÀGìU¸cûñ‹Vö±8{„Kÿ=Ìråª,.“ Ë3¶£ÎÆëžôóôó|æ*ÔÈØFé¤<¡G•Ì+b|ÕÆ>'” ™ÔA¨Ÿ^.Fì'•«Y㕹׺i#ÿýaÎ`—äÒä0£0…ÌôC‚s,I¨ÆÝOßÖ®þ|;$ûgï¯õhœ½W;ªšÊ™%e„ú…·Éòí°GùŽÆÓÏQöÖVŽÈèh/'sc4ö(‚“wR¹ÿÙŸR®—$Ÿ4ê5®3¶yõCrùw-7•zEÖuÛNENc7Ö‘ ©0̃1‘MÆoy|Þ)~¶üqÏß*ûS8{”¯so7®­ ¡"~®Æ)”ï|úyøE´–Ÿ5.’.|VàG¨¢ßvÛî¸ç Yå}OןJ®pu+ìõÉäúå¦Esh³†¤£dÛ‘&áiæ8“qex7*ýƒ»§í!›$cšwd¹?ÞtãF^·ÊîŽ/ÒP‹1ÝŸÞ~Œ|Š Œˆk³#݃D÷ãÀ}|z?ôñ 8>«ßØ'¾l•}"œ}ØUEŽªSˆþ© j-ˆHÏ{§ÿþwsê­Z´ö>«!"³Ê1°ŸÀ&2Ðzä sY´ÁìÏ#íã8Qÿæc*%‰òÞÒÚÓ¹° Îų# ó ™ÁÚœQ††Dú‡ ¾WkÚç~ÑÊ>ÎÞ_ªìuF%¨ý—PŠ€§¨4óWðmåÅkbÉk~uGóýØùtó—šâ¤×Ø‹÷ƒZ;&e;zRP¿c:¾ÐwÜÒO~$!‡¦ÌÁLH«ñ:ƒ½wúRe”ÎŒôUœ ©¹ÍfËc&Ì´åKVv©õxœ}îæ–‰t=Þ†÷Q!‚§€Ûíycñçñ¸»‡T†OÓ|õŒèçÏéßOðºÁ“ï Éx:×d.¹zåóí:Ÿ\ â––Ò³N>­ï» d‡Ùì®Vk×÷pü‹F£î6jmN´p¦å)Ÿ÷E+ûÄ8ûÀUeàu»ºÎ>Gˆ7Wå«âêc®ÙéF6TEß3ïs"ÜózqfÈ +¥ëÊyIl×ÝäjÊù·þpw¿Õºùx#LLä^¸»ka.q[£Rw¿ÜÝÝù*‹cP›éù_²²K­ÇãìýWÄãÀĹÊyÉ:Ñæ=D;yls$‡JîìMñýCòØD¹eÂyDcÄcnº‚ÙŸ3€»78¯—ñ3ÕcS¡-S®èyò;U¿Öù¼^lj  ÞFüjPoõºË ¯&8“Ô5ü]?žÞ2WßâìµöÅJû“_]¶oØó ”ÉË.惭”Ëñ˜µèƒS}ÿÐkuG­†•¿®Å^c+Ìÿœp?AKxJjJžêóªDž—€\.iî(3¾ÌƒÍ&©p k!—ѲäwUÉìåÖZX#Ð @.ߺiyw³ë:bf>?£îÊ)bYñ„½uë_Ÿþù[eŸqÅŠ2ÿÑ×"{› 2Ñóµh&!½s]ÅÅ\øƒ‘aô¿UÕ3ñ×2žž\Ù*»;5­,œËöýåTŸŸë(4&µ½ñNþ¹q~½Ùtå·IáíK»~ÑÊ>5Î. ¿š¯í„;£µeZ&Ò9GxØé”uÁß“Àñ'\ëò6ܰ§e}‹³‡;„8¿Bv-ç[ 9!ËÁ‡%zhGYÒ.®{IðØ'çÕó<²¢û¯U퉗ZF=¶8û¬µ—Ç…Lªç~ëÚõ[àºÉáÝA »µ^#²ìòºªÉ²ê!ìyš×õ78¢)h¨9¦±öxûVÙŸÂÙOÖ´v-¨ºrn.g<תHÃg- _繇OÒj=IZ4¿ºÀçã» &³Ã-¢U¾Kžûàí[e˜E>”8ú€•v”Kqy%ÄõóèÂÛA„…,«!Û1è㵇˜ûZ—­²CcÜ0·‘•ŧwÅ–&U?eÁÉDþ\|úåb1R8X¸«ÜmŽ‹åýUÎ µŠš=]¶Êîåo³·®s"ë%Èöòðä¨> ì}®,±>=¸¿6ȧÅ1Ël§-Î>¾ŒÄÙkœÑ¤ZÓ"¤Ø:Ãí+±HœÑN°”8™n%–]a;]Ä]ÕS!FËGÿ'+_²²K­»8»²?N…DÃýè2Ÿ\Cò–¥áÂa}øŸ»?€cƒa¯5‚¥ãÕÀ¥ÚG½±û†¶/{w q÷/ZÙŸÀÙÁÞÖb{‚b¿„ó8>ïyòW¬”žÛö£©f¹õQ™‚*B¶üjï}­;®WßâìýµîâÔnwL&gÚò„Ë-vTkÄv —‚kGOó—4ð:óë—WŸˆWÏ~pÐ× ÑëÀÞÑL>µv¸ûVÙ‡áìnÛ×8o9N(õÝ#ZuÇo©ø0øgЪa¯ï¬ >°ÙA5dÆøÕn» ÿQEÉŽÏ—¾ÅÙ—­ì16B?3㽸Çrpá.:ä*ö| FÜ_léa9jAì~÷Þ2ñÿ ËVÙcøŠÚ'ådz¶)ÿTëfàZMõüUÖ+Ìç²þ«Ê¢#R7ÌhSM o|Re«ìn•ä,½ülņ‰Ùõe_ÝžŒ¿¿¼kõZàöÇ4­¨~[œ=,8{•c:a¨Æ1v-ä…¬ªÔF üµ!ÿñÔzÐþªðÿÛ@eªˆiZqýâåKVv©u'ÆO‚0¿:X}}É¥»*|Ømt9“Ü_&ÞÎç¨R-R ÞŸh4B¼¦ÑÐ4Éô¾6xû­ì8{•OÍ­z÷ŒÐåågÅg¯*~ãd÷—V¯èÕÁÔhUŶ_E½¶8û¨Zwqv•áK2«{t•Ó%´Ð:­'Fͦ¹¿œk4¿`ÇÙÕ8¼ÊæÂr0!®_ßâìQ­ẏya$§z#®r0×±…ÕàÃnÄ2œìþ2ùínÄpÔ49g©&÷™ÿq#WR¿-ÎÞ_ë!!Ó1†®¯4?JÀlöÉï/«Z}HËÌJ[Å>Àˆ²Uvm[¾œò¥+»*Ǧrk•E›âîŠJgh}ÖªŠI•ª^´þ›¸ÕYuõbe”²¯Sû«Ùy¢æ«*É´×zÉ4åùÖú¨ÒXv©Ñ`•Ö¯’óK¹ê $W÷NI_už®bxw}Fc_M;1C±v™ŒYF£uÒ¤ ±ìh²®nwŸkSÏ„ºtmäI æk(ˆ(û¨j­ME¿lŸ}pŽ]ËYW›øæ:”!ºê*%+ߪ+0iéÛÚÀÝ5D›ðÞš-uÉ5®ì,ÒmH‰kûO¸ÔK[¯u…”P¹'’`CËFŠ¢õ™Ÿu´?#•gÍÛ\Ó¢õé&Tw:ÙV]™ëÜ鿱že¸©\?Ë>¼Æá"lhÙ,A†·½Öûúš”Mô dZëß™[ãOU6J¥ëÝ^|x½”=ÚvïôÕk›|Ä]ç*OQ6NŒ¾ ÷yëk¥íÃ7f6¢ÅûAQéñR­ºsÕw ¦cj¼!->@݈Z+&DOuµµcŽ­òãµx¯ºoLµŸ’hÕ˜ t±°xm7Áª?>¶ðËUWh²ÒÛÜëD”™½l”±ÊnŠªÇj-(ÇFÌFQÕã(ïæ´øHqV]éêÚéþº1E áM{¹A5W70«®Ò¼e“"›È±Ýxª(¤rƒêޣ,ÃÊÆÔ_‹–£ƒÚk^´H‚0~xcª®*þ¨*½ŽQ'Ó²ê LV:Q”ù9ëRóÇPG.¿¬µýËÖöMiy¥$=š²9 ¯…"l¬¶G¬º&sI±ê ô—OŸÏš|O?ïï﹚ÜÎôß§U×ojyI íáñ×O‘ªC¼GÜFâÊU×o\á^ø„¸ßáê?p=ü&]–0?²úÿöÛT>týËZ*;4 óøpÏ?>…61µêzÍR`¼?=î‘i×ööȬßËíÏaÖEUSm_ºa‡äáðØkÜ׿¬²£Y?â5ɨ㲷Gí¼ÃSèçU×oÚm@’í‡RöÏrG<˜U×lªú?Üß“a'»ÎŽ ú¯›#CXÖNÙ¥ ‰ÙÂgg«Îͬlþã†Ì›RIhÊã#êÿ«Rt ÙûûObÛ?‰áAûöÓuçþ>Vñè .ë§ì°êq%£¾¿ÖÞ¬i3¦÷À1ø …ÇÏŸ?ݯºb“å°?>P(wr'• ¥»ß¨þX;eÿÜÅèøï-µ¿›äð>lØúô‘eÙÿ +þyŸÐ2ôJÝ×ß´?<°?)¢¤ö†áÎè^6¦¬]eîµÃÜÛtl;­kŸîwNM3ýW=cš9]“ÔMÑwªë!Õ;½«}zÔ^dôGí g›iý1R󰌌<ê0‡êŽ>xul£ONòNV_uå¦(KWvécžÏ„ƒå¸Gk’Ù ?5=㘪8]ÿƒa;¤æ‡Ë2KǺž±.Òtë/HÞçßÈú<<ü˶”TÿO˜Í?…6úAæ¤Ï÷)=k‹4œ ®7Iå¤MÛ0më2­§±îNa¿²ïY-/È"˵Çë$Àa´¦m›¦A}òŽ~/¾Ñ2&Ý õ§¾hR Aú ÜúÏâ·…ËÜåËÒ[V`Ùűï-éO;šþÖ4³d5ô¬iQ :–嘶c™Î……Fvè76ý43: ‰ ËN¿ˆw€r5žðçÏ E‡(‘¦½/Àvkú»o,*e–€Œ"ÿ”AlÛç¶ùNÿDÛ.Û$·øÀ»ÿJçq%8xöŠg)‡a™ÜµObÅ»[ .ƒô,é°‘Ö?kGÇf…&²2”þ,Ú¢öPk»Às-IY©”éö·•B‡†i¥ÿû§TJ“Ùá3YöO@*×aƒd% Tâ¼XƒíH“‚C“Ùˆ“8æq4hùšÓ)—m«€¿KYz“,¥åD† JZ?ÊedÑ·O†– ì9Ü«Gí5ûæ¤â4ÓÃúL“<²ñ<†I?.*¤ÅvÆÑu‡7ÿ?6ýö9üΕáððÎ îU9‹,Ì…Å–¦jÎýdŠÒÓÍoh%BK§R)ؘÎÈ«ÏÒRö¯ü}²þP‚¬Ø›YþõAI®Ÿ:ù34ޅâL*\¨XPø¶Ì„hÂUQìY²̓3€sCN“‡õÌê¿Þ¯¤)i:¡®…q»&—Š„ŒwÞ,Ù¬¤à¶ae»ŒÚ:ÐL÷v¡"ÞûO[ôV°¯r@›È¼^‰R(ÃNÖ+‹iè‚VÓ&9*¬ä6ÏL˜¥èµó+’Òf¿¥D®¦åèpï9Îuú¯Ÿ™õFþ;Ö!«vaPV=~züD 4éò"ÌWìé+~(šì ‹¤>¶ýÁŠOo$M"ŸX4Iü`‡±Çm%¬È__dÑ¿˜cLÔ8ÛGn,_•'CŸ¿„;K…GÁ*åK—&ÞÅN°Á>°™7€l¿´}é¦]?A5 ×@Pc³p}& &ð*/V«JÉÏÑ ¼!«Îö©ü<}²ïø™â±û9Ú‰]aYήŸœqÓ9ì¾XbHk®Ù‚àWjÃß,™—Ôz4ñãJÍj—ÅõµÈ¼Ðû-Ò¡¬N6É9ÕW¥êïhžá)‡ÝsvcÄi±Ø1ÐêlÁµ±Ä +“^À˵ËeüM«—S òøëªpx=Ç–™†ã™]¤º:\eGͱ¢Ë—è™Ëgç’Ä3Lî’ºX*#“œ;ÙC[½ãž rðD8à4ËOŠOÄHº@äÔ±E#lÃÄJF:òp¯@ŸXF†9å˰ƒþYÏÀ 3eñ–D±Óÿ]ž”\¿Œ,÷OXB J.«‹AÊ]_=Êž´e¿¶@'ÔÞè' ¶ƒ¦EA±œyÛr@O áÂèa$r´‚(¤„ul€aã+ÃÔÈ… OíÂÌ 6O)üýÃoŸ÷SG§–ð@²ý]×ÿW(’+W÷ä”]8BÃ)Þ—›y‹zÆÆ”U4®кLZÛ­¬>߉ɉx èïÉ/.qISy¹mzÍ«6ˆ‰þ<æ„´«½Ê²O™øL (­¤IÍ-Ëú({€óîÛ®ßóÏõ¼»V ýò±ñ·:9/†É«QlØ@L¸äôÀõëר7êuÏë«ïN¤ .d è_ÿ§=*ô½ß×Ý@;ÌVІY2 ÖŽ3¿<äÞgôÕ¼MÿëþC '’%YD·ÿ{è‹‚›–vtJ&¨ì$nÙiñm¥ÿü=k@Ãm4C%™T–5Rv7ðú·c×Ö{w×jù·¤i‡Òˆ ‰  '!/·«)Nv:Z»½õ«m:Ó[wlú¹ËâÈ¡®ÍÖMëÎoú-íUιpxóè©$èÆ8…œîzü´ÀóGÔƒ5äåŒ8­=¢_Ô•^kë§Ô×^{&\®óVú?רGîüšºAê0st=y/(ì‡ôjµ–§ý„ÍünÐÐß’RE€åŒ¯;…ä-;pê†ç’4hþöƒ¾Mf !I{ˆ<ß‚=lµÈ!+8eø¤à &1ý ª×âç·žß­iéê¡á¾?Bšÿ‚@(_%¿Då¡5{e£åÙ,Ÿ]Ö;ýåö¶^‡Gqwwë·õ?ï›…(2u7¦:ÚùR7¬û>=k+Ü«6ÃMmòá¿´nÈšô—‰”ÝYh~¢žiðêDÏÃvÊ襶#jTàí³2ùù!¼ï+è …N±h[±‘ŸÑ5¶êÕf“lïìï@ûº“ÈòÐ' }Ÿ‡+Ú†~§ÕM½¡²›Å¢b7^PƒgREa¶—,k ž{@×(; ;œ•hf+ñ¾ Å½r)P¬­Æ.½žþ±æWiõV•¹dˆ¦l–²ÇÖÖáúŽ®^ày@F¯öâ”éÐhļU »«dÛ• ˺@㤩û5 [yFذØx§ÝûSËo] Õg2e﾿ï <¡YC{p’2¶?¥‹GXvqp„S"ÖÿL©?#}Lñ‘O¦0÷ù¨;5ÍNux»Õ Õ"«èGè’;Å,åöÖ¿Ù¶AR ?5\2jEÙéµArdî‘íS8`Ïç¤Ñf»$¨k‰8x]¶ú´ìˆÓ?a}2!ŽÆñéZ <ÿã@»Nƒ,­²·ÅWî/nÓ÷ono[7Ø+åó%¦ë‚ÀkC‰ÇZö3¥0dmXá‡M”l{$´öÓÉè-ò›jÍ[Z1LiA˜¨ö„e¦D_¢iGDZ‘*¾ºí Êš7Ð~ùwhÁµŒN8tJEÀ¬%gJ-½zªÿ‰Lpó¶Éó|-y¼…mhãYž$Kÿìæ’yo¶ý_îîH=êãE,´Á¾«ú” 0ª!͹xª Õ×\W‹'S¦m82§^Ò¬¼ãDS”Aÿ˜í”þñ%ÖQ~5¨úCfÜÄàlв+äCP†'×z»Þæ5¸¦Ÿ’q( ø‚M¤t}>Þ²ÃM1™ 9Ôéq¸iå%KÈ0Mé\±c^o}“YöÁÏ…W²†Luà vP‡snÝ©;^?5 †á1Ù³µ§K"ð—„G„§ßU"/·á±f×ë왹]_{RËîÉ·„r`õDc‡| º¹w¡9–´Üº¨M¥(£YÏÍë‚ œØ¶‹¨9 B²¢Êö¥\á?ËÊ…„~ÃêÃ]AJô±‘ÖS4+¹¯¤âýÍ8›eÙyUÍ6'´=øáy-\õ,ô;Ô…‚X@jܱ "y#ƆS(Çì®s¨œ÷3pܵŸ«TŸ›þúLlÙݾϩ+yd°…&s¿ì‚Ãú^`\ƶaµ‹~-HiàÚ¡ãeá+¦Ðá,ÓPƒÖ±ŒžÒ<ÏókäÞø´àÆŠ´åFõ©’ÆNjÙk19ºþ‘ÆP›Vï©ê†q.»œGƒâZ•Œp?˜êEçµüOë‡Y‹–‡Â¤aÓï`¹N«Ð¸)ãižB…–)6/ºwvz|õ¾~Ù,Ë.¾dCì §®´Ün¹uíðøÊ4/.Л°_ vc«},Ã>,I3/®O¿¶ÃE7l‰•ËakOK<-èÖ#¼NeÙƒŸ'çòU„VÑ—×LO/W"ÿeˆ[ÆUÆb¶Tb"0–ª%õŠXtƒƒ˜pçÌQóƒ\H]²è-r9\²É!šâMcÙ±úÃçê ö“®~"v¶“FøtžÖ XNæó—ùÈR›_ÓX„¢ЪÆ×_›ez÷á hGY4Lä(•¨5J\ýsÔX¥¯¥¿ å©ɾ 7’ 6onœeWe8z•o×ý=¦9§bY×$}z$š£Ìåè+i–O茬u™ð‰ñµôÚ‰¹4âu’½,â•ÁúLŽÆô~.¼¶R¯Ož$GÀaÆA- CÜ©©'ô`Óúïsv…å¸2BëYk”YƵ ‡OLC¶í6±»äÁºÇêÖž ±ù‰Ý_²éíê¿7}ý”l Üm‹­´“ÓõLV×siý+MϘÕr˜Ë‘œà¨¦õýÔý…×Én“kBNáœá]¯ä]§Ž|æ}Z[ÄAÙ¾A=Ù÷n]¦ï—õQvKkØöx¡L^®žoTÜ Då°õh_‰mý|³Mgˆ2™ßÈpˆ"÷­˜ŠÙðÝ{ÊÄh̨¢¿Sõ"j‚@*|aèä$&$uF”Ê*;f4.bø<É‘µÄÞK4³ãœ•̬À_o4È%lˆŽ(4fBnLOíëu¶î´~§õTC?6 ‰öEŸ`3K‡2gÓ¢ð)ýX©v–Õá¿¿)ól`Û`}fø3‡¼vˆ¿è3Gl¥áe”à5`.…,WiŒèÌf)ûpœ’´9Óˆ©¬uøÁ‰y†F:¥ÿ¥a'´Ôë̉f$üÁ”vôö˜_?`e?ÌÈBgG{u f#6¨`E²PöhæWÞ#ÕÆT Ú®N…çCcdײZ¦d£N0G%K*qLrìÛg;—ɱ6×ðõI†å8äÈÃì·Žd[9<ɰüÍtp¸Åô_¼ ~Q8;:¶\Z ݇ßÉ,uDµÜI½&U}%êÍrÍõ\‘#K³,'Þuˆ4I<Ø32dØ–_š†Xx¼£È[!èêœÓÚ„Þ-ëcªCÝý…g™)úe}”}(ÎNÓœÀiA F^Y9÷Ô@Ǫ)£†ÍJSÒ_¹Œº)vñuÆÊÓà8•û‡üÚAæ­jf…j˜Äà5Ͱ Tuë’δõlHć%vXŽLWŽ”~Jªÿõ9rj@“*É¢î]`9vcr¼ z4:A’¤øÈ>n«Þå Ί³“V1ºîCͪT'Ž.(Q½^JG´TÅ ­´Øy’§§úS´IêS¸Wœޝ’Ùà(‡µ6}n†Ä.½ÃvÌØÆ,¢S½á‘¿ÛG¯Å–ðYáìÕv­éïeåÀ9ŠßŒnFc§_ü¾kEÈnèïíbnWÏž²ÊÀnÓʮϱÁSæ{å3B¯³»[Xv³ëà0œ] o´ôõt²é1»>3ÎÎßA3DÛÕ^g8ÈNɦÈJG ¢ì¸þV¬ÞI$ǧ¾‚q¼«ÿŸjêäÈñàpùÉûOÿµ‰ÝN/èÁ2fÄÙy…úS³õ§–¶sðÞ,ÚùKÞùAî»Ež—2‘,<Œó-)úW<™yzí-×»€¡jÇúnòðjÄ<Ù å?Ê8Wg¬èh«"ïE`'û§Ì‘iñ¿n¿l3g¯ú¨i{Y<w8PvØhØGž2÷XÙs2ýgtMY úïÙ×}uÿïØ=#uÁ;úëX|$ÇŽà_ìQcù5jÁ¼8»BA‚º&Kkûä8­X²¬ÃÊáU&½ûÕŽLýïXŽœXC(ú?±;fcrB— ' ׇäx?Ô²“é¿õà?þ­.èã|8»Ë£¤M. ͶÙòyÑŽVF¹sØurwÿæH³Íœ»§2T¿by`Zh–Ú—{3m厞`U%ŸQ³T–7W…(à±þ3õ…ßbÆ…ðõŸÎ^¯k»'°çfÈ]¹RöLüV¥Ðá„oYYeEìbà5â«·v™­÷%†G–r—¾ÁFÓ‹“@ TK-^ÃçðR8Ëkÿªú.œ],»»gZ :²¨9^C™C9HbûTÿäÀ2­¨üÜS ªæ¹\(TŸ¬á Xö·È*½·öS}Øò[nœ]­­jÚÑ)H’Õƒ36þŽTUÙeªù±QJïÒZ‚V$ZJÏHÄÑ!©ò 8ŽïÞŠg¶ ¯K2¼ŽÊa¾#Ÿ­‘5M‡N†Ý`‡æTר® ‹>ôžÎNä–]oú³g}!nGîE¯»£¿U~kä³ÃRjû´`‚e?ÊX½e1ô*N³»¼\2¼%ÝÐ8lR“]Zö9pvìü5<íè½ 6à|À²½3••†ª²’¤ØÎõÊÁvñ%|öoÅz‹zÓýÝç9޲ƒhÔmßoÁˆ½šgf¾§~áéÖ`#t^‚BÚ ´gy_¸6i pB»7Ä0¯yäk۰Ϙ9âÏÓ{Lë Pꇂ}}λga†¡G쉜èû^«Y«7„Õ©fªç‚³ßù_cFÅ·bÚK²ò'õVŠûÕþ‹SN†L¶æö! ¿>µÿû,”"½Kêñ5^݉ü|¶5'yÆ؃ï¢=ÂÏã=HÛKbºsáìmß­úÕÃLÞ,Å+zVI,¬á1/6ÉS8ó+©a†í\ê5â9v¶ðjŠ<üÓPŽTJgÙéÊ–}@×ì‹=òo«1fÌ<8»ð€ˆ²¿ã46öuÁ‘Ím†k/Iå1ãO¤YâŒ&¼…aÂîA½d ÿ—òàÕØÌø2®ŠŽä;!ÍÏ_ÛE)¨T¨?d1ýc-ðH?˜¾_ÖGÙ‡âìdUUš;BqÖRi(™ã`—¹WÙ8ðâ’÷ÏJt$©Š#©Wðz)&M»Ô©(ê¯Z1ÛJž©&1\wfœJ ð!ОoAÈçÚÙL„’MÞ¡Á?ÎV†:ž‹{e}+éd„&cƒÝ{A P,ÂP"Ó™Á«÷a[ʽÁ¼o¬a}NœÝ×ÒóÈ“×Ã4ÔZ«Ò ©æf²Ãö¾ øØÊ&GÞÒËç¼®æR±ßt<ŽWÈ+f@]æ…ÅT¦Ù–÷© nfÚ焳7› ;RƒäѶiœnÛ¶(;Ƕ ^6 «©Ä’ ÚB"0x~Xa ”gÕÊèÔ®Í[ÿîî®å1ª;Î^ÓPW¦@µ…%5düa€ƒ¬â:X—%có`Å)´C¡Ð ëo‚Àµ!ìÍ9øì­_~!Ÿ?гÌyaMg¶¢z8`¬3£X®XJ‹‹·»蜩”H¦ú,|¡|ÉeçÌ…Žø‘e[±!ñ‹†Ëénë¦uÛÄ:¤Ieb”lÍ”}(ÎÞp?68œ™¯àVç©UL&N éÏtb)(œAR8ϰál(&S†Š#T¬A–¡Ã³FÙùÀ«þó?êìaÕÚä±Ö§À¦ãÑø®ŠÑ×ysß ]àyJ9¦rFžd ­)ð¤%&2šµ ÃQJ?löÚ4Oô -Q>¨ÿ|8»‹Üã_«ïÑ*BQظNùo,F´¨mç>7gðåT~ÒÐ'JîX—ð\LvvÎ Ô~ë¬$¢‚cc0‘ 3l‚°ŸDKÞú¿p|p ;àè?œƒ—ó2ÓdÝJ¹pY2BºM¿rF[ÓI‰šÞe\›'ÇSXÓ܇™v[u”ñäk³M—jv>;8خԹP*å/Ù3UÌ$¹2bvºG×½ÑVAˆv¡‚x%¥ô}“íDÁÚƒê^¸6Òÿ»ßv9²(œ{妘©L¯ÂlM»KJ¶ÍËoJŒ*”Jꆤ W4x­<‡u€£Oÿ L„'†d䛼üå$˜òDž}úψã§í¶G_6 †³{¤_ NYˆÂkË8·¿+‡–\RÛÓÒõÂ1#h²WqÑòW‘Ñ,(R@±X2$Õì]WqC4@+ÕÜ^Ëçè"àËÓâìá åÉ_ Z\:笅–Cލ Ú`3Mžü QÌÖ·ßVlúÀôfšÚ¾µØºÛ/üÄ‹³A7è”Ù›œ€F«7'Îîyßï¹ÿ²w”³i Y±`©M,.9ŒfÃkþµ¤f§Ñ…¢ð:ö9fâJ5¿¶xv*ÏѤͦü/4N û•R8¬Š£Ö0àé×€.µÕ óœpö ÖÖ߈%3íŠÅAÔ·ßJ’~n £”–?CøíˆòâiÐW%oz8>Ô¸ž_ç-;ý_H3±þåì8;Yö*‰§Ÿ2F­ëbñ=EíÊ*”ÎJCÜÅ#Å) ŽUàÅI1œ|تÚá¹,Ä]Á¦ß‘–Öy†šg—}ƒšöêø­lÞE©õ¾¡™ªÀ±cŠÛhÊ+¢bŠ3š.¤yÛLñ»L šAÎ+NJ°ð…Ü›‚ÅÈ’y75«{è‰z³tåÙ0Ë> g'K¤Ðti}ƒæ;¿æ€]Œørh“Ùr‹¶Câªk‡9pɃŒ,9ŸVTvì«!ª®ÎBÁ‡Î‡Sk7-ÔŒ¿iqö×nðOdβÌE9å ˜ÊÞË‹3§\,º1!ÆAKf‰¢ºÌç#‹‡}j äŸQ®ü°yЦ~¯Á›—ÏîóÚý¶¬°P©ú´·â„ƒ“WyÙ48lãZ…cóå » ö5vMÅéÿ€A™KFÀÌïÊ'Ÿ¿âÑrÑ÷´=l{8:@—žÎŽ,`Ç6MzdEöö$­©åY—A.!À–ùŒžaA˶™f´)©#`‘” ·HRÑ¡ŽÌÙµjuÞEen ²’MèÆ “ò1 õSV€³ÈYq¬|Ér†èjYŽ‚Êšb %TYáON9ædÕì: ™,#ý#ïy*ðb.œÝõ8;vPrÒ~²¦i¼WJõûï_`ËkÉ½Ø >ÐA.Çô¶ùÂOÍÈ™y‡YyŸ|Úsý¢Ž!?9IWé«?ßZº»m2¯þ9áì®Ûöt¦7a‹Ü¹Vd§pƒÂr”W Ï}x ‡ma„Él±-#½¦5ý£ö/T´’†ØG/hÔ›>öí¦ÅÙý8ú¸¼–“À6ïÊéZááK4XCÃ`bl˜ÏI#¦šç†7†m2Øì®7/ÎîÓo9 u>Õu¦êb§·ggúXX0á.ð…Ó%C`ç÷ü¦(–Ó¬ñþ·ºâE;ÃdÞ”Ƈ×üØ–=mÌ12Ó<#œ,ûïßm+%1™.EËÆCa|g…ÿÍVŒðTŠéFì ^#Ã&ÐtȦaÖ$lìÞ‹L†wQÕl&$“Šêë äqá1×›w­äcŠƒYÃÅÀ‡3 äÈ ¡WÙ·c»ÆûoxJ¢OïkÜ)zEØù;c1~KgÚûìosLSÁN?)™òïù*òõeýæð+'Lü‚2CÝ»lö£LV#x/8Wá"¹×ºïSi–~Yeг“O¶sx"«pм"ÊWNþÔ‹ÓS± b9˜óýJ~ó† S_i; T9Y¶)À¶C”$²?à„ŸZÅq>¬¯˜3GÞ˜:ö×%v“üþÿ!ai˜ wcrˆJ¼}ËuS Á,9!§y'$ë¾&*6!«„R’.ÃÜÄqè5Ü‹Sq£mÙÁZsç©+VŠçÌpÌluXkvÍ"æ:·óITÿ7†“Þ=|[`dˆœš7Ç»‡91=_qÖk06#æ>ª¼3-—9U‡#1»eÓüÐ_ðœpvß—Ã`MC­üOÈ2¼ËìB-ô\‘†Àîñ‰XQ’wÈË4ØwˆzËüij´·'º¢‡é¯OU¤ä«Ì{;wŸt=øbˆ pö§´ }8;¬ çîõ«’WÀ<Õ÷°ö‘õ„©Ñ¼Bq÷8×|br„½ƒAõ!eÇÕ„ïžÉ‘ ­áë÷f—1Q÷‚ÖØ&—ó ´ãüïqvÄ;‰§¬½†ÞõW<Ç~ɲë'Ê©Quc·íQú']BW24—ÎÔ'Aö((eW]b¸`œåà kàpÈ é³ÌÓðÂãÙ³Š±rÕÅÉFŒ!Ž b×sbm¨ 8xC¬ÔŒ¬ ’Ç¡’fò¥÷ºu žÚ}GPôóå©sþ ì÷!/!VÔ¥°Y9ô@®¬öŠßø:× 4$ûwÅòî½xŸåˆÍ4Ì©’ùM5<6JïÔ·2ú䔟N³S£­²>F¹gÅÙën»®2.ñr’æB«ë]ƒm¿v3L¤fwŒg)f¦_(s.!ÌQ¨_ñ|À³mÆþ–Þ<ކ<3Y9ÿež·ø…,3çYæñ›;°oàe+7†šÇâ½~¨3l3wøîᩲ0®ÎØç9öͳÝ9¼ŒÚÁ–;ýâàôdEIŽÞÿ/8t²«aÄ@*<ð=`ÕZˆ@§^¿ËˆX–]Ç2 Ú—UÈ¡0´Çrd$r ¨£:;‡9¦`‘CmAOm6kð¶‘;fNœÝçØ~²¯-N$éWqhû•ì}ðþ‡•GZ?ún¯lN-¬èzrLš#ÛÜñqm*Î ˆc‚˜)¨U2KžSAéZÔ°Ï.o ¯¼k*;bHv²ËT€¡Òf"øi Ó(±Ð:ì²Ûö…°jåìÓ.†LϹ¤-;êdeÛþ®l†TÙ´Owμ1>Òµ4<Á Ú`çgTòiôæE Heí½íÎJg¹CPƒJž$¯•%#š­ôB…³”Îø]’OÔ³CÂ4Ðp¾ÝF]Nˆšg`Oö>ßò8ñÁiYt‘w¨Ë6[xÞäs„gW‚6„©|®²%þ‘Úè‡PÜ.Õ6žm…„ø<ÆuOWf¸‚z¶ycš,Ï6nD¡$ËY©\á® ‹ë£Ï™ŸýŽã.s&ÛZ€4¶0äÕnA˜ÑlÄÆŒ8{O¡Uòß›LáBÒþxƒ$JI‚û.e'xxÙ,eÎgGZ·õK«­g û|ѪÎ40ã¹-r5õ¤ó³ó)3Úëwæ-­Bâ‡åUsZY1õÇPé¿~V>{ßÕóô·gŽÆ×Qé7˜¿XÈ9³®9Ü癟ýN2@ù.-2+‹8¢ª¿ÜVÊè³@¦² có³7}ÿuÆ´+2o/H I`mߨÇÁ=ÇÙó³÷”6ÎçÆ%ü^»?Þ`nIp2Á±^õµr´Ž®Ë†¡1Cqvr6±âµô*ƒ¤À¤ uÂ!¹gŸê3JÍÏiÌÔ.ðy[ pË"%ÃJ%ýCÐðbøK„Kψ³÷_áµëÿGÄ;Ï#f¶7Þ`΂øI㭴䤶;4ÏsÁÙyW8qÄ\Y|$X(¦u-I¢ùÙqžg ŸÅ+Ã,XÉŸj;*U6hR*ãMu ³âìý×9…ópÚ7˜»Ëòß\b˜ù=·±}‚爳‹-¤ë?ÀOþøöþº£AÞº–J!bs^œ}0L£^oéǶ„/Ê-Cr½ÚšÆ<úFdÙcüúYóÆô]ëuÌ~­ßIž³4ïTôÆÌ)ˆUq •Ó ø]7Còå?/œyØÍ&_=c.aä,£ßø·87ˆ-b¢ùÙùô:wç0‡ËJB*«=çjá|i®sj$™cjõ™gコ­êÏ·@ËÚ@™ªmÎç7˜W›&øWDDÞüÛÍèvÝ44fÎî#92 ]׿kiCC-’W÷rú/ä¶ÛlAæÄÙóà@ÆFJ;xE0æ®moáSk8ö'ýgZµ’¯¦—žgØwh×·åóù7½†Öo€LÈjö}›#NëÏV8{·à”ZdE4l΄–;“á,>ѱ{.è êí .ì2L9@ë"ßR‹yÏAÅwbïYÉHš-"¤.O}hn1bà6+'x é¿ÖšÕ'[4œ} yxÎ*Kl)Ç »ÛÒƒõWM.ùÐÌ®rÐ%µ v¸IІ‹qŸzðF)ûðsP{öËðÛ~*¥áiýÄdò…ySvFM«æ¡×Ì[Ø%2GóTÿˆ Z^Ëk…1›‰áìžÇ'¡º~ëînG;|G]Y×Mãšô=ÿõL><çâß»€r”ãÑÛ~@þtà Ã¥“ÃÙäsõLéJS–ƒä(T…Ö øf‡QÁÈþ…ïHÒdž'×­Õ=dxà9þYãìQQkïûm$£ž-ó2ÈF)»ç\ÐiKØÀd‘¾³±w ÚoÖf± cqv”»fÓuþo8•Ñw8{¸Æü@Wò·F«÷'F¿9ZNgE¥EÕ 8@ò/žG–[²ÝAuT{&„³^kÿvwG£Y{‘3ÿ9­»©×YÉÕ`=ÕCj]Zá ÆMË¿Ek×@ŠÆy–,Ç]ԆÞ»YÊ>‚Ïãµwÿ550f`íÉãuTò·™5…¤ù,G›ZØûˆÓ‡êˆO µìvç=Õc9±ÏQßãœCÃ$g:S«»$ÂQ¨vFר]'%ù_^@­4 —Ng×Vâià(" ˆÊ?¼8’èà„©kØàÌlÜ|ú¾ä5¨{ÞsÅÙ‡/ÂÀì g& —;ªu%O²%IÐ%˜Ãä0uËTø®!q횆>ª=±Ú8‘,—wwý”žµ ”¦‹JG]p ΀먃lóÌ,Wätz>­Æ<+_1ä%wš\ÎÞ_~ªÑ¬uÄXC„±ÕÂ:mH|S+¦ÒüjPA6KÙÇàì£pka»&’Q¼%(£) Ždn·EÉ%Å=€à0FÃ4Ï–•þX.YÚ¬ûÇûpÜÝýåîNe7H³"ð8¥ÅZùkh¼æÁ>Æ4ÄI­‹ ~|7Σå&Œ±õ_0Î>ìÚÈÛtÚQ–CË 0-GÇW¦u™ÑRñbÎKÝÝC:¯gŸàûŸ%Î>Ê2úmw{šÏ;‘HkXÂþîƒ2줄g%óÙ]t[…8§:­ó›ˆÑüSëîçê5Hgï/wÍfÛýùöÖeA\íð-<Ägæ/C䙯è‡"Ÿ?R._ñFx"G1ggÝý8Mû-g(7´º½»!¿dG{Íù!öü[‡sœí‘›"Å~/ÝwoLÿœ CcžÄÙG\½›VõïÕ¶Ï6wÿ(#>#¥’qÅin9 †¼\(1UìÈQ–#ËÀrƒ; eä_òI¡cž;/ÎþîÞB&ªç/ƒzÛeIÈÉ¿À¹Ù/º¾ïU†0 Þ÷:\!x¹|’ݸç-gäïcýÃ^|í{éúÚÐäV«…QÍhs-PìÌ:·?VdÞäßÿ;¶þ ÆÙK›Y-õ &3°+ž<&/Zœ#ŒIv89Qî€ÿ~\ù¢pö¥—„qö–¥àìK+›¥ì3áìK¿&Œ³/ÿº|œ}ñò|)8ûºY™pöU”eáìË*†ÆÌ‚³/ýš4ξ쫻dœ}Yòl3 ξôkÒ8ûª®KÂÙ—×/›eÙgÁÙ—~Mg_úÕ]2ξy¾œ}é×dqöÕ]—…³¯S¿¬²+ÔtÍKÒ8ûÒë¿tœ} ò¸ʲ>ʾÅÙ—\¶8ûê”}‹³/åºÅÙ×AÙ·8ûRËg_¥²oqöe\Ý-ξʾÅÙ—zÝâì«Tö-ξÅÙ·8ûz]·8ûz^7KÙjºæe‹³¯WÙâì‹,[œ}=Ëf)ûg_Êu‹³¯ƒ²oqö¥–-ξJeßâì˸º[œ}”}‹³/õºÅÙW©ì[œ}‹³oqöõºnqöõ¼n–²+ÔtÍËg_¯²ÅÙY¶8ûz–ÍRö-ξ”ëg_eßâìK-[œ}•ʾÅÙ—qu·8û:(ûg_êu‹³¯RÙ·8ûgßâìëuÝâìëyÝ,eW¨éš—-ξ^e#qv¶ ð]?µêúޏâ|Á`"˾Þýâûª¥7LÙ±Ö¨®I޼¶w ÍOiú#Oý«®ç¸+,»¿3zñLúeÍ”‹œß»ÖebY6 L ‹ôÈóè—µQömY~Y´)|f%Qeß¶ßj~q/¼šI*û†´éFÕôË’vÁ5MØÙœvý²Ê¶_PÖÜgïô]'}ÿèkQ¦¬Õú 1w¿¬¤¬·²Oצ‰n­JŠøÏiåX 1†ÔgÊ~Yµ‹Sö©$›µ:SÞ_uéL^½E‰°Ò~YmYoË>KYÏvž¥bk+ɦ–…)ûä=Õþö±SåÀçú¦ËéÊØíÙ^[Rõ†¼3Ñ~YuYËžät™PÛÎÚ]«Ðÿ¹µP‘­3æ§Ûþí¨ y¾£Ó½ŽÿýÑá‰m>‡¢¼œü#a² ^"ÃÈšõ~ŽåXŒ,+ìuaÊ®=N<‡wk¡ñŸm‘ÿ“ÒYˆÃûs2Y:±¿*ËJú%Á‘;c$ÿÝŸ™‡Ú€N÷3=÷{ïF¯`X=Ÿ‹éÇS1£,Ó|fˆÔO(Hg鲬¤_:ÏSÙã×HSpÑÂ΋ÞMÕÝ_âßÔéù¦—JÂ÷ÇÔ°Ÿ@—˜‚Äk2Ÿ,C[å Y^.L–•ôËËþ¯Y~Y´²k½ Öc)Uªæ’FzkŽ¡ßÔé~SÔ¨žoÇG:É)Hg„,/dééè¾ ¡·^Ñ‹Ydy¤G=‹~‘WTµ©› ùo4°/»v#v;j—ÐVD7â›4nýÎc÷#ñ¶ë®éz¾$iY´ dy)ËË¡’Ç>½=’%)k¸ú~yÖÊþد qË6øZìg§ï›†©Úc'Öh:8Iy9T–¸DOÉ9‰,Ñ·E¿G"$¯ì+ê—þQ°ü²8eïm—!oد± pÐÒí—Ý7*ð+öÜÄ ûä²¼|B–؇_ö}¼É¯s§G–®¼ÙýÒ7úWQä³Çzp¦FE‰Û¶¾¹´×@©æ>Ý#”Œ‚Œ“¥3‘,“Ë2ÄgOnºÊ~éo’å—E-Pzp²FòM=n`ôÕQ/‡*Hb ºYGÈ2LÙgåýò|•ýÉ6œ|!Ô½ö¾»ç;Ãw‡Srí9£,ÈÒ™H–Ä•}•ý’h×ÌÔÉcwF{ŒFö°VŽ^ë„Ó_÷J8]Æáº—ñi5æðöéz2¤ó´,a²<öËÒÛ*ÃÞý2.‹rŠ#ò@r¶påýo†Õ”…){O«vï÷X‰èµNÿ›û¿IÞór@©ìAY^FU-KŸà}û£Cß=Z–øÝMï—øGWCYÅ@Q$ûØãbõ©n?ùŽ5":.©_žl¨`±ï˜òÓKm±Î¿¹×yê£4 Ów{1ÜüU÷Ëj>yeïôþ6“XëB‡NDÓ& )ÙKVÏŸS¿ÌXgÙ;SÆÄ<ýÒä&n2Ü’M@2GgUýÒ÷U”U.Ž»ò}iª]bkn¸©›Y¸™úeåe”}[¶e)e«ìÛòÅ”­²oËS¶Ê¾-_Lùÿo fæk—~IEND®B`‚nagios-2.6/html/docs/images/indirectsvccheck2.png0000664000076500007650000014351707436604445021472 0ustar nagiosnagios‰PNG  IHDRìÅ *M„tIMEÑ Sör5 pHYsttk$³ÖPLTE)19B!BBBB!)1kk19s{ s11s19JJJ FRKR”œ¥¥­­­­µµµµµ½½½ÉÞÞççïï÷÷Bk1Bk95k9Bo=1{B1kBBw==JWX¿Wq±}{¯m~²u«„š™š)ç!)ç))â11Þ)1Þ11ç)1ç19â))ç91Þ91ç91çB9Þ19ç1=â5=ç=ÿï÷÷ ñ ÿÿÿ÷÷ÿÿï÷÷ÿ÷ÿï÷÷ÿÿÿ!ï÷ÿ!ÿï÷ÿ#÷$µ½ ½µ!½!ÆÆÆÎÎÎÞÞÞÞÞççççççïïïïïï÷÷÷÷Ì çççïï÷÷½ÆÎ½!Æ!Î!Á!ç§ÖÞÖÞÖÖÞÞÖçÞÖÿÎÆÿÎÎÿÒÒÿÖÖÖÞÞÞÞÞçÞÞïÞÞÿÖÞÖÞçÖÖÿÞÖÿ½÷½½ÿ½Æ÷½Æÿ½½÷ÆÊïÒ½ÿÆÆÿÆÎÿÆÖçÎÖçÖÖçÞÞçÎÞçÖÞïÖççÖÞçÞÞïÞÞÿÞÖççÖïçÞÞçÞççÞïççÞçÞÞïÞçïÞïïçÞïÖÞÿÞÞÿÞçÿççÞçççççïçç÷ççÿçïÞçïççïïçÿÞïÞçïÞïïçÞïççïçïïç÷ïïÞïïçïïï÷çç÷÷÷÷ÿ÷÷ÿÿÿïçÿïïÿï÷ÿïÿÿ÷çÿ÷ïÿ÷÷ÿ÷ÿÿÿ÷ÿÿÿˆ«²ÃâIDATxÚì½_ŒGz'5¤{¦Õ]·˜wËGÙ¼§½¦æL »h²%@ÐÌ hxX½28ÇÑ's xsª¦Ž­U yz°»%V±ÎjóaQÓh ûH…ÚŸ²ßÙÀˆh8 £ÜÝ¢r€Ó“ïáÝC? +/¾/"2#3#«2³2ëOvüÈê¬üùË/¿øÅ_GC㔀Œ»£‚&»Æ©&»Æ©&»Æ©&»Æ©&»Æ©&»Æ©Aîd·ÌkŒ§ézŒÂ²gÀ÷Q_’\ÏgGœÂ}™úŸ:Y˜7ÆL q>;öBl0*²'±îv¢Å#+rFûÚivÒgÂ~†„ɶìãy°{¾t;ÛCî?¶Ÿ;=ÈŸìQŽœWlŽ_lQ:[Z¨º,ÞJ5lo›•m5è|`;K#Ÿ*\U$å5‰ÿ;ÕeòNî+cr¤ÿ 9cTd'‘óŠÍ½ïqª=NÝÆ«w«¡.W¬]g ÒŸ;í¾Ì÷&´S,í~£À$“Ý÷mjÈo×ðÉ€í©wU][öT?ÝÏà˜dlŬÿ m‡·³Õé³iœ«4H¨‰:†íßc Ùóꟈ®ŸÐÙ¥2&:»&ûpdWW¶Ú.jëÐ6vèkœç¯-OÜV16 XTη`1ç´ƒsvôÚA¥‘jC>ß"ö+8ÿTüé~ßÄWëÙϲGü„@ÝÚŠÅ6JŽ·pUlå&v‚[ω »Ø<î&úØŽßú¸såØd÷$úÂñB‹ö£±ìd|ߟÿXë=ký·‡Ã.âØHœ¨LB6M”ÞguIðÐÕÄUZäu¾J²GÞ²@åˆïb ‹¬‹ð34⡪¨ q„+KUþZ÷?%Ôe ßGGvIÔKJv;¼»jWÙõT ì/ ›¾r©Èî¸&0taw%ñÆÇ}Å©| ·Lü‡÷W ñ܈ WTßÚqgƒ÷•ò;Q'’ S&e F@ö2¿0âg.í7ÏaÚØî†ÞÒ²¢nû‰w¡£õ^J²KT.ûŠ(¿+Åævè°¶âTr Õ4T•¶,W£­"»ÿL¶Ó§vØÑ¿¹µWÛ,ºö¤½Êþ-ÆänjȲûÈ®zèúŒ€ã„Ö†šO fòEÂUxã|[ÞßwG‰#•åB”%µŸø|Ü~¥Q¬,û‹®§`Á#Ž/»„ì9<»MÄOèShå„{pIŸß£ ÂWRu;#$; Îôucú=j²jWÿßþeùñâ `¬uõÛ©ÊXg«/»ÂðFüÚèJ‹úvDŪkËsGÿ`o2Q—φcTdw‡ »tಭ>šCú=T.uË*º¡ßÁ–ô/jÔ©…ôÑ]ÚÈŽ8lÇ}[•ÔNàqª4eeÙQU`ûÛeQ?v-Ù5”Žì¢'®QÙ•ÆKqýÊþæcŒB¸ßÃÑŽ$;Lves7x\ߎ„·y¼âJ΋ÜÿeË­Yÿ1lßiT•滈Äö-ò {øWH Êß«-»ÿKËN‚S eE!†¶ì~ãë¿‚Š&zó(‚ù˜>Dìå>Þ±ú¸!&zM( ÁT©²|­t¥ :‡­8ë80J²“ Ár%{\ËžÙLjCvÛ‰[ýÈÎ<¹pE%!»Ï9aó¡þ±Èá_åýZ–Ï8oÁÕ|–9$LÏÀV]; W«™œìe÷²eDöˆè{0Ù}ÏKÕï´ý­M%Ùmù½uýÉ.Ã1;pþlÙ•£$;ÉŸì0µû¢›+F!ìÐQUgRÐ9Šìî|ðÞä“è27ƒ#øêøÈ>èysêÊ’·ûºêø%n©Â*P˜Ç‚±“=x-“=ÊŠ•c\Îa,{èø¶_å1Bb÷üÔP”Ÿ2¸LªÕˆßé„Ì´ºžé_Yò q3û|}"wð*ª`ôÙµèçTB²‡÷èc¼úïK}ìdU O#ëd”;Ù%w[QyÊcõÑü‹œÈTÅ¢X…?´¯b×~›+È.!âAgŠøE¢K¦8VäÙ£.€>HŸ*ðÆ×ï4ŒŽìv°6ÔѲðj+ûÈuMÂkí@!×op!|?Å¿¥.µ¼¹í¸ ‚º³Á·²òŒ¡Ý‚•-U-¡Ywê³*Í ò¶O„.oÔÁÇZö°uµ@Û8ŠèÚ€÷ÖJÕdY©Ñdw÷*GG="ÔÇ-°¥µ ×½%ªç¹,`ûŸ&a&ù‹TÝÔª’E×Nxó=|[q"é[Y²ècçú(-»‚ì Rf®TÄDúk-4㧃ïºy…QÝU}Éuü™Vð+¸„óªd„‚ý¡Õ¼(‘ua«¥<{ðÊ…Ž+¶³úRêÇôø0¾ÓÛ}木~‡¾Öo´\v%Pnÿ:eâ›~c Ÿ?î~ñëA±&£IãŒçaÌ÷Z<(”íìëÐN“"fÄ•rˆiìb HœfLÙ“Ta?Ë>쥴Œã‡lÖeRºO¶@Åó2ÂÆzâØÒƒ®¸cP³-n ¿oógóɶoi}¤ N2ñ( Ù54Ô˜2êh²k¤ÇtRgJ£ãÅt’]C#4Ù5N ¦ˆìÚwÑSDv á É®qj É±;O½„yå]× Mö¾IÑí4N}Ó¢R©zÕÆ0ÐdO…D1UQoˆ`¶”ÈWs>Sh²÷‰XÂd*6$¡my<¾fÁVðèzwCÓ¯X§‘tö…¨Ï#!Þr9Á‘°Ud‡©íîá.GöÛò¼ü׉x3Æ0Ðdï oœmË#ùùâpcÌøI\.òÑ·NøYகæå¿l€‘f|–Ðdï ÏŽËd´]²¾ˆH«½/ÂôéÃ`+æ}–Ýs42ƒ&{_øÆR ®e÷y®…Ü÷¹)Žß°‡æd×ȺNûB¶ìŽKI昄<ɲû ˾ÛbÈ·ÿ¸î<óì5Ùóƒ®ÓhØ)%?Åöš›²S•ñfP¸1Ҹ߄}±ËÌ™±5Ùó‚®Ó¾p_ =_Æulü TAw¡íåOq$iÇÍ⟗¤G·-«½ö ¡É> èƒê|ªùAË5ÒB“=&ToSwH8&Æ·KÄØïøñ1šðYB“}$áb®kd MöX°c­”ÂÆ+*ù…¾²†&û°HÄIMàqB“]ãÔ@“]ãÔ@“]ãÔ@“]ãÔ@“]ãÔ@“]ãÔ@“]ãÔ@“]ãÔ@“]ãÔ@“]ãÔ@“]ãÔ@“]ãÔ@“]ãÔ@“]ãÔ@“]ãÔ@“]ãÔ@“]ãÔ@“]ãÔ@“]ãÔ@“]ãÔ@“]ãÔ@“]ãÔ@“]ãÔ@“]ãÔ@“]ãÔ@“]ãÔ@“]ãÔ@“]ãÔ@“]ãÔ@“]ãÔ@“]ãÔ@“]ãÔàÔ‘]¿ãåô¢xd·¥¿Ñë#æídûçq§è»/7ìÎð|žoƒŽ`ÇÜN#K’ì*œJ²Û >@®6Yü\p*ÉDÆ/¼·ÑDÏ šìCÁ޹Lµ^³zÔ(Ù Eÿõ{÷ïw ¶Šþ±û«ßÎ}·#Å».€¢U*áÀ•JHÝæ{ÛƒÉî[o+Ž¥\‡ìƒnT(N¥"ŸˆDö€»À•t--_|–½LÄ¡B'Pï£.Œ!ÊÇ'»öt2EqÈÎ~<åsî¾ß @y"SÚïÆÀÎÁ£¸_C[:üàÒÆ¶»¹¯îÔ»«øm¸Ý´mÏŪR5|N¦#‘*Öé‹wŒàmÀ¨gK vŒ2§¦ÿ4Ž|dßéC¥$¶t|'XHmÙ3FÁÈ^ö|™è1Ïçh»,tBþ·kžÝe›("JÞÀ;¥|v?Ù}·t|Ç{,hdŽbUªG[2œ-¥¯R‹ÕG¯0Ù£Ž";@òyJéŒ2Ù¥ã“àïÐÈŪTI^‡šyJ7Æ%{|¡˜ìvh?€í'{Ù»ù|οFæ(V¥ú|ö8d—]léð¿ÜÏBkÙG¹’7P5ÙóAÁ*UöÈ%ÆD1/H\‡»újF+Én—Ý¥öÐdW]#;¬R%kn÷¡i²;a²}ÍHýoƒ²£>e°ê;“ïø¾Òh5&SŒìœíå°ôèHä"Ù¹ç${Ù§¶¨oW¯Êq7•wzgp”Ç÷Ü.mÛ³GñªÔå‰lðy”bܶ=»*h»[9®d£:ŠëZ“ðO(²û:•ÊÒ2G[öŒQ<²Ë°£Ç`ÑÀMìd«Åý5ÜI5†@¡Èîz´aÌm•;&Z)yÍæ1¢PdFwE¬Ìùä¡ó\vÏ>.‡ìC 7Ê—xD78'…½™ÐwÜPX²;>>¢Išdè° V±£Èd÷Ð×—³_Î…Ó÷ÉHp:ÈH`Ú‡:ÁP‡Ô¬ÏE&»cɰGL¿U¶{jÄ@‘ÉÞ¶“Œ\Q·Ž&èÔ èd÷GÚkÝYW ” ý1.^Ç¿?š8IEô!úÆÉ'{0àK¹V5ÁYù@$[²ë¸ÞÜQðúõ‡úÙÄÇ©/¾=°4é_]’¨n,MöÑ¡àõŽF”þújÃ1жAÇe;Á°F"9IÞ‰;ÚÉÛŸ#ìßñuÜÕUp»~eŽ9b•]ƒ.H9aî;œø2€ìÒ4bŸ´&ô¨ÐÈÅ®^7ìÜ›8ÎνöŽËAÛQHÌ-uÙ ß‘ ¸¸álMö¢ØÕK¼<|VMvµå<‡ì¶:•û ñvÒ–}”(võH¤&»^§<*û1D„¤Ç »¼Øóâéÿ²_ËÑdŠ]½ñÈμt'lÎ=²º™Líà¤ó„Vùµï?oGh²Å®^Ÿ £l%z’è›A}¼Xd—wu=U;ÁÑdÏŮޠ…õÙìÁ T©òÇqTd÷µ 4ÙLjW¯Ô4•}o¿#­ý|&> $¢cÔd·}ûY œ“l(võý[0ÐëßáB¡Ì6O3aB¾·ž É;¸iÙ9©åWÈ·Ÿw"mÙG‚‚W¯Š>CœÛ¾¹þÛ†–ôÙEs=g¼~=ãË18ÆÝV¯Ê? Qö¼Qðúu•ñ,m—3y£©&{Þ(xýŠ ñÉP3é¸o¿>C÷lÍõ¼¡+¸/ìT«4&&;²ñxܥИ˜ìÇSÉõÞ¸ PT—ì(qϩƸë°`(n}Ë2 £k˜SúÏ2¬â^œñ ¸õI([LÎäütMáoq/ÎxPÜú$h×oÌ©›šÚ²gâÖ'q93SúT*» †“¬ºÉ¸3EÿL°í¼ÜŽ8ãAq듘Ì>N+hé‹{qƃâÖ'ñT t™išj5&·>I´éE³Û"º{)S˜ìàûRûØA[ÙiO×ÔЖ={·>™hq[9]Ó¦¥-{Æ(0ÙÑó5вS{Ùž¦)µìmmÙ3Gqë“XÂgžûtM ݃š5Š[ŸÐƒJicL#Ø3I“=c·>µÎ®@qëSëì·>µÎ®@É®uv ?Š[ŸZg× Àd×:»†Å­O­³kPÜúÔ:»FÅ­Ïý°iGÆaËœ|Þý‡_<~ ¶üðPZ®uöÌQÜúTëì­<èÝŠ££±þv§Ó6[݃à€NÚZgÏ Å­Ï½ ùXJóó0™›wbŠÊêÖÑçôyóØWP­³gŽ“]©³·öµízµFѨUïÕÆŒÆ¹Ÿw[ÿˆcOiùÚZgÏÅ­Ïýpñ£ziv¯>n¢ªçþêó£xܤ­ZZôڵΞ LvµÎÞYÜ¿»]«íÔ¶··ÇMt@ãÜ/º­Ú–qž»ÖÙóBqëS­³.|´]k4>©Õ€ìƸÉþÉsÿ«qÄÊö˜—Qëì9¡¸õ©ÖÙÛíҵ­zµ:n’ TÏýüÈÀ|1B_×:{>(n}Fų/î›ß²ÿÂ8jvñ¶ì¶¤k=s·>#âÙ'ìµçþʰÐã²¼¼`ZgÏŭϨxöI#û¹¿2 ö jv›’e×:{æ(0ÙÕñì“Gö_@"y´è Äh=?·>£âÙ'ŒìÕse˜-jÓ[nµÎž LvµÎ>id§–ÅÃPk‘1:ž=?·>£âÙ'ŒìõsOèEè“cô¼ZZgÏŭψxöI#{í¹E~觃޺ÖÙsBqë3Bg¼dßúä“FµÊº–Zõ³ÏàëögUÑÛÔ€¥*nºÝQÛÔ*ÓÙÍÍZƒN 7Ö&';ZvNwÑÊÐ:{.(n}ªuvèAÝe¬½W­5î"M‘¶.v·£«uu4Ac{û3 ý=Œ˜ÜÞÝ­í RvN²ìZgÏÅ­Ï(Zv´¿»µíF­^ߪoRª×©©¯¹aÀÝÆîönà.`ëø¼cè½°¹ v¶Ò“=²k=s˜ìyc6¶ Œnú§ÊÜÚ}/ZfÍB"wUìäÑ’[[t«­ú}|J W“.¨ÌoÙ Cë칡¸õ©³Ì=kjÏk»Hgê«Ê)ì ûíë4jwïѽç^ÿ°–½ë•Së왣ÀdWêì¸1 ehuw·Ñø3¶TßÚb´eþ:ývM{ký³Æ=Â_V«u»ÖÙsBqë3Bg?à:;6?,”È:OI¿×TF²×wéç¿VåÖt»s‹0r»4wå!wøëµTcŸ‚jŒÖÙsCqë3N<û%ì'{­¶C=lv²†k­Æ¼ö-æÉs«½I]ýÍú6ôÊGõê¹Pw¶áöë¾E×ßÅv]VçÛÓ/[ v—ÔqÛ­ºp{ªµªÖÙG†âÖgT~v?Ù÷»V»»O)»Û[½ðœös”üç_ߎº¶{na†Pb×÷çÀ’ïq’.^ÙÛjPh~>¢¤T­=·Hæ¿õn”s 䫯ïݯî/²gÇþ"™!äÊ>Ü$dF¸Ràüh}d(n}Ɖg‹~ná;{-Wö÷YF—ß}D O×Á÷Å«[¿…[,~v]™-z[üΞ{´Î>2·>£ò³}öZm»J M›Ž%l¡^Ù{Ȩ¥+ÁÖccsnqoíz‰~½T”o¼½Y§\5¦ZÛ­î¡ Xl²ÎSëM!2Géÿè·Jôð Ü ©'ô©ÐØÖ:ûhQÜúŒÐÙ¿XØßeqçŸ}†–~¥. õ½«@æï€î¾ýJW˜ôÈ=ù*×X¾M)\Û}ÜÐË-,<`º9øñW>þŒÞ  ¾|‹Þ û dîÙ½zn Ré[Ý£ç*¡¶_ã‘ÄZgŠ[Ÿj½ÓÁxvª¾Y¯íBs³¾ sõÍû¼ó‡Þ µ_ÙÛÂ`ß-À‹–øîî]$¶;Êc–W·k;Ô¸ßo¦¾µµó FT«¸?‹¸ùt{’LÒ¿˜hÖjZg!Š[Ÿ:ûã…=h:6v>©áìâßêÑÇ»ç¸Îþ¯©¾Ï{Rëî YóêÑŽáH÷Í-N}èuÝaá”ÈÛÛÛ÷…³t¿¶ÞîÞ€¿UÖ¹ÊÂÇ´Î>2˜ìJýà`ñcŒáiMïת;;@Îêö_V?â²N¥ÅGUdc’zûÏ€–;ww! ò¢Ö¶wÁ@Sî“a÷î.=ÜNCÄÐþov;UÖzÃ÷àü.„ZFÅÆh=G·>£tö…‡à@ÜÛD¦ý„oÁ8 JGJÈúýϼ(öÿ€™­`Z‡°˜ú}ê±|B[õM8%½vosk§^£ÏŠê}8 DÀ@tûÓ[pÀÓæ&=ƒ%0:Jˆ1Zg LvµÎ~°øÍ*öarboS?»Žn6µÔ; ÏÀøÔ-f¿@Sjü«ÌH×¹wCI]¯ã°<2‰7ì_»Ëäˆß:Þ0ÛÛõ-pÙëxæm­³ŭψxv–]€óó.Ò½¡ëHåF•úðwwé—Ævüìêým à­QêÒìnßeÎ6ú÷Øsã%Å—°~·Æ#w·av«á†k}d(n}ªuvê³ïׂà!½`Ëqhé=hCîny–¹Qç¾8FñòˆÅš,Êð…2<»¾ÍŸ!Ô{©¢Ã_é„ÁÃZgŠ[Ÿ ò³ƒiçN -» ²`sÕ]Xã:}Ut[>½_ÝÜÚÚk-±_è4lÇà¸bT«ÖÙG†âÖgìü윞`ÝÏ-|k é€ðêyc†Và >vG@#´†Ìß_\܃¡«àçƒÌ²½- úxx¸øì~m‡Rü.Èç^D}$E­³ Å­ÏØùÙis´ÖøõØ` äWÙ1½s´óÉ'»Ð>Å(öIý¬¶ÿ,Dª×îmnRoíTë;àݧ®Ê½{÷¶àh¹”ª™æ„œíÔÐ:ûÈP`²ÇÏÏ&y§±ÁùÙ>Pþþ£ÅR bÜè×YƒS$í`¢»j#kþ÷ÝåéòXz±{›¼Ciç~m÷.ÜŸþ/‹‹ÿŽº=ŠdJZgŠ[Ÿ1ó³³ _÷îá@;j©·Î-€s²õÉo×@ŸAt¯ÿt‹.ýN©D^´¿Hæ~ç£{Õû÷6ÑQÙ¤ûS¿½úˆð²°ÞïƱð‡ã‘Å?«bÈðþ@Ÿ]ëìy¢Àd—Ÿ]H€Ýíç¿õ²ê¾þ€ÚrJõÿyû¥ziŽúÞtéÜÁàÝŒ Ý¡ÍQ´±ËBe Z}ž”¾õ †ñÈܳ©ÝÿZ3O-ú¹Åo=P¥ÚÐ:ûÈPÜúŒ™Ÿ}k ;“ÔU9·ÀF}ëÁ†pAÖ"Ž,’/îïâðêO«Ï-|gž”ìï‚ÿé>ÆEòñ¨äÛú[t»Ÿ.À¨TŒ¦\x‡s_Ù«V·û[v­³ç‰âÖgÌüì‘E°ÉWU«0 ûõwpÉ>¤JúÎÞs ß~ä5^¯ìínÞ=O’ºÏ›¶‹{û”â]³ðSòÉ—ØÑ·klÄÓ Ë®uöQÜúŒ©³»ºx}S Ç[܇à·7ë0Pï#pE®|Ã8¶vöÙ©e¿»»ùÓJåÍz•YüÚ_<„çŒGmÐoÿ2Ð)úñÕúfžIÔ­³gŽâÖg\{Mñ}˜ þѳ‹(­™c²°@š%Hª±Ã7> þ;Sh )ºÏ€k†~ûãçöp¿Ÿ²ý±a0~µ–ýßÿE Ë®uöÜPÜúŒ¯³³|_Û˜ö¨±ùˆ ’.Ñí{´Y:‡y_ž[ü/÷ ´å.yýQ}³¾ùH(ò?½WƒñG¤ô»èó—P¥ÿˆZûO¶øí:Œ~ºò¨– Uë왣Àd©³oÝ«‚ôHiø`‚Ķ·Y<û•ýííÏî?·H怤&£±U¯î-|µ„YêµÆz[Ì—Js‹ûŽßé‘···R²g†Zuȳ ÖÅŸÖ·vj¿]°»,»ÖÙsDqë3Á{P!çÑÝMj‹¡ýÿÛŸ‚¿EmXRÅÆn­^½Ç¢ÑwY>_»„¶˜Î7¶¨ƒ³Ç]$è5mÀó kïgٵΞ' Lö˜ïA¥<½Wo4vïîbʤêg,ò±ÑØÙ¬b˜/ÝG­Vy¨ïîv‡=â§OYÎRÖ×ZßÃló3’a£Ëîï?»¸ûŶìZgÏÅ­ÏDïAåñŠ˜ÓëÏîcÙi`@:µý»ÌLÿy“þ¬9vqPê=ÑqÓ³WÏ¡bóúƒÆ6lÿÞ&mýÞ§K¿óˆ>¯^Ò:ûÈPÜúLôÔ-PÂ!VX@¸9ïX­búê:{'Ð(é†ûK[;<Œñ>¾‰©Ê(A0&¬®oí²«ìq ~?‡ÖÙG†âÖg‚xö±Bëì#Cqë3v<û¸É®uöQ¡¸õ[g7ÙµÎ>*˜ìñãÙÇKv­³ Å­Ï:ûxÉ®uöQ¡Àd©³ZgŠ[Ÿ‰töq’]ëì£Bqë3‘Î>N²k}T(n}j]#€âÖ§ÖÙ5(n}j]#€“]ëì~·>µÎ®@É®uv ?Š[ŸZg× ¸õ©uvŠ[Ÿ:ûã–½Þ$ã¢oŠ#8êb ‡o£tö2Gfà½ë¥Ò<ÁoC`ÈÝ´¨ÇÇ=òTëìy£ÀdWëìí_¶–Amh«Gޝy8ðÓƒ)§è|ïÅß·ßçØõÙM­³çˆâÖg„ÎÞmÒ¥M¬~Ótìd´ôd’ÍñC˜“rB¿ni=G˜ìJÝøâKj×;´Ÿ§ñ)ièß³ z>NNJì»upÐÖ:{n(n}ªuv`øÃF·yxh:‰é)Ùudûðtï‰ïÔºSÏJëìù¡¸õ¡³·¬ãÀj[mê³·“SÓ3ìNVŽLéää˜ôžÂS¦CïO­³ç†âÖgT<»«vP>9)èYæNŒãØÙ82ÒGdzçŠâÖg”Înr» sŒ²ŽgêwdÄ÷øûÇ9¾aéxöQÜúŒÒÙeÛÞë%°¼RÕ]–™"¶ìZgÏ&»Zgç¾ß’¨1ŽSv8½YóÔΔæìCKÖÖ:{n(n}Fų{:¶asËn;q§Bsô[öøû‡§=1߃û³¥uöüP`²«ãÙ™eow:ÌgšTñÍgÓDuÅÇž÷ìÑ:{(n}Fų‹i8Õ=»Å[„¦pçàDç¡%IÑ5IüýûO)šӴΞŠ[ŸQñì²ÕdVŒ)%;Swà°¦ ÷I²ßi×´šœõZgÏÅ­ÏA:{r´Ì&‘uðýGà[×pÛÙAë왣¸õ¥³§ŸÒ±äåÔ—!|l‘•áy´ÎžŠ[ŸƒuödhÒñÏw›Vs¦ùe“¯ÍZgÏ&{D<{Ú)ü%²^Ï"'ÁÖ[WþÓÂ5­ÌΣuöÜP`²«uöÔS°æ„[paÛF‡X´óC_žj=·>é쉧Ð>•tpî§ô8|˳™j=s·>#tö!À³ÒÙE+Zphõ¶0Æ€oÁL½åþÓ:û£¸õ™µÎn¶š]ƒ4Mæ«7ÍgÇ ·úÍÌ-»ÖÙ3GÉžÎîÆ¿3ÕzL­Nþã0ŽNÛݤ£uö)@që3{´oÂíº–}†wSØz­³O< LöltvƒÇ¿·ÿ_ÔÚ­Ë8#,;™ÇþÓŽÖ٧ŭϬuö¦^Á¶#ýÓrÓj´¬V†çÑ:{n(n}f¤³»ñï,ÎÑ`^;ÌyÙÁ ‘W]ëìâÖgÖ:;ĬãñHË[îRÝÉZgÏÅ­ÏìãÙ-&¶SCcŠ×=]ëìŽâÖgæ:»i~)¢Ú[–É-»Á5öì-»ÖÙ3GÉžm<;è/"нD &Æ caô£ÖÙ'Å­ÏŠ[ŸYëìØZ“ùê-ÓèÝ»\1¬ìΣuöÜPÜúÌ:žm8KjêPž³D¤„e#Õ:ûT ¸õ™VgçzºÁ2&ë7%„³Ï–ë þ£u‡•|#xðL2Í!”~­³gŽâÖgZ½‹o¿À9Ì–nv-2Ç#!ÚöNF½`ËnOç®uö\PÜúBgçzz‹kJãcVWœÝÉÝon=B«Ùmâ†éYÕ:{æ(0ÙÓéì¿ÖÙsCqë3­Î~>tYÃV’V×:{.(n}¦ÔÙái`ñ×â sz,>±X–™4%Ñ:{æ(n}¦gò eë-D`»è]Õ:ûD ¸õ™VgÏ’cÄ¥½i¥Ñ۵Ξ9 Lö”:;xn›s°® ›ÇÍt0^ëìãGqë3­ÎN[§YÁ&†ülÑ:û˜Q`²§ÕÙ‰=”A÷‚ÚöŽ‘Xo×:{.(n}¦ÔÙ 3Û*!^´Î>f·>Sêì 8¢aš}'^f­³ŭϤ:;*~am]Ùwšà68F­sˆV’i=s·>ãêìÞ¯CNrú¶»0ÌöHþ³Œa]Ã2åw­³ŭϤ:;ôs ùC GRÕáÕ|ì-pqì°(È"Ö5”Hë왣Àd§³–7õ*ƒ`°ý²;ç-”îØ„ðUü»Øœƒ=èÑ!³RlÝ_ëì9 ¸õ™Tg§–ô¸)L÷,Olâ»+d’KÛyÀÀôdZX"­³ &{<Ýð¢Î-Ù^c¨Ër[Ú³ÛL§Ô—ÈîÀ“€/òÁ&®'®uö±¡¸õ™Tg§–Ô"’ewáÜÀ?ÙeËîÝþ̓šMa^"­³ ŭϘ:»é©1–KQ—×®ÿâ[è'»"»º4f­»ÖÙdžâÖgBÝ2ÔŽš„·ŒôÙ™j0=~ô£ÖÙ3Gqë3‰ÎÎÞ¤!ïì^ÔjŒÍ|vŸePclH•gh}Ì(n}&ÕÙA‹aùaRõ”:Ì^itQ{Œ]­³gŽ“=™ÎÞîðd1 Ž­Ð2ñ/ŠÜÚvf˜Ç®uö1¢¸õ™Tgo‘c°ìÇ|÷pÎŒ¸f^½iò1Zg Lö:;v:´=øtÀ1mż)Ðg€¬Ö]‡´Î>6·>“êì”[ÇÁÖÊÿ75Áƒl/‹ü¾Zg#Š[ŸItv= u]$i¤ª¶åO BPg×®uö\PÜúL¨³w[)¹óf8&Þ›Tã©CZgÏÅ­Ï¡tv ™ý¡ì¶V0¨(L§7”3ÖÙsAqë3¡ÎN7%½ÞqýÃÆ/oNücÚÙ»9L¡ÅÖÙ3GÉžLgï cÂÁndŠŒ.‡ˆgïvµÎ>f·>êì0Léø¸§¶¥D&¶ûMž , ¼Idz&{2Ý ‘"»í·åAÎ;ƒÉYÁ²Ã8T­³ ŭϤ:;AýXy¬òPdÇö©ÕdíàØåÑ:{æ(n}&ÖÙûTŰ–ùT:ž}Ì(n}&ÕÙZ ™§ÏðµGý“þdÇh"tÐøåÑ:{ö(n}&ÏÏ®NÇŽåD ™u>ÓOÄ÷Í$(‡ÖÙsBqë3q<{·i6M¥b—ƒÕD;ŽC ÏLÓç“ǃÖÙ3GÉž4oL‡þke'‘büt9É[hˆÈ_ ó³Å­ÏäùÙ!wL¿ñꙨǽããcÒm%(‡ÖÙsBÉž$oŒ!ÞDy}0Ÿ¾c¹ú¹ÖÙdžâÖgR½ÅÞk×§BR¥°&&„€á»®u~ö1£¸õ™,o öøX9Øvâé0"CÖÙÇ„âÖgê÷ ²*9NyÚÀ&’¼®}×dÏÅ­ÏôïAu³Äàq†{ÿIq~­³ç„âÖgÚ÷ ¢÷NfˆÙ…tÃê!é-»ÖÙ3GÉžò=¨Vþv £Ã³ ¤0í¶øC’êëZgÏÅ­Ï”ïA…~TˆP4M p‡#¥qdÐ ²I‚øu­³çŽ“=å{PÛ É´-èR-‘A‰d"ñë¾L)ÙûOµÎž+Š[Ÿ)߃ÊtxÜ)3üM‘ñ»ížÝJ¿®uöÜQÜúLùT£ëF(ZéûT Sab¦‰Ñ:ûhPÜúL©³ᾟ€Oèï<«µ™<~=­³gŽâÖgzÝ7í0¹ˆD=wˆ‡ìÚØÞY©¯nYV²øu­³Å­Ïô:»-Æt˜]ÐfXö°Fb‹Š$FŒr“çtæüZgÏ&{:]ïÞ¶X¿*´D"üî¿ÀžøI{>­³ç‡âÖgJ=4…¿Í/›à¾Sß²üN¼ûNTïƒö-‹pL¿®uöÜQ`²§ÓÙƒS‹ÅBZ¶ú»Ñ%Þk–H™°wìIwÕñ5~üºÖÙG‚âÖç0:»<åö¿7ßÊŽC³ d:ÞO˜<€.†·&YÐÿ:Ìù´ÎžŠ[Ÿiuö ¬à¿¼·éŽó]|—/¼T¾±Ü¥l>~üºÖÙG‚âÖgF:{†à:VIxžþHtö™‡íDd¨ N¿ØšìÙý²ŒtöÅåv:íÔMÏϲ竳w‚Æ–yþòÐ{Ü$D^ãÛÎá] ¨ÊòŽôâ{"ŽNØ“„o)­–SÞçO‰ÑjÄÈHgëîdFÝo¿Ëðø#ÒÙ=/Æå/ËnVvd>;ŽoVÚŽH[x÷ íŠ3vè Ò‘ã¾Ð!ƒ=’³ŒYéìÁ)§:!æ\Ïüøùëì8ª„W’0Ø„“˜QO¦¤#ÓÜ%»œáo±±Ý,‚D>Xí¸¯ê!ò#a{ɞΜ}¬D:»LBÉ@—‘ùeÉeçÌ-Kd'ž#"Ž%ÖÙŽÔeÎC$çG¬æ÷±GÊÀ“=#=0…·g®cµ²>¾9]2ì¶ä‚“€ÇáH¾ñoçÝ%D¢µ´+ßÃVA>ò()1ÂsYéìaÝݰÀ¦ Ëžr×Ù}^ 7Ñ‚À²!Úey!AÒúÛ§ŽÛõ5kåÕî1FD‰žk´ÈQg7I·…Ù•Èôêì~dâ2+‹zøQ`²ç¤³c¤!ë†È 3…:{ؾIà«TãêÝä×h*>²û`Rê3‡_–“ÎŽ¹~M³Õ¤ßf0Â1Œ&ž=Ñì$ù‹Ù¼˜ìyéìm«CèÇ‚€ÆÔyaÆ«³Û‰W(×zûëÐÅÉ&{N:{Ëlbš/ˆnlÍ ·>¾xv;yûÄûbG®»U˜ìùèìØ‡Ú6:°½ùv¦úú8ãÙmIMŒ &kä.%oüEPŸ8*ŽTƒQ”±pÈIg‡w/“÷œ$}^˜qéì},¬`¦Ýg}økßsúGmåÎÚú—夳3•ÝÍø;u:;‘Ur" ãnà ðÄwÑ[äõ»ù n0™W ½Xö]É+¤3Œ¬k©ÀdÏIgo™,&†Ùt8K ?Y#/]îæ”»5™ÖþþN›Ha^nèŒ#G?Ç óŸÁ[ÂŽ"¢‡á ¶×!;˜ì¹Å³wŒ)SÚ ÃÏ4ñ:» ã`,ŒÔ¥éxävg€“’‰gÚÄ¿ƒdã¿yä…<0Áöï&.JŒâ$cA~:;Á\-–E€)3ÝfægÉZgI(î†È±\¾(E""Z$ŸÆÏIâÈdG/_ÚÈ&Þ|dw¤`Ç¿n49 LöœtöŽEXnPÚ5óÀ´èìC&aYòkÜo¡Ø0[¶Üü¿ÍB|˲m÷~É”ÜÚgÏà—夳c÷)ZõfWXöVybò×Ùy¹œåÈÁ©‘Ù‰ä¦bÃ\R¶Þ¡aL¡ÑbX’`½·ÃˆFè˜ìùèìíéxï«6@™¡vÝH—‡}ô:;‰%ôù»›<7¿O”OP·ÃÇSÅv¢öÈ&{N:{‹´X ²Û‚¼Ž¤‰ÏfæçÉGg—dZt÷§ˆk+ùiû7+ý£ çðã †ÜâÙ™ãê/Þûð¦Cg?Å(l}£ÞÍ^ÿ&¾q§l>[EßÕLÉÐ/ë ;m|Œ­^ØïhÃG⠇’^ÊhXÍìã͉dÕù¼edw|Áu3·Ø˜xaæŠ]ì8‡ó~;ê~p^ÎÈP`²3¦goÙ¿„¿Mw>ë˜vƒõ€#CzNN¦=Â?£þ¥%À0™ÚÁ~ÏÁ)`t<{^¿ŒÛʬãÍùqÅ|‡X ™Ž/Øž¿eÎ{ÝNÒФ¾e˜2öLYq“ü2ž«Î{F&SŒs4»-w9qí|6çá}aV>jŒ¢ž¼>T/}—ø"w™J¼×+^øêH¡b^¨‹ÿØ¢'É;Ĩ)1úSŽê—IXXÞ ¦"WŒ˜gJ»ÑÎêø’¶“W<{P÷ºvÜ. ` ñ÷¼ª"½|Ñ‘åà±Cñg$T’Pb´§å/C”Iæ˜þqPÎI—¶åÊ|)ÝÀŸ;ÿÂ|ž¨ môŽíÅÌŒ,> H‰qœt„ÈÜvK&;ˆH‰Án@·"Ùè ¯Q]òhè&ôþ\¬q÷ñNHÌe“ƒQXöP+‰§´ØI÷Z” íò¼PE¼1¦‹ìâ ôaºÂ6‡v ÉŽ^¥ø? ˜h²O‡ÒÜÉ4ÝÕ3rL(Ùíégú( k(ÆOv7˜Ð/¾LÐ8Nh²'ADf”±V"™ºéØ Éž$ÑâQ(è¼h¶÷&{LÙm—éšà1¡ÉžDvÝ M]cI0)d`º6ñý¡ÉžAvmÓÓ"To"%ø‰ô]ƒ#²'ÐF4ÓC’R¶>í9''ð­×ë«·Œ¨ºãù“½ý'ãþ-“„(ç!+ªFä{'×Dï‡'ôØî"lªÃÕ÷ÔqŽñÖxò¨ZÓd—A.O†h£.†7¨ÆŸrôÄŸ'kÕG¿êQúOTžIø2ƒU§Û>ù¨FñH“]‚ŠÔÙÅøz£ë½£Ú G£‡ „}òp§VÛÝÿwJT¸¢ýkêù<ùx{{»Ñ¨íi²KÈÕ²‡IMD «Æôz'Oöªµ­Zm{œ™§ÔÀ÷NòVêËôäQmw»±[­Õ5ÙeD‘º<4mpU}Äo .ô~µ_Û¥ÿ(öž¸NŒß‘Q©1OöjÛÚg—‘Ÿe'Ù=ÝCTŽ[ —ÐOÔj[›õ:£;Øzg ÙÕwkõ­êý»5Ù%äEv÷ ºæv$Ž9{¿zÆy›[i껇·% » ÿi ÖAª7ÝÚv-&ª?ÿm T>j‹öJðBR©4Ozx~µ_‹<³]hÅbí•ôzÕàW?¿Š·þ\/™s´„Ñõ=ìõú9œw³¾ç®Þ«V÷ž„©ä)#xô'þ„z LŸ ƪüŸx“˜UÆÀË»ÛhxÊmADîÕh°bÔwèÏýù¯Bdx·ƒì $`}‹ÖÁÏŸ¨|Ûÿ~qn¾Dd7öªÖƒžË×þø»R]/øyèø\‚D׫'Χ„)®%+½^¼°›u¸%v~ö³­‡OžþÚOönPZ¿òp»Z­Þ¯íîÞ­ãcнʭ­[OU……ØV>¶èÍT•~ハ°+p|Ü÷ïײÓóѽðG?ö%)àwKøYÿ*¯¥°ìµs ‚és„°jÙiÍmÕ¢ž¯Üÿâ‰ß%}²·Ut¶Ä×k ~5“)zÚˆu½|÷“³3¾^Û»ìwÕ¯œ²´pÕmú;–kˆˆ‡Eï×=v`zgnm‰c.ïSù>|ÐhðÛ[½?´!¿p}*¬ ~÷FÞ\ÆÎmFüBöÄìXd¯ƒCâV8ûðXôÛ°„Ü áçÉÃÝz=‚Mu8Mþ&&;ÔÔæ/)ÑK¬¸ ý¶ÇKÓàuèöÓß5ðW%¿^ô'o5 §ó䤗øz “ñ4–™I}½~^ýÌGXZf(­Ï²‹/'ÔIê¡Â¾· ?‘ÞæpŸTcàp®gÛã± gž'pÜíåã8/tfÇ{ªŠÕ‰Ñtëq#Ñ“Ê+ÝgQ? ‹ä&ÐêéýzN½5qƒ€ûÜ'ÇhÜKÒéO"¶ïI{þÚû‰óÁãœ/ÉõzQMq¯|¥§ëaŸf¬*Jq½¨}8¦7mmo¿ûÕͽ'h¼ýA2Ä=ÿS÷ä~&’ýA5Fò}„ìÅŽ$t•XO‚JeÕ&ªŒQ"úúzmR™Xøõ¤¤Þe5æ×âÙqÂò¡H'=>î·c/¬¿r^¯©¶NyÒ¯l¡ë¯|ɯwÄ鳿³*º µO<¡¦é$TJ"~÷±×¬‡†ê6{B5’].¶îûWEïØs |ûGüßñcÙ®¬@‚NÈ6¨7†ìà†€8‚÷ Ø‹ó+ÛÄãzÒëå­<9‘Z¶±¯‹DLRÂdÀcƒÅ~²W§­Mp­ö° þkXh úËéÞÀ ÑWã¸1ls|jùEÖ`pMœ*†äáóùŒTÿꩼW/Ÿ€v×S€nnï„1~‘kŸÖR¢ë¶ÿ1Np>JìÂ%¿^°ÅÔÙY‡_6¸ ù_íÕªØ}™àvù§:\Àu_Möqãdˆwìë+õ®"Jøx„ ÂiÀø3‚i1@¬‘ ºNL-ÑãOÐdŸ4$¡i¤ÏO„ãD‡: ÐdŸ80Í$T»×;NæÆDIo€(²ëÜq‚ù0OŸ>àŽDº1 Úe÷C[öIƒ)ƒªú:%‚&û4C_§DÐdŸfèëÓõÒ_0ôuJMö)†¾N1a÷I‡¤+q: ¯S2h²O1ôuJMö)†¾NÉ@b.Ó˜@è •$Ö"I„¾P ¡É>½Ð*!¯BÕu8%Ð*!x…ÙáE“}¡B»1Ó }¡Â÷¶i‘ÆäC_¨¤ 1–hL$ô…J Mö©…¾PIA.ИPè+•PcvpÆ4@_©¤Ð–}j¡¯TR„É®G[O 4ÙÃ_e¶®Á©¾T‰A‚ý§Ú²O 4ÙƒôÕ˜\èK•šìÓ }©’ë3[Wà4a*¯ÕXä@6vE¬ŒFôÄ›|ìÜëq*É>f°:³åŒ+ÝõµJ •eט Lçµ"ÅÃh3nÞ¦M kŒÿ §ôC¬q–¤ÿÌ.ÿ¦ÉUj™ÿLú¯‹G35致LÏn™¤kt[ÖÏ_Ä)Ö¥&»’e7L¬/Àh¦xˆið;•„2~Ôå(Ôž’“@ötÍc[µ»íDÍ$=1Ǹ»º®< Ì6Ý릑c {tsÁV~ÅYeãB£OÓƒÈCõaÆÝeP©]/fäS¸.ÀqÃjQ¶“?¯§ §ã³ìv𯱴±Xj{S©×Àí‡s6gyß“ã;+ÇhÙÁ†[Ô¡…DËn5-êÁ›ÍqÆ©éõŽs~E£¯ëÛñ‰zEƒ°ýÌ&–½ì[kw÷ïçö8wétÚ´ £ž‚i‹nòJBûÔ¡Ÿ1•gê§ÜÂw:#·ì¶ßKÌê²ïð×–×߉½>7Æ[ɶ·\Ksu-»a¶¸Mé”1ž¢¤|msÔå(Üt¤–]¦('½C|D.ûÈè~óO‰ÿHŽ|¤²´‰${7†mÏ-;ý;ê)ýÛ²,ÒõÊK—µ-k\å™ö©°ó#µìžMdÓEeÏžK‹]¾âW[úë¨[—ùÞ¶8š|—ñ‡ìh „2â)ˆí–ûÛfšîº1•§ Óqª1Ü;·#„ÖEÝ6ïÅòyãè7bkcl0 ¦´ ¸Ú‚F*0ãaŒXñ7Pý|IvŸS&‘»—ê‹$<ƶì©pØ2[Vk]¼…ÑBZ_?4ŽèñŒÃÃv›Îœ^ŒÇ²Ó?Œž ®EÙ–8k;®Ž›9®WNH@X ‘]nÙzgõ?Pt/¥×ÙÛí_¶éÜA÷ kvÛ^dF’môcæI{¨¸ú¯kB™Úmè£êоóÔ¿oú¦cÒÙmG¶Ò‚Ê2u#,{Ùï­ËG·†ŸÝ²¹·¥»ª¸ Rg?ŒO pÛV’øH«°ÖÞ4¸µôD['rcRëìíöe*²ü,;è2âNŽè_zŸ=éþ©uÓƒ>aÚ {ŸÝçi8é1üWÞª¿ô(l·-· øÄp=¦eO«³·Ì&­]ÊY³Å-{ ×ÄÒ#´º¦9Cˆ™h¿¨éa Z­ÃCZšÃÃÃÄ¿§(Ó±Yv?Û½å̯ ¸Þvhã ãøVù ®1wÉKzL¯³wè´$;J=w°§Iþ¢.fÛ Ì´“í­:ïíRëÞ1Œ Ñ¿ ­³ Ž:ªŽ}÷{°áhGoï¨6í³Q’ðÊ!tö¿››ã–R©DÆ|J±Ènê·§þ]S?C XÌÝ숹¬ÆËÆPcÒáèñÙ‹ËËK—–.#.]º|yé2›‰;½|yyiiùòÒ2ý‹’îï›._záÿ>_ýà€Zu¼ô§ ãÑÙ§ ÃD=ž¹t½,þŒ/ügfÝä>ØI@“—Š· Mü ;±—€ š\Uju[&ö¶|>Å/Ñd*µ‘>}ÂȾ|þ?B–0>µÇ®{û§‹Ûç#±g e|†·_øÖð-4"wbuö©ÀÐñìFö¥þ³°‚‡eÙ™moš-‹ÙsÓìB9ŠS˜ë °ëMÐTZM6ý²™âlcPc¦CèìFöejÙ™ÎñZgŸ,²3ËÎtwaÙ'C÷fvÝÀÃËt!†“9®xÜm⸭ܺÅ÷K~>mÙ£JZgŸlË>º·«ÿÒ Û(±ƒøGTú.†Åmþ|‡{âô꯳O †‰gŸ,²ƒãEÝCü®Ìuo2Cš]Ñé§¾@ýÞṉ̃ÉIé×t¬äñýšìQ¥B×0²/ŸéÑ0˜ÄÑ·î-À½”d—Z­žÎïzŒUg—Â\bþÖAÛ…BÂ|ñÁï¾0™¨#šé1adŸ]d•oˆ_6¼öÄõ·èÑW ‘Å­{7I>qÝÏÈ8%°c¸1/¾C+¿—GÇHg_zá;§>”îÿkÆ×§³Ÿò,g]Ë&ó"¸ð# (×­îÀóŽSgÇ $ÀöQ}7謚ñ=ê`EÓÙ/ŸŠô˜’76ËβߴºMˆÑ"ó"¿Ôð¨`™GâZö1¨1¾¨t‰yîW‰¹D½Ê?¢Ô‘=xh'LðA–½0:ûååÎðË@?)?¶¸òv»#zŒÌ4vÖoðˆ…ÖÝô{Æ©³“Adb…/ð‚Û‰…¶Šì¶T  §³ Ëî w–ü÷d§«£FÞ%±‚¬ÓB_šX=à?+3oœjÔ¼då…OâÆ ªíâèì”ìhÙO¸e7ÆÏÎú?ÁÉ(rÕí]\=Hv'Hö¨¯êU"u˜çØ n Æ!;Ú‚BèìË/<µ=Ë>Äï~J[ÇÃj"Rϱ°µûüc'»Q ²{’]¬qg‘=½~=œE€I1Ì€ìßqüœöñ»Dz§Ã¤‘ýÙgŸCi²xf”£í*Té]Ôg`ÆÜ@áÆ”Ý,Þ|Dž` ˜~# Æ ´ìÑÙ/ƒóÔµìcÔÙ³»1û>3¬~¿k,:»,ƒø o°iDz£ÏR³Lü‡$ÓÜž¥IÑX*œÎî·ìã2쨉t³dô4-väVŒüõãTcÿ8 Ë2£ËýÉîòV¸F˜<Ì–ïßÍ&»w¨¥éìŸÝ—ÎÞ¶:”Šc4¹@]2˜Ê3q:»tAˆÏR÷³ìvð. ¹1aD’ýéìË`ÙŸ:'̲w“ÿž¬¦!™›VÐÚ[î9&Hgw[¨Á%Êô}Wòª7súEx¥è'÷Hg¿ìëA5̱éìôôO3g!m«Ý6Ú¦³{ï~‰ËM™ô¶.]÷ƒkè—ÙaðÙ¡ÛYba{©Õ¶¨Eĸ’fÈ77IàÛ‰}û‰£7»^&÷.PÝîwqú3†Úk"• úºL}Þ˜¼îœ,uöógξ 6û…3ÏS²3¢œ½°¼tþ7æ‘ãÿ쥋gç9žèú2ܘïúùÑУ™»-¼á¹Œþ<õk–à6–3¶Óûãw…–¹ÎΚôèA£?‹ydÚ8~4h2f3˜þ¶ô]‹Üœ–ÉÒÊó8óZõ~­C/€/´"ÞµzJæá9$ìùDèì.| a‘ö@ƒRVû<ÀátöógÈÌ×_‚é7.ž?ûüK`éôÂù3@åß?s楋ôÃí2ª1ÏЛ~ý}ºŠ3—.q÷2YƒÄæñP‹ÏS[/1ÏgYÈ6—± Œ:»°Æ”íMjÉ1¦¤‹On¥›n^1mZÒ¡¤å^þ. ‹åãÿ ›Á6ŠiHù¾BUÍ¢7R‹t½c§Ç{† é¾.Z‰*uf:ûòòù³¿I¾þòò«@njÝ/Bòu ;ýþ‡——_>sæeJö  1"wéäÂWμ̾pöìE¼Yè“uþìÙ —–¾yæÌÅóôö¸pffæ÷èMq‘>¾raùÒËgÎÒåä«¿÷´ –…eGŸ¸–Ý”,²?'.×gL¥ºâS7X;•Í›áíùýøô}Z§P4›Fp_âÎŽ@iJ<¯ó³,u<áE‰ Ï~þÌoÎPË}é…¯<–ý€€çÏ~ˆO)þ¥îîÜ”JßxtJþo‚”xñìÙÁŸ§>Æ×ÿà%ôñŸ¿@·æoô˜›?C}ÿó¸ü/žAW‚œ¹x™¿ éø/<õ¹3&ZMÓðýSZnËÔ4ͦr{ö½i ¾ÕõßS}UvÞ.‘Ýw掷ìè“%ØöMö¨Rg¨³SbS‹û?<æëi£}ñ3೟-¿Ëÿüå—9ÙÉüóßíý¥³g_á ëUTT qû‹ÿòìo¼ô}€½>{ÜŸ—ÎÀ À,ýÜÌqñâYJvxãvJ-17Šð°c™*›­Fø÷)ß³m  Cq<‹½Ë]¥>©3ÙËÈk[æ¼­ôåUWËšP}Ò‘y<;Xð—(á_8óÏ_ ÔçÁÒŸAÚS[Né{½šfD:º’.‚C {þÌW‘Ðssdæ µðg_^¢GýúK/ÒíþÕoœ}i‰º0g.¾„·ýû"è–¯0Íž~C²sçü¦¾´¸ÒÞ4£Õ¥0šáè–éj8þ¸rjëg¼VA²» ÔЄ³¿/Ž{„˜“«³O2ÔÙ/¯ô=ÿØ@}™úÚ„6<—_€Æ*v}óìÙ?D±œ÷&QŸýâ«´Ù –} öÿþÅÎsμø"ܨíÀzú¡Oøö¢ûíÒ%Ñk¼ä³—¡Ë”«$ü-z\Gõ¢ÃUŒŽ«føõ óç¶³˜FÃÞߊ=®ôóâ™b °ìްåNËÎÆ,M¢Î>éÈCg¿°„öõ÷þ¦K—©ûAÉLIü¾`ìÒ¿8ó•ß%}úWÑ}¡ Òe¤98-€>þËtî_@T ¥óEj¯Ï>T›—è­7ujhóu‰6W)ٹʎ–}Ùz$‚z3¤izÿ‚vÛ›†-}K±ýÛbª}Ój^,ëÃˆ× DD&{ÀYCöãÞññ1á¥+´Îž[©³Óٗσ³üMô­©=~y™º-s„6Vér& ÿ˳¬½I—^XF‹NIÂtö ´Ù9?_"3ÿìÂ…³ÌÛ§·ÂEðÙì_¹n™Çn!úTׇ’1EÆíAíAÔ£yÄbË SÖ;Þ¬ƒ¿¡íN•zµb;ŒŸáݪô›×¦ËK¬IlõËv'‘]âwY8ñq-û„êìÓ€ìtvp8¾ñâ¥Kßä IJçW^yõ<ʇ߸Èq 4³ƒÏC*µôÈ–Ú\}õU 3ùMhÒ.C“–9/ C>ñ_QÇe n ºöÒucþëåeðÜ—˜Ò¾ÌÕ 9žk*h _')YŒÎ㎖JiIÇq×ìÍ1„´°Mœ€¼Å{byåÕ:{òRg¦³»A]¯¼Š/¼œùKѸ´|‰÷ô³žÑËpccÀð£WAŽhú’0ÀwiI„\æñ7еŒPt-÷Üý¹®a©ÿ…¢ÔúŒ:t@zû;’ÂbJ;‹{LDƒ~íYÕæâ¼ZgOWj3=&lðFÚ¼1jVÏÄÏ;4éòÉüh`;ÇÄ2ÌÁåÒd*u†:û¸‘6oŒ˜Fõ¨ö›òˆ÷œ‰¦uö´Ðyc\x¾»È•›äM(4MÊ4’ýØSïzQË.ô!­³§)õéÍÓGuéøõb´Ûm¦½Ö0ïˆq±0Š^ëì) óƸÓ&W®¹ßJöþÑ&ÿ@û´Éò¯år½0fcc´Îž®Ô§7oŒðuÙX¤vGLùø¦vÜú€Èv6ŠºÍ–)B²f<ôøÆ)i=q©}àiÍãŽ/íÆÙÏp-;©Ä¢Ï ’1ÓYšv–Õ ij=m©³ÖÙLJ¤yc¼ñŠ|\x{˜üCrqePf×:û¥6ÓcÂÈ>)ùÙÁ¶ö0ÍK¶à#PµÎž¾ÔZgÏ|šƒme±3–1yùÙ§ZgÏ †1sÜc‚{Vï³oá‹ñ\ÑjŒºÔ§WgÏþý§Ò4c6à›Ýa$mgó³O´ÎžÓß{DÜœÌYp ³ÞµPeo<¿¶ìQ¥>½:{öï?5ܱLVÛ q^V÷*±c[8Bj¢ò³O´ÎžýUzžËðÊY\%l‡b¶cðù5Ù£J}zuö¬áêö^$=v0 }lâÅdZίuö~¥6ÓcÂÈ>A:;FO²È0ð SøïôÑÐ}=*ÚìQ¥Ö:{ŽSüNÀ‘Á—,Å¥;ߎ޻ËÕx>­³GCëì#±îÔƒ‡Ð°ãd–7Æ>S9þ&¦e×jLD©µÎž«î޹áét>ÕÅ!MÙá*OÜø|mÙÃÐ:{Þzû—Ì·¬&5¶«1.GË¢™ÇºF·e5Å×kËUj­³ç¬»³|3œöð›qpß*jXe‚±õâý }ôu­³Ç.5Ú­³ç1…ü’,ç$õ©fÜ|a}ßÁÌþòÖmóMò÷òÅÿ=šìQ¥Ö:{~»aq}ÄU†õªò̧¸f_’cíNëìƒJm¦Ç™—.ã›1à}¯âkÀØ;aøTÜÁ剧ì%’ƒ'Ô˜úìã×ÙÃཪ]ƒôø+°¥”xÇNÊMD¾ŒÔgÑd*ujÙlaNõ¥%ö2Þ%þSï³´¼äÒs¸#ø ã-Ÿ?Óó|öÖ$èìÁ8wÏÆ“2Þ“Ü’fó‘ç†!? ’_ëìÑ^g¿ˆ¹Öˆ,Ë]çN—ÄkíË“N1ï¾D©ßñ––^8éAw¦ÆL„fÂr´€ã"ÿFÒ̘- ÓŠAš!žLZ‰*ujýÝxgÝå¥W1W#fÓe/>þŲ4Ÿvê¾4iÀñ–ÏŸ=éOŽÎ®ÒÁyöŒ^ÄX½7ž†ån·ÛV*]_ëìj ¯³_d/é…·¼pëº,h “%4î¡åI§Kìåz·üÂÉ ÷S8¢³‡óË4Ý){g1ݼÂðŽm‹÷”ºïMJwmÙ£JZg7Ÿù}þvÆexyûež×›.ó\ÖÁå §Ì¸<¾-ïÄ)Ñ›-{ì¼/#ÕÝ ÷‰ïMå~ &Éàïme£Lákªãk½_©¹i&žìí¢¥™Пs‚T?!L£¯Î˜v›"· {7¶aZDäÏÍÅѰw@ÜO“=ªÔéeäöÑã#ÃjuÑãôºsÜË@'ƒ|¼^o›§=§tât[Ýñ ì ¶Ü´ ‘…—ZoâåŠyºÜ{7ëêAh}`©Í,`˜ ;õl’Õæ1o!câÙ£k Ð2\/a¿€&{T©ôº±üÆg¿ö¸Î—ÙÃ[v°í6~·áírø2Eø®>ödij÷s7ˆ÷ÃÈ ¼ZgÆÐ:»øšÇ²e—Ýè -»Gw÷mDÒ6öÔXvö潦EÄ[?`I†åÕjLT©Sëì®®‹ª±Ú‰q4L÷ñš þóDm#þ{|z{»ùxÙ8$Ò;³þ:h=†ÖÙù´ yRz½žÒó¸VŸENú±eÏ(&ÝÙH¥ÉÐ×Ãz;föšieÇ÷15¥w~ |mÙ£JZg‘Ö˜5¼­¶ÄNÈÙÒ²+š¦ê檕\§ÞÎò¬˜S‹tÜ7p«ãk½_©Ñ §#ƒÏî¨|ldzìÃ6Q]ª‡š¼6qt7& ž=zÚ´Àžcëæf¼7­fq|Mö¨R§—Í(5ÆoÙ³i¢CëbÄ –Ðb„šBbūǺMö¨R›Ãì øì0ÈòØõÏÃþõqÊOO8+= ûV‹®ç~&X1XIªyÂzV³‚&{T© â´éŸ ¥•,:›–œ!-;;Ve‡-ûøõôÈi\v÷É–½©uö<‘¡ÎàoœëBDÁo‹îƒw¼uá)+Ö'œâU„ÿM« A$ì½v–·P® Á³wýþïä–ñ˦dÙ[3£©uöÜ1„Îî껠ǀ¬Ú‚ºa:r‡e=é6›ãë“NÛp.|§ótÛüm b=jB8mãË)&-Ž=¬‡ƒãúìôwÌý«uö‘•ÎŽÙ‡ÅìQûkŠ<âÌΛhËÄú¤Ó¦)´izÒ4›Òš·ê"gñp2tõðJ;ãÍ=y­³çŒ!tvIßí𘽳,`Ï-Ï›6Œ¯Oþ¡çhƒ: ½Gët¤õøÝê ­ï`-x©éØõô~z8<þ ¯ŸÒ h=ÿR£-2? mo1» 1ªà±[¦!†¦k¸Äú„Ó.Ž:r}s‚QßÌŽ±íXÊrþ†Pê×·Æ®£÷kÇèc“xõ×%ØÂÑ:{Þ¥ÎF9¶¤ñðÄ—)-{pÄ|êp¢:’ˆÇ0ñltëý§R?É¢¼ZgXj3K`ŒQLÍnÓ]J2VG8Û#׃ÕlñQžF¢ü·£r’ÈåÏö*h²G•ÚÈN?6\Ëî³¹1‚¶>½ŽÌti£ïñü}’“£·Ë=ÎÞóIXölޝuv52ÓÙP±@/aj»l·dK?¼é2Ðë(@¨Ú¸ãô' ¨4I–½‰O¢ «G«1¥^g—õöNÇ(1UÝru㎫; y|W—6D„Gnj Á8ÂNçÍ2o Öd䵈¼ó°k=Gd¦³{}¨€ÞûÙË [×úøîyàéÑ>^ÓS÷¹?n]=Ø/!,»(/I”]ëìiK¡–´C:LewucÒfÖ6™å,Ç^ÙèíÚ¿;‡ý¸ÁyÍGš7ë¨íYv¬7ëLëì¹—mAF:2Äó“+ M±œgÔÍLGî6áíe¤Ïñ ¦ÄÌbÐDèëî[’Rù ®Wi=ïRg*[’âêÆÄðÏ¥#35þ÷+¹…™µ ’Éy³‚(¿…Y¿|ÅÏä*h}`©Íì€=—’ÊÐbY°ø¨9äK'ƒ´{Oo—Û%ãËýEXs¹ÎÇ,eT1# Í¸y›®ÔF¶z²áªìܦZÌÖç¡w“ë ßsfrôv6•´u_Ï„ÖÙó@æ:;3+Þ×&~ VÅä±-Ù¢EšúG…Þnv“½I4_°¸M•"ðß›¦Žg²ÔÙ1*›XÞ|» êÔv ¬§%ÇÙ+žËCàšóôC¿Zì Ð:{î¥F[•ÎÞ /„EΠ?jdwü>ùΙEcñ•¡õ-Tb $ð ÆæÊ3`ê½ÚÖL‹1´Îž©³V]u_{ÈBÊs†ñìhZPñžÔ<÷cÞà;!"ço×U`à®Ã{Ï›Î~xØ2 d]úÔëÒ¯P 2õbþŸæß›Üª›_638“Vc¢JÎîéÚÆ¼dK¡ã„²®kå7óü¢æBæ fõÿ:’‹Ü¹¾.¦è>=èP^wÀÏ•J¤;×iÿ_í#³Ûí°·èi=ä ³ó÷¢Z߃!¨ŽÏÖnvùÇ£õk–±­qãcØå>ñG}^öÇæÑÑçÝÿH—}ñ…9íSž{á±”e^ëìù”:û<æ8v¾ãZSjÂZµínT{nz6ªìød¡S‹xÞ;µ÷+Mqõ1§íö/±ã·ºà×Q?½÷äa×èðþfx}Iê÷· ;¯-{d©Ñdâ ‰P?,Ô¶3Ô‘ûʼn7»wbHÞ{“©1^yr/GÔ”zë†ñ÷M{N¿€Lí&¡®Ìçô¹3GÚ]ÞÂú<šìQ¥ÎAP–Um7gŒiæp¦ðyQ——Ì{q— 5f­³Gchg ÀQI†ð8Qqìš8µŒükr~Ko„ËSí m›&çi1†·QÙ_½h¦ß´ØÙèÜMü´¬ÖßR_œÞ+kÔ’_û7«`Ò««ï¬®®ðÁÆújìúmXx³²Z¹ºzk•~]«T®Ï¶i˾uøÅ=Æ‘»|Z‰*uz©ÏÑKçMl•âQ‰…oš†¿<^ÔK¼}óÔÛÛGÈ2C¢ÁKUö— ãßÙ›øP¥Ïèü,_ÎçGd|ñÿd‘koW*ïü åð:ôµµ50Ý@ûµµ>X§7pÁÆÆ:Îйo~¸¾2Û:88€'æQsòt^Cëìj ­³7»­zÆfäxO^ 68ÇXK•p—Ùòôðüò²€oÛB‘ß@†;6/-• s¶@Û‚O5³Ñ¹YZ3@õµë³G´ \þXL?œæk•õÕÛïUÖÐÖSÒ°ñ“ŸTVo¿NÎ;ë«7×6^û?ØX¦¦qÐ_>mÙ£J=„Înñìç4œÜšGœÆƵíz9æeᣗð„±–j^¼){[ֻ鯜½A}ðƒ½¾ Æœšò÷vEVPößÄM*¢gC¿ÝA‹Ooê÷¬ßymöÚÛ7fIû—ØúP>açµe,5Ú‚´ñëh¬»Ä9Xî:ÖnÍDOŽ˜²R™Ä³æü› XÐ;ž¡?†gêïéÜ<_Î쯣õ^bWÖÞGNÿl7èª ¸`–šÿ›ROæÃ›pSÜùàÝÊ{«ì†X­¬Ý¾-TšØåÓd*õ0Ò13‹¡Ö¿ñÝyÊNHøÛîrBD©úWƒe2¤Îí‚4pVÖ×o­sæn|°æYvæÎ ûŽ^ú*Þ Ð2]§-× zÀÌÆ»oÏÒgÝ÷µA:¼ÖÙ–ÚL‘‚ 6è28ï 6y«5½÷Oš0êÕ¾TÂËá–ÊUO—ë°…:áçИ!&xìÙâêß`;‰¬OA4Ù£J@?–FÚ€Ú` ÷%ÍYåžMσH¯kãQºØOš¾.,lâäM+i?ÀÁÁa|þK2û6ôfNöŸ\ýOmˆ3¢Þybm´Îžéuvì)JU©’uwÈLËÈ$[ ËÑÛê6qŒÈdg-Zì6RÄß?-üËÙ•ÕÊûYuÄ›³Ñ }ö£~¥ÓjLT©ãëìBÇ›ÂúfEË/>žÂÉ;îùatm–‰¥Æô· ¨ËdIãø!Rýˆ\{ûæFåveu=cª¯WÞžý%ô.ýÃ}ˆ@´›ÖÙã#½Înj9°§Æ¥IÒÛ\ ñž+Yı›]BËû’ÂW|⎙MVjoAp|zK×6nfnÙ8K¹ü%e3m<>zlj=i©ãëì®:Þ)¬òÔwœXd·ƒÓÇCÛoÙSéÚÜ®ó˜ñÕ‰°‘‰Êq@ý(sþÚ ÓTXÏQ¦ØX™=zü¸ ña8îIëì‰KÍl· ñtäÛ 7MŸ>Wˆ‹Ç¤›Íû?Á“²þmï/Á趤z»a´ òÆõ µé·Ö7Ö†§wÀ¹1K>§öœú0ZgOWêøò±›÷DýKc°]qö Î“V×F…7cº|îÔ‹i[äÚ›B>ÏÚ°ÃÃb"!h]µµÎž¼Ôfl°àÅám¨‡Xv>3}>ƒ…§‡Je'˜—¾CKÕGOOÔyÿáLŒX?€²?~ü¸{@¾û}Ö…a‹ _¤ÄÿÃnòõ;w±›amcu²KÀoŽ6Þ…ö-]öNåÃÃÖ!LR¿Ýüœžúþ‚&{T©ãëÙ]äz‹k{ÙøÇÄÿ.ÓÔñëæÌß~ŽQdÛ+>3¬¾å2°RLÔƒ:Pƒ¾ûæú**1w>xw£ð«· îå:#k?yÂÁnoBd¥4PÂÙéòõUV@9¾¼G“¾ñïÂ웳ö/Ù(V­³'@b½ÉbZHÚ®$uµUìv[C¼FÉWØŽÃk[úغGKÕ´Ø‘UùÞÝGÊQûÆ™G° !³76 ßm2šNßçíT`ñ °íhÑéß[·VW?¬°xÇuë[©¼Ç•Õ÷+”ÖÂگߺŎS¹}{õÖYÈC²èZ‰*uÝ”bÃ3>PO KMdÚ8r S$8§­0õ!­šÈŽ©:/e:ø`_˜M ûÁìJeíæm°Âô³ö.%é76ÐWÙà,Þ`¾Äý®Á6¸æý¨`ïUî0îߪÜ\«P‚÷×éMs‡;8ëx˜•Y2w€ï̱ÚZgä:»Õ$Ùšu¬7/`$×µ]}›€)³ß‚³ ¦KwhíÞ˜ªˆó‚gtdÝC³ :Ìúû«•wnß®¼»q³ò>õIÞ]»ýÎÀs¿Yù‚ÀÞA?¦R¹õãuˆí…ç€ðUÀ¡{Á6y€‹sgÃkž®ƒÁߨX»:Kº-ãÀÔ:{ÒR'ÐÙóñ¡Û3®í•‹ø¥ ¥‘'~7'N© ç;¼Ùµo¿C×8ètšfÛ*]»±N öÍß]ÛXíx«Æ­¸ŽQ‹0§Àݫ躯ݮÜ\§nÉì÷o¾·¶qçßÞº‰j%øê8Ê£²zãk³×7n­ƒ»³AŸ «7é}Do:w}–ZgOZjf£„ÚoÚÍ­éÃ2IÇ-GpjÌ€—},Ma´ã¹9þŽÔ7*3úü\Iú»Ù7Oï óÚìµë?œ}“ZwpÂAG¡ jïë+"†v(}–zýÖ*Ýà¢kÿ»Û«–kàæÚÚÊ3³ÿ†ö‡úD7©ïOÝ$hÃ^ŸµL­³'-u%9{Æ•¶‡ˆ#—Æ¢ëN?„Gy¡Dx¶ [Å¿‹Íå^Þþï'…—5f„ï#ƒR|qhÞºµNɾBmöÛ¯Íò=zÜÙ•µÊk³ß+•ÈìuºlîÚÊÕÙRéïW*h÷)í! <^ûÚ½pî¨Øƒ-§ÎÏJ€i7n®^ý[ö¾îð“G«1Q¥N¢³GµòìáxŽåHžGþbþŽ(²–½‚˵ì^.„ÐùadèìÖçdæ0»KÝö÷W© rRx¦7(ÙßBâR2¿qƒ9'?œ}æ:´8+ïÿ`ö™·*ïâ–tݽ>¼YŸŸmùîvC­¯³)®¸o@£=½ñZg:»¯ý&ÁŽœ‰ØÅæºâ”òø/¹}ô_B~B?Ù‰Ú¡ö‘¸ïM5çÜÅè¯n‹\{óF¡ý¥íGðÕ¡‰º3o¾E­ôõÙ9ríºKá?~s|ó٨ƬÜ~ç=ðòW®>ó½ÒìÛ×±aûݯ1;Çe¹ept6uÚ¡›éêß6ågœoª-{T©ãëì}~ w¿àÄUü˜ø˜T_71Â@ÖÏý‹RÁÖ°°ìÞvþdd{¬Èr@ÆÑ6ŒNZÁ@asòý 47q ØkpT ‘zíÍÌ¢úÎHO7®WÖð d„&+ýûæê­«³%z´tƒ„SãE‰¹_èMòUÈ;ïöðj=N©}ißxí¨h;2kb¦¨ ’Xgg9r]-&úÌýÃ#ïÇÞ±Ó#F×ýý¡rþä€|hß}‹¥A-c~üoirýꃬbvÇ÷Ö~ëAKy½îï|ÀºnbT#ëGÚXmÒ t_6ðx뼫 £hàø˜}惷g½±ZgWê4zv¶LvÉŒÊÿÞ)^˜Ú5¥ÖiÌŸK ÄÑô}ø€Ò‘Yžšööxîô•®óˆ.&‰ßæã-*7×Ù0\¹Q]<‹ŒØ‚ èß!ËÉ”F–ƒ­‹aOk<$ÄOþÉ›³B‰Ñ:{ÜRÇ?úº1N€ì®Þíuë/tˆä:ûM{ø¦ØLc,UŸü‡­ÃCóñãæÐÃ?ÀGë^Cãvסy‰’!b‡˜FŒy¹É’%ÝÂOf0Ù1¿obÓŽlï{èa"‘{„˜}uöÇù[îŽJo¼Miººþ!3½8$é6µá?¾µz üm˜¯|ø£Ÿ`„Où> Õø1úèÐ%J}z/|¸ŽÛ`¦Ó;l°}YTð‡ÀqèR¢‹Vf!û#}®˜øt¡ÿ<Û®Õ˜¨RÇ×Ùû%éåN¹Jñ‹gÙ!¿oº÷~Æ«÷”}»RÞ2E=ËF¿C_èraÐùzÖÜYwÇ\󤎔®ÐŸþöê:¼q»òˆ^¯°D§ïߢNÍÿ'•>€Jð}6ÖÞ¥ ‡%ÚÆ…[bíûúÍ•gÃX©|ß_AO®ÖÙ#‘XgïóÛ‰ÛYrÖc‘Ýf­‡Ä:{7É3Û¸À‡ãÞññ1áçSé쌯ê˜Sà]0Òl¢i‡ÐtðUîÀ%æ²PªƒE_]Ûàý  ÌC¸ã»ëÐAïl¸åóÞo ä^߸ w Í« ëonl¬Â6Wÿs³ÁóíÈ@Ë®uöþ¥ÎHg÷¦A³žÌ²'‰cï9†:y‚QMD´i”å8è¶ÚäÚ ðVDD”Tn¾»#2ÖqL5ÉÛØ t¾½z‹z6p¬[_¹ q03Ϭ€ÆÂFr¼wãácoWXÚvÔbÖáÑàõ£òè³Íž1ZgXjŸGÚ?/J’,D¬ÅšÀ]HÏÎZ‹}öt9¤REéì † §Ü‚>RÚH…p.JZꈀŽiÁ6*,UÊ‘˜K[¬«·qºJ-ùÕÙgV0~…ÎÞ¦îê—à«Üf#V߃æê:“{0»;|ƒ@±Ï›_øÊ¦uöþ¥Nª³Ç寳ãmŸ*žÝÐ>  „Äÿ¥ŠÒÙXùÙbn`ôâ €¾ÑëÐ#ºRY zD¯¿öµkØýO—ý®™Ãw-Ñ-®Ñí¾GfߦςÛ@xØ–½zà¿YY™›Ÿ]ùsgGÅ1K6À¬ú‘yDý¨ZÂNûHëìKKõ€·ÊåX‡è±§Qc̾:; ºRÉÄÛ9Æ7ýEþð>GG´f®]‡€Þ›kÊÄÿ£«³×X|úu°ùô&`±.×+ën„ÌAlã v ¼õFɬ`„ä5Øžî7ƒC=`ŽÇÀ߀6ïÆÍqàut}i²G•:¶® ¿/ó‘J½4:;ø}»?Eð.6 Sˆÿ}uv°é˜]à¯gWnVnÌÎÍÍ‘ÙïSºñ)Ig¯¯­ýƒÀ€Ào@äc Æ3]}^'#”€¾+ϼñßÂx¦Ù·Þb{BXðVž™ýÞ8t¯7ÞÞ¨À–ô8ßGbÞykVçI‚:;Äþ‘^fé3H1R 22öMbÃEè¡ö ²CÔ£/.Ýááa×è¶þîМ½q F–¢ ç Õ·ß¿M—¾ù±ôÆ÷_ûÚ÷ Ô -{†LcDû Ήá{ós³o€·E<;Pe}mev·®@T%¼OocãÎkiÙµQêÁ:;Ï)xÇ¹Õ ¾á%•Î>@#ò¹KÜ­kuÚF”ÎÞfvò.r7F ¥[{gu^ I Ó¸±~ëMz ¬£;rí-ˆ€áNN¥òÝ4ûC6néê3ß}û>!6 h`ãÝwñ…z×gtÞ˜H ³7áCòscPá3ëì-Ð'ÆŒ0V§ÿ{ÐGÉÞ|¡³ƒºÝ=88˜»†V½‚ƒªg¯S_œÚçkÿ{ï÷·•¥‹îjŠiÙó0ÿÀ™›Ä3qúÀnôÀ–b@ÈJ€¸ŽƒòÈ .L†H ÛW¤4Eµ¨ó/Õa^ÄúÜt¦q#M!ìÉ%‡g™K¸î==O%¿µ¥»¾µÉúý‹%–Š%qÉ.V±Xä.ÖÇÅo{íµ>msö"O¶xeØ/o÷œ'îxß0ÚÛ[üÉ˸l”Ï9²}SÎ`zõ4F‹QÕçÊðó•{öa­¯³Û¾±öþïtÚÀPOœ7ÆæºÙNÆØ°ß&bð÷&»ñ÷¬³#%¨KÞÎÀ-¨¯ÖÛ+ˆHg-ðâèÌ«õ;Ÿ¬Ü&ï_º# ïJ‘¨ÉÆË¢®#é]º†Xv¢;ÊÆçðô|™È8÷WèÖB»16@X§µažŸ=y«»é="_¢bѨF°Š8¶tv®×n©ëÛw ijðÆšæ±IÎâ;Hg·9.†ìÿ:mX£*í²Ú£!#Ùu£é¿Š*[Ë ±5ïúµŒÚÕÔ/_ïÉ€uM{Í»:ÀÑ2f˜Åwm_Û'‚ÔhŒ8/9؇µz"=[þ L R+¦ÓÙãúÁƒCÔúqÝË>¦Uܨ¡:»çÊhvQíØóæV”ª‘¸€p³74°›iV/É”y_8`@5d»& ­•Ä×à\H|˜QÄ#g" †AòìÕýs}L«Èr&ÿ¤ÙŸÇZ¼(?Ëeê¡"›Fê$5š:q»dÕ 9aI›A-‚¶¡°ŸëìÉ[@×FßÔ“‚IöÜqÿHžŸ}¾L¶*´GçgïZÖQu\å\F­@ö´ Sñv9®ò€º§Ž—×AMbÉóÆtŸÉË{wŽ\±9åRQm¤o:K©Ql¨ÿWá›´bó%X†dà3qí†ñs<ªÕõ¨ ÏT–«1C[=y<»#ãDRÓc¢ÜÐ2§éuGc$ATûä§%ªâÍUV'­ƒª<ç~$fÛÆQêÄ8ö±¨ º¦À><×Ù'·ÄùÙ­ŽÞ`3%ÈK¶.Gå§ÍÏÎuÄ„7&k÷~eÆ­ÚÄí@â LŸ–)zӻƥ Š¿¥;aÐp޽\gOÞêÉãÙŽ2Ä|‰Vr¡K’#éºH¬³3WÅønè¦ÙªxFlÈY·&mÿÃ;eÈ…²ºÆaê;?C²kúôöT Å%Ø*µêúºíL¡ûŸœø>¢CÅæVIuW1“T¦MnƒŸ¤”‰A×ÊKõOaÒÑìÃZ=…®ÝZ"Ræ|êlwBˆö]bªã÷-¹§›œµGßà-õ`BnU4 *Ññ‘ÁÅ· „((ú®² ¥§[T8ÁQB“³¬5£:BÞÓ,+!æxû>²òå:{K¬³÷¹v6ÝÙŠªÑÕ†WžÒ»ƒG«:n8“\¼ ™Jž¼UÆÉɉsÚ°ÐÓvN;Ϲ$ç;šfˆ ½eGB¬rÅÈh®p=³çjÌVO®³÷éîð%<½rßÞª¡DT5ì0y^ö‘º;=¢Öt_ÀÚDMÂçøýHåIx|ßÿo]{E\ýB׃ñ©gÐêN®³'muRu»K×gÞËyL£0E+°S9I¤d³Öý"Ê 7y«ø³^woå|‰ú Q±%ˆá­ê¸+¤v|×õÈ{žgË3‚iÕ˜~ôIIuSÎFè÷*(ѾkʲU.ü®—ïÄ]ˆ/ú¶3ö¸¹Î>Ü.­³÷yRD Fó²͈Ùù¨Âl-/G¸–¶÷ß&þ“8@©S/šÍ'–©µ²N¶©Ci³xïØsCîlnU‘«]ãdw’ª¨{²´ §lW¹;úRÙày%Åj¡szzŠ|ާÞäGÍÕ˜a­ž^gïÓÝy&Sl¬ŒÜµÛõÜP/tm75]}ÂxwïGÛ}Ù‘Àwϲ*ïs aÚír£kÊ=õ‚º…)«…‚RR«(û(Ó[Ç¥’4ugç9ѳZ58ÝR)Š‚ÿwŽ„ ìú¤ñý¹3ÀRÐÙ{ò¨´¡~/"™Ø=xëOµP2h'A|xjº{P³eL$«Fq/Ô!¿)ï5­YRéŸUÀ–ÕŸØ3S–O¿¿S–  ‰2>.iLZ8q©fhëo A\ÝÿÁöN' Gò“ºz®³OÚêéuöA:ï½–c´áÇs} aûíW—?Þ„ñîôY5Ù•ÌÛÁlÞ]ö!ð4õã{ãvX¯ÛÁ10ïºuÎG‚RïïBÙ* #;ŒpYQA b>ªNÒ}ÇC¦`bÿuë8vœ!×ÙG´:òAÎå—2÷b›Å„<:*8ÞœûŠma]"n=éÇg51èj—`vJ._cN0ÍãÛR! ¬ÆÉ÷ß{F„ˆÅÑ÷÷pÔ{…»®çÕÐwÄò2® ë;ôr¨G{LWb Õ0fÀ}‰Ó‘ybr}ÒV§¦rÛr&SëòOÄžsZýú ²[j~‹_ázìlKéñNêí"wÌ~}òÊ„òåÑÈKÿ/òã„ùúê!ªí}]¯»%øs??Œî b‡È§×Qßcì×Íuöq­vÒ³8Â6ŠÝü›p,[fxŸ—u`¯B¯>¿öÌÚr°kµ¶¾M½SÑéÅ;¼|ªÇ™$Ï ûº0šGÈæGªÕÒ#ÇžùRKŒ@¿®–í22ÄÁdQVjÇIªÿ[<[6ŠÓáxwG¤GŸ¹eöa­NQYn©ê½"Ž-¼R‹òÊDQ"ÖÔYWshÏ•|_Xöa­vÒ3ÄŸ Ô\D§½rc'ÞÙ2´3Q€ø‚Yöa­¶ÓÔ{m18¿ŒÝz5Ý–B{ØÒÝÛ÷šlèã¹Î>{K]g‡S±&_{efkïtå–®Î>¸žé°õ3¶õÿNÝMºn–ëìc[Ûõ³+€Í¼q;¥Tp«µ31`¯Mõ@‰m@ÖÕ…ü¹2c‹wöfÀ®“ÐŒs?5= h¶×Í÷"œ¡Íö‹ÍýMjÍŽÇÙž„¹ŸšA7œ¹7j‘íÆŸ¼æÅ€½ÝÔkëÙgksÿE3a+^ÌùÔ æQ×û÷šñE¼ˆ'/íSÒHÚç~f†Ýo®³[Ï9ûì­Ù}Dëaž–QrµÀ–Ÿ;¶®ÓÀšïüOLö´-?w}*p\²v –ƒ=mËϬ‹µ_ÕxÞ8ËÁž¶åç.²ö‰ÈÁ~]-?w°f?Øçbr°§mù¹‹­U8²{snO3{Ú–Ÿ;i͸èðí"ÑêÜ&°üܵ-®>: sk­Îm»öç®{Zãùù›7o.ÞÒ_´úììü ¿qvq†³q¶!ýíÛ lEÛ¿}{~~þGù‰ÙΑì²ì©Û8w g®æ ŸŸE}‹‡s,äL_ÚL¬¢È‹„žüñüìì >þ×ÉÕ™H¸>·±vN@zÎØ=‹ç¯¿Šó@ÿÅWÄ;‚^Ò›LaÎéa¹uKhÒVoþ¼ñUYöÔíFœºsé¾Ù1GÞùüâìäÏ/ …åÍ’¦•å7oÄæö¶r!6·´JQyo‡·à1WéÚs°§n7àÔ1‘~Z2‚=<ø9ëëÊ+ ¥ÊÍ]½|ûö–¡U´¢ijÆß|i¬£ "Ñšsø|Gà’™qb“NËÁžºÝSG€©9X»/´ÃõÛ¥ljôgrÕfT¯U4Í<4"SKÊ*<›ºVRÄÅUºö¡`¿Î!¾³µv`ôœ~Þ¼PȃkÆW;E•mÀ±é:j•ôÉL]×ñD×µ"Þ6TB~Iùc&<{Žö)íÚƒÃsN›G”¥¬iÅ~KÌ8&$Ã{k²J9¡¼Êþ^hìçÉÝW¯÷xÓ0ô²r• ÏiLêvíOTutFõ’©› &âÙ¶¦ªzòq¦Ç[™FñŸ…( «zÉ;3lø0~í±ÙÙµ?uo™oÞ¼QÊ•=쮩5é­5m<Ò5ô] ƒÌЦ­+eâî¼CÞû i ~™æõ¹Me×þÔ½•ÿ 쟛ªJÔ›0«íì 1ÌXÆšÜæKB}å;0ו9øhPjf6‚Æä¤}:»ö`—P?{sNR|äHÓ÷Û>]‹t#â1:x û-Ì_#ÈŸŸÍ²¿:,^ ‡ú´víÁþ†•Fq÷­R†ÂR…°¢iUS“ÓIŒ7™ÁMÁÔ¸/kTLsýŸgÚòáÁ19ܧ³kvî˜jZIQ¶É9¿f÷L}W—P7'‚;ž(;˜;»ys—þëZq`Ÿÿܨŵkö 9ÛZ1 òèÆÎÎWÐÍÉ Î[ë´1qþ=¬¨i‘÷K‘ùä´íÚŸ;±Y¨ y:ú¥èšîJ˜›ã‰ŒÎ,F^„úC<3«`ðúKe–jLöÔíÚ;) rT.DGP˜T zŒaè:-¶”vÊߨ€Ÿ&Ïlz)[Ès7 [<Ñ" ɽ¸(l”ÓÅ:±z…½¸sv1Cþ̲KßÞ¯–³_¯ÎÁB‚}´½á0Ç3~$“²g›ŸQÆC¨3BDϨRVRP.°]»s'qÉ©¿9??Kì†ujwÔªir$äÅÕј‹+þÁ®—c_P°­ÏSÀ§X+›[é{v6óP×*š¶¥Ì»Ñ,íÞõBûB‚½Ù®üÜ÷çy®wêÙõzÝ ñé{öØ·cPU7¶T± íYüõ~K.—7£cõÿñÑæýK§k‹ùu¸B¢üMPY0°Ž¥wì4Ž}O(%}l8@r´›R­¤NªJeÅŠk”ö¶ãrKÛv–ŽïÇß6tD`V8ƒãõ.C'°®¢6é•ÂfÞ ˜Æ:<{T74®ŠK ©×}×£çJY7ª“ÅLáßMèï:Ï_ŒŽžv\~iKÏ¿Ž®lùÍ ñ©¯gy#=ût¬­9èãÍ‹a/úÖ9ªp†Z£AžÏ"Ty½§™ª¡™˜”QÑcR­²šÒòÏ&2xÞ†®Òö‡ÄÆ5õõ¾VÁª×ÄÎåGÀ«ôÔ4åUô+]ÆÈ("¨Û¾c9§­ªÍ—·jþ¶÷G—5}«@\f— ;Õ7éÛ²9ð)¿˜@+Þ‡ž^+~§¿håä×ê‹é]ú?ü5ç8,|¼U5+¦®Ñ…,l|®ajfì¨ûê ‡U«f<>ªk{{_ª{EeãùŽF[ ƒ8Iã+ýH^)q%hÓetçÎÞ}Çà9LäÞ¹ÎvM¾ì¬p-ËZ·ß·[<~úý'8þ5÷ìM1íÃ÷ÑÞ¸Ù³¶Ù^òCWaÇîƒÑŒ?òèá(È¢R›Ûå+!6è•R**Ï^¨:_ &bÖ …oUÖi«±ñ’.‡möë­Ž*ùöº'|KÇ'„ n×ÄËøåú¾/B¿s½ë‡bêý&=þõ÷ìÍna_>¹ñ <6;ß]OÚ{î¦1í7åöÍNÞ­îŽ{˳ƒÃF>¨sIÞ•úo¡²eèD¶Í*{i¨&Ê‹’¢l­3 ?YVÊÚ¥u†™ßû¤P(|\ÖöŠ·é1°½Üjs Éfi›^­ßþx‹C˜ ©{¯C@ô¾øEìÉîmÏe–÷,~Þq·©ìw¢e jÌuõì@ߑҖ‡º8N'2;–¢{O{º×ñ91ì]ŸÚêÈãÑcÏÒýW÷mÏ –Ÿ•uv¾ðÚwÅ&AYðãÆçµR*Æ·o—4c« j‚þ³Ïv´õ;϶ ­¤ÜÁúmúÌ ðúÝ äV‘¢ Àï;2w¨oð;ß{p»&^JÏJ¯C—•öŽõ®kßs§ÝoÒã_kÏÞæÑ½ö^ÛŸw¬nᕟ6;/ï [ß‹>ÝŒ÷ÖÑÑî°Ží1HæóÙî¥íÁ¿b8 ¬‰ÆÜÙx¡î¨˜¾QfN¾Å¾ü%½~Ubó9æ” åy‘/„mÉܵ£òmåå§ÒÿoÓe³Ãw„O™ÆDÁÁ ƒWö‹ßØåyCÛ•pÖ¨¯+è1^O=bìvZû»„žz]ÁÞÂ\·ó¾èbуWô½×³§¾­`:ºtúßÜj{¨ÅX¢°±Åc:r8>Û>¬²@XØ$/½)yûˆ :–BÐ+º  ³làŸ‘¯ÇV<»i+&;L„ðŠÍF¹*ów»ÆmÖÃHǸ”9]jë#më}=ë8¾}<{ŒÇæÅ`´»d:ð½°uLß›ƒ/Œæx¨ÔÙmòHb㕺#ûŽ;jQ¹+Ð[[w¢j™üým꒖˲ƒJমgùóÛàíDYŽ8­aêmÅ—‹¤1ÏÉ•KU3–X—/~ãDŒ=-£/Þ#]½¶ô·W©²ß ý¢å}ûøXÏK‹ÍQ`¿¸è¼€â×ñuÕœìCubg/l”d:€hR5Æõ÷Tƒ€©ª;GÒ+W C5Ì]M«p¦;WÃx§ €íaä©ò%uA_Gù*œÏ0ä•fR·sô4õ•B^÷8 ‚un<¦ó=¼Ìuöém€ôØ^Œ¡1¢´ÍÎ-šý`ïÚºƒëG픽9–ÃŒÓÙ=ç;Kl¼$TîI9]5Œ}ÄȘ»2ŠùC« ps·bê2…é Ìszçà€‡Xy+BsC®†¾«ÓECÈ¡at$ÛçÉ%ÅjÎiZnlîQ5~a9¼¼RÇ~­uöt-¦qѣƴ5š{}ïTcîõoÝþ@|eÄÝSѳ›Á­®³ÓoáÉÔœœ×Ôd’RÖfÔ=“}rÅ„Ÿ×0jT0§ÔÔw éÒÕ=¾FªUÖu9ÑZ×+ÚQ…¡O0GXA¬°KÌïk&âCŸ,-Û¥G!ßÃkúÊÂoé$¹Î>…u}nòÑ%è„v+‡Í„:{ÇAšÒ©w‚ýÞÔ:;ùC+T^°êNä{U£Zi 9æ¯8˜©ÉD½šÌ ¶ÿ…jT8W8¹ ß®ª´êèþv€häœ1èrÓ°5ý° ŽdîêÚ–B=TÛrÒÓ»÷eÑÝ¢¯{ø\gŸÒziÌHköo8pµ;Œ¦Ù¿v‚£ŒnõpÝûºÊ+¦2O/à¼Gœæ BèÖ™›è¿’qÆŽa"gõ²ÚšgÐ÷ùºà1)ÜpIÈk‚s‚’[ßáëHî›Øñöõobí^Z:7ý¹Rq£×ôÜõÃ\gŸÞEµ$ˆtlŽ^Ùü^sðö“_#töFƒ|¡#6·¶R³~a^‘$ð˜^¤EÙªÙE3ÀñÞ–;*O1•É«ë…àǣʑÀ<_.º±fÄr8ßÀ–" nh oWâ%ÇñÚ‚|¹|á@rD5×Ù§´$_ç æhMxˆá:»hö‘,@´¤1†Ì #,Œ`LpU£éF\äÐFð’¯ðº¤{|1èQU—±ø„M¶Æ¥ïU’iPì½z¸nš:;œ+{X2¨ìv®³_Æó댒%j-61HÄüqëôüЬì³Ã–]̸ ˜º¨†tÚ_¾æ¦f¥•-LFDJéQB¿4}—îxçÎÝÜ#­ø÷µÓ'eˆô‘Û–³D®Ên´gÏŽ ×Ùiyê,o”J<GDŸ³$¸î€†«1*@ñ!s}!²Z%] EÑʶ¶·§ƒŸïêˆó‚cG¾È*½¢Å|}_ûR5¾”Þ½Z]ÿ£¨iëÞ@{,QuÏÍuö¤°™w’ÚØxvÛs]Ä»(¯xØ¿T!¦M~xG•òéˆc7!Æ0‡gÑ\ã%BþúíÛ[2à©ÚGt¿Ù{­©jìèwÍH‹²ÃK}÷áf>øuêþU´<;{÷+óë7@g_ ®³û¾8âb·Ìê:‡ðbÈÿs¥PP>79r³´ ß¿ € ¿ #M¼í¶œéô1‚–•(Þ¤÷–ų²)ãÚi[òê5ÇÿôupF{ ëNxÙxù\g_ «³Óz±ña[†Ê‘0<)°§W+ Þ!o–e ¯©“÷ÿŒ·Ã;¥Wòø”ÃÀ蕌–Áű¥¬†K‚ªšY‘:ý–b :vÍI]÷-ÏÎ,#×Ù§¶…»lµ?\'ölbÖjÌÙ_*¹ŽI[š 8oMA˜îzkÎÒÆç»&A÷9m»]âË`eå6¢"_¼Rn—A…,/Ä<ò…@÷ ºœ íÈÄ] º­üh{ȺîM~Ýn1öȳç:ût°™w¦kuäÃËÓï”’¾Á‘ɇ((%#_*w0_ésðsöÏ/öÍO÷ô—òâØÚ扈‚üdY^.xÿS¾7à.A`¥"싨Ræ<í ë¿m¶_wRÖ»ÁØÃëµ0g¿ læÝ€éZ=T&–™À¼«l#³B{ Œñ<£ˆ~`¦)ÈÈÝÛ%•:±/y¶Ò M7õOÍ@×–£Ü žÃŠÏ”å€;®&.%M=ˆâi`/ž]ä8—hï5 ýž9‹L®³O›ëR<˜yùr¡Æœœ gÌs0jU“`ïàìByþ\Áœ$Ì6…§æìrî¶{Ud®®i-^xÿ—׿®–î0ƒ&mÓåT–aÁˆ½ÙVà kŽÝh8®ƒ\zâHŽ}9C„ŒSg-8qÐ&êN¸Þq㤑$*óZ{ö8ÈwTö˜Ž å³fW¨nWÞø1÷âøÇ®]zÞ9?oh«‡êÄu?tÝ:è  HÀý+©Æ¼lMÓ@¾Ie>‰ª-­ÄV¨óiúÄŠò UO—]"·79³€¼hÊPuJj¤êD‰•´Ê~ñw?ÚÜgfÞ븰Ð/ Ïn‹ ¨G–ôãt6꾌³¡3ƒ»O®³·Wt}Ô·mv}d¸onvENvízàóŽiv9Ngþ[è4èªQ1T•#Pæs,8ëQš½=M¯ü­z$Ã^Feý=µ¡Ç£¬œ;I=à1#CÛã<4G<æç›áÀH‚¾‹Œ1<{‰&ìá=±,.mwù_:¶Rÿzb¿~­uöÞyyh¹5é1Úp0;žË×öG®³»Þ b£¬íp GÃP_kœñ+ øâÈCÛ†$çæ˜.-ÊߨñÄ ™.ƒÞÁ ?™—]å莌$z ÉYKƶâœz¡MÆõÉ›×jK º·~±¶¶zi[㗵Ǵ“ûÿæŒÓéo”ÎÞ1ë¨cVQ³ýTˆV·çR‹ÎéÓ}`om§ëV+Û8½qâÓ‡Ü(i{2ñ.f‘þ²íVvhrT 㵊8ÆØ_ÆW2ØK•Iî0•UFƨ^€w}¤Ýî ¥Ò±GؿܧQ{މÁ/}°öø’¶Fê´Ÿ'”ãaumötÿß'×鯳ÎÞ•’®ì½n¹÷é`FÒBn÷víY{`¿× vÑÕ¬ÞV×Ù}ŸsÆuÌWÚ5‰vè»ä:<äU ûËr¦#"$<±c_ÎÀÛç\ÔûȆ€0dÊУPvÚàˆcƒ‰ UáÕ÷¿ÓP©'º¡U]bëžä¾XZK²ËÚêÚÓÕ©÷óäÉÚ-èºY»ÿޏI:»ˆ'Þõè¢ûž6¾Õ ö‹þ‹buéº\F¶:R œþ%„(Ž%ž½i¯È¨vžDª©{Œ\CÖ{rM¹k0ý6wÉ[ËÔàòpá#%‡þ•ÁÈ7¢xÞ¯øÊ1ÙÏÓÕ³­ð}„ê“‚³‡5Ç —þòòìcíñå>}œùÔýŸ<þèìÝ®y²”#Þê»HÐA öáêCÝ!p».+ qÜ9~IÞÂL/ãÌÕ†ÍiâØG•g®rT;_#LÑ “§k˜1Ç“š2·/~ÍÄ£ûçBñ¡öÓãÒÓ»äØ˜È´9û7üÚÓ5 þþ3töÎì]<$°_ô‚=~§õb ؇tRGF=ºnô R#+F©3 uÇH©‡¼€ýEj|¡+{o[['“ àq¼ÿï‘>êØ²tÃÈ(Í›ãÙ»R%õÁ8΀z¯ì¯»ÁÞNcÚ±ëþœ`ÒÆçÓÏN¿ñvY”2‚vA°«&Ï\2+pnÆá!.›”›AjŽâ7¡ȸÖ[Ç<%«´Ô¡BÚKSQÒ;ß$îÿºÂ0Îön‡7Vgog{iû÷î„0Ÿ6'òì`ï”t.º¶êz1ȯÏÏN¬ýDúWñìqUÝÓ¤¤‚9¤—·¨xM…ÙÐú·Ä™~ÒøÇjD••pä†#ó©gȳ¢ê¿ÇzËøÙk­³wó^oþ !ј¾jØ;¯•öV“söQñì~ˆL; êa3È𨒔µËY‚ânòð¸|ñwá©caÒ¯ƒ·;n§N}ëa:{*`í_{ÿߤւ 7òÿÖÙ»°ÖJ»;X˜¹öÒc´½/îuyöIÀ>Fgo4Nèìçp©ÈØH¾øˆ#^Œv¯K#^ס²W‹ßR! /èa GG;¤g¯e˳¯®E:{͉ó¾[7Tgïfg²í©ûÆ—†AÜîcvõt»vÝEcîMv¹­?".9¹ †p ÏÆàRIǘ¨‘J÷T7e!‚ý}µ¤¸¶ãẠóvÕÝN:CžiÌûÿõ;Øx´7ôo®Î'¢” ©Ïz3Àô¾îÇksÄŽzÞîÈ9°ÕCõaTñ$ÏD¤Â ½SÇnXäÝE`ûö’#ª—uêR…×+únYñ¼c»^"NÌr;ÚAYòì袾ÿ£Â™…Q€Ž77UgoŽ 8Œ·µÏ~çœ<šfäG†ëì®ëŸƒÇ¸!þ/ÃsþǨÇ%{/yžŠ',ÎÚkÕ3P×ë\ÄjŒ-5æ1Fbß_Š~rúk07RgïÀÙe÷ÙMÙ§ÛÃè÷Çj ÚŒƒMG6ÊÆÎ‹(ˆèâQ$u,ª!Ôsî ó³+ñJŽnWD´÷~}:c:;,ñ÷߯PÇ)´Ç䡹îžýb|,ù$;½$Ö›ã><2oL×ÒeO¿©wzº,6^Ê,`ZÌÞÍÃ1žÞÜý¯»²V*è‹~ ¢:äëâ7¾õÿU—v»›A=ê8¬uyv›[ØŸOþ†èìp»Ì>'aüíbMPµßN Ûþý?:BðD#xhý¨‚Œ½P¸ÿ}­²O ŒQqx€C=ƒcïûµ62§³KÏé±åÙÏ#}Äê ÐÙÇ£mœM—!5ÙGFèìýº1f A¯#Ç.q÷—G2s©z€´Hc‘n˜‡Uƒc„ õõ ¸zPS¯Ê—žA}MvPW×î·=ûyà„ì×o°ÎžyŸŸ½gÙ`uÖ+°OÁƒ.¼h‘»®™{L½‚Ò¿Žý¯nh5ïô÷'›1}€g¿àêÙöˆº­7@gOÕf–öw¤ÎÞµ¬Ã{a–±þþª‹r M-¦6Ñ O4EuýÛºxGühÓÎcÑn@;2¨³·<{—ㄌö›ª³·íò0z“|pTÞ˜>ÝÝs‘=¯ï8ÞÏ¡žê;Bبe=‘ÊXE °º¥ “……é|¯N¾}h—LéìÕÍÙáMÖÙÄFij÷ ïPŽm0…¯ ddþQf¬—8SLÕ(¡fRï.—ºŒ…éMä’E]zöj ÎÇMÖÙÂÒ(ÇùX–7ž—å3U×£)q!¦’²Qb1þõ EyÎeá¿!|˪uc÷[–={®³/ˆM®³×FXwX+îú˜Ó„ä»{÷ã-Ì5E®ÈÍçZÅÔ׿ieŸ‹ï #÷Ÿë왵…û:SéìƒMfSçšEËJ©¢4ËËe‚:bjî"±µý‡ºmÛ?‘C`2Ïžëì™´…»lõä:û°xmŽéF|dày®ëzˆƒK£õw…¨×Ý0D-#ž[êDlŸ:ãó¯ç:{fmá¾Nb}¨ŽŒºÑ¡ÌÐhuÇ>=¥g¡:ÕÈçå4jýSí»jÔ¼ãïýM¾ýx¢ýç:{&máÀ.[=±Î><^›ç4ñkòìÈGàGæ¡&£N¾Y~´?tœzýëºãŒ=N®³gÖóëL®³_²ÂŒÙ¿ÔœSúÝOà-¤ÞÅ Ï#¸¶ä®ÅùEiN¸ÿ\gÏ -æ×I ³Ð‘9)òu0WÏ ¡Ÿ³¦B" fï8§vwüþs=£¶˜_'5fVÖ¥³#7Ñ“'«rÅã'”ƒqu ™és~;f;xò˜¶å^kOÖž`3ú÷ä oŽ„G«Hi÷x ùìxOOyåGrŸáÂ×8IähÏžëì b—ÑÙg½ìÑÙ?T%Ø×¿¿ôÞd线ôîÃ?¿%DìÝÓúÂ;byéÁÚÚÃ[ïDS_Þ{x>¼UâîŠx÷O¥ƒŽ5óÇkÈḺút à½M»ø×äª'1ØWs}ñÀž¢Î>;ÏÞ¡³Ç¹áŸWï/-=\åå»?‰1½²ô‹ÕU~^(ˆw?üp©€'xN—ÅêãåVbY¼÷hUb}í)\úª„úªL’±úôéS€^šqÿ‘L(Ðöì¹Î¾p`—­ž^gŸù²WgÝ`È#IA÷Ýkû/îßz÷ 0÷ÉÛÓëkOÞ¿uë—¿¼µÄ ýbiéÃUb0´õfÉ~ºL…Ƚ?޼öãˆÂ¬FóMñîê“(]u®³_\, ØSÓÙg¹lëìän ¶Leˆuß_úSñÞ~Ltâ½è?º¯ 4@kÖÈ‹/=øðgœæ:º8Öž<¤u€õzú€ OKê좛 Úó>Ó—[Ëÿàñãû·þ7ÀûÏÁù‰ùì‰á?xB ï+×Ù[°™w¦kuôô‰ãÙåÐ'X¡º,‰wˆÊ—ºösæä 5R ä)® ÖæW?¢Ž(.ƒ?§ORwôPžÿÄÿ)]´æC&6ITæ]ðúK2ØyK ¹ÎÃfÞ Hj‹¦³G~•Ç|ãD ”ï>zŸ:¨àäïòÖ·þì!ØÑÙdzÃe%ýL&|-P·óÑ’¬«ú-ýüç€3´êØ.ìß¿%‡£ØÇƒç?Êuö[8°ËV/Î.ýª”Úɳ±ø…BHŽ«¬³/=º¿ôÞ‡¬ GƒH€ûŸ<>!&²òB{zÂ:ýŸFºK¡ðî°t0þ?!ø¼Wÿ’ÖâNA0ÿ`uõ¼Kä:{ 6ón@R[0=ö«äµŸÊ` m>‰.Õð≬Û(U))íRk Š¢kxÈTFÕÈ<•åÁ>úˆ?²dꓨd®³·máÀ.[½8:{gØcTýnm­Uˆ—@ù8} ìZ•>å`°U¾Ndx,Žô˜óòâÃk6ÀÍš ãW«ò[]ëòì¹Î¾€¶@:{ r<ÂÕ®Fxçp€'q b”åÉ'¯ÉÚÔQä € õRF9²Þþ8†óê“'qü æ›@„m\3ž=×Ùóë,œÎÎA¾q˜ï õµÇq\ïZÌøXò¹fMýèZ‘å3žDÁ^kÎ2>ë¸ðû*#™L|¼\gï€Í¼0]«,[ž7&£¶˜_g¡töù[®³G°™w’Úâéìó·\g—¶p`—­^$}þ–ëìlæÝ€¤¶x:ûü-×Ù¥-Øe«SgŸ'Øs}aÁqc'³Ë ­»èðìÉ–"»˜òó’§³·ïPcr}A,Ã:»ç¹Ä^¤t½0ŒôÇ–Þ]Ës<Ÿt)¡)ZpOüyxó•s@Ÿøß›\g_4Ë´3Øì‹¾œä?\ûEGosÚýôþg¿æ:{æ-Ë:û ÝKœê·SÀRtyv‘Ô/Îm'tœñ¹ÎžM˾Î>ÄΨÙè*^LÍæEÊP—þ"×ÙÁ²­³Ô­Cöêwß^4#¸[v˜‹‹{Ö'øÜ¤ËÀÎuö¬[æuöaËóó³å³Äž]´–iòuü¸‹“ëì· ëìî ÝK>Õw/A^¸)‡’$‡IîR#ÊuöÌ[–uö!Ëðì| HŠÊLzœû£¹Îžq˰Î>P·¶#uÃ÷ýDJŽÏÂÖ£HO)²ÃøU®³gÚQIhŒ:Ñ¡–ØNÍqõTiãØÓï9AÃa3ïL×ê èç3_†-ÏÎ~8R¾;žÏn\ ×Ù³a «³OaËV×K‹|û²ƒ¼òÿl-×Ù3b ¤³O»ôÝЯ¡‘Ð_17m½dfã¹gÏ€-¬Îž|)"ÿÝöï5§&¤‡·f~ü\gψ-Î~ }^øaÇk?¤g~(|›}ûLÇr=C¶€:{âeͶÝ~ÍyàÙkN¤ÌÌøø¹Îž[ }jƒò"Õîø5ÿ‰–N>Ëuö¬ÙMPclÏ$ê2¾nå:ûT°™w¦kµ|Æ:·-b-½ë}aÛ×§~üœ³ÏßnŽÎ.j¡3Àƒã»×®àð¹Îž»Æ:{KçöE§.Òz?öÀõ¹Î>læÝ€¤vctv‹8{-¬õ­_jœû=×ÙÛÂ]¶úúêì-¿-\7í{Ÿ={˜ëìÓÀfÞ ˜®Õì{²¡‡Ïj);tÄ› ò¹Îˆ8ô\g›y7`ºVÏGú¾ kéÜ,¨Ûýzz<ŸnÖÇÏuöŒØMPc"±½ÓéÕgi¹gÏ„Ý]„Šz×ì%~’ëìÉa3ï$µ¤³Ç»mœ½6ûÃç:{Fì&èìrµ;þîn®³O›y7 ©Ýݱ_ï^Oß=Èuö©láÀ.[}tv¸ð°ÿý8ê1×Ù§€Í¼0]«Ù÷dCŸ™Î ÎÞŸ?]´sxå:{RØÌ»Óµú …ï+¶¶Î-Æ­‹ëfs|;×Ù3a7Aá¬1AçüSꥄ˜ƒj5bíWÒ‚yÿÐ)ÃfÞ ˜®ÕöüõðÙ/Eد³‡]Qî¹Îž 6ón@R»9:{+»€4ùœç FjÌl-×Ù3b×Xgoå‰ñmá»í¸ud µˆ…DT{®³O›y7 ©Ýx¹è|m±w—*»•ëìÓØÂ]¶úúêì­eè†øšú7ý/Àãûa®³O›y7`ºV³ïɆ>Ëeç÷´ákEœ3¦6óãç:{Fìëì-cÏj‡ÝkD[;™‘å:{Öì&¨12A»ÿ\! ŒY·4ý,&:†ÃfÞ ˜®Õvtð/Ùµ†BÀ›ËöÎ|í3[æ:{vì¦èìa MC.’G?.ËlWc¹Îž»:;}`ý®~¤‘ˆpvùbr=ƒvctvÄÁ,Ëò§¼Ê Dô¯JçÏuöLØ ÐÙáW Bzv~Å¡2³Ó×s=«vtöÀ- ç(ZÚúÅÓç:{6ì&èì÷(Ínkî3e‡å:{Ö,‰c…Ñ\ÎýŽFÃÂ/És€N½cç䔞y§ÌTÁUi‹Ð>=ñ\ÇöŽ=«Ñ8uB‹>zrrê6NB7Á‘“™ÅŒ¢ÝC7×ÙÀfÞ HjIuöÀÂßOÇÄÀ]Ï „Ø(™Úºb¯(/^kzÕÔöTCc3Œ×üh¨šfêZI±…RÖiÅ–‚˜ëÿ©1ÿŸ‘®Jî±o·—…8'Ï ¿Ž Ðe,x{ù¿§Nj®³±…»lõÄ:»+«AÈ[ÙÒôŠfjEè¯kú®aì ߻&–]'°›ûb…^jÿ=+ÝáÞ¢ÕŠ,Ÿ…ÎMM•ã¤w¢ÙÅÅ[úkÿF⢠äö]éåý¶"žëì“ÁfÞ ˜®Õì{&­'JžJMQ‹ßØbs‹`­iºNäK>ü¸´}8vÍ ×ꎡ’Ë'àÓP-+§žÄ5êf¤kK?-ÄÅùYäÍ/.΀p¶fÇ—ü¦¼zgמ\gφM®³×1ãgtÄÔÊJ(6Kä¨cl€2=Á»FÕ$þQ€ÞÔÁavp1˜Õõo„(ðbV·=Š,%¾›ýß¾õ$L_wÏuö¬ÙH5ÆucOéÙN£Qs”’©ª¡ëFÑ0b4Oj¯÷4mO3Ö•ÍRI¿?iÔÈã5¤V_ÿÚ™ÞdÅj©õá ü<œü÷©Ÿ‰TBGrø4u÷ܳg†ëìuÛgÕ¬^¯{Ñ:ås¢çÐY*pÖÉŒ8ŒIdFÓ1ò…Bá϶Ý¡½Ÿ:1ÇJ×n©é„wq~ÁhOx#ÞX• 0Ú”ëì#N×¼ÔÆèìFƒ~sèên:ŒÝ°å9¡V%Ÿ®j‰Á¼¯Wé£ZIQ¶Mm¯R¼c}çœ~ïÙÞeýh͉ÆEƒ©‡sPxÔ_ªñUSKͯç:{Fl´Î…nh; ,ÛÔ9Ý '«˜I¡N^.Ó$o¢ÃZ5Tmýwß;Ò‹Öí©umº>º˜†f²soνU?c9a8}{r=s6Ng¯Û'Eh@` 奦ñ€‘®ïîqOJØáÖ«P%5½«ñ¸ŠßÖÁÛƒAùÓ'_ò3¢(=!Ô{íL“‰ªëå:û[8°ËVÕÙ]Ï{mÀÇ)¥jõ¾s °æb˜Iñ®jÚZ9ÒMÀ^%2dVt³¤Ô1¢JGª_NÏ&Šž)á=©cï4þ(ú1Aä“s} -æ×£³{¬Çˆ®›‡Õ*;hòÊG•äœ]týï"ÎÿJ±+ÛJO-:cÛQ|g®³±Åü:#tvP˜zÝuëÊV›Ÿë¬›k¿‚oOHc "톼RŒjUà mKùÑu]dçrœé%íÈw^’À´ÏI¬§ä:û°S4ïL×ê*B}Ó1ùõhØ?]Sw4­RVì°î\*2Š©Oïü‹(ʽLߨž&æž= 6\g÷ëÿa»ˆtÏ>SA^’÷IG{zóPg§xÇÞeãÉíƒHcìLéĹç:{vll<»Õ8ù}ãØ›%“ú’i;v {T ­¬,÷]p¥#Ó<ý‚k‹Yrß—·\gψÒÙ]dzC£`Ò'1d&䒦ݡHO§gûâmjç„Ü0ŒŽëìý¶p_gl<»å4̶ÛÜ2ŒôÑ®;ªºG¾Ý e,Êt:¶íÔ„H÷ô ;”1üiÔIÍuöŒØ¨xöÝ‚P^qÄׯt3±®>Îö÷M"íFÕ,+Þñ÷N0µ® q‘ž_Î Ï`ºTœ{®³gÍFéì§ò_TQŽÚ¯Ô;¨ˆ’ Éó—V|{x;Æ,¹kš®ãl^ðÜì\gf‹ùuFèìVPØØ’!-†–~ÿTÃ(B yx©¨LŸÁfFg^\RoÏuö¬Ù5&ÒÌ瘺¦Æ‚KcS§ßÙ(abé–¢”0¤ª¿ÞCˆ‹ajEF/x‰fà]‰fúôᡦíÉ IÕ¨êe“³Ý%JŠQµÄ”ë2ŠQÆÚÚqÎ!œ¨ePÁ©™2wv'^¤ý˜{öLؽ•MEy¥þ5‡k18‹ÊÇ[ã-D¤ó<¼jÕÜ5‰Êëš^b€ˆ¿ÖŒm~UÅFÕ*î úE›Ò¥A{à©×FlMås%<Æœ½:éDñäqj#É|£vü7ÁhR󒣪ҷ;¹ÎÞwbæÝ€¤6Bg‡a#zýˆ¹áuåÙgÕm$ÇøDˆ‚ò À'bEÜùë6KE¥ ž•Zž]%_½|§¤ª´¾°IŠÊóçŠòbh,üîúß[?Y+Âㄨ]VÒkÐF~Bëàááùƒh¶Æ°/xÙðG:;a/ ŸÆr=#6Hgé¯È³£½¨ln½R½,¸œHƒ|¸¹NW^Ág®(/¿€÷ÞÆè躲Qâ÷J/è=":†|¥17ê<­)~ƒ,¤ËÇžçÖë‚+•r[B7Îÿbû´ô£ÒHø5[¯):F”s½ã¼Ì»Im˜Îm9dV,6·AY0¿@Ý(]ù|@Oþùó¢®N^ýî'¥ˆƒæh’—kò¼UL¾b•º'Ü)›LŒzYŒ±ó·;ëß2o)øÞ鲈î0NÄÑ­Vn¼Âbƒ9§ÃÎ|3Ñê>;;?[nåq¿L¼}®³gÄèì\žTˆò¡äìäw©ƒº²"6ȳo~J E^úžR*ÝV¶Ð….°eÛˆiÌkÜ Ø—os¯¼„wW>Yæ Q? ÛLsýÛºhçÛ2zñ?v‘˜)××9›ã½vö€ImX®^{KœÝ[~=×ÙÛ¶˜_g€ÎÊ,¸ÄÂË„À– •Íçh)’¿¦.hYRøy†ðV‰(ŽÉlžOŠò=ÁÉñðùÏø²(‘õë1ÄÄÅÝÂ]!þà2+¯9rÆP¬ˆØ‘_sdý §ÍØ`W^5Ñt»î7&<9¢#®}úøö\gψ R·™ÔÍ #y_¸ƒº¹eèšÃw—¢N)þ²‚×üŸ ¦SuLq.Žô™Ÿ÷a]/~Öc•1âä¬.Æü<ìùs–iƒ§=šS:1¶íªÏ”ö¹Îž5¤ÆpFs²¾» Âñ•¡b¤“ÀZFV;™÷Ø™¼¬€®°Sø˜9;²˜ÊË„f]¹+6·$Ía°Ë¤§½hW_)ÂáÚG+…‚†Ç¶4=§•ïkðwkƒ=vð­W\`ÙÂN%LîÙ3a:{Œ!Yzó¹Š,ŽGÚ•}xöý.Å:®»U³B´9Tuïµ®©*SqN†ÔÉÅ£GƒŸ‹ÅðÓ+¥ ;¡}T9ÿc¯/Fƒ½Ùì;ÿë\Œ==y<ûàó2ï$µ‘ñì–x¶eTxðÇÔ%P ¸ 4ëºÁ3IYCĪá[U •>³{Ô‰cîâi鯰dbG•²”:qµÆüÆØ~ÏÞåÜÇýìüL„iämÏuöŒX‡ÎëÂ~ˆ|å¾R&”c Ÿ0\…‡7*è¬îšQr¯H.Ôé;Hrjò¨(ßdDÄuLZdªS“u—Ò#ýADè;Ò´„ÈõK àæ´½ÄY4³büZ•˜F6Gõþ¾Æ)‘ˆì¦*y‰\`†ôâýT†:¶++ÿoêGHw~o¸~Íâw¬ÛŒøn]`=‹‰È·"ªÈ‘ëìݧvÞ ˜®Õ‘Zàt,¹þP(GA‘nZùàD; Q¬.É7#^UxLQïUPÕh÷Q(@¸íßµ!¬à¾üû'@ͦùÒ¡³·K›Žønm°K|7»¥1z<êŒî}Ë"¸|þ˜\gψ‰º0«1%{…¹L½+8ûi WÂÿžÔÌ£Ètbä{|pŠ<¸úèC&ç ·Íx´´wV«Ün]‘ã·ǽ ±° u‘ÈgF=Ö‰7ÓG³ç:{ölS ¥Î”[n¹zHx=Œ:“ÚßÀÅk áÈSGþÚ4‹&¢ß9¹’*i‹:oj_¾¡üfüfËÉ#»¹þÛe®R&óG~<Êß‚ûåX6+ŽlËɰ.û¬“n{&Uö\gtçÝ€éZ=PFTвõ¹¢” ú¿’©M³ªi_hðõôüÜ:S—Ê~eOÓ19ØÐ*j“;t Cíš’Ÿê¾®)ïú®Ýþš¾Càáé!튻-µ‚€Õô°¥]ÇqöH>٪О^º˜Ág'g|bæÝ€¤6Tg—±1rðŸC{Ëë·WijçÏ•eJ)݈–áûË´Fy®j€ë³Ò¶òÉ;J‰]z¥¨ˆel[¸'ÄÆs9¦Êe¶Fü»!ÑN¾¿øí±Î"héµ´ŒVþùX“³˜x¨UÜ›ÍYg"=¨µ2Lo¹Îž ³ËØñ»›/ËÊç;;2x ¼ëʳÝòü•¢¼ˆ"_0üŽÈõ¥TVýODa….ã%m‡Kfý6_[¯æ­O–ÿJA*ìï fIA–öÐó<ò؈b—mŠó·€Ëû¶"¢<ûÝÆžR¢ÇN{+üø¬ä:{—-Üך7†}§äìˆqÙÚ& ËP.D¦o)··#èo3d_|A¾þÙ–¡mݾÍ÷¶9´ŸÄ+‚ÿ+L飽âïàñã-d‹ãßc¶¿­ #üIƒü7uAëôé(¢=ÊßR‹î;ÈÃÞS',};;–e…ñ½®}~r}ñÀ.[=Pg÷}¿°It„ý2ž0¿¢|¶¥¬¬(DEäÚˆÆÆdìšV¾ƒ¨l¿ñôçLß#»óœ¶}!'~DaÁ%Í(s âßc!’ˆÌÿøW»îÿ€6xùèFcº1öeœ=-Éç.crê Oû]»‰Ç³÷Ûb~ayc,bÓäw?×Ì8,Ú:Ø6‘•—/yòÆ&<ûÊíÏv4LÀãÐÞçèhn‘g×ÔužÔ~kñΑ"º@îì 4ÚÑ‹Vü{4 º_Vüº%çóŸžpD½m×:ôöjsu þ j½V‘Da™Ä">'ÌãÙØb~Á:;Æ'7K˜[¤«’³G¾\N³C|ú6¼4‡ì–õ#ÐéåÒ€}ÙÔ%¿/Ý&_~›|9±~Ÿ¶Üˆ¶–ñïP+Q×c[A2ßÇó¥:ÝšµÔÊ-yJü“æ3ò›ÍVÄcÏÞo‹ùu«1`ÇÜÙ,iês†§ˆ"Ò;ãÓãÙJ(Œw0›IÜÝ|^D¹-œ±Q&°oAÅ‘`ß&£lEªÎÊ_c`jKA¥:«_÷haÞrœY\8]õyê§æ yÚÓÈâ›ëì±ÁùÙñ? @Gñ¹û¢?>]û1ª¤Üü¨ªH¾‘Ô Â|5Öäe´cÐ)05wè³Qt0R$µ”ôºµv®ë}_žû´õaoO®³/–ŽgwNO©WºÂóPõÖ(g|ºÆ¹ÂP Œž™(õzþšÌå–ÌŠÉ£N]„yD èTÚQ9ô‘ÃôÖ×9³´öSm€_t˜É[¬ÊXÞ_>?;KÕ·S/à\,;íü—±\gψ ÈãGêpX^éîŽ_fO|ºaV1GIÿ;-’Éy²]õ¿jGqð@….tl ®Œgh¯÷ô]Ë£—àèGór:È_•е§Þ§ûÇ:;t"× ûul?L1;»<-¡ÌZC ÊãÙŸy7 © ÕÙ­È»ÚuKl– «ZL6ºxŒªîÀ9ÿ ÂKÄO̯Œ]K¶ï©Z”2CÿBm…‚©_raI˜Ûð]CÇôukp>ôU™°Ö»žkA- ÏyÙ\w]?¦TajQtÏÞ{~æÝ€éZíÖ‡}ìñì9\ðÖŸÎ,dONNE¸ãžºG—…ƹNuʆ ZnVeØîUÜ"Ð)åŒïû´ÍÞë=C«ëßøÒöÔ7µýúvoýS;о¿Q€²‹àwµ'×Ù;Nм0]«cVܱ$OÉÚ0æ ±ÂÞîbvƧóÓjµ  s¹Š¶6TŽøÕx¶ª¡Uö÷u}Ç8`Î5Ý£°_ ¦Œµr0D5ö·½¼@V±v´—cfBM9½—ÆYáþ¥Ì1™Ç³:AónÀt­.ÞÒ—}[ÙªQü¹ÙŸNýMÎ: £iU•cÖ£i˜ÁÄÔEÆFšÑeÀÙ}ù"€xÓAôâïÜÅväCoåÌèÍÓû~k‹ÔâÄ ãå:{Ç šw¦kõ‘ã ”ƒãŽf¡V¸|Àô&ëþÒå bþ¶® V{|iÕƒ‘ˆsÖe’säøMÆzF{»e‹‰Ž¡¶˜_gxT7ôNzÝ…Ï«ÿûŽÓUò—KÔÏ“`§Ëç׌õoÿP»ŒžÝ¥Ç'ô¡Í®'êñë¹ÎÞ›y7 ©«ƒj[šçz¶³,6·5­²€\d›–³ô¦wíf4 •ç¯jŰ=Ïu/í?¥’c‹å³ó3ú—´«zÖD>v±,jŽõSŠn=×Ù³bÃë Öëíù®pôÕÆ‹’"B¥¬Wö´HX¿„g7ÍŠÜ á~Kñ~ó¯ÇèL©gwèGÐÅé ’…†5[t6d{§ÞŸëì`3ï$µquP½cÖ9rêˆBXÍ’i\£Ç`gÃi tÔéàŒ½ß Ï3ù²k68K< z.³ÄtŽš^¶=¹Îž)U5D' . ]h‚¡­Ä“è.y)Π<Çĸø?Øõ©ë ú=þ”¾ÿÍ ~Iu¢Äa>"ùevtZÒhO®³gÈFÔA ‰Á¨†j;5Ïc/«]sÖcê"À‡‡E™öÚ&¾ÚÞ÷Nù¼žm’#“gçŸc ›i‘zpuÁZÏomIëyÔa°™w¦kõp™ØöœÐÿÿX…“y\<70Žõ2ÔÊ2</ùU0iîj¨»TpÓÐÕG/a<ÓI’ø·ø•Þ2—3ãÙ¡èñëé?×Ù³cãtö~ÿDÎïÄi–P>Õª†yX4Œ ùë¦VÁTŽVh/W¶6Õ£ ;ò}ôE÷p' ¦þœ‹·Y;vŽXäZ5ŽÌE@ßv¹&ÎΖ©.ÄÙ¹ù˜é§:bÚm¹Îž®³ÐÝ­H¥¡ßb¯÷‹rpiï5bM˜®_ýZ‹)ºë•\é4DU ×m)ÐSëØã–~Ç<#–W„@EUxrßµý° ìVT£Ÿ‚®žëì¶q:{ß’«L‡õÆÉ‰Ãý¿»ÂZF ûURj{ˆ†sWwx.B!ÄHt¬Àú§ Qq -{Ø›3ˆ…µm¯Åþþ§Z4ÚÚþ_GŸÊ2×Ù3b£töî¥ëz5ZÖëžçûÇ?º>Ñ¿ ”8ÜiKãN*ñt™¤W7w9zLÓ‘6 Ý×’â;ߟz¿áÌ_—ÕÕ'йíH5ç×\GÕÅJŽÕ}Œ¸’Ó‡—·´gqü\gÏ”ÐÙ{—Þ1ø­gg5,øgú#H¤äY9®i-«ÉÐï– “°÷¡€ü}¥øÍYy¼·´tìaãväUm‡ãÌè93xøy'®¦*#„É÷§¨«ç:{FMŒ•‹»tìÿù? -ë(žÍ\Ä BÖ; ÌPßR„øi©µmz¶B&1u™s·0›¦ûèüë)°Ö_=uø_Ú‡ÏuöŒY5f˜É|.23oQui-•”eº–¹00ýðÞ,uì¬[îÙ3a“ëì£õìx¦{ô¼‚@Ü îCýð;G7g©«gk™ëìÙ±Ä:û(#oY?# /”ÆI£vz ̓è¹u"ó¾ÜTËuöŒØä:ûp=;R“=<€ë!í&?B¨‡VàþPë3ÖÕ³¶´s=;–XgªgGyfjõÝ?5N#°]Û9Zó/5»îÚ¡õû'xõÅ\æ:{Flr}\¹¨ÚẈ´õPš™«çþ˱gG9af©«gmiç:{Æ,Î>tå™áÚ¥5ïØ;… o{{^hù.rá¦eQ—¹ÎžK¢³³XgAvuÔʨŽEÑu_ƒ×Ì^WϘå:{Ö,-5&·Q–{öLX::{¾Ìuöl[ª:{nÃ-×Ù3b)èìùrðÒÎuöìXj:{¾Ìuö…°tö|9xiç:{Æ, =_æ:ûBX:{n-×Ù³f¢¥‘ŹýóeªKÛ–u6çýC§ ›y7` CÞ}ž«WHžåË—fº.":FØÂ}™¤Ùž7®ýžÝYN¿÷£XT‰ùÂúc$Eéÿ)†,,q!¬~ä,@B÷yƒÂ‹/r¯˜¿z5àýÔý⛓¢€Æ[$Ž>etƒäX:?_(¼8W –%s`te‘då=]šy……óóF¾@Œ0ÿé«áÆ=M ªä±'erEY‚φ#P¾òžF`ZÑô›¤×Có…ÇÉÏqöÏÎ=%,© ·È®T(¼üåç_¤ÞôÙþè³~§äjÉY*^``Ž—ø÷” 5`I®¼zþË/Ëä󲨅ÏþÑ Ÿ"`õ,ïcW'‹Å9Y¦9„ŒÂ (“Ï ¢³9÷Y‚/ÉÈðù” °’ Åh™Jv&x–Ì Å¢ÏSÑL;°ŠÒ[!R9xj¨˜çZ˨'ùUÂ|@^¡˜^xþ§?ùÉó(cå?÷Âg®æo¨.4ãtýŸD‚¹P¼=¾¦}¢+ø$¬q€tóâó?ùÉOŸ'q õ3/|Žk"J›Såhàòz*!¦?(¡ª6¯ËD±B™¨óT²ùùÇ‚a£óWe nxõÅÀ‘K¸*΂²#ëwEIáîVðTM|*öÿfU\O#d©Vç߳ƃsO&`Ð.î_óä’/ÌɯêOþà§/ÃSñê'>uµg6›gÀ"#Wœ6gØT ‚x¿lÄûÉO]$ÌŸTNŠÔßÍìDf­ðòOÿà'(cI¸›¿ú©O^-š&- ºèRéÒŸbdéZéW^*D±Gurß*Àâ2IÕS–Ê„8,•@°¦z”Õ,Añ”€aÖXjƒGG÷  ëÁƒHÀ::Ò²¦|xp¯/bŠyˆëéÔ ÀÊßÈ«/™€•/¨Ã¨ÆÏ£@P,bµ‚ŠñòOŸþKsð»i>oT:vѹã£Ã#ÓHš÷>—÷‹À>Ôçk0Þ?ñΫx™­NkÅ✊”2O©8*#`¦%{ñÜ—žþ§/K&œƒ¹óà?¯ëëÞ=Öa ÅOʃG2¹£bñèЇÊ8 p£X<¼W HêW^Õ…1M#6J”4Ò6ø’ŽîÁ[ _Ðïdsý¼Dù‰ÖbÀºáÿ°™I&! bb#$Ä…Èσ蒇ZÊSÉ!±ç¿ô²¬çÿšâFÀ Ê7؇GsE¨·¼V(tùŠ‹Š7¨ž©ÜE¨ìä§X€ž¤kž5Öx/!‰Š2,˜QÈ<÷ÞÓIégHgçžLÀ*ÎoÜ¿Wª€yÀ*¸ÂOqNvÐ9 X_ž“6Ý”,°ŽîÎÍÍI椯‘ yÄŠ£#¸+Øø^vªèx|À¼~t÷Ú5™ɇæòZV¹Wäù]·yÀÍ¿"kN²ø sã@aÑèGÈØ(=‘Ò{Œ[GGss׎ÌÝ¿«ÌÉè­ˆ#Y·s ô/¯ Xtç®×«BtE–‚: ÷æ°Í°Nó(Ûák¸}ñKX¦/?ÿ"h›W?õ‰«!-›ëÚ]™cЩ@º-U„æÎBöo¨È Å{X0©νø×²/¸a {ÃÝû×Tm«j‡(ù¡HîEí›ïî}ì|øžûbQ7?x?h™È\Q¹©ŒíO5œ{òV?æwu'[&t„»È©ó…¯¼\Œöò‹ÿì¥O_¥nê)4»(kȬ×X×,¢ACÞ_+ªnEzˆï§ÍxOXAˆ/Låèœ#Ø€ÎÅE`Áúg/¾üüO_,¼ü•Â<ä r@ZZjYJ 3ssË5 DÈÙVˆQîߟS%׸VDèa—¾å¥_É9”yÚœSºnQÆym®È{©T(q™æd™æÌ2ùj”ëèþKÐî×p)%h&Bø¹‚ŸHvΫÌù{Ïñ&¹äîËR)$H»Ez1‘£ûj‹Pmq‹( Ï‘áúßáýk²lÅÃû÷ ×ÀË5ˆáè ^9Ÿ÷¡IŽŽîÍa=AÜÔ! xLOf5œ{ ÖJXòî‚—ìf÷ ‡wïß+ÂXÚ‹/B7+̽ôé?ºú‡ŸøÔUÿH!)wîî‚@ýëú|Á îRb“*Ò½# _¼/„âˆXÖ;BqãðHf©øU«Ã»wæ RMœÝ#Àš3øüÂhš”Fþðê!‹'Š ™ï¤6—"¢ f@å(oáèÁƒ +Ê^çdÊÅDå-Д–ê wïQc?:XJs„u Y“Y‘2Ò™(b¦(Ó§ÿèjXÂÊÀ»Þ—±@Pd ád'˜»'õE©æÎAÞ»/{Ö—àE³ù<«}:ò¢„sè î¾ôÒJ‹/É?ù‘µ’‘|ž;|0'åòklŠ@ÀºÿTæ­xWJÊЩî߉YºÊF| äÊ{ò┞°÷¯ôÊœ"çç“XìÏ5œ{ ¨„@ †#kÜ….5'Yûþ}©Û‘º)Lt¸ú™OÈnú¹Ï¼pÕßÿ @Še˜@ðÁ!Ê ×ˤj$™ ø[>sR¼EïUŒ7:³»,ù¿ßÝ9ø>ß“’‰üfK.¸&K%¿èGR’Ÿð{, "sK‚/ÉÜŸøÌU˜"¥Ç¼<°ÿKÕ D‘¹»Ä# ê!`„—PqÿîáÜý# /GÀôÅüù“å¾{P’´¼°ŠXP_Xg p>@™åED 4×$ŽÉ’B~@Ø6Êô9,Ó§Ã*¡’uèC…GG2ÿ2ÇwQZ‘îP&ù{·Èu€…3¼žPôE*m|ÿîäô¥kœÛBQB¼Á¶)h^› ù~¡Äwï’Jˆ¥?„{øüA¸CR„ ×îAœ€làv¨~¯aO+>…JáYãÁ¹'ß(!~¯®Ý¿Ë:2Jô ä`Óç‘Ñò8ôÿ‰O|ò…Oæ… „E8h¬k$©2\À3D9G¬Á2»Ž·`Æ{š1}/'7ŠÅ£» 0¸ lAêÄ(È8🃂ŠóÀÜ/‚Eû³/|æ_ø$–ψì,ö9ÖææP±¹1Oò”†˜ì>°%(Ó¬bƒ?ÐQ)ºDåÕibk(Öe«ªPsX¢C*—î––²‰FñâϽð™OS™†&NáñÿÝû^*2Ù"ÍÝÿGJ9w‹Eb I‚œÎýõó/B}Z— ï›ðÎýÔ3 Z‹(]aŽÉ>R¶ô#;R¸±gÜÅ¿¢º×%W€…v+)—Q‰ñcÄðqΩqŸÌèþ[F`Pm1: JZø]½OÃ}ÀØ$HÆ–ŸlùÍþlÀ†FaÀ9Ìe}JÚÅ®)ƒ4ò(ôr¯6‡xa/*Þ(¯ÇëÁM9‘zù!²·’´€Ý](J#ÐÁ? ø‰O@œWÓŽŽÈZUµï.~ëçÀœTq%,fl©b¡âÆ6A]¯q=&*/Ý E %GÔ¨2P©:½Æ¼/Ðh”i–}öu™òÁàÂ`TÔ€uíJ ^E%ñˆoð< Q@$¾‹cd‡¢ñ ’¤Pê.`ÞU ƒª\±x ¥§9XdãÕŸ{H[ÖœH×¼?סéÆCÔg@ÒYãÁ¹'Ÿ„|`HwA0!¿«@óÔM¥(1ßìOúgOëyX`r˜kÅ5´å‚~xÿ%°ð›*?ìs<_Äxq’æÕp¼ÌT`ãL±HÌ6“û/ù:60М&yºáÜó_š£ÎýYÌÀUœB€ïòyÍÚ×Ðæöì.’Ñæ®IHB¥î \J¹$8¬G”Ê^º8Hy °Ž®‘˜åIX`qyu!h¤ð.›‹Xe‘ƒ6“I¿txTú#’-pêèWÔ&)7B™ò¤pt_aHÌÝ¿†_­ˆâ ‹4/ #Âóº'„YgÞ=8B É?8<Äi÷ÀdEsËî=î»È"C!€¨2tê?ÂÁì…þÁ=^(À˜ö®{GúüÃýƒO½·ɨ'F à¨@Ë=V.Ò@ñœX¸ø à yÐ̪§kPS]¬@]´ˆ}–⼯ç<ÀRñx€GûN«²ùÿˆƒ ü‡jZlǼæÔPzA•k~žæ"@¼ÝŠjifüŸ"<!»=(P~y¢ªb¶Â àŽîìH¢zLZ^–y©RŽ8æ"%U„:¾†9âÂÝ“ñ? ya7òÆBõ¨¥êy‚a€ìy5å¿#Œ»pdŒéJ¤‘€Œ#oEî 0_ŠâáV™t1ûN+ñfNé)YvçÉX0÷_ø) 5W¤@¢,­šÌ…ø¬[ž6ûÕZF=ɯÞ0Û[ÍÃË›¯¦IçÀ¦"¸‚O÷(o‘­q¥Å|ÁŒžÆo¨TaŠ÷”ëðë¯TBš˜T,ªKᆿlOŒ[,zoÍY™\UG- ö)ÐDؼ¿ôÈ˱æ .U$y,„ÙPê†ÊœWõ•çêÀø1ûª‹ÐLâ6NAÇ)ȰLÁù†Z „‹¼ý}`Vé œpAÏ×½aôª¼Y7yœ}vƒ§õ©ª8kðIØ_õ Å °ú‘oñ3®üÈS¯A>-âvM¼ÄÁœ‡M“ªuï­¥õ<Ík^1XÓ\=WôCºË@€sRÌÓú½²ó¢‡éòE¼h¹¿ñ¨yÊX&Œ#…y¶EÄ"þ €R¡*×â÷ô+/-WaÀBNœ÷f|R©¼FÅ|AÏŽ‡ü ÕŠÓÑVQc©úæíÍT©æ}ó§ Á‚²-ŽçÞÀ¥E´ú‡™_¬HÀòj\§Ž…Õ%Æ.§ÖKäÅ5z›<׫¯ðj‘WÌ{ëˆô»§f;?X\¸³ÆƒsO1;Žö6ðО7ª(* Ì¡¨‰ †ö5]UMÉ?1Fæ9•Ø<®ÉCŽú<âÁ¼^ì_Ìû÷'ÌsÑ êÞc5??ϸÀŒøž§ß"/î)"„ŠW^8 ¤SŽ ·E³ %ÆÕ<]Ê<ªP ʧ´Ìn>4‘’Ì„„¢.Š÷‰ºÚ°æ*ý5Ã:SŽúC¤Ó6÷Ìxâ¢/w(³‘p‘÷bÈS®ŒåÌy…ùF¿*pƵS>ï}aK¿ÓO‹9"Q>£žX¸¾×»½q#á¼€¢ÀnÐ× o ç±Hç$Øgq1¦V4Ч³Óà ¼¹SdóûT«nUá \…|DؘòtšQÕ—çÐÅÈŠ.†p±o˜ÒN°š¼å‘ySH—÷Å«Á!r‚oÜÞ5Z2ÄKÁ€Ð¼Æçÿæýo’RþT¡Îš0·gçž"%¬|PÂöQ!âîUöY·¹™“b"­ À%iÑüÕ=öç&2õ¥ Ø1p5%¢BŸ!·¨ "x<%ª_B:k<8÷”š“QF=5”VFeôÔX¶].—mÛ¶ðg~ÊöF¹/a8ø•Q¬Ë{Kþm`¸uÍ¿^[c2…ò¦cSØà߆|/_Û6’ ]6ý¯­ã¯¥ÒöÈ’iËœ,¦K''–NÛÂÿ*Cº¤*©\>9ñ\,«Ì©zéëÛޟΣô!ÒŽKZY¥P.SÓc>mþ±Ùdo èt~l¯ÍÔŸ¯á|½‰žƒ}Ãp³¢úŽeFeD•–e¦Á•€þ,Ë¿™¦?}‹º±qQm€¿V²ÊÔîÎÎ=€µF•fItXæY[KTãªÁ-àjnb ëÚƒŒÏ¶c8{Í‹’ äšE°ƒ¯•C]Þë X+‹ ð³àÞ•…•ùgº.KŸ±´L€…5Nñ±<žNd··Ó‡9Q±¹÷ÆçÍJ’y\+§H °Ê‘ÙŽ%«Ï³¿ï}4øyϱ=¥oF¹·¼›È8­žýëí¬ñàÜ“°¾€=wûîZ²>¬ËÆ.ºŽ`'¥#`Eµ.|áT6§·á,x `§³hÿÈc!tšx·+KK ¹$V-{îü—P²lËì³C„+(„Á†xE)ûD.+ÈÀåD¼‚_˜òÚŠÁ€±•ÄÑêéǶýEõä2+28½gÁÊÒ>£s⵫'°EHKJº6â±¼@ƒ!µ •V?2«_—Š&‰l_¦uƒr’/‚$Ÿï5 ¬ˆ4{åQ©„+ËJxRàÄRcÂX_ÄZ! S¶ó:AšFôþZJ&‹ôÌå—°R†_‹TÂÔUæ>©F[©¥É£èSmúΊþMOtÔgçžB€e­V*ö*\U²×°¢BÚÞX¦ˆõÖV«µjeuÕîX|·nƪ»Ÿt]/GÖ2ˆR+ ˆ8€I 6¡”µ°¢±Œ +­¤/ÓžäÿŽt‹ýÙwÌG@¸èŸC`¥Ÿ}Û2ìJɨ[1þ­Þ¾Â*dûôiCÄê™E+œªƒX\kõ¤°„U)MUV«õéze ú^£þ/Cæêÿ´\öËEQºeuv|6W¯~qCÖÚzÈŸV!W]>%²2U æÓEÀ’–éG,.‰=Ÿ†ànÀ©>È–-ðÏ*Ë_üKÃF݃(M!è‰~èQ¨téÑ̇öß¿ÁX²Pvò  ³o›ùW$ÅYkäÏŠ}¦*xOîôBØÆ;NÜð¯¬Õ4¡^EæœóÇu­ ühE?*G10T[`õ#°6*U)óÔJ—j•ÍÜX©:x•€UŸ.MW¥”UQKÆ·¾Z­¾"%!vÀëꪔ‹jW>_*å6kòümPêøVz“ôT— »Zš©J0¢ˆmô[ùbeóR(—`10ꡞ”»z‰C+)ƒ1xPð_ ]Æ “b4¾êÔËeïÑ̇°üo{ó”JÈ“¡,!dÍ¥‰XhÃòòo$í_ÞŸ-áªÞûÜ °ü>¢1ùãϨ‚¤È ¯Â…þ8…­è·–ç8 þk ëÑûÇg ç˜LÀªÔgfrõÒ•+¹ÍÉúÀ€e¡JX)Í–¦6¥”U¯MÖK33õJuv¶Z™š™)mnæäµ^ÏI¹êXõÒ4ûƒÔåÛé\}³4-ogf¦¥_ùWÏMVW«Ëå/Vá}õ‹Ÿô;{ù€¥pKÁj)¶`ÙBwÎ!ËW„ÿŠáù£­ËÇS6ÊwÛÂGÑ×nC€܇Òcª€e¡J(x˜_-m ’T(…–½"òUÕ4¹û<À ƒ€åöàø1Û ¡œ1Mdï}ÙC*À«TÌŸB4ºZTåA•¡,tTe¿X¢C?ƒvûäøß}ó½³F…sL>À*]–R*]©×jõY ƒÕ6Vu¶TªË8&$lAt3ÕÚxi³V*cÔ¥Ò´¼©­JÀ¿~YâZ鹺Gé¯:S*áÛº¼ƒ°Bþ®®«RÇ÷UŠo|ÅÖ‚ õTB Lb–AD•Phè`ÇZê X²c -â„T–´ áÄBÉ@0³°B*¼ïº…`ƒ~A‘‘-Ĭ¾Ÿx X€@šsÈèb•\,dj’Êü‚þ«ò UF= ¸BË,Œ€ÝËe¯ŠðQ¦Ë€¥+JQYå…ãÂ$Ô`÷Y°lJmË‚²(¤PÜ3, XÏ€•fŸ<úï_ëþ(±bɬjivsS¢ÀDmuµ6 P¨ÿªIw_Q¬I<™®n^¹~EÑsRš€ÙÜ|VÆ>~)Wû*B[ЙZmF–D ñ1‰bÓ®àoó3S[E•ÐÀ—zýÇ7-JÀZAÙiÅ“°P¦ZF[ö Yò¦ù>€EÀ ”ˆ“®Á'ºeïkÍ€e1s) K¹DX£D?vaHä8ÒW -œ~ l’DP<©Èl>#µ–Ñ„Ä#˶É*„a ”Ò䯥<ØøÈqY^ü hTX¦„Åa•:‰­hEOV•žôÊÁlmÏ4K+‚` þ5“ÖÿÖýú›ïxÖ¸pnÉ/aå*)ÑLW×mù[°$mÈ.úJM‚•Ô K32®*HIUˆ\—`ä›KR«­Zk”‚J3W©ISðVâF!ÿrµ¾[“þ¦7«ÕZ]8¾\M‚WäЀV €EHµ²àÃW2 «,”Üo¥ÊÜ1,b-a1Øh—5Vq,yû¦@RE`˜jöÁ†ei•‹€ÕöKXD~ «lHX$!±„¥0ÈöKEt_V÷–‡V`¡àÒ¨mMy•⢙ì‚ÕX?Œ›DP¥BúËR†C]—ÚÏ $µ”÷¿qûµŸe"V™G_©O~qu²^Ÿš¬®¾2Y_-ûfP÷%)a­V'k5 +SµÚT}µRŸ½7#嬤ՌßrYÙ«µ©éQÄ3+㘿<;3{iìòøøåK³ð3;{yüòØÌ øzvfftLÞÏ^znR›¹ty|bb|\z½<1;ó‘Ë~}ËÀ2’K—/Ëû ˆhæYé7V C‹Ÿh‚èÊB¶@%ZšÅPÃ%LÓXçLÚ?¯úSÝËqKÒ KVÜôOËDݘy™VìCÄÊ(?P…žÁªñŒ’‘Á¬‡Ð³ÕûäÃGoÜþÞ£³†óJ`Y•’êX‰+} ¾¯Të¥'KõXÀ T+2ÉC†yª—L¬Ä+sS!Ë[šcñÿˆål}3ÔW%y€•NEõšFÒcubÔb46 ‰$~øvo¿ñ^&bE“©®ÃlMM•Êê€2íÉÉ:Lú¤ÀfLÕxª˜ úRוžá#–æXj-ar@R "ÌÚ W†ŸŠh~¿Zü¼fìhK§È5ÀÒk +%©ÑAã°ÕºúAÖFÄZíN¹ÛH"bµcÀÅϼu»ûà °¢)zñóéÈŒ"Àdëˆ+ôàAŒ±¯õ£·°ÚŒ4INCªS¨„O°¼½ÀÌÚŠôªÜd€•œz–M[ŠÀöo§Œyã °ŽØ=xëáY#Ã9¥lÇÑŒ2:_tüÞ·»ïd"V$e€•QFçŒ}ÿààíLÄŠ¤tËq\G“ëÂ]éÏ{ãÒ Ÿk˜Ø“á«·åÉ‚J,W‚|<&QšýS:}^ÌR )ûi×] Öÿm*íxšÌŲÑñ»w^¿•Ílˆ¤´Ë1°hgg‡o¶\M;HÛ’À« Ç‹agK†B_жÝ~Ôp` jv&Ø­ÁË&äÉÝê›Ç%‡ÒÜ2jHVIDùU ¾\ïsÑ/Çñê×ñ×uÙO… „ÁR& Õ÷mŒŸÁêa+µÞ@€uòè;Ý¿Ê+ŠÒ,nl†¢@.²½½µ£PGšƒÝF…ÀŽÛþŽãlÇö®`£;É%¬¤€†ÜÇà›^÷ìE 7šã AÍâÇ¥Àp²šd2®ú€ÐË´ò?8`E•%º®·}}à §Á:æ“B¥¤oaÄ·2”›þÀ¯,ÌÐiÚㆬãw^»ý÷ÏÎ%¥,a¹;Ífsšnggw××z’%àÁ–ë4[­&7¶Ñ Ý]éiG]ÏC’1`õõ±¢K1õV²\<&9NoÀrS¬ œ"sÀ‚˜{ÕžX½s;¥Ï­m÷T bÆÆŒôþ›·»?ÎD¬J°šívgo:Æn«µ‹í©›°Ùw¤äIíNÓì€äs·ÕwdÈ\ˆ òÚ¯ÉQò`ÀZލ…¾8eÐòò¢V =•¾‡é)Pe8Ñà~™õ<¯ ]ÙŽÓP.!e\q‡s:DhÈq6°¾à³ØÐi58“úÁ{-³loë\æ¼WÈ­,•¢³Ýð`Æ+»¬‹FI0nÇmlaŒ_ GË­ôUr´|µ̇ñëè· eÊ¢L¦>`ÿ¸{ûÏ?8kp8”6`µFÆrÖ®¤æd§¹ë87woå8ÍNndª³ë¢äÕšžjJ™Ë¿í­?–Wh±fç™‘ß‘á›øüËfókÒ7È\ÿüŸïþ2‰e{{‡ËÜ ögXÑ‹ŸŒ­üxφ…€%d‡ú·1¨¥cbÀ‚t„Àþ ˤ…L¼!€wè-±¦Õð\z‰À‚àƒ¦‡Y X*? ƒÑ…RʵA «^(Ð%(ew\õÁj@†Ýmzî‚Õ’#Ìœ@ñä:::[Êß6FÏb3– À¢ª—WN¥_¬.o£Á¯µgH¯\$®5¢÷îܾõ3+LéÖ~{²£¨uófk€¢Î^çc» yíHR’ÖiJY«énÁtÆVn¿Óú˜ ²òÈd­Ý¦ôºÛÚÛkí&€Txúl‘¼2ÀÉÚ†%{½ÜhÈŽ(!»¿34ÈrI§Âþ_k¡X]«0Ë8‚Üt! K8n p™€%¬¨p§a±H¶s(r/ÿäÚ`U´aŒ³ܺTGósƒ$l”Ð0—Íž`O” ɰ®äzL [Mp ’_™:»¦lD¹äO„pɃƒ(ªz‡£‚`…ᣫ@Q]á›ñœ¢æ'ýú»Ýƒïf Ô:`îw:SíöÔÇäU"”ŸöȈ„$·ÕiI°úåîï"`íwvÖÈh§3:Úiµàú5Ùš9©6v:ígFrФ¼6"sS-z¤ÓܰL4Zðo‘¼¢‹¶ù[î«#â(uH±¢GíR"'®út+ù®AO Å&.m‘̬ ßxÅ aòÊqÓ,×,.JN%/‚‡åB‡¥G_¹äNX"® â(øf)‘¤Á© ðè¨TÙe“Á ƒîˆŽT“¢”†« ÏQ©2 ¾PÇ©â¸Ñ‰>üù­×ïd[%‡)} «½·7²¿ÿÌÞÞ3íöXûwZ‰W_Økl·Ú3-ÔÁÝ]É2{ãWr­›RÛ•ÿÛtmnoƒÞ8ÒiïKœ’ˆÕjïí·¥Žù±ö8Ä’"TBØ"™6F^æÍ°ÐaÕÄ~6`Q'ž†1hLLRmÃ1<Ýù!¹²±¨¨ÄGÅ´‚䡲'Dì',6œ‚Ëòòš¼<ö(€!Û= Áìy¢Ž£šR cúƒ@…Ù®BTURWùIJ7\/—£ •wW–é³AµéÕ¿“>moÒ¹Xÿ$Ò÷Š$=WÁþ°ÆŠÖ€50üã0€f¥‡ß<èþ(±B”:`IÉ©““€ÓåpLþî_¿>.«Ù‘’TsmX°öÛX°™ ] °Úûû¹v[J^Ri쌎tÀ«Ó¾± Xdwd{7•À•ÐÉÉ$, ŒÃ,ôàD³óñ¡,Ç,·¡T'aªb â,%68 ƒGX;;X GU›P`¡AÁLµÈñ ƒ}:Êzçªg,(RFü2Mø\ø¨h KG.°—P+:&`íìÞ`)©S €7-Ì2`y˜å!oƒKä ôIóÖñϺ·³­’Ô6`í¿ºŸët°F°Æ^}u¿å‚ìÔÞoO5¥ZxÓq”J~öÛm¸îK•Ïm=³€µ?ÑFØÚßo·åÍT{b_Æ’@ÆÖ*á ){Q[$óÏ²ð´ÆØù 4S‹«!„aÌp‡!b‘º¶³³åúáD¸*]%Uyo‰ÝÛ† ‹„ŒÈüéy†J¨@"­1`©ü(8 JX n1Ü*ÐÐZ-É.^ö<* XŽcêgBËt.՚М¾m—@,îÖßÞFq–K€ö.WÙ ! 6Â3Gi‹† [ÈT%äž«(Û*9’R¬›ñëW¤Œµ¶©}Ð ;öø8X©¤”4ñÑñýÎÞTglVm´\Ÿ±‰X`­’.ûk·÷¯ÀU†”ø.ãݻ٨Øotש®èÓõAªdÍêwª,6ySçnõhä,Ó,ƒlC£„Ê@Å£R,%l+ÿÊwt zê©1J( ÓN:Ä–¶L)Hds¹ª4[l[®Re=–1ð¦$! d^ÍPÒÂEÕÏe°qÙ?%»­QÔñâRVw5 +X¤r]mcsézûµ¡ ³ènDéÎã¥ãt²­’C”.`ÝÜ“ HLûšÚì¢Üԣ馽j‡W¯ïGP§u3AÃ7`’xßq¿ä´´¸¸˜â:“A8>t÷ÉçüÀ&bíÀÔÔt§aé¥É¼‡îœP~üsΜ@¸äéør¥'N‰Xº«G«A†°Þýw²…AJ°&s###ÓÓ#q„oFé6àkz]FG§GÆÆÇÇÂas“0µÁGk°=Ec w-%ÖÞ~"‹rŸ $ °¶Ý¡¥€™gÀf=~MPN9Çz~Õébzœ .Þœ}°Nþá탃l«ä ¥¬î6[©ÐÞ^„c³ùË$]ªÁ*a/ÀŠz×Ë?*Oî ’Ìã¤éÙ@ú1„ù> I³1L¹‘а™Ÿ~ÏQe ¾O}ÜÐF|û“.KìãŸw_ão3³»ŸÒ6º›,m|a z£.˜‹Mq&ŒÑ¡’jƒ,~NJjË“ ä 3†3ÄHÂföÓÏ2\ζÆâg¢‡ß>ȶJRêÛ˨XQ¤)¹}zÑP÷ÃzRØ^,mrŸšý°žá‡âlÉä¦ãwÞúû³FˆsFÙŽ£et>éø½7²­’”VFSʶJSº€…'üê“xË|Ú>Ç;gƒ76ÈͶé¼Ï7ù‚m¯—ËëkäiBY_‡c””ŽÎ÷>v:þOÙVÉAJ°l;úH¥5ŸÆ´nÁ¤hbà²Õ“ÓZÒ³-}€ËnðTU:ûyŸVÕ–2+‹ Î~¦±|Çþù˜M, ݦ“yÐ{„ky ÿ~_ñ'ÙÇi|ïç§ãw^;ȶJöQÊ€¥ˆ@ ÂÅC>-Ý×PÖ²‰ñìÈÆUàäÅd£z¸–øðR XŒM+ê—g€®0`I°˜ZZZ  ý+ÄC§“”@­Ûù’îÁ< 2©åÆa‡«,(”Tl¡ÖúI–ËAVÜ› PÅ„J§ €uòÁ7²­’}”6`­VkÕÊêê:IYk$rqk¬Wà`ùÕjuÕþêj¥²¡å0_k³µ&}olÈ(­ÛÖ RMÀ†µ¤1+¬âýÊÂJ2À tСâ–¬uN*(Gx'È6I!( a¥‹\ ®©ì—ã ÐÓÝê“+«ßmXÓˆ·þVô!˜"?"åS ³¢ `Á̆oe[%”.`Ùåêìøl®^]Õ-‡R”…œW™ªWÊÒG©ºZ­OËû/( C‘>ˆà®RŸªÀ_9V‹§Ð~X°Îya!bñób¿ÅÏ`Ù¶7äŸ-d©DÙz¼£Ï{v[› i An‹OBy„G?shÿ1¬ä³˜ c™P(ècÝC‘ZFöË&žeFø‹£Þ[pcó÷CØá„MîBÕ{Ëðg@’Àø,®kÁñS] úÁ†±¹¸œ²Vå• ܬ@†“P°NÞ»óú­¿ÉD,Ò¬Ú•Ï—J¹ÚêF¥ ’_+•Wäus¬T-KWê¯.—jÒ]þ¯V«5)•­¯ƒß –ÐV¿jWK3ÕjéYðU_•ðk9~‹dcÇQÞ˯ߒC°'Yа ó ”‡#by€%4÷ ňB±ž~Ôz¡…O‚ùOXVLÜ&`!"Ã¥X™}а%°D–ey˜&‚ï9¬°¼ Û‡W» Û¨5‚5.0`Æ'ëƒ=¨25<×¢À?AþÊ ˆ^#G2§1„ëäáÛ·»?ÊtBMé–eUgKu©èÕêRl’´¹ù‰Sãc9¼Ÿ•*¡U½„p5îÛJ³›õ‰’,^¾š®­²J8S«Í\ª—®\¿€•ˆÙ×`FKX ¡GW ÍP(,`ÙÈFÔ3 ¬áIY¬– 6öXL?’Àe+ÞלêaLîl‚e9]扣Œ>‚r¨PŠÅ(!´ÉÉBWK°pÈÖ;†Ux®z›±IÝPü¶Y ’„=™I¨°figKxF2­öiXójÖ,ÞôVÙh­) XÇÿ!Û*Ù¤´%¬J®$U·ÕZä)©Ò%)"Õ¥ž¸9 ï*ÓÒaTJY¥g¥³t¯È0¾ëliT‚S¥žÛÜ”Ð%eµ©º”»J§¬EÞUtÁ§š{º÷S C€EýÑÒ¦¢¡Q°¬0`(?–YâùÅoÃb[ްR,eì¶4ë CŠb+UÙÒOBI7D X}C`±ÙŒˆæt–¹líè^=BñðqP¥bX ÌRÁ1*Øl#åQ”=4«›+Ý Ö ý# X'd[%›”2`­W&ëÛZÝÌ=71-QjzörI‚Ö¥Üf­–›ž®W¬²ôQŸªÕ¦êµÍÙ±\½>¹º*]&+ rõWä} $±µòê?•!rõͩٙZµ>{YJXŽ*ã•0 ¸{p”p%É´Ù¿@Ÿø`Hh¥ÌâÄñʦCŸª2 -s*ûë•®žQö®²•Ò(¡Z ‚Ù·l5©ä$ýçKÑ|ôØœV±ÔsÐA_ùFW‡*7 È–smEJ¤³HP3\•w% O84ÓÕÒ™0 ú”“äm®øNú©ÕÙ…îKp-•Øý#¥M<ÜÄ8äß&ÆW{ÅN: +þ´Á% Ot³¼¼¸Ø°,½PæÔ³l’w^˜©pžD¤ÔÐà s(®OîxÅ%HM¹5ËxŠ'Q>­FjXšØª^Ũµ¬QK|V9d³xÆhÄô\s^ 5× °Þý¯w‘é„LéÖ+ÕÉ™Ùggfff/O\º$¯ã—gg'äeæ#—Ç'Æä«ggÇ&ž“>fgž•.³cÒmöÒ¥Yyƒ{ù7{ùò%éqFŸ¸4vy\>É(f§ª«<~Ö—Ð辸°²äŸ$ºÀ—ežÅ°²°ÀÓÜã,O%ôuΡ/ÍÀŠž¥è秸Б!BÕð›& #`y 7Ç’Ýú­à‹r¶bÕƒî1Qš÷~ùÒòåÉÒ9 Õ÷&Ù ÙЬ“GÙVÉ¥ X$Z …`:ª°V`á ¡Ñ²!NÁÊçe¥zkƒK‹>ÀbŠZø˜6…ãù„oÑ]hI\bðê‚#oñs¿h=Vï3¥ÝòŠW\ßOHøôùŒ]Ó˜¨ôâÂÐÚ)¾£(À:þy÷àw3+QÊGWi&(üù©â¹U|o+a¿Ñ¯+«‰ÇˆQ%”8µbHVAa ÷kXé¿îÙ¬Äk›Öpn†e,ö6ÕªÄRCÏ"?§.aù$ÑÈ…Êe=hÒã$E¯ô£´å3Ve6UKß„+æ `Äg…š 2ý( °²­’MJ°¾ Äl­›j·–ñq»ïÁ?[…, Ë?µ„ËßŘçä€5ÔE„eX¶±ÜŒ4©Í+‰3Ú^&mÂÈõÞqº]„y¨Å[z™È"ÖZÆy-+cXô ªŒ•OÓG"ëøÇÝ×ßÊe;Žf”Ñù¦ã÷ß¼m•Ì”VFszôýîíl«d¢´OÍÙ¡Sqèˆpã8×»Õ® òêðá0½ÎÓð0“•0Š–)‡êã'vz ŸõîêÊ U„ñõ">WlÃGªá©j©•À;C)œŸØTÜÞÏqg)¹æ»~ÝÈMèϼºôß5BÅŠh‹Ák3’­>|7Û*YQÊ€µ¥ÎvÛÞÙ¡"ùpº}þڎ믹Í'²áÝû‘!ôI¸§Ñ:½ò±Ò*¾ü4âò×èñ܈ñ¯Sèã¹õ› /¶F¤¿F´{(Ô`çÆÖÉ#Ø*9›Ù”öAªf'eÀ"XÚ–Fܰ­[ÎÛÙñÓ<¡Gùf#s9ç—…ä,˜':¯¨ËŠ÷º'\-,ê£ê·ŸÄÙ TVX “#¾ºj„!½lQ5D7¾³¥S>BTUßè ñÎIaÇ5 +×TÝö†ªèØüPû‘ ”3s‘°N£ƒ£ùêø[·ÿU¶U2PÚ€µÓlµšŽ³» m€`änm¹òÙ%À¦Á·ÎÍ›pÝÝýã`¹¦<&Iúãø5>\$`-ùk!¨øé÷ý6EÐâ3’°†~6°°‚Ìáø(öÉ` ³æ¬@ô©F°t ®ôÄ1þ}Pòd€òöv?éê´õ‘ƒ£ëŠÛÔqcëäƒoÞζJFJ°šv»ÓÜmµnìl»íݽ½]OF’ow%I·Þï¨fõ€ ¥+x„°­_Bøä "ðzpVè–9¿aɯ´Œ^¤³‚ÓOé¨úÓ+©ƒ° #ŸgVñzº/?NQJßÎUñ5Ø ”Jù(ÿJŠÊO|ÈX½œ°\×eÃW±ßÂåº^Õ‡l‰æNrD¶zHX0³áö7³™ 'i–ë¶F&Fs½öÔ^swä¢Ý&ÐÇöv&H^M)}m²Ót?ɵ›;Í=y¿Co@6kî‚4µ»»#Ýš(YIœlŸ”ݚ𪯬µÃ*ap?,Þg´çÉQ« ADÀð'²#ŠÔ9E“X Gæ—@EÐU>Ê+C>zÌü!]zó‰X,É0ú!à&@ö óy¢ëN<øì 'Ú¿ð;¨É|ŽŽpÃþÔ»½u¸réêU½àÊÇGÌ•£kßmà5¶œ¡ö`Àr{ÖÉû߸}ë癈•¾„ÕÙïìåÚûcí6ÈY»»­N§Ý‘t³)]nîɇ¯µ$Tm»ë×;ÍÎèh[ÂQçk7[R4“eˆ=y½)%µÎÞM)]í6Û¹&ýI—øÐLkÙòvÅMGAï“°´âßtÔ·;VcÖ¬Àî.bŸ­­$rpÚÞFÀrGˆ#€m­I˜…é­™EsHN=Àa Kâ¡Kœh0òcÓKX˜×õI§z´M» €'ÔP%¿¥Bn{²¥ð$ž¼Wq “£@M(YÇa7h.L€…'!%wWµ¢£…(ŠjBæ`<4¨Šeè†àöP-ÕF)b¤òü¸êÕ€u¶ãÆÖ£ÿ¹{ðï2³û$¬ÑýN'·¿rÖdgOþMv¦$Öä¦öþ¤“›kµFÚ-¬vg|\¢Ô訔ɞéHøz&×i¶FäýÞÞÇZ»­öH«ÕÝÛ•ñ´GFÚMähì\½kAHÙH¡ÑÊBï-’W–Aö™¡q¼`Î¥6%Ýð¾îÄœ´E2±›K JYucµ°Ý0Âk‡fež „’å% “”‚L‚T³‚€A8ƒ5Ý`)󬣮‚¡ÈU¸¡d".½`¿„$‚>5T‹òÍ©X˜PC&Ÿ; GÁ·¹«¤P Òh(wª2ÇU}BšC‘ ³¢‰7޳Ž~ëàÎþÍYÃÅÙSÊVcoüúÄ3RŽ’ô ÈYÏt~goo¤½ÿL§õ1)m½:¾G€µ7ñêØþÄþx»=ÚÞm·G$píïKI*W)©µÇÚ¿Óú¥ƒ€µ?Ö™”ñtÆ_}ubÏíÝ'Z%ŒÜ"yÙØ"9æ$ R ©+;f¹=lÊO[¨2` (J)Eq¡á–K„ ã(T%‹©§m°\Í‘B¤¡*æ£id¬Hyÿ¹4ê!o¸\ú?‹?„_žw£¼Ú³€ˆÞ¢êp»©°|m˜òª`ЦÞ#dOÂ&V`…ÕãIX„¬.\Ê(µ‡–{¬Îž€uòðíƒî÷³C SW ÷Æ_Ý—ò€ÌÈþþ¨†c íï€Bמ¸~¥C€%e±î?'!«ýÜå‰1ùC˜× ùëºM€2 ^OçÊõëãX½º‚,›ÀÉ‹¨’ª¨zë„`Q§u C5Á#`¹°”"â2GÃÇ„;¬ :dP‰ÍL1q·•„¥!ØI]%t•€"D°\W¶@bè@éÈC\4€«gX^Tl Õ0¢¡Òp•„¤‹å2†&áÅÅ® ‚"È)”¬Kò–£U†£ñLÕ²p•BέÒ8…„¯ž¿Ó=xóÿˬXiKX­1‰W;-„)5`µ÷¥Z¸ßεÛSí+¯¾*kºÝrw$$·GÚòĦv`I÷ l»’ãiO¼º¿ß"ûÕ7r˜Uú–gÛÚ†µÒ°XJºC3ôä×,ŸŒ@6?„ª±„Ã.<¡×ñ Q é•H©„†%,°¼5\¥[ù|¢1ˆ€# a9´¢|ë-©iE×°¯®-\ê´ÑY>m+(Â+ÿrÈfc Tã`£Þà*?.ò •ÙÃè~ròÁ[·»ÙVÉiÖîÞh»ÓjJ(¼v{|¿==R–¼—¿ûRBº"ß )u=§ÞHÂpÝßÇ{Zú“ú娏TG žýËã£{0K™»#ËÕ€µ¼¸¹Erx”p!`±…{*¡VÚ(eö^5†§¡Œ‘+ÍrBC˜‹£WÊâCªQ#V%ô‹C°i'=ÀrL•âæNNÌñ9Õp††c¸‚BªÁ9,d½òÆìPÃÝiDeš„`ìÐdU^•éŸÕíФjvæïž ùí§l{Gõ@YzF9¥ê>ÍY›4Ý30ýÓ5çy¢…«áeÑËž7ã)bâ¹òš§Þ |”iîhwž¯ì‚D;”ó†—^oéªÉe¸óÀ%åñ1ê°`}øî·»Ù‚´k272=3:2==$E£±“¦Íûißã(]F=Ú{åûÜ$wÌ8f”YXÔKr"ðhžXèV X.®qlTwU¡,Uל „Ô¼Á¢Á‰]¨¢ãÑ)hVLQb¤È»û—¤ã­˜:ÜâyhžOΣc†wØ(°Åõ¢Z¤A“¼RnsÝ5¤OÂâ—g‡ê³ÑÐS,Œ!‡†Ñ¾f³ONÆKÄ,_]=ëäWo¼}ág6¤­ÂôOƒööZA{QÁ›Í]ZäãD®1Äõ~µ„Oþe2š¡†[ °Ü]ÂÍx¬«ìÏÃÓi‰<¾D;ªšCq9\ûýÂ’oA½ë}…Æê\űø Dq¾ªÖbéøÝ׳­’Ó%Œêºá¯¿«æ:~Þ27Ç5•À_Ðs€¡íe†XC_¦£÷Rˆ|©ÿ:zÔ?†V‡Œîþ¼ÆåÙssBWv×ê%û µ~ïúp¢:_l>žÀú«± Ú‹»²­’OÒß+D®¹ÔÊxáÖë½›$ì0ë‰ÓðÓj )FÞ¯< zByèÅ]Ç?~íàÂo•œí8šQFO}˜m•œVF=5ôèû݃‹¾Urº€µ§ëóGäe}mMþÚpžàÆFY„ªNVDzÛêP^>™Æ¶78–õu›ÏÝ1Nù²!.ø£€&AzÖTB•//ÿVD œøká!\œ¥´±áÕ—WoXp¿AnPÇPkð•·ÑZyãäÄ*«r;¦ý˜ÀxàXiÈ̯zïåW•Ë«W³oPxuãÇ ÓïOûÕ} û¦‡Jscë”ÓSõ«ÒÖyH”v‚úRå“uµÑ›¿Þ½sû¢o•œ.`QÇX žß§:]ÐÕo —ª¡˜‡ãŽJ²BÇ|=.-ã1_”ÅòÐhMÇ.Ó\óàj@²ƒµUOÞAª*4JÆ>Öðv‹J9ì/­šWå5+*ïÎŽH9Ü.ýk=Ž,èÿkvoþzôÛÝ¿ºØ S,nÇ`áµGã2`©pëÄö:ųÝYŒÆ'ÀZ C˜ü Â3¬²X|¶ÝipíË:kåaæwí·°ÊÐeÄ’"`•“ÖñÿñÚEß*9eÀBÌ žøKÍh‡l8„gòÖí4qt ÷ Z€³²” ²zpßÐÒŒ?ÎÓŠ<;4é¤^ þð©fŸÔ¢ðéͽ2q†u¯cOÙÁ$l»œ,²È“Z{œùl<õ+NêXÙVÉ©KX«ÕZµÖ¯¯V«_]¯TìõJµZY+À:è‹ÀiE/Íѧå,/®,è©ï¡­Þ{VôQëC"°0Åœ÷lf Ç1õý²„á4‹c)Àò"\{bGÌ™ó||((Úä,+aÄÁóü"þdg?êÅŸ\Ýë°éSVg?À:þq÷à›\äm±Ò¬ê¥ñÙ\½^šªTgKÕÊT½R©ÏÌÔ+Êþ4ijѹɢ·HŽ\ü¼D[$Ç.Ï! Àöµ!düg ®XÂ’ùEÓµ%Mñ±,»Ó£ÉÒ%‚éz¤! U„‘Ùé• Ë²ê܈`"0ÄPA_ææÐßw„z+Ê X|o•¸ bk$+Œ ~²Tþ,U×P=@tÃå¡GjìTï^lƒWf?À:yÿ¯¿ö.²ˆ•6`Õ®|¾TÊÕK3ÕÚ•+õÚLi³–+•fj«¶îxÃ%°Íýl'£’o‘¬ ÁÃV€%"úzÚiJ¦°±«b0áñ=šØDpæq¼Õ?`>d=)͉ôÚ‡$,Œ9ø&ú^ü`ö•†fÛ!œÓX¶‰PR˜Å…-|õÁ•&"ó&t$à@ ñÊ‚@"LOàŸt¤(„ŠÍ¢8©F¯µ¾€õ诺ß¹È ‡ X×KõçäCm³TªWW©A†XHz{°<¹j%´ErBÀ²¨ã[O°ˆAðKî– iC€ƒ{Sü¥ïÿ'À200ÍBiÀ"ɰ¬å.PÙ`i¡òÌnRÚÓ™¢²°Ù„áJÿ58`½X:„EÎ,ø'óCÒEY±ÊªI5PiÙÍ«;zI2`qóð'%UÛÉAû{_À:þÅ­×ï¼ûáYÃÆÙQê€5~}TB¬Òli¢Tš®V§gr5,oÞËI«„ËI·H^NXØ -á)…C.„–P4ó×/ØêѦ{åx¿ô‚A®_ „ƒ qžF$è¹äf›U%ï趬Ÿ,ï–ƒË ecå—ͪÿºƒÊÌàeùÞBY‚¤!Q6ëÊÀja ’Û†¼¦Ð¯¶`äâ:ÓeD¡ŒòqjÀúÍÃÿ;^é{øöíî÷/°ˆ•.`­­UgKõÊjM–¼+]/•¦67ëõ) X4—*e®Žc–EÿŽ£+ æÉô%ÑÉ&`IFI0Âû‡,¿üƒ¶“ùÙ®e²M(I ~×g6–NAÉ ©KX–ÊHG$vÆZdB‰ˆ44Fòi“õKihP,ò`aœe…_S?&h„ã·â†G´CQ8}=…ØÔ¸ ø² -aÙê½ú†±„Å€5(!`½ÿÝ7âà¿Ó½ý?¾qE¬´«2]ª”×*¥\¥¶+ _›“õúäfõ,kEÑÒÂJx‹d)]¡Ödžµèôq6T˜Æ£¡¥àDÉš+ÌGË/°EŠì.–'¤Ù–¶!¸[ÿ*~ÑKմ퇖° øT¼²°,¿Ž/ °Ê¾ªaû”êlÌ¥g²÷ã•¡Í‚MÍU°Œö À²N X¿ù_ouߌßF惷n¿vg6¤­V&땵òj}rõ‹“õZmª^­lNNnV¾hŸjúã©™…ŽM]ô&8Hµ×´êàÃ1øD¢¬©´EømNÆ£á"*w*2ì' •8û¶Ê?ÛŸŒVÓ¨ÅO 3ùxyÐW5Z§Fî”Iªl@eØÃ´µLµ¢`{ ÄZ^MÂçIOªöÕ¸ñÈšßñTò*JXßîv¿»+Ãñ»·/ðVÉéÖújµ^¯U«5y5þäµ²ñ¤Ë?K”ö£[ºS@šÄii‰eÈ3¸4Ö¥¢‚UNYxŒ¹a4˶uÌéf?´Ö/bZg9zÔÐ+qŽ01•f%Süv`^FpÊVT)Õ˜ª%üž{Í ¤bGϘ/ДS¬ãwßúz÷߯aÒ‡ï¾ñúÞ*9]ÀZ­NÎÌÎHºtiffv–ÿ.ÍÎLU³ÿD¼–ЛÇÛ¸/ëÉVËDËt· ìíK‘³Þ—ЯžbiLr2hY‰gן2#Aâ°JB€uä×`½ö­çÇÊx¢†(¬r4R®5„H%<þùÿtpçßÇaÒ£ ½Urº€õJµ^ЦúÖÊÏo_X\^^Zâ•„0Ù}ÜW–%X£ƒÑ€EGU¨™î–_:òLwã;oÜ9ëÚpY¥3¡<ì›Uä¯.Ë*KæKÚŠ}¶"bó!öÅZLgÅE³ïi°êÔLh¿upçç1ˆuü‹îí7.ì̆´UÂÕJ¥* /x¿å'µ4E5OaÿIÐYbñФ®Q½Î÷2”B,\žhùéI­°zlw U˧¢F®ƒë• ¦`¬µKC-Ô1áL÷@»ô¢àò?ýLª^´º‹ßÆ©¼!¥× %[.Ç`W¨„ýEˆój ^›8åéá¿í¼gxøíÛÝ\T0]À2Lëë`óñwã'FíeÌu7 9jÙ¸ö2ºCÁB«·‡°:ǃNÊå *^‰©×¾ùR€åۻ̲RX™ã¬9¥ !ñŠ™?XÖX‰2€b¸LƲ½uÆšC+”±h4]T^,;$ùQv-+ÒžÖŸ, X'|»ÛýNŒáýøgÝ×/ìVÉÙŽ£etþèøÝ7ºù«èwïËwu«ä °2ÊèÒñ;wnÅMÿèûv«ä °2Êè<Ò£üéÁ¿úOшõî¯ßúùű2ÀÊ(£óH~ðÝn÷›Ñ‹pý»n÷»sfCXet.éÃ÷Þ’°©ùÿÍ­‹ºUrXet>éøÿú—ÝG Rw«ä °2ÊèœÒñÏþìë·"‡ܽý­.âäÑ °2Êè¼Ò£¿èüëÈù£ïãöŸ^È™ `e”Ñy¥ãÞî|ëýˆC'~}Q·JÎ+£ŒÎ-¿÷ÖA÷/"€‰¶J>ëìe€•QFç—Ž~ëëw¢ ïß>8¸ˆ[%g€•QFç˜ýe÷àˆI¢Çït¿þæûÏŠ•VFgzøÝn÷­÷ÂÈôTÿ}Xe”Ñy¢ã÷¿uÐ};¼9l•ü­‹· Ð,çq)…(Ò rÒ›«èIÍuŸDuºîS8'½á©!jõ=~÷Ý< ;¿q»{ñú :±{j‚.zúÐéÑŽëjÀZî·ÑU_Z–{º?¹¢mm ¿:eÌ[CNáœô†§‰¢ëäø[w“®}ï"n•lÖãV÷¹é¢(a-=.Ty´B€µõdrÿ„k{˜) ë“Þðt´z `<úQ÷àй°Uò¿|÷¢‰X`qÍ9»»ŽÓl6wíoØEf«Õt0ïowฆ¢ºÛÛO(û¿VXƒR/À:ùà;Ýî¿ ^È­’MÀÚi@Íí¶Z»Ív»ÓÚÝí*¡: Ze³#ƒ6!üÛkýr·µ'ãrwvvOžõ¬ˆÜÍ#(àÞ{µRqŸR™±¼CÉ:ĺ-‰á„i8”2;<ÅŸH)Ô–öOÞw”´æ#íF_˜è˜¿hcàø1è]e±áª¾Õ Âq.¼‚rñ\áYæ½Aå”OèŠÝÊỆ* –ßËŠtdªÁrmãkJ£AaFÛnmíèq8¯ºžð“BAéi‡²k”Ãå»­Á¤ò8À:~ï›7ÿ쵃}ÑölðÖ®¬všíÜÞ^n:×ùÚ…¬ÖÈĨ ß™üZë™ýVs²Ójv&';»ÔèO°èU:HŽª_YT©.„R]ðÖ¢©Q*ÀrüÉØåŸ¼o 'ëAXŽèÚXwøA.SoÀ àkåÂ5½“°dˆK`ÐôˆñVåÇ€ ¨Cbë_»e.$jÒ·p¼*Æá! p·é=¸KLb?*(¼ë*7ð#¼Ìɰ[èÏˇã}‹–̺ãòÕÕ7?;Ô xXðÖqô±Kxy Ö"éøÿêàÖíwüðý7¿ÞýÙ±LÖ/[R…Yÿ1íݰN~¯{ðfÐÄþîÛm«dS%l¶G:gö÷':­½ÎT§¹“ÔÌlÖÞøõ1 zû#­½‰WÇö'ö÷ŸÙÛ›í$“×Ò!'¬J`X+K‹JÖêÞ›€¥TBÏ…UBáõYO±Bþ®N‡U⑆RJ5/;ÄM|EõyŸô¥Ìô¨&,×Ñ\Ÿb8ŽÂ/“tq[×ãµà2ºÿë’Rø†@ER˜Hâpæ¥èVÃ8z(·¢£Z5Ë™,y RQ4¼ã{JÂÌ%êQËbž¼šŒÐÏ©`xüõè;m«d°Zí‘–TéöG¥L4Ò–€•´ª}€õê~§©b›Øo|í`í$Ž/fQªe­Jàʲð9p ð~Ã;wZBƒá™ä4`)YEãËBJ:ÒˆF†-/ˆiúU“’ᔑj ÛQ’ˆ; ,B¸ˆ½uÍ2ç«—œ;‚UWhÙÊ1ÊîÅi’9ZÂò¼a…ŠK}ȯL„îhð«G ³ôõ(•nƒo†)H ß±n>€¥Á2žSß}ë Xî|üoݾóÞYcÈ%S%lI¹¨5½bÑ•W÷Û-ÐúÊX i•°é0`µG@A|ñꉡ•Ë€µâ!•°ä¬eáÙ°V{VUW}›êÉ»m`± Óm–ïü€E¦s¶àúmĤà5˜¶Ë(ŽK¯ 3ÿ‹<†0$h¬€eOvÕ–²V$,×'p« až„åR­ W(åQW¦nEŸxFînqÎ¥úuÈÞ… 8*j6­³ñLIXøÎ%ëÖ@uÖ °$:…þúà[l«d`µ¥l5º¿?þÑ+ׯ_ÝÛÝIXþ.º»7Úî´ZŠ©Ý~NÖþø8ˆkOj“ë“°X%$øR£„ Xd§QÂÅD€å:ªã»~£vzd–ß,ã:,v«¸Þ¨Ž!bv¡¬=nÃé‘þêQBŠŽ"K± @Úц'ÙšÔÐùt ë hS £~6<¨ÑGmÉò†ç¤éžm~. l®?”k ¨7ÂGuˆ ùKxz¯4YbcgGy3b:…¼Ú°Ný°{pË?¶Jþæ…Ú*Ù¯î›D³§’TôÖëß7÷:m Sf,üÐi>!ÀÚÅ(4ëqVè,)Àâ™?88…õ2Ô©¤Àñ ‚xs¦¼QxïÁœÅ„9ìÙzÛ¾¹4¥+Ýì;:¿ýì}ÞÛ0fú&Š…s¸Œ!‚v¢ã6µAÍ—ª¨ˆ£r‚¡·"êyèçvk4zÖÉy»{ظáýoÜ~íBm•lV£95bPnRV‚Ž £„`MæF"iêI~±Ã€µ= ¸ÔÏÂJ°¶4 °ÂŽºÎ5`¹Þ½X˜Ã>ŸÇ›¿Ol8à4Ç$ÙïXþ‘Ýð9aTýª0^ɶÖÎŽéÇ%5ÇÌ)¨&`QzþšM °ÜžF÷ظ!tð×£‹¶U²©î4[Áâœj¦fßüš/#6g &|r,ÍYb¸JXžJøÄ–š ; Ç7h„¦m+UÑ`ŽímtÑ,œížñ7LÀJT|XQ6œ8y+‰4O%tpB¦~¼¸ý±ÓnxŠ×Ö–éOƒYèSU' Úr྽mäâ”u©Û Ñ°NŽñÆA÷/ù\nݾs‘úvkhxŽ  Í£/qÿW,åWZôïð™ž7é@ÝKX!eeˆS÷¨†*0\ÚǨ)JÁP Ó+£TÂ)Ѥ_EÆí?¡W*zcnªÌ ëË…±ˆ¨GÞ"Z WF©ÏóPOúõÏîøþúÍ÷ow/ÒVÉÁý°TwâÎæô%mQ‰Ù)AéÓS½–Wˆ¸ÚsÓ¨T7Û+H4Å>ÒýIQ?~}ôƒ×¾aJTÇïtÞxïâ˜Ý³G3Êèé¡ß|ð݃îŸ` Öß¿u¡f6d€•QFO¿0¼ÿ°{ð­ÿrÖÙzb”.`ÙëëåòÆF¹¼VF²m.ü°N.v™ÜèÊÊŸm{ï¼÷žŸø÷ÞßÚTÂòšJеVæKŸü ø 5·nkÖɉ%Ó„Ú4Ë¿±Áe\Óañ½óû®l¸‡Öƒ~·<ÔþÒñädÃk[p#wï¯\¶ÛÆFÐüzåÅßuÝÞk>¿e&ã݆ íGmÏ뺾! ¼]“/-£<štÚä•ã çÝLó”õ'3a÷ç±ã¿¹u»kü[%¿vq¦ Xºá¸ù¬r˜Ö¼[K·2>¬qG ŽÂ¾×Bᥠpr9ž¼-’ia3Md_Y7+‹üŸwÅZYì;ÏËË.ÝYå!¤éK$:E«¯)ا›$r;èf&+t£ž­ˆÈ»Vç¤ œ*# '‹Þú¡p«ä sEº€Uà•­[nïÖŒvÔ·6>¨ÞÌ_B~€eQ÷ôh}­`Á~ìsVhJ•‚.€©••Å¥…$³±¤,âÏôÐáÊÀ²TR×OTºVÏXzQÓ$šy±zñ¾YLKyòú†ö‚1NÁêÙVVﬞxjyï-Ó¿ß»åû¤‚’ÖÉ£¿ðÍýðwnßz÷¢˜ÝS¬@õ“íïlôƒº#‹@w~¥ElÕã76‚ñ’ØE¡"ˆ @Iý.-!\­8Ig¾[  ý+Ô߇Nœ¦`»(¡ËÉŒ†$-2`À’Š-”ޏgȘ~ÒKp2êÛTúœÒ©ÂD€uüwowÞöäü÷.ÎVÉiÖjµV­¬®V*€1 ‚Á²WW±Ç|[eß¾R­®Ú_eŸªÕX­¯ a˜uéC†X÷:†e³¢Ø °LZQ×…°¸BWßÅÏÁn'ï¤G$ÃrD€w‚ßõ¤°ÒE.,Ke¿_€žîVŸ\Yýn9u£ŸXqûÅ2L1’S/¡wh*!üõš7ôBm•œ6`UŸnº^/MU°Ö$­¯Û«¿[]õŒW•©º|[-UW«õœ¼×v*m¯2:X¥>U?åe-‘è°èßËÛ\”–: ÜÛÏØ"9 Ë2fü³à÷‰Ø°l™_zXlzÊ <ú™Cû7YªW *„}ììÛùÁBøUƒ‰ûž¡?ÛWõÞ¶2–ZèLAÈ—àGx"Ô«¨Š²(‹ëš `q] Uåú­|´,ï‘ɲu<Q2Àƒ¿¼Í‘?|ÿ̓ ³UrÚ€U»òùR)W*]ÚD9kõ•JµZ­Tëõ*Ä,¸½Ìò²¹Eò¢Þ"ÙÜqTmšÜ°, z#ã…0»ÿªShÇü¨õB̞Š&Ãö˦ÀlîGÂT²o«ê²â,já©lÁR€å{Ïa…å}à„¯lù_ø„o"¢ÀVY•ШpÕCá,a  `Gl3[Ç3%¬“GiüOþA O9¥ XkkXõÒåY)gM—êõ\i&7YŸ»\½V›º<[ÀZ“€u½$ý—ê›Ó9)“ÍÌÌŽ_ªW*õ™™z¥:;>[ª×&«_$Àš•±ÉxJð®Œr–Ý£Ýy{™åÅÀÒ[» c?÷döP‹@D ­Ê ',h1È~Â1¢}Ú™áØ»°ûå þlà0+mÀ¢"Ø-- …K[BxEä«‚t´ dÛ¶ ¯‡ Wਥ:/éGÀ§cH}èÀnTqÙC1K+ô KTø(ëL˜$Cµƒä ”°N~·{ð–>øë½;¯_”­’S¬ñë ^.•¦Kòš+Í–$X]ÂÇ)ù¢t¥€e—kã¥KÒÃ8¾ÉaˆëŸpš)ÉkmüóÒejÓ¬©’¤qx'»RÀZª„Â8+Çç ú+…¬*6J[‰)©;^’Æg>ü¨˜o‘£û~âMÀ’JŒHUÏÕ*¡ Ìk‹²­$Sõ_øÁ,øªŒ¶max~k©{[08¨{KÇg‰²l7ª«`õ™Ò“ö@qZªf ù 2eÛ¦¸ËxÌÒ }ŠêL XÇïý›ƒîÛÙðþè»d«ät˲ªc¥zeµVšÝÜœ|™ÞÜ|V¢Öfu³^ºrKú¼Tš$]Ÿ€5»Y¿\Ò€%ãеUV gjµ™K‹)V5Ôø-°µ´TÉ¡H X e…Ö0¥,CŠ,‹¹^ÒæÏF°D²Ë/¦“}¥¦ÙX_–m ”’t<Îb”aáжõK$–Z( E™%¬2‹œbÁ«¬ËÃCXBøËx¶”@W6«\öÕ‰Oá<éÓ³1†k`J X'Ç¿¸sÐýƒÔÚ*9mVeº$U¶J)W©äJRºz¶VÉJ‚P®VýÝúléóã5ö3-aìYÀ>2„7m\gK£U0ºç67KÓUŒGÊ]%°Ê}‹5CÖýÇ|±¹=‘Zh›e´©hh,+ X~ù@{({ÌÛ72ÕØ¶°R,ÎJHå ‹jÐòKXѪ™ÍÙCÀÂj'ÀR2”´²°t-Añ,FJ[Õ§e…ªÏ2€ 3aQZ¦ m˰¨=¬ ` Ú?’ÖÉñÏþÔ;øëâl•œú´†Éú+åò+õÉ/Ê»Úæ¥R}jöÙZEÞ×rSÕÚÌø•Ùª|³Š>KSµøš•V}rUºÈë+`ìªTÐ]Jbk«•Zn:Wßœºôl­ZŸ¹,%¬/Ø [õ˜9Þ"yÁ%\ÒÊá[·VLk°™·-Å÷aY¶0Í.z¨Ê4´jŽaêË/Þ(!€¥›}[ž©DŒ?_Šžà£Çæ´Š¥žYÂòÆãt´¶9<‡Ñ±ùJAªÈV ,Ì…ås-—ýò›E ]- Ã3Çd‘˜ß¤4`áÁ_ßú€Pêýoüé…Ø*9]Àz¥:93;#iö¹gg.]š¹tyü²üÿ‘ÑÙÙ™ÙË—gf._–·àgtöÒ?znffllfôòøÄì¥Y¸‡ë¥Kp…—)2ùþÒx‚ÛÙ©êjìxÍ, J\ZZ4ç±/¨ ?¯,,ðëÓüóÉV籠½¦-$š×ªæÒ'0!`y Þ«ââç†öt¶bÕƒî1Qš÷~ùÒòåÉÒhEEæ{“l†l XÇûæA÷{´Šð×e«ä´«^:Õaj¹Ük6ÎÃâÓœyÁócׯ|^\XR«vúZ°z,ͲÑ=&UO$ 1ek%I!ÕÂxV¿h=Vï3¥ÝòŠW\ßOHøôùŒ]Ó˜¨ôâÂÐÚ)¾£ëäøçwn‘éêø·^ÿ³‹° 0]ÀZ'€2ñm¥t Q%àÇôŒ¥²úб—G³ J¨°h!ŒL$TÁ‚èp¬'AÞ‚ë +%–ú¦³%ì›'r¡rY7cHgŒ[½rÐÒV”ÏØÏŒ‰hQâZÌÀˆÏ 5AdúÑ`€uòëÞ:¸C°¾}pp¶JN{J=žö¾¾Ü¿ Þ64¶½Á)[…´í5s;- ÄMeðÅš[Œ”XK¸ø]Œy>…„5D §³j­Çhƒ¦röÕ®A=òeêEшMËë퀧P¨ˆÌÄ(¨ýÒ7ÙɶʧÔ4 `}øð{݃7qã†ãwº¯¿ñÞo¿+Ûq4£ŒžZúðï¾Ýí~Wå|ðÖA÷‡`e”QFç—ðà/TؽýÖߟu~†Néœ0ÒðŸ7âë:…Ä8±É8”I‡.¹:óÚóä:{$±ê·œH9<ËSs\³öü§ùÝÈñ5åêRÁ©bnÊ'᱊¹÷§’ ´¤kÞøÚ;åPT„®?ޏ"ÓÅõýÆù3¯.Q§»«ëOÊuCM“°©ÌrÇïÜ9¸[5¿÷Æíîoÿ‚”«ánm«ÃÛà@Êí-u¾.IG¯ïð±“u”¥úó^omÁ ÛÛÛžßÞ„±x[$/Ó!z–÷eŒO`s§“Ÿ£˜Æ9‹*NßÉÏЙ¤ }Á0 _ØÈLC ÉR±ï-7õ#!û[x,ž?êz‡ÊCr 7ê”iÌ5UŠ×†*BªéŸÂl»F0¢ˆ¸™¶èak+ú W8"°á ×pé8[—K•¹‹Ê—ëIG ökÇwìëà<÷è]:øëÑ÷ºoÿÃYʰ)eÀ¢ŠUSJ©ñõ .ü. D –»èdVXýÏÖ…8ƒÖ‚®¥%Þ.y~WpqyÉDŒ«å’°(nÕ]‡HÏg½7 PòªP±si€Ù¼“Cû%ÄgKë O¯\ŸÒ ùi¸úÌz•­-Ç5K1m&ë ÎI°¬ÞYÐÓÖ–TFœˆ ÙÐ¥¢ÂÈÍI’ÏF°I¦‡ow¾õÿ~È[%ÿ¶‹Xiwßô$,¯+ÀÍî.ô‡_îº~äýöŽ×U"$§_þÒqnÞd Pþú–¬Å@ec^ÝóÉ=å+€·åE>…yGqÑ q Në,E 8ió95<å+ð2Ž;„)–Ê‚ÿpúðQõ XAŸ<DûKŠUÊÍ·,L‚Ò• XŽÎã&ðà·Ã¹1d5ÜÓÖ‡ï½u€=üöíî_e€59n³³ßî4UWñw‡ÝVk—®mº'Ø&J~á7[­_’/°ú«„.5ûb`V¨:>'šzÈX´±2Uïz`0 U0\J©aVfÈè掤<Ò@!ãiPTʬŽìÎ&¸p~(èZÜ2åóˆ²l µˆE}$C•™©Áa©Zz œµµÍÝòlV*O\o*b‡d[ïÑ/%in’Á ï?|Ë¡oã·}«ätËu[#£ÏtšÎN³Ù¼é8ÍVsW^›²ÿ¸¹7 PÖzf¿éà=ºï6A&_»’0Ü®”¿n:ÍÎdþv |#‰EtÏè-’—ý[$/´E²ì¬þdì¢÷C&Ò©d~”(Ax„{&ùhô÷yHŒX•J@ydœ4eÀj8áü4°œ%üðäˆ \ ß“÷Þl á ”hzmtw G ÙŠTÕò-Ô5U(…‚jËQ-á:ä¨Þ:ä¹A÷ Je°Ú;`I¤ú³ƒ[ï¿ÿæëOt«äcLëÉN¯O[Âjìw:¹v³ÙnwZ7›¼¶Û¨äu¬-µÅÎõëf{TÞ7;¯í¶:í6øÝ•wò !öä=„ÊÉXr-)³uö:ðn;)79z·Þ»]ê}––…‰Tþݱb‰ÎÖÁñ4臂º»à¾>Dk‰Ož—:3C÷ŽV|„ò)™Y8}$AN| Ž;Íìsþ]C )‡ü Þ”Cp&Œ±BtÖ0Mƒ7‚F]¯œŽ/Ã…ÂAsa=²xÌå¤VTÃŒê‡1HÂ8xp¹¨f©<œº O˜Ê›àÚç ®÷1éEàU­†~õ¯|ãoý¨{ðÍÀVÉ>þ¿HXù}žÿÿ~0ðïŸv~üñ;¿w,c|ˆ1ßÇÙå÷5˜ÿcùôkŸÛo}\å ÞJ å(u k¬€Õ‘8“ÉÉëèh§ÕêäF'Ú-¬v§=>.Mºïµs#£# _¹\‡Ãµ>ÖÚmµGZ­öèÞÞèØd§=2"A/é÷ß¡G=IjqeAøÑ*°Er¼kiÑXNƒz)}h‡ XÔñõ%Wò‹](3|©¿ô$ ʪ“°0,ÎpËÑpHR¦"źº¢R'¨$4ºTÕB4½äB1žl Ž.ƒƒÃòŽÃb(§H¥ k„«Â¢¨§êWfFv(dP§*ÞGCPXåÓq””¦û'Dè–@?O°~óþwºoÿÝñ{wn·J~ôßüwO>üø£ãã?<9þ½‡pZ¼áGºáÓoô™1"Óo`_s›Gÿä¿=>þøÃ‡—Q¨ÃªøŽ£";þø¯xÊ…¤_}üü}xò¡vûͣߓ·2kÇÇÿð{”ÉÿŸ½kýãºîSfL‘TCñ gÉ%¹& REõ/ø)‘³ÝôJ±äJ¨Ò/cRð6@B\5áˆL FàÂERK5 ÃRØ2ú%’#Ôe#DE!Ô‰d¿ÓZÇYi¤»-{÷Îc_Ü%wå6Õ%wfîûι¿9çÜsîu º¸1ÖÃZj¶pç‹ËË­ét×Êʾåå–å4üÃuËòâ¹ÌRÇùÖåŽå¿„ð4ü§÷aør×âbWz¹ k±¿XücŠk¹u¥s9½´Òqþ|ÇR-ÏŸ¿åeY²K$OÕºD²üÀjîû«eRõÏÕ8Øi”û‹F¦d¦]ˆÑ’c‡-ƒÍ‚¦š§)X«Tƒ,Y†õs,ÃR EÈÂ4ºy9/ïAÞ…ûÏÀ‘aüò’ûŽ *±Û Œ0n,\ò¹¹½$édE4©]‘YBÉ.¸äXJ}\&Pâ«T¾Ðó)«N±úïrà9[o®­¾oÛï®®-•,BW ¬lc[F8 ð’1Ývr£z^NèƒaýZâG³N$ë|fÜrrCˆ˜b+ÿLÎÉQê-¡ŸÊ?ó%DS§ßú@ø^ßÕáþ’…DŸ‰(ïcç ,ÞáþñW¯Û1êÐ9ÐíÍ~#òªe„l]\7ú#·ÂziCð‘ÛM¬ÌRûùå•—_|y¥¥ ‰ÁW†áë4Öb €Uü¥ÛÚ:Z!|@ ÝêºÎ/ 9Ò­++­-K+íÏ>Û¾RÓó÷cwrwû𒬢 ¨e‰dùrË¡á’4MqÌù‹+ÉaIâ#ã‹õÆÓ\’º©VƒÂrIˆÞƒÒ{Uý%ÅEŠºZšJFÔ‘‡¸TŽò+¸‘´\Ï{`­i.ìd<Ôs)!,_Þ…Œ¬_óC TÀó|Æ££¤‰ËªYIa‘˜ŸÉÆŒ¬Œ¦¸øš?i{,`Ïþñ{o|dßÄ¥’ëø‰¾‡‘- f_Ê]»Îå 1rÚþˆÙ´oŽ!ýz7wC0véÞ™qù²øÖðEqü(j¢ŽüRˆãÇÅ¥#‚®mã†?~T\9‚%ß=”"œ»ß@nô’}="°Œ2‘w|J>­ `ÕÿÐwéÄÏßX{ýVö§Š–J†³aØP:9éà¶D(BBÆ1î#Öñúƒ­1ûÐÍCvׇ§†s`çS¯!'mGì±;?‡7³a!B÷f[ǺˆtŒ–ºà·®P›€ÂÂ8±]¦Ïé£zCöχß"í1,çÛÃo}jÛÄ òÝ.’ˆ5°^ZjYFyUº€L[û¥ŽŽ}€;­(·‚8àÛÒX¾ÜBT!Oš®—)ÝÒ æ–±@k¹½½eé¥ë¬©‰À,áDåYÂÞy>MJ8NŽT¸ ÅR¹2¬”+B‘CQ“Ì)ñ\ žÄ‡%Ö ÕËWƒ&E;딟%ÌH ˉMMJ ‹eMZFIë2 ®è^å\‚fL0ÏYçüäOÒQÃÉÔL¢‚MWz%i7ÆKM†º2,’Sfýå£ÂÜy@OLèÎJ’Û7“˜’l{ݽ¶[‡ìàï|xá²~šDè…‘+ X6Ò1NëO¶ýSꢀPB€%"·²6# YÛlJIôõM°äŒ~4Lôð—ÀØõݳö„°é÷Â[9²QHèƒ#°B‚ë:×6µèæ¥CßV€åÜ|oø*#øm&`½´”&j ŽèÎ8¿üìy¼J/s˜Å.í?¥ÝhÌHGneñ;™s;*ŽÊÇ.fR‰Ô½…G''X‹t×Ârm«’X®âh†'㚯…ÅŠ£8˜YÓ(@,‘ÆŽÔ¡”Æ)¾R”üóçªM øGym¾qB¹”«‡å5Û§êÕ,xþ8ž <7?ï7?R—óÌÒÎËÔAEy©ZšÊ”ÑKsU¨ˆÅçÏ-¤$È¥ü"¿y¯%AwÍ6ø}ȱ} ©=þËɾµºöέ]øn@³kÛF–Y¾Ï®FÎØ€A#sÿ:Æ€åtŽÏ;§‡/‰ÓÃD9#íÇçJèoLýÑÖÕáÓ,U0¡»*tàC À~ÑaÈ@,!„ôÙGˆ&S€å@z;oˆBëÐfî=` KÙ̽¶uÄ9Á¾¦²„/-uvíc×ÝÝR+þ¤_±k¡ ÷ œÌÃanLWg}€…kNLúõG]2jRª‘N¡™ÎÎë#3`e¤Ùÿ…n¦“€Eú)¿J¥²µ hc—˜èà0:7?_#`±Êè|u€«·ù)?È”R•ÀQ¢J¦¸ý)WÍSu ]Ÿ Þ=Õ÷Úzå«’Ø'ã ѽ¥}{nÞê}-Ê9×xg7½¶{ĺóæêwñÎÚ…·ý…_ BÌ/uABõüXÿCÝÉ‘ÛNvÔ¾‹)P aã휾åä Ö>…H‘3ìmLÙ"'RÊ©èí0ÈWRèN””¤ÐBÎåš8ÁpP¦ÓÅíHŸqÝ!!»î|1ú7ÅÈ ÝÉw#x—f _^ôܻź]ÙL¤\ºó#']xÏ4çX1øxÇŽ¯ðxìXyÈbM÷Úôì÷îæå»‹c©D×ÝF*“)6þi¤S¦9õ»½ÝמÚüµÔªÞ) n{}ù›¯\øþûß_£t©äB¡à ž#u=)_¹a»PN›S°ß"èüŸ‡œÒ4ª7T–,µ¬ÂDÁ Qì+JÝhµ†’WÀ¯”Wü†/2Rúö”{‰RUÿH…¦Ø–pÏŽKÚ™5ÿ{E.þÒð²U×3¦4£õ¥•QÃóúÿþ§Þiš·ÜÅò2~'~¾ºþÚ7š¼T²~½™¥ïä¾Vª†vpå’VÊŸ©µàfÖãv™æ×ÙÔ¾Ž%Äþ﻽¿Ü;kë¯m4y©ä¯w÷Ã'+Ž>qOÜŸ‹s¶~°¶ñÚúÿ¾¥’goø°ž¸'îÏÆ9·ÞXߨXßíRÉAùÑvÁ©”,èWéü+/oÁàœ±™ãT+³’kðÎÏÓqµkÓô´·û­eᆧx´pn;Á'Ã8<Æã'x7* sÉÜÖÎ»éšÆlKÈûóð}wÔw´ó³i•Öç¯×²vþ•ìÌ"wJ¶¬ím³†ô»ØûŸÓö6nrkÖÖÆÚüÅùE«è¯³êiÛ^ï§ÜýÑÙ¬{ל2XòÑ* Öj¹M wdåœñUÀàØ,ŸpPqmP ç=Ë¿‚gè\4Bº.pâï•( „뢤®‘²Ö`À’ûr¹›o!ø¨GÜ’Ë·•>ØÊ?=íÅp@¹ÜÕœY²ÍWãëñ8®«xççr/¹ß_ï`1­Ò­ç‚…Wð».}Õ¼{—¦ôÕkÂÙÜ;`m?üÙÚÆÆÚEÛ yäˆˆÌ Ý³”ŸxDÁG·… ü”Ó:e+ Ê(×Ba>02d"²gB–è8_a èòÕY™.ƒ"¨¢íÈë¦ÃTðªr\ÑOÓ•ËŸ»6بŸÂª¦ÒÀ€ÿ:«"b• Øú ÙÜ} ‹Ë×è'€U¾íDíî} æÞþÞÆº©ä܈>ô{ÒˆÊ:úéaýšƒ6Å¿urc}±‘ß;@í8ú@8,g¾$cgˆÜ² 4u¶ÉÔYæ¡Ô¡‡¯9¹QÌŸ ^7H5}PôÙÙˆ¡Â|3•¨/Œ³Cú (ÿšÑù†ŠX&51bl†Æ‚† –XµLòÙh7 °¨ãyËS¾ô n•yRÆO[þ‘8íKã$µ¹ª,gge¨G§”®èÔäÄøäd©ÎÎÛÔóJðwçg°Ê;¹gÉVɵoHÊΫ¡ Ã7R-jzÅÆ–Ùúú¶§å³W¬b§ÂÊîÔZeÏgumî|;µ¸–sçõW×/ü"÷Œ3zF¡Kâšn‡/Ї7s7GÆI3™\*æèQqæˆÝÌmŽÙúÈÔ¹ÐyJ-K9üï˜ Ê5lCšÙpÖå¬RjÂø–øu¿­ ýˆý A lš3Ž—HcÞàšÉ&Ñ~f$Hb5°¢‰ÙÄÌ †œž˜ö=µè §f‰™“8­ø)JÇhäß-ú¦9µ(¹züî`™tªá `ÀW€4NÛML¹»åð.:¾Mì«/ê¬ò[­7Ü)ÀâѽÃNÄU¶©ß©yÍÜÏÚôSXf¹cU쨰缇rYýÛÅOÇËg÷WP–ž ìIoV/ÁWq¥ˆº] 7þZ_Ã%Lh}*GôçЖŒí†l9"dôŒ<›`Cd,;"FïØF_(¾¦ÏöØGdsd+/úï;Àa†Ðlùæ7l,×°Cœ?Ga)¬˜Â–±Oœ>rãÉv°Ž{>¾§;…‡!»¿o BîWÚÎ}#(Êj4`%ö·÷&gðF¿™ˆÂ#{î9ùfDs]==±™8mPžèmï=8#ß®“'ãæsœj&ÙÓÓ•LDK_Úçâ¦Ç.Vs Xe–H¯²Dò¤‚‡©AC4x©äÏl\)‡ÝiA{I@njÓØ à…Í”$*{ñE·dc ¤Ì «R—aYšI»',Ór[èkV 47âTÊ£ØI-1šJªùri|¡ ¶8@3ÝÏ¢Ìl!tEûWöµ¦1»Èý$ïDz8\ÝvžéKCC«¿3X¤?ºúž"±`Ý#ã燴äÞo.Y91`…h-,4v~ðÈÁ>6uÞ¿¹<|Vøá-ÌùsÂ6ÐtÚÆü¾°`=z$ô‚CÖ‚ùOκB6Œ¶}órä,–ȆïCm¹°5S^¬œÑL[Âx|¶=ëš*i&‘LÎ0]>Ù‹ÅBÐOæì¿‰Åf€›AžÂà ¼L`V‹è-,‚K9Q`I¡»ZÅ!Ç[[Æ…®š–HveXøvÆ`iph¶Ìë„AaÒ€‰kÓr€Q#¸nöšqˆjj¦7âÍkˆsyŒ¦o˜c KE ¦Ì5%µáÔ|yo&Æ×ë/_SGÓc>5“¨KÂ[¹¶1€S{4÷(¿8"æ‘-÷Ð}Å4¾g‹Ë©×)ÀzDêB ä(9™ßàù«ì?­¯¿r[Q&À ý1sÀë&"7ìËCÀ :Ì*B¬±iœ}lÙ•¾³y`Æœ_F€2rMeJÍ äç?½5tÚ¦=¢֌Ϋ0ßL"SX¸6@àÐÇâg]S™´òÖÑ­CÀ~l <ÀšŸ!Àʉ‘ãÏŒ!¦áÖÓ±ä, SWg²'Ö×ÉXOOh©™X÷BR^lXÉhâé¶d²«+9;›ìîšÃp¬ÙDŒè¬fM)º“ÉX •R›“€59Q°Ô~ZM`¥Öt§/'P ðÚZæc,I!ÀÛ_pòëÎcE£/ºŸÑ䇿ÒÞU€…Ñ’ƒ´¡Í—×2%µhi<Ø$©=òSÀ>:ÁB=ÍZQK•¥É‡êÓÍara„3.–éæeÕ Í%¨$îÐŒìU‡ÉÏ? š,6¾„^×,$kqÙSFv6»….{÷ó­þÀݽ{OŸ޾»vçÃõW¨V™aA9ɯQ¸¾=(>Æ5ÃY@‘üoëúÐY]Œ(ø¶m¶c΂¯ ,¡Gy¾€²þ KÙ‚$_8¹ÈÐ]Ü ü:† A™æ)E8ƒò§‹AçP÷ ŠÿÆ2ñò^$r[w®éÆg0pDwþÑG›,tÀ™MtÇbû“ÉÞX¬-vp.Ù‹õ$L¬ž„TS4Á€u +=‹Aâ®d³Q„µÖ–®Ù9È ¡3³±Rl@sá¹'Qû`A*ª–%’ÕN:Sµ¾„¿°ôk.O()¬8ÕGŸzX¦¨`Åe‚¸£<6 ä* `™<ð‘åm$^!`™ |àÂ8¤= ÇiHÄå?ò’ê-™ŸïÑ»_™Ÿ‡IÝÂÀ÷ÊAJ ¹]ÌnZþ¼qZŽ{å2K¨f ‚!…gº Hq~Àâþ”xÖîëê_¿¾'÷æ66þaõ´"q”Zƒ`¤Ã<µW9BQ‘J* ønGäzìë¦æ^NÏùÃ, B)ý(,/òl-Û!›ˆ¼¦`Õ ¥ö°Ýtµ¬äÜA—ÙÙo Út'æ<{¡ ÁÊŠž„7 Ñ›Z@ÅÚÚ÷w᱕+ Œ$Rhûçæº¶zº€ª{ K™©!JV÷/‘Õ†Vtf®«ûàÜ)–aÍt&‘ž‚4sû÷w Õ‹–Îì&–°á­kG7R\‰äþ¶–ÎÖ6X&h?œ‰À,a ©NN–Çz/©zß›¥ýγ¡ÛÛ'-Op#Ç…æÊÝ‹½¾­æ‡®;KhjñÚrÕáX­Áß~5¼¹²¸š‹»T”× Íe•¿$(VÊÄhj"$s§)êÈŸ×CMÊ»4“µ-¤äЍ'— ³¼ICþD¨U·{͘¶Ìé] ÝÉøn·î}ç'€W¯Üjê3_›k°¦{té¥ÙÙ¤ÿAs8m8çÆ%tœÁ#‡òC0õЬæèšãø˜ÈZKñ2íÁ­êMLLø¡i¼2`M›—zX”^5°Ì Êl‘V#OÓïR7̬z2ÕãÊØý”ªuªÙÍâÊjÔ7‹XöÕý³Ì ‹U>=}+5›Z¾U«­¸–Uüt•ÈÛfª+:?CakQ7zº®ŽåiÍF¨5Øï­sj]*áñná¼K×XÀŠ&ö¶uôöô´>ýž^8ï‡_oG[[Ow\´µ·aØþôôÊcoæ€c‡t´u<õT[;&íÅS+ÆÁuGûÓI?ËÿÒU€ išã*º3$ù%ëîuu½Q‚°)OÓ]ª„Õõ.îΙ5k×ïª!8蔵bSî„«RÑeU\‹u4=¿US)õ¹"CrSÓÕê(²4›®MK°’#%é†hº³ù³·°{éÞÌÎǃ­ØÌ8˜Žw_¦š+’jÎHùðâý¥….*šQ—óùÍž‹s6°^HQÔ,Ç ¥þ—·*`MKýö±5©àjJETÝ2gjr@Kiº›.OÚ¼‘îÝ„OÜôÞrµšff9LaUP(oLóý]ì.ÓŒßY êâ[1­ uY¶óÍ’‹¢{+_D™Ž›®T\¹’¥5‡Xõ˜yŽ©¶½–sû\`æMOÓöfÞlLaÜÀÿPÐMÖÆ† í¾h{-Zpw_FóÀGr‡fÌä­ÃÓ‡p¦ši-dÇ CÝ0Ü_ºà-ĜȄ)'—Z†úY©Õ-·óÁ¹C¶ƒæÜvSG­S¤áé9Ò÷ôyU\ÕH.ìTM,¡I¶„lÎŒ†8SÇŽ»$ÕÔÿ°wµ¿mé}aDŒH)bùŠ£V/–y.dùàþ ù$Yæw©£|µÓ:ŸT®ÀD„ª¹ "6S À©¾6­q6\#È‹‹³ÕæC“Kš«Ý©@Õ‰PìÇÂ1N(m²Öšê<ϼììrù&‘r•Ûǹ;/ÏÌÎîüøÌ³3ó“>Çó{1„“¬¦æï]´k ½ž%BB×ÁUw ïKèÔuàL÷ðj×½(-€GµqX«ƒßC–ÏT¯Ã «½â°ÑïC‹íÊ“{Æ«kÅ×þòµ¢à†5Ͷ ÜÌî–àzê‡øð¿:0éiM…¥0ÎáüÑö õød_ Ín ™aľvÓGÒ¸”¼B½3ðî;ñ@ëñ÷û=~iÔµ„Ôb?(»[H( |_¸´|ÕÞÀ3JH1`ÿ ½×?4¸LÓn)1°ÔßÉ¥9ÏN>ëݧsôžÃ§å\í½¬ ·¼Â%:Ò-|nZº•4¾VØð¯ùZa"Ù"¾ª7÷`w"æÈÏspYgÕP`ùrµ½CÂæq¾Ê¼ª‘Ik'5Îå5‡šVU±p¤þ¯é`˜dOôׂÒZB½y{,ûváÕ¿ý«×Vy7¯8ƒe»¸™‘ëù$–=èl¬Øëªsê¦ýQÂÂ7ƒå2M—X±×†ÊƒÄì Íê·§Hf˜’å&V6׆6aÞú Ió`ôfèÃî~6ò›ãÑúÙPyˆ”üÒË ªk‹3FW(?4-¿ß>…gª³C)¿H(ä§LÓ@Hv»£€I$‘”n•–ßo0òUºÛäÜ"ùÓt§×FI$NÜ•…bñ÷šLW¾©x¥BŒ`o†‘bÖõ%î¬np¸`ó4ê$Þ_!e_F†f`†F&g´°Þ_ ‹@Þ €…yãö(je€þ¨Äû¿^£€%–QÓÒhùR pñµÈ?PÚ´ÙâçNZX N€ÞÆâ„7œ(‹1ãX]ñ Á+Ö1¡Îš’7.µµÂ¢¡\ÑÜxŸðòã'ÔbË-]/nÛîê«W75ªtPÚ X™|,w(;K¬¬ÙlžHv–XR™LÞ„#öIt¤l—™Ï2óó$Õ< ¿O²sKrš$ÎÌg ïýl~>{?cö4é47 ‡´¦yØÌ„ßv2Øó¶‘¡Ÿ¢ð “! jw¬f†„ð*´( 4Òé–žÇ$ c*Ÿüá ²h¿ÓyEäæžPFaŽ:ð“NƒW¥°þK»š¾«L˜~††R}‚ïÙ,¿­¢>Ë…^¶ü†Xo‰)Àñ7uаwÙ5ç÷^ÚÀ»¦Ð˜5ÉÊR争r`2X>lzvja*V˜J=D+9‹Áõ´"{xKXÙº](¼YrÛ…âíföi¨bo]ú\q[ш•5>të{š¸¤Ð´í¬¬ùD.–'VÖ|öûy³«+ŸÉ=šÍvî"¨Ô{ôùŒÅæÀ:œËç{MóI×{ˆ€SþÈ“4v>43{c]$þÐü|þÈ÷³³Y³+KúAf¾·—ä¦úæ{c›Ù°/6ð ß"y\V’G7$¡ðQöXâïì~þÚ‹Sn ±ÞD·H¶øˆš%¨2Yü€"‹#°aÔÏÒZí™…%ÀÓ³<ÅëÒºE[–Yz KÏ~¨íL­Kƒ'PèµKàÀÚ…Å!ºÐ´ì¨)nñµ¥ ñ[ÁÁNñþ[6`YŠÐÓŠì°œ»¯¯®¹néÅW~Ý̈ðX [®ìú4«§Êý0þGÞÖ{np)´¼V»°VkH¥Ý€5ß}9—‹™¹Ãæ‘l¾çòåÇç‰%•Í’€œÙK(gÆr¹ÃùÌ IùT 1»æç™¹Þl¶×ÌØ±›Lr@>z‰ –ËuÍÏÙVÆ……xV®Òd[¥Ä÷®Ë]¹Z\Xv]w©P|3àržçÆóÌw.®°íŒÿ3ßÖØAÆ.‘¹œˆ ’+ÞÖÈ0khÂaÃãm'Sh„ØŠÓ_¶«˜Ÿ)#u¥B)7@?IŒéi œGº£€5—ïyâp¬'gö€!ôT7,bIź» ðï\®§»»ÇÌÌm=]Äþ"qðiz¼›@QÏQ‚p]¦y4ŸÇ8ËÊ»-K†ŠD %=}5+)o‘<^=¤4•RßÀšÀ!!ëFÌ‚Q£mÝ»œx€–ˆE»9ÒS04ô‹wzª0s¬™pˆÉ½.m’TŠ;ÝiÝÅX·’€wñ›§äæúŒÄ Œ'¯šß‹…XA€Å äme(ò9¬G( hü“µ¬ÅYQŠAÇä~Ïjz·•øÞ-`¹ë¯ oÙ;;›× wüC5œÍ'ûFKnüÝa7Qr¿vŽ9%$§(ªtEt܉ÿx8¾ š)'4¤UíRŽ¿H¨Ã/²œ4´ýyB=~¡‡× 'ã—¾4ìiüp‡.¬V_ 0?ÓRNüÒýà˜þø=õÝKÇ>pã«0ç+n—€[º£€5G†}'9³ èðåËföϻЪêΙ‡À."193Ÿ± f `ã bÍ1ÂrpFFŒ½7£gÍx«ˆ!Äü2sÝfôÕ´°¨+X 3ÐØ‡Åî´gXb”ÖáÙ °< B”Ë .ÎäP_ ·¤×‰ Jð:_{„–.ÕŸµŸl)óG‘Ìâ÷Vù-,ÃÐ%;- _è3<`¤á#8žL‚ðÝyv³™×ù ½Á¹eHÇ&æJôYXÔ•ÖÒÚ®‡„å[…­21QVƒ.wÊÙÌxžûWœÊÅœgÎlM°8Ÿú÷­•“0§]µãÏ8˃°>P¤uã›§–Ê+£Nb–*¿ð‚sæ jEªÏÞNüÊ^R°6ÉÉø¥WÀ‹Ï8Á¤T\§xÆY°U`~þñŒ–²•ØHØ.ê·û—Öÿç/ãvÿÍo‰–>SttÖKdP—'Ã<2¦U®»;†VUw÷ï‹È|¼û G==GóóÄZŠ™h3‘&±—è' ž.³‡¤†¦ùÑDm+¢L3³ç1[pL¾“ÏZ€E½Scãg½-’Ç«·Hní-!¼µcÏ;z¨; YtÒ"¹lè[)fÑ®(\÷·(ÜÇ¥³Ù M• üdmº ”å½%äõ–üÖ’S‹B„"Kéë6?ŠpFqŸZ8ðIœ3Ç,OŸç$³by6Ëkyn;/TvÉ3ûK²ÂØ»?úÖÃo qB€Ko Ù»Ê}¬oÞ+¯­ÃXêíbñVÀå^¹'xžÕoûíÊN9áœÜ ¶ÓÐ&°8c¸K™mÊÍßqzЮ¸qàrîS¯aQ3±¶HNÊͨN­ŸÂážcŸ-º²üåL£ÊHSƒÌÏ.-Ùùx`٭ХЃe—P•·A˦WRç‹Hžx§—ŸÈ垺Ì!m¦œH"¡‘VX¸ä}Xɱ¤o÷+zèM&•§•Ž5X$¶Ò¤ÂfIñS=ìKš-º‹E6Ò\z>zlß!`é|z:{C(U¯­Vq4OH­{«KåIS¾ÚK­D×Ð3œ#¥cV=%’ÑI!8ð ™Ój„U3“myl°ÍåzïËLwwù•âÕßàVSo,¾¼tû8+ÀÙLyžû`Ϙ“+ „…MÜTæKüF°8:î73–Hߢ\ΣwÖ~«Úß`NŒEG¡Ä‹kë°\W-#`Q®hª1¾ÃË•˜Ÿ\i)X.Ñ_êcÌÓñM,×!^RÇknþÉC]]]±.þ!$ÖEÌ¡Ãð‡'1{Ô—0ƃ‚Hrr;*ë# ÉǑരÐût–-ÑIŽŸ•¶tŸH&ÏJPÕx“dÚµÓ)?"tÖÄâ“U½}Ó7+»ºÛ4×;¤ ¨m¢Üb3ñuZ?¯ϰªº2+†Ç龦À5îMÚ ÌO÷O‡O¥¼/)6ÂS)¾J‘œ_9ðI¦¼ÞÒ­§yk´›¾—gb7€å®ýt±p–O ¯¾^ Îà<ÏÀÉwúÞyË™Åù†?¤8ÊÍ츔šó;C>u}ó‡qÇ!9݌ݡ0äÄ76OÚdHøIœ/p~i¡‘Ö×x¬óó'Î{Ç…N`)6 Õõ­s4¤"Pzêë3° zT”Ô)À2æ2™l ™ŸŸÇ¿öJ&~Û¥™îtïѱä¬'d†Å)<«k_ML@ja¥Å¼võ¨NàGÅÖ/ºƒ<·žwò§{&C`9[ÝÞA­FìÔz{çíË3Ýa¨7…U×ñ\nKËo:ÒzÈÍk¦[^|ÊwÅÞ™ÿÂS3–¯]$7VŠ– >ÅŠ˜Û u^GúÁΚYÌݨÕZÆ«ÒõbRNØ7 ÷ªÞ«}.ñ<ãTçX*ƒÓý!|ø«ÊÊŒŸ'ŽÑ´¿óW•KêðŸãdžœ‹š9î‹Ãê;°»h<ñß §à—q"à •#ósœ2?ÓQ§;êwøêÁ»ê Ûeew° î;±¼a.[eC1òàkð-)¡oiŸ(Ö?XU+G #Ü0`»5ÈÃ½ä¸Ø¸!)Ö?Ë;94y!²nÙ´MøUñ2 Ë›céû”*²«žÂFmƒo6$-Z–¯D:×¥Oi]¤á¥©d­!¬÷¬P­ÜJ2Vž¯ÁY³Ëµ”L¿g¬H—†{~vXöíBáïKè_[X¼º^• ‚üÊ|ÂB çÌÏtŸîà ~gLµÍ§(°üBóT*Û‚­™å¥àJh¾»Ã´U€ùy›ÅSÍ´ð‚-º²­Ú|Z­[GË›Ÿ\CêÅ5'–·ž¯†öÃÚ»wŽÚé|™-áQ4Y§eo{]5#-w9çN¡xe¢Â?ª\îQ*ÇœÚóU£G#‰äàŠ»ºPükFéêr?ˆRoOX‘Dr`ÅݸVxùíoèñr¡øzé»Xõ$¬H"9°R¾Q(^/Ñå|öbˆË}?Å݇Ò#ÀŠ$’ƒ*Î/ Å7ÖÙþžë Å«ÿó(k㮨G¬°"‰ä€Š»|µ¸À½V.¯Ÿ»/åŠMgp3d—»œœ aD'$¬H"9˜â®]!ƒ@þZ°|­øòrçÃýAÙ]S?wKÃŒúßÔ‘5Œ¹$=í„D€I$R*¥(þÑfgîJa±z–{ûÅ}æçÆñ‹ÎÍ?¤¬ÎNüFyù8”ûÛ‘RX‘DI¨Tì· …778DØ7ŠÅ÷öÃå^>i¬ŒØ#kNùâé‘AçÅão~†ë‚N-—€Þ¾ÃV$‘Dqî.À£ìÌ]‡Yî7°€³yuÄ]N8”!ÚqWÞ¹DÂ+êìˆÕéâ#ÀŠ$’(0ctÁ£ÇA—»½…Mü ÿÉÊêì$>-¿CÂÊ[u;>µ!¬H"9xân¼^(¼í!Ô>¹ÜA6âewCÝtô uàcã-vîœD€I$O`ÑŸ{›·»+0Ë}?F„;í'•Þù¢B"ÀŠ$’ƒ&{…â•ÿò€Â—ûw`Ýsc‰+’Hš¸+W¯JëœÝõ+‹…µ}2°­H€õìó““ÓÓ“ð!¾ð @ò§MïìLkrv!ÏO‹t,¥ÛËÈí1-I‡®€´'–©M¤V=jI­2@ñÎŽÖdúÖ¯Ÿ†ÉI­™:Ö¯¿ÿ¯ÕöËï¥l܆ÁüÒ¶”¾Ñgw¥©N뮿Q,üB2¨Ü»…Åýq¹?r‘«V36ý2çÎUE]×ñ–·_¶ï;ëßÀÏ·µ{ÀÒD þï¬@™¾BÂKÔ¦¨[ÂnóÖr¿ `…Öµår´ª~®…(Ûóeh ‚«‚Æ÷¥i™n¦ÏÒ=FË’çhëÚâËKßõ}¨‹·ò³ä¯Ulá€E3NK½úÜäsçö°< ‚ÝÛÏžKžc°EòDr<™œ@Øj¸í(±E€k{x[ àDômR«Ù9´ºZêI$¶ï„/I«‰@ìB'}@ ñÀ´Íâ/FÓ&åß”°KÔªðN«‹§š¯ùòø4­:ªµvk¦ÏÚ·_.\ÛðÉ]-¼zeãwbD(“Ý?ÀÓÒ6 h‚ÚÙ÷®H)°&’ô¸(Æ„-$Ç´&ÆhбF€å·8;ŽW“ÂþÑÝ.ÌèÒZF2©„Y‹ °‚`KEÕ¼(­Zq‹×L§ÕŠ© TZ¸¢=I3€å,ŠWVe{ \î7'\î~ ë6ûóSSO?=uþüÔÓ­7öääÓçBrNýdê¹?;þé禦ž'úÎO=‡÷s?‹ÙRèT“{‰ÐäX²9À ü‚v·þWÛ¾ü]o‚V{‘ KãÕo¶{‡™Kõj¥5:¬6Á´ZŠýf™_S‹–Ó®†¾ M–»z¥xuI†'wýŠ4çý;.Õ>¬© GÿøBï÷¾waŠ ˜ö|K=9yþ±îÇz/\øÑ‘©ó¿ÿ£óSG.LM]ˆ®},J :.ˆTÇÆüDªgås#"UT"`)ôoR!Ï¢²?>¬iR_z¦` § O§þÎ!Ò3Ñ•Às(UY÷\ýéúàEøNy ƒ…WUFñ_×qOã+AaáŠ× Šœ5ØPU¢±¶V˜~ÚÖ or Çg‹æá‰5þÉõ´$ëÿØ{·çFŽôÐ3§¹5š`I´þ‹ýú‰ Eá)Á±ï%Œ‚+@ `všGÓ|;¡–Ï<̆wä˜õ:Âöz¬8û´ãÇÄFÌyRœ¨ç£X…Â:–Ž9êÍü.™Y7T,t·†õu³P••÷˯¾ÌÊÊTkŒ^þ"´ŒÌrë\éUow›µf½Ùlîu$°ÜUÕ}øFS9ßët>ìu÷š]uÕ=Á×87¬ü« lóÞ‡ÞìSÏ[Õ«¿ÆšeË‘•òM—j¾°«ÿÚÁllµˆ:ô™1È0.Ð0uNVì nÎ!}—Aá¤+Xj#î1ŽašˆÞ'·"L1›WL'açšv∄;-!´Whl'g½) D¥˜Ÿg7á&°~‡kŒ†Æ«¾þɳËÿxG¬°Ú½½=©=|¸+U$‰œ;p1`=jööåE÷¢ÙìuVí`ÞJPÃJsKØ·3uzêªg«p¬b­´RÝOÀ‰KÕ GµyåÒ¥+àéNõiøøÏˆ!Ì<0&ÞX®ôÞ¬ZÊŠ`>š&ía’ÈG¢ƒCª Yp´)u0ØPkuVB–šúsm ÃU†v+‹[†bŽ¡‘€) ‚,ÒÌ4Ȩºf(ûÂ]97a2Èrùæï¨×%¹þíåÕ]r«ÓÜT°yãa³w±s¿y3`Õm)ÞI`ÕšûÍ­fs·ÛÝ}­Þ=y!ãWº±D»„",m ²:… ,U U#l­$T]–CÀÖãšK—p"ìg?¡ÊôV–„aË¡6^`¨iIºËÿíS›ö d®I² Æ|G¸†-»BçƒÑ©Á]>(·–±Óru°n$T2gÝ 0ŒrÖ±­µÂ¼ÒznåìÌ–š1ú4²3Î7yõì“;2äѰšûÍf­wÑî6wU—°µZ—Ð9íì7{méz¯ÝyÐln֚͋‹^o‡€•2ìžÙUÌ?'ìT‰Ö°Œ†Å@«g(Äñ!iåtWUž[6DgZâÄB’Ý/±.ˆ—¥‘Bâ¤kX®!ÒÕ)XÃÂrƒlc…ˆbÊšŽéÂ9DTuŽ!pËd=æ‰Ã rÐ×N†òÊðPYó$sëÚ>” *_ÃyêpY‹2£d"Ú[\I2€uýÙO¬5FQ¾ýüƒ÷/sWz„`í¶Û»Íf¥¹-»qõ¶*‘\À¢yƪþ·ëͶ{Ú–®Ûªcø@*kÛ½ÞöEçäVx&s¶Í0°àGMiuV¯0«[ˆ›Û[À¢ak¬wM–â€í8¡Æ’Þ^8 X8T#œÂå`—ÖutÓ¶JC9è„5,@ôÞŒ*Ñc°€â†ç®£5,64‰çK•]%¿ø–äôd»÷G­Ö[½í“··{ÝîN¯Ó¾ØÞ¾hŸ¨™Y·ýð#÷—#!`q—ÐtÿެÎ!b«‘cZƒª€ošŽŒ#ÖD+þ¤[¼=ì¢_U釽 ÌØZƒ5Hã, »„<Þåô–P?ZTôÔ“H]2Jˆb ÷c…õºMw±ø:j tb^Ïé!oFœ»¶[Ò@…ò‘­³þ%Œr‡ÓÚ™±L>9f4lÅ\ËÖ×}yõat•¾ÿú³«Ë_Þ+¬·{1=%ͦ'+¬¯«ž??;éH?:.úÄòØ>?OÖVaØjÀ:N z¤ñDÓJst œÿߺÅ,›ü•¿%tÝ„IDÜ N²_ÅeÄŽ¿…ÐAa[X!Í8ežTBú tRìY¡AjRg¨šŒáoãÓN½„B3F¦çøX­îí´[Y]ºäOoo¤•Á ûáAã(¼A[ê”úòùئÔòÞàÑaXœâVÈÕ5±•óÑ]쓸Üð‰†PhbÌ·„YÞš¦ž1¥Ý1INKnè'¦|†l¦~Ó˜?B>$sUY¬ëÏzyùDç‡~ûùÏîÐ{XŽš8j¤}r殔窇qòýÁ£½·—èÈîJýmõr‡.a¾ ÔšUTÙ‚õÙß=[Àz1ŸaHêû"çÔÑîVåÖ–†{=ˆ› ËαÄ•[º ÄúŒi$%9¦´“d3µËlº–NèËÑØ€{ ÉŸìXÖ‹Ó°¾þÅååÿ[TôúÓË«;4äÖ°tæžÝèžÌìs» í"O>ϳbÐÍeä8ò{˜rXëþ.åžžZÀJT@¢Ã+¹#†ÀZã§àùééòx% -“ôq­eCdQ¬,û2Q”\/í±³ o¬¨Y¡§6Ôoþöòêƒøƒ_ß­!÷rÅÑRJù.Èõ¯Ÿþø£_ÇÈtýÙGWÿþ ¹—À*¥”ï€\Yc”䛿¹¼úä®|÷ R,°|/|À:¦™SË,Q‚, Ié&Éq®Î¡LÚ ¢q ‘A©0Î9’©œÓ 0U”®@ý/0…ìyR|RC –_)ö?_eJÉÊ”h!7—º˜»ñh®ž›ÉíêwÿüIdQ”o¿øðÙå¯ï’‚U4°ú²’ZC(Gù£e0 È²½Z*ÃL!ñíõ°jxýè(üN°Áƒñ9ÆÜ,ˆÆŠñ¸ NÌ¥Ë%/œu^ÂÝìl¢°ú:ÔÂRècô9¡øxiñó–\{)öu–½¤‹Ôhß¼D{¡ò0鉹ÊSV¦%ëwÿú×?¼úóÿÓõ¯~øì'_eµÊß+)X²€PH£@ª]Cl­HÅÂ&â§•!ºrO¸ì2·Å¯ŽBü /ãw°W¨aAü³Ã¿½¨\2Àòìé…rÀ‹ç‡—@¶¤Â,0ã[‘‚VŸ”°¼lk^Ê…FW×8o—£*Ù·pÒ3gÑXäÌS.‘4 ëúWzõ4I‘úo?“Å;¥`¬áx2üÑÈ–l}òê ŽWþ—#¥2FÌE6H,Ìàñ—~0úè¯ä–:H`…‰uíøéûY‹´°· .¸aÇ% ,» ™Ê­¯BòE- ¬ˆ÷… xî§z›Â• EÌK±BUÌ’e•·¹‘•G²xŸË.S?HÖõo?¸ºüeÂäÐo?ûèý§wjȽh`yÁx1Ÿ-Æ£ÉdÄE¡*Éh:yŒe£ô)y÷ñ`ðXÚñyü“!uIA´Êícò/_‡Eµõè¬Ð#À–=¿áÈR¯´ŽÿH§ÓO¡õåÒðn/a`I46îbÕôP|üm„;}᧘â Å’>Œ?kXIñIak¥û« äBðèe±=ÌDåáé"ñ컫Æn8 TŽ©6¬a}û…Zc4idý›¿¹úñÝr/XA0ÙØªÜ[LçÛÓ±zÖh¬äõéc<Æ+ÿÝíÅx0xïÞl<Oåùp<ª;PΤ+åNZ„s‰Àíwß]l+[ãÜ˪Ô%Œ®‡EëŒê%’–HNúªPu'XBýÉ„¬ˆ¢ð–¢Å–çËøbƒx”—òHh‚KÓ8Tû&ËÛ‰)AÒ…|¶ËÄ)§…Ù âSy’óNDxô:~²}6Œa‘… }Äíñ=ïú”¹x4Y¯ËrK )Ý…Ü<8¦¦3V¬ X_rùì/þ¿=êÛ/>¼ºcCîÅw '³Å´>ŸUç¨g&‹Å|!å±Ô½Æ§òâÝI}>‹GãE¥2‹wÕ©›-¤‹©<*Û‹©<ŸŒÆóúx<¿7“…²¡Å`R B+ŽÂw8 ‰¥FxÑÑÐêXKDAŒš¶bTwácóé÷óTÊÕe0`ùÐF°E¨fƒ´ =É Zñò¨QƒMùO,` €%Û_€-ÑjÈ·–!iXŸ <þ¨ß¶iPð¿o£»˜ÈÑ-…Ñx† •k°„Ô˜FƒåK$7r‹!"p|fmÀÂ/¨åâCƒö|œ“Þ€yRµÀÔG Â~KoXÐÜÀÃ5ÄY‚^ø Áºœ¢„Š$€Rà æ,ê* ¸(IE-Ü“®ÃGA(¢üñµND©dI"ðQƒ¹(ÔKä±c´9ô|~@P™¬…’ߺ„œ§:ÁPóÑóú¬ðb)Ö¤®ýÑÕÓ_%ªQßüüêòÿºc Vá󰦵G[÷¤¶$tOéY÷ߛͦÓùìÞbòºÔ¶žÔ¦¬éÖ“êlkV›Ï+óYe>ßàšÍ¤6UWG©©Í«óïM¾ôX³êb[ú³¨=y²5 –×ßOî&.‘|l-‘œ²v ±*û³‚%cÊ·—>t X ;¥ .xX*ÒÏTEŠ¥äÓÀV [¤…Ð QA ¸#eþSjø'”.ý_UÆ·¬[éÕ–m‡"¼ *¨OåÆnéèÙúª hcíŽ'A3¬ {ð¶aêAeCO_ë½+fg"°®?ûW—“¸ÃïþóGϞޕݽ´Ý%œÖžÌ¤~¤ ³1›U%²æU¥ÍfªC7ßzôpÀ’ºØf÷%²æ÷7·ªò>¸°[ò7Æ e^ éÏâá£G5¬eUA yY"ù:‚ØUdƒå}B XXK¤·Ö!xV Å]B,h^¨©+èã€Jjìd‡s XÃÒö ﬠV@úI_u£ âÂ8_3°ŒW¶ŒráqF"`‘^FhÆ/2ÅyÏBÅ É„Á¨oaìñÑ¥ƒ˜bp‡œJÅ»†ï~õóø£$×ÿp×f¹+)ZÚT%¯†@ŽÔš°æ3Ù-œÍëóùÎüá“'X»óI0”HªÍ7æòŽdÓ<XÒ|C‚m´.ÉŸùÖ“Ùl‚ãW}*äxSÉ–Ûz «‘ ,ŸÅÚ•Xó;C£ÿ°B:Ž™„†T# #¥¹Ð$^ß Q÷t‹Kw -Æ5,5òæÑkXÌ8 g¢§SêGh…ñÖ'ZSÓ]KÃòM^YãPÂ` òn€x¢#ýj`l™_¦3Í©¥>c°ª†•4èþõ_©5F“µ(5ËýWwMÁ*X£ie¾˜LT—PvðæóÚl¾[UZ–<—¿3©!=”wÀŽÔºîó )p¡Ž³ZmçÒµ´'û—Õšì8n(f›µÊô±ª4ܬ@ëøð0q‰äø[ƒ\À¢¨ïH­5€J×^~‡Ç/¡¬7WºÉ °^òˆv¼Ô.¡¹ ¡â€åÛ]Bô›^pR`¾yÉɯ3x´Žq¥É/ç,8ze½³ÓêrÙ/ $»Åwy Ÿú¬Ÿé{`+ðXÿ keyˆÈå·„2/`eM'ËgVʳ(°®õô꣔÷€×¿þÑÕÇ_¼l~¼p)X§sèLR=™±€éìÉ8›Ó}s¢m1»¶ ISõžzüé…a,jØ£êÃc6²0•¹¦;Ô|%^0ôVþXh5û8YÕÊžÕíã¤j2¦ïÆífuHfâ¨~QVÜ w uˆO{Ö&N÷Œ×bOÆìëÔ„3ÁÌxJø:‰mÆæ©{ÈGæP›Ó||DbÌ=ã—þÞ2ˆy <ýÔ»UF€uýÙÇW?üeÊr¢jÈýïþ-G£üý’¢µ]ßØÝ«lìîn(‘ªQuÖ]û|7tYÁCŘH׿ªR¡óúötd*fZcQ”98ÔŸä$ð耶ž8È‚K…6àÏ„ÖûU¡§'°§p¨„ø¼ÕD£9’ú¡ŠöG‡ÀM±È..zÎÍ=L\ÔŽû)yاyhÆ&ÅÑ·Ýû4(Ч|áñh„Éäå'múÊ-í*ž§§hÈÙó‹?­Ïr‹vàavëGmÅÝÆò\û‘„§|)J³íq®QkŒþäó&©Ý½îÞ{ño “ªnüéð@?lÁ|ææVG%òµ/¶¼Ì:€µöÏtôZ ‰7õ¿{ýµ%ÁÇA÷p\ÓâlÌüØ‘ÌuwŒìÆJy~øI•/5Ù¹btÒ¢rQ«1}óéGW¤.×þÕO¯.?½{ VÑÀŠK`>K\(H0[v?ÈãvÀzá²þ0×BžgÕ‘!/(¦-]ÿÓÓgéHºþ§=û³/~÷²ññâ¥\q´”R^A¹þü'——º×7¿¸ºüÅÚÝKK ¬RJyõäÛ¯>¹¼üßb›äèÛjÈý.íX`ÛwÁ¾#g§jƒz×=kµÔÞÏggÖ=Ú:•7NGw´)«ËÛ‚¹ÒLÝ;7û˜¸Ê/õ‡mQá9kèr¼LüqY·XQé<‡_6á¢ð0¤ós“_&ß /Ô9í­­òXåšúM €Êè´uþü¹Ó²6Âu)ì[&üqa%Ø4+çp|9]&_íºybò&ìí&ëOÛÕu ê¦å‡y~yJáqþrØ|¯åÆã“T>™ùÅé“yuÎ-雿ÿáÕÇéK]©!÷¿øêö VŒÓèa\颦ásËÙYt÷#FÕhÃi[%9±m¾n+ǰ͗Fñü¼µ69Õ¾Ë0O ®V”ÄMi£ùd6RåŠH0¾¬e#n–rÜ^Q9Ï鵕Š9ss…|£mAUÿOy›¯K[cåw_ýôý;9ä^8°Zž°² 7 :þµª“2qQ?à —5bÒ°Žbûæßˆð%«e€E{ÛÝd×̦sÚZ° ¾§¿Àj% kiÚo±Ñ£¬ëÿôÁÕåߦQ]ÿÓÞÿ³»7Ë]IÁÀRJ6T×Xa8Æ 6¶Ç_{cJ¸qJޏ²à]ç4׿”°)-ÝŽG`ÝФpGùµ¤õ­M€ÿ©Ûy:‰{‡æÝÔ„v_hô±[ß½yYdö°^¶í)‹± Âu[ùy[NNÚßov”‡=É«ÍfîJ{®ÔÊÎÀÅhhÒɉÛiîuä_ýӳ³En€uh¯,Ôr2lp‰dÀÃe`‰„º^´¨0eCs6Wn`´3¼´Ù„83-ÞÉAúÍY6GGÜf &,¨aÏÑ;Éç"b¢Ï½-×q.Ž·†ˆc4 ¡˜%BùA™&ã& ‰¤)à•£N,ð!¹Â–[ª´àÜÕ·V¬ëß|tõtéˆú]å®dMÀ:iïìí5{½zŽõ^·Û«ïo!°5{ÍÍš4ßÝíõš{{ûµÚý^»ÝÛÛëµ;ûµýf¯»-•0Ö¾²µ­l5Ûù‡4õò26°Œ^Õˆ-‘œXV|ç Uõèv °jB©0ðÔ·AOúì<Ëb`‘‰ÒÀB¤¥õJPËjÒ‚ãLfRÛӑ´Y„eŠÿ5 _íÂAcW°ÈÔ†ŒŠÓâ"ÕìѺ›É„Þà€MbZ–C©©º’«>°>ÿðêò/—}%xý›§ïôùË&ÇK’ÂU{´)»„ín³Yk6w›ÍM8Ö%wÔ¹V­ùýæÝ­ƒ…GoH8µåå^§[{CÞܹ``=èí4›à×^;ÿ €îç]"ù8° R…ÅÇø:…4¬–0D†¥Ú‚Ë—.ž³l£ð¤¹¬ƒªÇy•`™ç¶Ô…2p‰Ÿ¶ô•cîA:( R.d~ËN,ÿwÀ\u™ ^Nè®Ê"€¥ž6v^Y¬•,l[úÓÏÒ›„cîjŸ@)ÃxÜXÿ÷Óþ쟗µ²o~qyõó»9ä^4°NO;R?’=ÁnOªMIûÍæV­Zï©ó XÒÆ¦PM™oI`U/z› U=8î+:ívOÎ:ÍÝv§ùZ·ûÚƒ^óᣇ{íUËaxÅÑÆ½D2þoäZ"Ù–’a F˜çðzÄ ë?BõìÆOãZvsÃi 4 èßeÌÆÒ!8¶ Q€†åp|”v„j2ÖÁñ Ј°‡FÄA›.Ž~q§K%€…ð³ÅüBŸZð0A8ºkˆ#0…1 ð M‡Øîq[ør¨ó©o‡†ÞøFkUQÀúúÿù—oŽúÅŸ=ûÑr/Xíz³í¶Nº¨:!°4e÷Oö/vÕ »´Qm¾&ÿؼ­t+y¬óñA³ÒQƒîÒ…D—ÔÕvz¥–ÕÉ?‰€Õ`4âK$Kí 4°Œ1¬C,UÇi Â&¯–£ý×þ%«ÊŸb¥Î…Xš!û0¯8ŸBÀbËŽ],çÆÀz~ýõR©YîwuÈ} Ó¶”ÞîÖ«[j€jw³)¡õ ~ÑíÖwë½öé©´ÑÛévwzÝ‹ýûRóÚ>Q&Ûí5ԥλU¥‰´/ê»»½‹û{ÝNïÁæ^gµ.aC^­°‘ê²i XÁ×3à“œˆ–~I¥XDxÌɺ´LDη€ûy]厾Ëñ§ñ'ë «=¨EWÌLºãF®côQ°ÿ®5¶×€…&ЬéŽÒx¾ˆuLNªÇ“F«¶sÜ®¤¬…íÜH_us4²¯~úìι ¬³“N¯×ítº=5ðãV5 ,uÞUÇ7ºÙ[”Ò•G0é5ÕyMؼڼèHûʧ ð¯{’û¥;ìK"®-š&K–tG‡8‰ÓÑËšg4P"ð]—þÈ:X­è”…[Ì ÃyX®«}.6ú±oý¦u¶’ßš'ˆe¨&¦Âg_-ôßT‘è”­¤Tò”#–—Í„â&Ϙo­PÓÀºþíÓgwvȽh`t¶w÷÷¤ìoÖ6·ÜßܬÕ6_ûþææ–4Å£¼÷àü­V_{°Y“vàü÷•yU«Òñfe—<ùê´´_‘§÷w:ïäíÒ·„f»ZÆýXO¶:ãÙ·%Îz?»zŠ¥5ÉiÍÐrrÏ®¿aDDâºR‚ÀJó:qŠkòÍ%±»UÄ#üIzEá´–„Qp®"óëï./ïì{ÑÀz«ªÕzDOGÍVãˆæ·Ñ—„j²û±2oKXYo“…[UðLw'¬¬y¦»õœw¬Ö›ªã¬øY†2¡¼˜èÛYÎ.ÇiES ÚI½v| %!õÆiŠ ç¤yç$ØqÒ-­–95¬/>~ö£_ßÙaá]B5Å3,d3Dc7õˆuËŒÏÚoŸä–RxžBþIè‘z…ZWƒµl/«SˆÀ‚ϺsÍ!¿¹ðâ*Î’åtÄ uQ¿ƒ[ „`}kWD·Pû3Ý#å²L¢Ÿÿékìê%w·Rùmý`—7ÖéubÁ¶Z)ìJô>55WgõÜ„)Ïrý«Ëg~Q«Q³^ÜsX[ÁqÎi=$^_Áq­oOC%OWÊxa׆7(ÜsÜ-‰,/cwsÑ£Ž­ã²Aw£Ø2kø:Ç Ãà¤ÕŠ6AªIi™ñb`…Ö.sœ¾Ì +AOÉ!¦^Qã¦ÕɉøLÆqÍwÖ7‡N,bÉ,J‰µÑ¸-µÊuœÄñ´lqrëëO®.ÿáîòª\q´”R¾CrýÛ§ïôÙËŽÅK”X¥”òݑ뿻óܕ¬mלȮ]>n¡dÝ7;‘æFÒÖ$¼Á—ö`ùÞ#7èö-ï†"ž×b“©ÃLÞkHoG$XÉ·èÆ6…¦(V0ž¡*3À@û‹(ooê­’³)êJ) m•ê>wªRrm¹|ñç?¾ËCîkٗЃwiÏ^½¯Ú,r¨÷ñX»ûâ îÎk6]lE©¬òî[jë@Â;Ö+£FC/šµLŽXzßs{#õ5‰Ùù9lïŽ|7;"[qÉÜë9žM¾å$kkûÕ·ªçéyæÈnôÑð’Â÷–F‹nõ‰{Ö¼{¤g=>UåDK‘\ô¬‡¬ÝG3ðßö‘·¤WwL•ˆEvÅÍÖõ?^^}x7—%)XC,Ä!C Êl ްÓû@š÷q]+oN›Y¸ tc˜±Ïo¤ØyBlE¯V%\1¶èa#Ï›Bµ©itcx¨øë£íõΗ¡Æ‚f< j÷~?޵¤Bv–Û_9ú¾Þ¢Þ”j꾟’sáǾÂǘ³äŒŽ„çHèÌ3äóôo"2=Îm³}?ˆXµ¼ðè¾ñs‰÷9rm©Üõ!÷â5OÞ}Œ[F’In ºÕpŒÛÌK ¿O&ci}@Ò6ྼ1ö=“?è÷P!WªN§#£hZ3Ûs® ;?Cç©ÖúDµxõ»9†›k¤•ÀI`Y~z…¦GËó£j›gmñ¾”1!ñ°Ó—jÏ ŒN”àƒ¿ð‚0³"Ð(¤ö^Ì‚­ƒ™|ß_]2€uýÙ¿¿úè³X…‰ŒóÅä±êþ&“/uÁ)Ü áž2 úãù|¾ËSxÞšMóùØ'7¾Ýôòï ߦ÷ö´úE\k4r‹Æ-ð©þB€¥÷B瞊LáKÓ0’u°¬<‹YK—ýöš–$hX¦Ëæy^¸CÆÚ64x}º »<ž„ z€pÓÁy¾²N˜dÄÓ~_ƒu|ÏŒ z‘øYñõ8Û|J¥•^»V¯’kËäúï/¯~öß^63^ª ¬ÉFµ¾FGã×å¯/õ,)_JøH^ÝÛØYŒ‚/G²('›•±?)ÿdñŽÆH)eé{“ÑHêY Xògä• éåcŸ:†™¢º„¡%’ÔÚ ñŸ¨ò}ü,«¤ƒ¾ Y!òs}=BÒ°d|ñ]ƒ€Qu çˆ1ºKP Xšð¥ÝØSC ÊOvZ\ô}Šp?"Ä4¯Àî«ûR*Ô¹²"ô¸:àß @^x*ÂÄB`Ψ0ûHÿ¾ÑúT9+_ s1W<+¯1A”Ñ:»õ¥•f±zõÈÖW?¹ºüÕV°ŠVe6ß^L(’<“éb:Œ$Šæuiþúci2RÀš-$¯ó±ÔµÞUwc…€q}¶˜¼.J=+(l:’÷Þ}\v&¶:V`AUXÝ…O¤XŸŽ8!<pÍ!ð=íáR¿¼RÝh˜d"²4R š<`Kx…¥Ç'ÆD,hÉß>ëÚ¶±ÞtúÚ­/ø51ÙGÓ@Äš Ò] jG.Ð€ÅÆC@=í#i}‚=‘ö<PH‚üQ,¼‹qúª„”?7ʵ%rýëË÷?üâÛœñ÷SŠ–Ñ|±Ø™Ïw¶åqg1•ð™ol¨Îßd¾1M§£/ÿ@ËŸTg‹‘?Ù¨,•Êb2QG©G Æõ9ா»#¯¥¾¶1Ÿ.êß›NÈ—¼Å~x[Ó—íãü/–œÞw´¥´ BA@_ä ÿ a‹Á9<å±åàÉzvšøÔÀ³C€æF´¸ôà´AÝM£¬@Ö>)$¤ÔŽ3žª _0¤ñf ó€ŽR‚x#&€QÚ p&†p¨¾Ö†¤š&¨tLñYÔï#4Ì‚¿ ú!³]ÄH?0Àxùú™¶b®-‘¯?¹ºú›»< ëùZ€5nÌæ»S©CͪóÉbëÉ“­©À F#5/ rZ{XŸ<–væ•Ù¬2ŸWæò:U]’i>ÛÌš¿;™Ï¶fJ3{}^S¾äÇJÜ5'q‰d«›˜ñ–ÐãjÏm$üâ»p±…¤ô4° [˜FŽˆªD1i °°—)nЖzîûº«ÿkè3’ú¹}…Nñ*@(°õèÑ·‚I`ðùÒ*9“{\ŠÊ¶pâcA+°¬!É és»–T4:‰bDëÕs-]®?{úã;>ä¾`IÍI¢fV™(mÍ6&ÓÚ£G5 ¬ñ|CjRã¡ÿ%k6G`mÕ¶ªmµÚÖ|# «™r¿X(]­R“ö6¤Î5¨|É‹ˆÐ~ú¹u`6Ï¡n"ê]yư M³NcÍ9X‡X]Bü#gÔNdg%€Ž‡Õ8Á¶aVvÐÅË‘q¤ÛGŸº¦¾`•Ïšª÷qw²D m’ÆÊ 8vÅ„ÂsÝCD`yÆ-ÄKÑc,`N‘ŠªyYOʬop‡Ck>uÏ)…Ôm¼Q®¥ ¹·-þžJÁÀò¦µ'³úBvXX“ê“'³©ŒÇfß9™>öêV”Ù|¾PÇŸ¯Æ°f³{óÙ¦T¬@ïªÁÉŽÒ°f“á*ÓŠŽãÀÒkÒp{î1,lðDUCîb­Cîq`º‘Ð¥Ò¿X¡AhÝ/gFk,2úä{À8¤“Ö°øå]±îJŒÃÑ!=ÆSÀˆwÑüx× °ÿt¦5X ª–Ùú”o‚Ñ4#t_3°¥5¬ Ø·„_ýäê‡w|ȽðA÷ÑâᣇR3R’„Ѽ*Ï絚¥’ZÒÖ~0_LÕÈÖDÞ…‘+e§º1‡#˜ÏjµûláX“"ïmmÍ%¹j•éh˜XLJ±%’“6R=Îÿ–0€·„Œ•œâZx"N¨K…¯¨<˲ô)ëF£Wd;O+?ú}XqÑ×ñ·ñ ÷:Ä>h ü‡1 &›~ñÆ}.z«©ŽžO^úæE^À/|Ó÷Ó£WXÒ–=>0ØfNvlj£ zOêlíâZ¼ýM‡ný¤O“Ì=˺Ìé,ôaŠ=C3:U”¯Íg3˜d/Þ™õ8 h¶|è #ýz¦dB¡(xfʃþ¸æZØÓôÛR6ù‹!ŸA(;C‹œéþÍ'WWuÇ‡Ü Öt»¾±»Rã.žª‹Ý]mJ?{)R­ÕªÚáîF¬ïÖ·Õôˆ<¢¿%<`X©É¡p‚ëŠ6¼„ßAö+BÖ°ü0`Já‘þ4'öiJÚ—ùcû4§_ì§9< 6õÛ‹ÄÑúÎÏš>j§:–(ÏSÛšAšûʪ8ÏIø•à v`¾è÷û¦0<ý¤öÒšèzƒ\K“ëÏ>øñŸþö®÷ ïþÏãI¶¼;‰Êtš`8ü\Íư­ 4*=¹ý@}U¨¾+<:Bh¥Ë+ü-™š½.^ñÇÏ ·b?Ó™ùü9ñË“x6ùÚ¯`úb—Pg—„DµÐ¦ZŸ>å‹cÅPÂ6ðúœ Æ^èÓ$+_”“kVÔØ*ÀãЬÑËUño¥Ó3×Òäú——Ïîü{ño ­ÂÖ…`.¶.O0¨^€Y/€ðg0a÷WüùqÒÇåeøgÖ¡´ÊÕäÝ=ó³–(NÂ6Ó{Š7ž|ËÄó)¶Db+= ëóÛRTÓ‹{0 ÝHÿþÁ bÚ\š_Ö¼TsÁ¸rCôËÆ ˆZ±ly™ùÉÕå¼ó ÖúÖÃZãrQÙYëö]9êÅ$â;Âm<_µîÜ®®½ÌšŽÆ ëú7—Ï>ø¼V¹âh)¥|¤rG)UJ)¯¾\öÁû—å{ÑÀry—b÷ìTï¡âº§§ò÷ÔÞùDísì´b[8)ûggÒŽ«öÊqÏa÷)ÊKãßùGṡ°ÖÐ%TæœB ì8ÇÿíµÙBÅìüœõÇ~¸nÿáöhyþÜIõëæñ'sØ5ÇuòÄ;œö¤óUíàÖ=ËóÆÞç'ì—¶¾×2~Çò=ê6$yò ·ðIÝ5§r')z›¯îÙe²½;™‡wË„7qŠo_…& ^xy&ywº«Ý8ëVRl’+ýí®© Ói¥7ÎU$ÙÙæ+Ëþ*×ô û:9ã™áWbx·‘åÀJ·{›ð2ÂÄ­ÌÒZÖ×?»ºüe©` ,µ‰ ,ÆSt;¿0°NW– ,ûnØÆR`Ù;<å\r4kÛøHø·¸Ëְ슾jІ‡EžªÛ¤Çåè¯ÖPY&«õVF~¡Æ›¬oû§ïð_J`¬Á»„€¢ÄŒ"Ìež=Àªsæ»§‰>„¤H`˜Ÿ_¬À¾´ëóþTu:—æâm£ï®m{ì*E+§¨¾A¢|óWWWŸ”CîÏ‹–Ú¬¾}F8In4tÒévÚ''ÑçŽØtÙà¬Ý¦Þ Õl«°‹}Í]Â!áŸ×ºõû /XXÉíêúóÞ¿üM©`=/X'‹z¯™»~Çv?Å.bg¿VÝíuNä)¡ÈÞ^Ümà9­Óvo§­ï:\Äí^;Vò0à{Y«‘òñó!~üœ½¼ŒôW8òOú.Ô9©ñk¬Á,_¼Âyé¨P‚»¡`²;ÚgÅS^Ê„©“B£oÅ'$ÂÞÏ¥Uá‚vÇ]&²àDïÛP˜Â5¶‡íÙ›×·¨l]Ì\W%À…Mä1¯^³9ÚAsù«í Ù Æ“ÛÕõ§—Ï~òÕËfÅ+!…«·ÛÜíJ-ëí·OÞjw¤õN§srg'ê¨DêU­V÷áÍfý¢ÛFã3¶ƒö:ÊŒ®¤gæ^G–ç º»o´/ö›x¡#°Ž“WµÖm0§ÇYÞU÷ìLµlá:ª" *êšõhQŽÐm N…–ãb{s1pírÃÄáRBP RÀ"}Ÿ8Ö‘OTcwS€äºN‹Óæ´¨›ìD…Î0Í"’L¡À2ÓO¿B±3V†3ä( êAEO*‡TôÐ’^+{»ë Ë  ¬7eG¯ ÚTØÚlJÌtkÍ‹n³Y#ãæ®<éÊŽ`·öhKÁ©Úëí+{ycîöö¤[ò®¤i¥ô7E¸^Çò/ Xá]szEd !‹Ž6R—H>â¿°èI­[ùúDiJ«Ó•k? »¥Xh9!™‹¤ÞX4› °t«/J`ZƒË ±à âk@€ÚŠ«PV œº/ÊL/ZkéòpLÁ„‚Cà(¿À2(I¤Í9ÔµgÛ.=ƒH¥m±ÂÉÜh‚ƈ´‘z`eiƒ7ÈÎd`}ó—å;KÁG†jî+žìv.>z(A$qÔÛ¯IÀì^\¼&S{ €u&Í¥ZÕmVº] ¨×:m…)y÷¾Tªv%®v7Á…dÖ^÷ÕF“žå_°Ô¨ÕAƒT¨ƒp'ÐZq”‡´r ºÓs5Мu È"° ±8‚»]àÒŽn´ ,è¼€&¡Z¹»<~,Ç<ÞRx—âÊ‘€ñ?áo]3Dmä ™jé,g=P‡Ò™ÎÄ¡;IÀ¢hÀ  ƒür) Æ8Â¥ŒèØ2=I:ºT‹Ÿ ®f—py¼ìFì¤VU¹[R,°NNºšJQjî5ëíŽDN³Ó®7{¤[]\<€›M¥aµe7Бª·¥æ.wÔÝžT»šÊ›ªTźJ¥{»N·W¿èjÿê] ¯vr±K I š”°Drãxõ%’qÔD®™ð|v×,ƉÛbƒÇmŒ6 ¸êéh-CEŠa@ºI6°¸k]¦“@ŒÇ‘„V£e²ßÅЃҢÕÒªÂÀÑ–C}-£›¹Vž0°\f~²€Õ²ÅcafPœãↀ¥f¿9à—k)P-]ø ¶¹L)§¥Ë#¬Õû„I­êúW—Ï~ò//›¯ˆ ¬·:ÛÝ®ÄÊN·»£F¥ö7÷:'Û½^ý¾ìýI*ío6%´þPiX§om÷¶zÛí5TurÒÛÙ¹è^ìWe—p·¹¿¿Û“¸’ÈêmŸ@gpwo¯Ž&õê&ÜÝ­+?°š¹¡bG`©±tì(}‹»<¶%õÉÖ”,î*9>6–iÁ;AR2bä$«*›j)b=Ð~§ÖÇ z¤æ`P¾U¹íSÀÕ^ôûIÙyi|Óùìc èÒ€WÝíSjøW=ÀUf9oM‘ùü£÷Ÿ–»{EÄ–Ìì!ˆ'Á⩦?ège¸’!Ò TyÕ`IþPù£ü{ÀŠiX\GG´drCý6Ôßáñsk ®ŽPÃB¿¡j¹Q™(C þ{”Lõçæmαi³,¡¤K©Èt¡†åA|¼ÀEF%Ïl`q£Mb²Ž“Á˜~Zö0wØ,ì·mÏ£˜DÓj÷$Qû¨,?}*Aßä¼§éæi€²ÁÊùf5ÍëO/Ÿýô¿¾l@¼jbkYìF~0ŽÇÃ`%`aýŽ'“ñ£‘ò'ð¿ùþèñãÑP5tðð–-!;.AX‡Š:ÇÖ¾9x¼:h,㬠|­/  ‚,/' ±‘g:_‘›ÉY!ÊQ\Ðs_§ÈÄ>|E¶“/¦»xa`1P ªØ,ì·–“¨v¶áÌ·N©° "M+ Ë ÂÀúê§ÏÊ!÷˜„5™6šL$_ÆóÅØ“Üfgôdˆõ<ŸK—Ê/'“/ñw±˜|¼íJW&µÍ—ÝÄAªtMj‰ŽÕ€»*i<|¡‡1Öž ‰Çú zD«|þ6âþxè•W@ºTS‡æNCpñø`8ɹØ×u$YçŠ>@½ˆ/ò<±–EBR„vƒãZ¥*é¾26¾~`gy¡Ñ>ÈHŸÍ9¬'Þ*:«GEÂrýOÿ˳?+‡Ü£Öh4ûãùÎd<^T6&JZX“­J}1oÇõùx¼½˜ŒÛÛ‹ÙÍÀÛ jXBàÎÎø+ÿóFªz»g<ÏÞø%ÔŸô]xp¾þDÈ6 ãëƒþ€ªKuN"/­úî¡…ÜÄò1UB¥Gú©œ ,ÏÇǃ<ôcz–ãÉQ\‰Ð•¹o…ðAK´­zÌ}ËP¹UHJ,EÌjyWå5f(ºs %u R—èÄÃsCY-÷,`ýÛ__]ý¢rŠý–p4YÌçãé¬6_Ì+³ÝIàç®û°f‹i}>«-$´‹íÅâõÇPëïêb?ÔD \5$–xƒúC³q}#s«zÜ{Þ§AÅê.¨®¯q4 ²ÓàI…gBǦ ÊzòdŸîÂÏÐ)´)Èï"£Oñ¬n`R· 5Aï×™°Þ‚±0J‡Þúdnü:_øÕ!¸SÅùHê1¥K‘_3ò O<°P`Î «$00, |–‘t˜‡É2Ñ€ç\cùâã?ý§²G[Ã/îmÜ›.>¬Ì«³'ÕÅH6‚úà¬êl±¨Ïf ¬ù¢2›o±˜/¦jDìÅë€Á»¦‹a•>Žut–ïAå„*¹v`aŧx õ;R»@gàç¼ a+hPøø×oÚ—À U5Ë×8D-»ð<0…Ni+¨¹ Â‚ˆaW‚Ew{•o^ÀP󑆙í' X0äþU¹ßsTl k<ߨ<œÝŸÍž<\LFY¹ 2h`òùsÏ›ÖmIèÍ7&Ó­Yu¾)Ñ5nT+‹qqmayCñÓº„",ø×0ÝÄŒ.!VA¡ë¯XA]9 ªXÀ‚–I)RaËS<÷k žàè ÆZZ,òƒZ}q‚cX ) 6jNö) ” ýÁ ¿Œuëè±e H}u *7K¤'³ÒÄ>ê"v ©oèiuÌ×9k)b`ï î|°V6 AÝË!÷d±5‘˜‘]ºÙfÕJõÑÃ{Ó€åÓ{Z{2[Œ¥Oï)Ÿ¶j³Ù½Åb6{)ÀBÖ˜ÁÀjPW‘ ó+Ô4´J³¦4øøšÍË<Î5÷€Fft '·¨s‘v³,KÃÒ*Diày¯œ_M2Usµ[íÈüákÆ éVò¼o`-„ÆN`¨Çz#Ër«&7ð”…PBW¿ý@k>M 1]B_Ç~ ½yT‘¥0Ü‹ÏýH‹ëú7O¯>úüw/¯ž$KöꦋYuñ8£Kb†Ñu—pìOf•É{³ù†ê Þ›+^ a.Özg0Y1Y,ÝEÖ1™4ò‹žû Žu'ôn“~XŽœXZ¥øì(£¹ð(c„›l1smu÷È稚ø¢©7ðXòÀI9så…å’¢HÀ²”²ÀJ#óÄ7Ѱf® ¬€5¯ °¢¢¯4Œ£áë´²ÃïIV-t”o~qyY¹'HX•Å¢"µ¡€U™ŽVÖhZ™/&“ú4Ÿ+`Íj51„Õ Åb`5Co ÓßfMxÇ÷i4Âᮎ¤$‚»Tz ‹ÔÆÝ%åô~y…³–Ë AÐÐNq¼òí.a@–†„¯&Iñ&ðh]À¸‚´Ò»:F³²ÐG§}ÏVÇø%ƒ\ð›D‰½"Ý y)ÈTaÁ8eÀú—¥…qz˜0€ñL%ž:ãu™ùùß×Ú¹†òÅÇÏ~Tîî• ö ûd>cQg‹éã\xA¨Á[ÂÇÓÅ\bJ¹VGãßì…u ©Ø 4Ç<¤ì:@#œE*Ì7„KU,=q4À—q럅…GUcÆ™F!e fìÐJš[mÙ  ¤pÝ_:ñמ8Š/ÐúÅ Êùz–‰¶53ÔÌ 7†ö=ÊôûöçG|ÚÇ.mŸl‡'ÊÓÔR?H˜—Æ3Ha æSõžOóí!¿¾‰I"Å=ë£+~y‹\Q Ëü´\j4ABƒî;–Ô·WVà°¶ïmlTȇŠåÛkýó-©ØÕë=Å%{þ¨V£ŽiiC}¦sÙD`ôÙ]¡×œ Ìoôí)•ü­]h6vìÕŒý~N`á”Ñ~?ß— 9£ïÛ‰kip$ªÑøûzš'g œ©Çj¢ùÑØsÒÙ'ü‡> °%Ã>ѯAŸM¡$ü­u éî%LE…™8uÕ÷–=î†&MC3óiÎQ>Æàè(|¦ŽGGÉÈ™î/fÚ++ êÓd?õû€Û}7€SŽÂÿ)üiÎêò⾇ˆÅù¥„ÊuŠà†Mñú·Oßÿèó—͆WRBËËpÁ­öÑ{xý½ˆý™BèÃW~k®%áÖýÐJlÏ7óã±ñâßÞZX~Rxëø‡É¤Å_ ÷[çŽa­!öº6ܨ>Ý­Ü à½%//óßÿîòêçå{’DÖú•¼¸E£‚ŒûëÖ‹–`ýa®5„—±„Øw_°)~ññû?üDzG˜$劣¥”òŠÉõ¯/ßÿð‹r–{’”À*¥”WLÔû?” V¢ ,×uO[òà¶à' æþÃm¾ã¢qëôŒMNOÏ\Û•k<;G³siÇòÞGš:kèžžB¸ç+û¯xQikÉD¨ÔÄóÃuÝ쿨¹Ì¨çÏöW(™çÏÏUqä‹cŽø†ÿ¸.¥]¯˜G«Äí¶éIJüª¼R­èú·OŸ}ôY ¬D)XN¤á™ƒ>ÚEˆ¦RÎ\Ë…ëž¹!`!Ä”(7èêì ÿâ"#±6`½Á°$°œ4цp“ÆâÈÖ±ÞbŒBž§5øûžq½Ôí-ಖœ‚pùë°Ê!÷t)Xà ·°h_,×r¡eWH XÚmDV×°–Mi@`µ^°R‰k°«7@CX—D€eEºVrÜAÛU­¨œå¾DŠ–)âŠÝÊU…ˆ6@÷M.,Ö´N}«nŽò']ã‘wxÅÑÏmÇ?ÀÉœ3Š“L×Ù´SÐZ†ÿœ°I+fš%&„å÷ÜMðÚɈ¬?wo¦çÌÒüÈòÌIº™®“+9yDëú/Ÿ}X.5š"Eë¤Óí´•œQq½ Úî;o»æ vÞn»Êfç÷„lÂcƱ.:*ëÓ3iCþSù»vï1QX ¤Øn¢¡wËÁ]tˆTÊÖòEÝCÀŠÖ¿5´sJAKµxlÝËq›xÞèE‘Xdr[Ãr’ŽKÙá$9¥_'Ñ©4Õ§­dçv‰ú” ,æC”‰é9wƒìTÀ*‡Ü—IÑÀêܯíïözÍ?Â@¾œüAçÄѨiïôÚÒæ~³sÒéíªóh±ŸŸëóvo§­þ¤_çoÆ*d‚ °–H>X²Dr†ª¥àáY…Œý9k‹ÊNWÆÈqª€¼”w„ãbkÀKÈgŠŒ4IhtKB@?\W8pR\š°WÇЊH”0}#´ÅÜaĶ*,WODÈc „y܉°Óp eV´TþR^ ÝEÌ'Î_ü…<ƒz Ì-;PbõÌ”Àºþìéûý§rNCŠ ¬îÃ7šÍz¯ùà¢ýö ¨ZN[r©§ô®·ß9‘—ïtöšeóa¯ÝÛÝlvÛd¯Ó•Ú™Ô¦¤‹ó·•¦vròö‰ÛiîµÛÍ=eë|C–¥8œÒ ;¯âŽÈ1kËhtåZ"Ya©JÙb` yX÷˜‡ ¼§ÔÀ 6^ªfÁÝml˜¦Å;Ù!´Ð?FG´ Ô°¡; ç`Õ ™Cô)mð°‹´}iû/øè˜Î§p ¸ÐCá-)npˆÐ(I1ù‡éq`.—å"<ÅÈŽ‹þ¬* Xû£ËŸýëËæÂ++ëÖæ~½×«7{½Ýæ^}»·§Îv{ÝîÎæ~G«}*m>jJ{5y§.u²ÞÞÞ~­v¿×n˳^»³_ÛoöºÛR `í+÷Û½æžtkpÊHëø0 X¼€ŸÈ+^ÓžœRcÕÖu^ °HCPOrj ®‹O}lwžè¶"#HkJ{Àëi,Õ]j¤…FŸ®ë@[tj¨Iˆ= ð ŽRsœF±à²_‚ ÈG»pÐ3àŒBëh·¨¢ Ì_ÊHÊBŒŸzcGùÁa8XæŽÀ2PÀF‡-0×Ì#¡·§ÏŸÿë'OŸþªì¦IáÀª=Ú’¨jnJl5›[ÍÝæ~S"i .wä7v;» :ÝZóûÒB­)í¨›ÒÅ£7š{ gò¨À·Õܹ`u:Íû½¦”šºg?£Óuk‰dÞI§‘XªºªB |¯·OHV ƒG=6,‡ªV‹,´¨bÛÈ¥4 X6|Õå-’W-xgLp°à‚‚4‘ÖC÷¢ÿ«¾$§Ñ%÷˜F“^r‡åá@¶ =ZÆ¥i[„É7*?£-·Œ¿Ø%ä·†L0&GCïáƒÁK!KkX7ÖõŸþOå{ª>†µß¼hŸt›û»Š/»¯=è5ÿPb©Û¹è5kvÛÐ%”67¥‰ ÍZõ^³Y½PXÛ%`É»Êuº„X{Ý®òçᣇ•NžÆr^q´q`/‘|_"9uJƒtWšz…Z¥Y#² ,n{(MܸaÔŸk€E]AÔ$±D4ï!iL FʊװŽ@( —Àâ ¦#¨­;¨”`΂—yKYî0°` ž€Ð•f5þ$\Ç‚8PRXž; ,ºæ E}ÊÕ Ö±ÕÒÙ£o;öxõÒ°B.ó‹tÿÝu©_¥KÑÀjוöÔnÖÛòLjW4J³’ªw;¯÷ö›oÔºdg·Ym¾¦0¥ƒ5•‹Ý&¹Û%וÎi«Ý«w/$ºÀŸ‡RËÊ,\q”¶ù ÷ á¶0cX¹€­*ô8ȺÄ1cX¬2è±csé´l`ñXŠéƤIXäKÁÀrt|P+á±?†„¯„†„«5¬–Ë÷X8žÒÚà-„N³Ë^ÅÕÒn)X×ËÁ𠬞ZembaÙåÀrn ¬R–IáÓ¶{'òØÛ~Kžu/¾ßìíì¿ÖíÈón}§ÓÝ«=Üïmy¯ÛÝ‘¶öïË^äv»½-''½z½§Î¥ySë¤Ý­ïîö.vîïu;½ýÍJ'› X =xµÂFªÇÇQ`™.¡©³\ß×5û§È>~îšjB»G/-‘£s§š®~KèˆV>W+Nk°ãÏÍkñ¸–Ö¢L,„î0òuÌ‚yKcbðj¢¥‡¯¨s'X;²ÝÒïζ ‘+п´æ†ÂE—®k•‹ÉxS×9-µ)x¦»zØí´»ò¨þ$r”\À¹ü½ÐWmiG*V]ºÓì‹&º3®/:Nï£Ky”ÝDÇþà'±±D—ioUtxxh£é X£Ãƒš‡¥ßiÑèÕÚå„Çè"³žFÛJ°”Ù4Ü4q4!jæ7:™Øä0°B×))äôó¸’™pÌVÍ|+~›š+ÓV´¡ëƦ,‡'ê:æƒØ7CãPø]†‹E—;cñµf ¬,)X'í½ý=)䱺¿÷ýÍÚæfmK^?ØÛßÜüþþf­¶¹¿·vö«Õª<î¿ö`ss³z_™ü¡:>@ó=iþ}°(}©>Ø’._“Çû;w¨—ëКè~€H²GÖõùòy£€°†™éî`]©.ÞLœÜ³ëoÕ¼ùkŵ¤•æuâ×ä9šÐ Ly‚c+‹ywš? þtì¦âK`eI±Àz§Ók®]z»B% «q@óÛCÊÖ1ãªÁ7–n™Ó8>Ðâ™îN‹ç®®¯¥›DXóÁ«õ&…ê8+~–ƒVÊ„òb¢ogQ8»§MYtâxøÚ k—‰™ïÄN"iKö"!ãNÓ¼KʬƒŽÖ*ŸA­½V–Ü%|[Í I»mÿ¶Ûóv;Án²È»í·ONtE13âCT}KˆŸ3«qGGZ¥jXǃìý½ˆp–¶“kùíÅÉø–Ðj,­p ^1ûS_a]這îÉÑ^š('£t;Kø 1á§xÿ:)°%_fdÜŠùJɗ̓W^ŠÖ›JáÞÿ©)¹ÓÈB0çöʶ£Ç2xEfåá ¬Þà´lOñój7X±åe8 h%IlåJÚ›­õ‰ž`×ÿ|¸\òÕP X!WÒ+Ò%ÌÏù˜z•þ©^:NœÔkû›CljE,8þ•Ô1egnÄÿ4”¦ ÖùXYR®8ZJ)¥|g¤V)¥”ò‘bÚ•Ë–°©ÞÕËKµ“€Í=?¯Dº„©Ý¾£ÃœbmÄNÖ¶ÊÒ€> VòÅ-º±M¡)ÂÑ,Ÿy4Ë0g€AºAm¹0Ñ9žaë61xÙ CoïÙ·‘Ía…BN JÏCSΰG4ˆ¢›ºî¤í¶K°Ï+Žª÷„j+z¥\5ŽŽ6¶Ô]¸Èñ¦PíÂÐ.Ô·©ùr#ºu²Ç92€m×á7‰aùc‡!h¿–åèê‚À üFíŸä¸…!; »Þ{ž¾öø–Ä-ž4l=ä,¾6ŽøæYì¹åEmf”MZ®•²TŠ–?†méí2”}9MàFJµü ?TGe…!†U’¶§‘6|²å³w¬ X¬:Yê“™uu6ÊÕ%”þö‡ÔDÖ¬\i`én5!k¨a=)÷–ëFì!U  ú~Ä[/ˆ7õlÏ "íß@Åamˆª QoØ­Å—x81^š… Õƒåf ¬,)XãÅl¶sþSgÀ2šLÃq F“éH[ò=î6ZGÓÉìBAúʆ‡]JU ‡iE®Â`5Òa›Ü~¼lº»šëMÛ§ÎŽƒS]ÖÂ…r qâÇë=Œ£˜sÏî.ùágEÒ1—G)AOs³nyìåCˆ£oXebX{ò}Rϳ{V2R EäW‚Ožª>|N#£ìÞÃüñô˜)þùúhrNCIß |ßET—¾e…X…GÕðAâ[šk^)•%EaM6¶*÷ãáp<<üáx,Ûǧ; ©|ëóñÎ¥¹Ô¡ÆR'›¼ûXiSJ§’.àÜw±=/¶ÇàÓc)¾Õü†™Àj„×Ã:à5¬ÞÀ?+P‰Œ5ü4°„¬‡BýÊJ)°}õ ëB…S†åËø¢©€–£.1hˆw-=FÛgÏ¢¾GÅ.„ ª `ÉnþFôåiL‹|b5T™¨ˆG-ðK— ¶t '¾Á¦€üò´;O„ÚhŠ=°èQVröxV^ \Rw}ÝPNpÉ·TÚƒX…KñÀš/¦õÅx¼¿Çóùb2Ï%œò¼:ŸÁâÑ£ÅxQ‘çÒüÝÑd1Ÿ­/§‹Å\LA³ÏïIuði±˜J}kô©Í 3‹]vöÌ22ªë'/˜¬ b«cåéªz(°‚FVLn.CÕ§ò¡þcQÛÇMÈ©Õ=P†–ÀÅü ‡J R©Ô~±©yu XŸè+¶@kt]ûŠ’Í‰óñ9a½;¦ûÊ­ïRšÕÑ7>A© €´I KØqÓ1d0ù䲞.22wz@+Û‰Ïþ¬"å[Âl)XÕKjZ‹é¢¾QŸO•Êb2™Ö+[¬ùböƒšÄ4Ÿ.îmT¶ª qõ{Êݦt7y}òåd¾1™Ì+Ói¥º½˜olÌǃ€´ƒ<ÀŠÒ(º¯éN·37¡m‡j?TKxì¾(`ÁÓ^_².D­ —Hꘅ˜ÊJÀÀbûþr'«Åž4, O£y€0MÚC­…5=Aöé逺‹J0j—>[˜v ”/tèBp ã#r‹3TÇNy*úYÁ°ÖLÁ°6Å´?«H ¬l)XÓÚ£ªä•Äͬ:Ÿ×‹ù¼2›Uà¼2ŸøþtëIu¶5«ÍÐ|¶!Íg3©IÕÕq"Ï«³é(@`UçÛ3‰¼Í'O¶¦ {fdÆþå?xv&îš“¸Dò¡Y#+ã-¡ÇÕ^3Ë·GŠôd‹®±ö° 2€€J¥Z¯Ò6BKøhpƒ§ö§»x±ðL,vâƒBâO]ÂÀÓÒÿ9¾t`:°yÛ RÈb([Ö-¯‚@øݘL ùG/` ô1yMŽFÿ Œ¾#[íú‚TEºà@#ùl€eáY~©—Nü”ÀÊ”âõd¶û²ÏW«ÍFÕ­­*žK ËoCÂê¾DÖ¼ºYÛ’æ“ÉFøX•¿?žKŠzÕÊtñðÑ£šv —U ¬†½Dòa¼ˆhKdÍ …áih%KàFŽ y+`6°¼ulà^_u °¸yॠu,°<Œº ¬€i#DX>kIæÝaw~Ù&«Kê7Ð2¶`§šË# “Ä5°(@Ì«i¦6Æ$¯ûL()gÁ%ïó]¼0øÖ¦ýÉV@ã~%°²¥``yªK8ößUœ’:T}>ß”šÍæRÚϠK8QÀÚªÓ\šÏæq`Íw°‚ñâÞ|¦€5›m/6gOfxŸKµÖcXƒ8°ÂŒ òaa•t/mͳXFƒÐáb ጃc)¬9øçç Ah¿‹»KhpHýAÍ®€Æ£¢$ XÃâѪ°†åûjIá´ëN¤­v°=Š…Ö<ÿƯ€GÇÔà;`”°Mô¹(HÿS¯<„±C¥‚êØJ¯1Ê.a¶ ¬Ñ´2_L&‹ùjµHmÕJ&U«²c(Ïk3uO²lS^Iˆ)óY´0yœ«ûò|>{Óż*MæU­Ô*Ó‘äŽNØK$Æ—HÎó–Ð º«:é ]e½µ" 'kÈßJ‘F„MQw¸nM‚Ǹ¼Ð$ÞŒô8YQƒîyKÈñ¶Æ­­A-D„°ú¥øºñ#ô`´"°†΀ԱÀøgÉ06Æm`†íŒ©=$Oú—¥…Ñ»?Ðoí»>Æ’†Ùô Dê-®Tä%°2¥X`=~o®ÞùI¥äÉÃÙìÑ<'CºÉ6ôùܶ%ÝO´,ÔÌ­H'‡Å\ÃÔSÃ:¢]éC#ê žLz XÕà;Ë&3°PB_šD•üx|nr ów'ÑÉ•~èÊš-ºü#ã?Î ‚?k.=÷½˜ý›]ÓœÇÓ›ÔT)kªLòÓñè餲Ÿà9 èÝáÀž4¥éK¾¶¯`Ž”i…ï+xb3εàé X°&¢~l&½“õðÜšAoÑJùiåZ)K¥``M·ëZ¤‚T­È¿ [v7*ø#¥RÙ¨ìînD¥úé¦B{øSÙ¸·= W‚H¯ÛgO$=j4øÓƒÌW„zV0ì{:,þŠià À x²ª©ü¡†štíÚ}"²•fÿf×PÍÄ÷0~M½p˜^B¤i‚ÅÀ£„Ú1T_MøfÒnxú¹™ûæÊZååû4㿯ù+Ei+4 01<#(1<‘"áãž„(U”Ý%|w¢å½ét*{vê°¢'ïY¦ãѰŸg"}ülQv¾Š¡'ÇüQaö: íH`™Z‰-j]B~G…ß/šl xhÍ­W± OÆF« ‘ÏÙ–ÄÀÈûüövÂñÏ”–Ð÷2ãè‹Q—nÂøùÕÍ  ­oOþ¾Ž0ªÉLLí0 †³Äã42°úe#Ñc¸#6!ÁͰoBSàä:€×^^+åY ¬l)X¦-øß¼]I+9?õš#YqÐ’Ýr—ðP¯‚Ü8Ô 74âË6äò¾zYý»½Õ⿌œaéYáÑÑ‹t†–älr@Øk[ЖoâÎ)±è€nôöèh}éû ‘ wmsßvë±–Äæ‰NÙnÇ"røC"µÆxþ­ëC ¬,)üãç„©Ã/^"ëaÝ^“¶öD|§CxY¶nYke†§ôËæÁ+/劣¥”RÊwFJ`•RJ)ß)x›/µcîÉr®÷f9;C³s³éÈ)›©]pàçï³%jG÷Lí·sÚÂÍq”ÜØüE®ÑÞº„á]ƒSÿí5§7Rux·aÛÜç|Òæ*o(ïu$“ÂÓáœ:îó王û· K—¿ »æ¸N<ìV(~I~…‰ñüɺsª‘ðì{‰çÉyIÓò¿VȾ·Œü2íCm¶Sîš“%oóÅ[ŒÃÆ\);áb¡ÅÐUž†ì·Zf°LqÖ¬ÓÓõmNo o]¦ÂLÚ(*¼-:Ÿc#Y-œÜ{KßD`_B'!®7NYrÚÍožp’ì$=ŒÒ‹_2áäI„ãÎ_6^y)Xj/A ¬èÖÝÜà€ö4Û¾IbÙn]R%r+QÃ:ÊÜpâè(Ý«õ"€E¿iÛœ&6ÚVh+È Íƒu•’>_Ù‰Sv ³¤h`tº6>mNNBÀrOÔ.ôí3ÖÛÊÞY¤½H );'oÇyåWûÒ¼X+v ã aÝÀjålñ7VKq}@Y+ £’¬(±ò«u#`ÝÈE ¬,)Xng¿¶ßû#•÷'Ð9± ä¤ÓÛÝÛëµñJÚ»¿Ó—–Ú—¾ÝÛÛ«÷:ï`‘‡ŠßuskYñõ°×o³ãcó54~üœ½¼Œ¬L‘²¶ ‚°â½&Á0…@„a€òÒÑÃeÄ™äÛ¨¼T‰rÑï£ïrü£q´c§ƒŒ¥„O6 %I$9$;!¿¤™«Ì…y!Áy$ÈG'”pag¥<ÊÜ‘9„'‚Ä-ൂ«-[iާl6ë]¥%uz½nûD èU-‰¢Ýf³¹ÓVšW«Õ}øF³)-I+íö['oËãÉÉ™Óêì)KÒéÉ{®Ü*!_VÖqÚŠ£zÝsš9¾¥tWµl!ë®Pu1Ä…µˆÂ‰ldŽ-A@ëgº£Û·9Œ ™èó!HËØÑï£OˆzêXÇV@1 I\`¸À~¸…€åÒëTVØ+YdÊÌUC¬œ5üˆ„^·&s%\‡€®þaŠˆj©ØácDYXf®ög%)•%Ew ;ûÍ‹n]Bk»·×ÜköºÛ½&êUíæî…„ÎùÛ y)`]œtö7{õz¯ÛíÉcçí«ÛA=ë¼½³Wiöz»õ‹‹¦ÑÎ2DªâÐ%Tª”8 )֝޵´x ÏŸŸžžÉ¨ÕXWEkͼrXNK?ºu3Q{¼uW•£ÆÍò ]äd\n9•ÀrXãiýƒ²NèÞvtU3WϪ¬ƒiA Ž‚ªB‡K)T¤@Ü¢[\¿ê#}ƒšû2IúàFp4Å8^-B£%L¨È([&!˜Z>¥ä!\hä+v‹K`eIáÀÚ“¸‘ªÔ~¯·ßln6w.z›Íf¥#ï4÷:gRkz»Àª=¬wÞîÖÞhJËõžÒ¾êÝ·[o¶›û{õîEsK™vºÍfMžHKý¾ÖÉGVxל†^ùX" ;‡Çd°|‰d5ÞÅÀROjRq mÜÉ¢´:ÒP˜(LlËX.sT5?ÓþDVm`Ùü((ú.@,8‚SCm@ ¯T2á± 4>Pq]„@À¥»¤çêävä:¸Ë%ÿ]¾¥n@Ì\mäÒ3HkQÜ §ZÐlõ,ÒïÓÕÈè¢?%°Š–5«w±#áÒí¾¦h³Û½xøèáë +Ù%”ÀêT›Ý·£ V«Ö{Í­ÚýzWš¿%;’JC{pq±+u«5 ªÝ I0ðå4§R£VU«Š‘ uîZ+Žòz~yưà p ¬¿Kè@?›4Õ–¹„¾ ]êîœK­Z¹»¼ÁP—P7á⻄  ¶8žüKãA¦ 8†F ‘*-*ͨµ W?74¯Ñj¤-Šk, ƒ‡°È Îe“ Ça|i”{….ÙõÍxY ¬5È:€µ}ÑkÖÛm‰½æn»+5¬fûTv ëÝÎŶÖ;²Û»MÕM”v$³z½æyìžœ:'Û,yìÕ•’¦ÜýAï!ú’·±Ú‹¹†—Hn®¾DrË!`ÑXS¨:’œ"Bµœ° 8Ôü ;8Þ…0À_'X«7΀Å#?.“K‹].ËR½àõ†Ö°“Hžà´»n X.B…Õ²Õ²²†‡¥\ÖÍ,`ÁÛaËkí©ÅÏ L[n™»~'£,–À*Z Önµ~Ñîô¶ON¶¥®´Ók·{{›J7:owë»;Ý|{(ï¾Çîžtѹ¨V¥†åœžtwvU—ps¿Þí^Ôlí*«Þé4åiÎ.!MU:â.á½DòY"ù0k‰ä#3­Aà0†¥Ž8ë~KhFv¬wS»óKCG÷yÄ•ƒü!è!¦â„ÓèÕ£ þ”CD]âTQ?ÖáX¨Ûö5ö¿ÐÀöxÅÝ2Ô=g«ÛΧ{®ñbFü¬7®D*PÛ„Q…Ñû´#‡ÿ„•ñÖ[Ârнh)Xgow›JUêöì?itÑi·;ú^»£Ž8¢)•‰²}¡†¬.àïáy÷$ßKë†ËíµD­óØ"Xy€…ÂZ÷œH‡ÂŒ½N36ã°B¼B³ËŠNŒa¥&n¥pÓk'rÏ#œ³ÀæaÇž^zKayãF$9ø”D¬œ§%°²¤X`tvªµÍý½½Õ½½}õû@þnÑîÞÞ&œHó]¼ G¼½÷öà¤ZݬÕ6Á¥4}íÁæ&˜ïï„gv¥W’¿%lDµfÁ&¡Žë Ó4ºu„ ãÿB'ŽÞöÓŸVѯVŽ¿þd¼”¥R,°Þê€R´.éå–"ÖZ>~~QU—ŽÎ‹VñjâwXJ^Ô—D ñÇÙf%°²¤à.!|~ÓQq[tŒÝ‹_¶c7Û'oå~K˜G²?ˆVr||ðe'bÍígmH¤è»/­ýßDÖ:™WJ`eIÁëaÙ™~Î žD¿ª²WRŸKðÊC(Ú¶þzИä¬z/HÃro÷y~†¬÷ëaì9¯/þÎÚy»†8¿<‹¤V–”+Ž–RJ)ß)UJ)¥|g¤è]sp·$Ú;)ew ýŽý«¯¬»y¶- ~vÍYó–Ckß5ç¥l™tyÉ.wÍÉ”¢÷%Â~mCÚøÒÚ¦Íì0È›bÈ ¶‘Äýzõ&—t[ÉÞ0ç6Ÿ~X<°~tbÏ7än€¥ãºV1»9ZÛ<®%bʺâo¶•~!’¯dÒmyëÙwñ±HJY*E wã5Ûˆ›=m­êbï N{ðÚ÷"`Íöãª9 ÈÚnïBíQ,”¹¦™¼ ¬Ô­–k¥,•¢%2ކªð}…¢*nyʪ€ï@_Žóùbì!ƆPâÜéó°;è!½|uãËÉd„{‡{Ô9Tuq$M“Ê]ëÀ"Ò‘M¦FÃ|Š¿9ÖJ–IóPg§Šµþîañe€mÆò`}ìExfs{ÏAb…B0i+$ò~€Àâmçýeññ"[Ú£þÊkmâuXhÕ§CUG(·øñ¢Q÷¼ ì‹öÙ |ão ©¥¯|= ËG¤©=6KûÞߨÐKY*EºÇÓíÅx8zìKMk4z,Çc?OÆ|)#ÿËñXªSƒádc«R_ŒÇÊ–üóý/Õq8ÿ±?RÊ—åvè?~<ú‰·í±ª.Cå›ôi >©°’Ê=¾D²Z¼Oül–òƒs‘­iAÓ² õ+Cù˜psñ'2¾Ø0ð.=¡4Yù€KßjÊ`Ñ"–¶ AµGN  #ß­QòÎÊ?„‘B€Ò× "¤Üø‚Ï„oÐ"|ºGZ0›ák|™Øóƒ°æ‘kÏ£ü  弦÷,uTêŸo.}pèS=Y±Š”ÀÊ’¢5žWf÷&JËMR&Ç I%©LMFR§ZLGêZ•ÍdC^ÕçÊÒtº˜|9š,¦¸+ϤýÅLºÃ+éj2¿÷žªlÊÄ È¿ù¼:Ki_¾^­!y‰dX»Á¬Žu,–|ülKø-UùÅšt,݉€Aw Σ6¦BÆÐ¹©Rse}Ä#¦BsYA°ÀDJYQ‚À£éø–jbkQð(0¶ðñ`½/ÐÃIzKÝ·` [¯RWsÃãÂÃR´bè$nãɇ¬A'*Š”I>´xê Xwñ™l»Q®•²TŠÖtöðIe1Ý‘ðy}1ߨßÛØ˜L*[K÷6ê‹é¢RY(-iR-õù|çõÅâ^}!Qµ³ƒw§óz¥2ߨlÈûu ³íÉãÉ|c2üñâ޽Żþ{Uå_½²5ŸDŠ| °¬­'bK$¯,ª–kR°XJâŠOvlhÐô¸M!¢p‰dÝ%AøÍf Cq!ŠK+=¥ˆ°Ž‚­›!‰ á8+› ÌiÖl”uT\|Ð1QýQ7í…b䕸Ð?´Ù‡½J–ðñA@º¬@lÆP)¤Ý¡ÊÊZ  %*ÂÑÃÈ‹åZ)K¥è1¬iíÉlV™IÕç{“ÅÖ“'›S©IM&³Yu>¯O3©Í*óñ@Ú|T½·XÌw§ÓÝÙ¬>ß›Íwð®´+Oä¡®6Û˜ŽüÉlc"y5—.î-Æ“ù¬:Sw+1`Q±'t Edõ>6X¾Dr¨K5\ëYþZû„„ßcLzXØÄtsÃÿØÌ´mËËhXܼ ¾é$ù:žB¤û¬ùÖˆ DGx¶cÎarƒÿ#aè?d—[Ä-+MÚ/pдž‰,bÕÎY"è?^œh Ë Äêc%°²¤``[«•MÉ' ‰¤G5 ,©IUjµÙLjL’G[[›UÖ“Ù|¬4'icG‰¨êÖÖÖl¶¹!ÏäŸt÷Ád^YLdWQ™Ì-ÿ–‹T+ý#ÂÖjK$cg%K­¬K Å£†E­Éjqó¸ù˜¦ˆ7‚ûw95,_kXÅw ÆÇÑ$!Sa±Í€G‚”ŽƒìÿoçŒrÛÆ*Ô€£ÎÝæ@ý2°öYÌb ´@²•rUeEr†¤$ÇNÍ掠e‹–(YzRCu­ä1M¢Pç†3åx§+qYªa×¾î´-­† ÅWÒ‘_}>x­±ÖR5Õ–é<ÂZu…õóé9öJÑÑ&*h×ÿFOíÇxièïãœ~xþõoxÚ cã.FN½hk›æ}^|õi>õýÃ(¥Çáóù–—×ljÏý5a/ kÚ*¼Õ,ŒÝñ‡ÒéÞi7†Ï?¢ëS/ аê™Yc‚P"¬™°: ôl½åíªÉc·âv¤4zUªžú“@ªÓ>¥é 1Nçõ‚B7û¤.Ê5Úò%Øl"¬Üqß«K5¼aµÂ’5åÞ0{³ËK ËÖJ÷6a‰ÿ´><+ ëùë0<=Ç6Ýý(®a¿ß¦¨j?2Úæ~ÿ×裻Øÿ4FKÛ!ÅLÛT.v²QÓ0ÜÝoúÝ8µO¯v©u˜ÊÅeÜMÁ»ñ½Ì?·–›GX©I8¹Erë­[·HÎÎJYSÒk"ÇõêΚ K:¯‚4ïôÊÕ8/MyipeaéUBíËySÊ'šf¥íÈ9ÚùVÛSÚcäuf˜öÊu°^œ+YªfûØ•‹©²²Ò]¥ Ê]gA»ÁdCÓ·è:él®¸JÏ}Šåš(¬kª×\4 QXÒ‹Ø\I”í|‹°œCX7Y[X1 ê21ôéé÷øï{ßÿ]fK Í䂺Ð%/uºŸ$+ß(ù¸Ì[8šWZÓŽÇ¥­bVü$'ʽwÖ9æzç´Îöz»NŸsÂdîêÕyeàrþQ›Ã¾\~*YGKv‘{k¢ã´I˜× u]ä‚/_פ*yÛßæ”¡ªuºæ;ä¤Ï°XY]r^tM ¾†gy…šâʧ\öRD’ ½~óíHr¯ø9«{Üå+-p•µ›„_¿m2›–‡‡ÍîË~·ÛÙÕw6Ûíf{±|ËVJ7¯bémú÷÷Ëi ê l'iÛO‡QK*¨k¼v¢‘äÛs6Õ³ñE¤ÚÅÈ*6·"û¦Ómì1?F¾3 ŽáõÆv.ø°À9Ÿ8kÔÌ'/ Stžá8wg¬s«³2ñÒž{þ½ªºª»IV)±žVW½õÖóþ}~õ{Ÿ÷­*õ¸”RJ)å"ê¼3PJ)¥”2®”€UJ)¥|`¤¬RJ)å#%`•RJ))«”RJùÀH X¥”RÊFJÀ*¥”R>0bëZ¶,àßJ2¬–8‹â\^»vb3N¿vâ<åÖEnñÆÔ¿úM%xºše5su-‘ÂãÇjÇ«‘…¡g‡ÖÑq{Óùô– +ç _’€µ¸¸X«9]dqqaaeaq»YM›t渢&-'Vð‚tÐofÕèÌ ÙGuž®¥õÞÊBÂÖ®­dD_ |qºµÚ‚M·ft-&/\Y0¿‹X'‘ÚBF¡±21‰9¤ÊZ¤j»¶Èûôçd>+£©šÌ>µÎ§èî²°äV#è–¦‘ÛÎÊÂðtVÌ¥ :I,³è\¸¦ÜÉðBº- )’äwD3J]ûÜyÃÁŰ¡6@£jµ•Ú³ÏÖtØÂ3ÏÔ8*šE :µ6Ád^°4m ÃÎùEGsF'êјÀ¦_[I"V‚"¸P,nmaQÒ•Üs]¤ò» 5mÒ ++ˆä‰i(YYÐ¥¦LÍëZ[áêZÂ’y8¬¾ÅkyØ—gàÜ.tïXyú†Dmê"5 (Xlœ Y¸ÆèDz!UÛ2 ‹ŽZI„±‡k y³ËÉ­ü)kªù.œ7\|qËt îQ™ðlsúä³ýܳú^¾ô[O/P§¬ `¡¹éN˜4-}¿_ɰÎßFè Œ:OÞʰV]SY d­­/h+òÌ3X\àt圀w-_Tµb~I#Û,˜·c¨ºðX+Rk˜@LÉÖ5° êÀx¬e[¯i¬g ‡ò½ R ´YÉÇ&F DŠŸýí΃Z¬§kÉmVR‹ ´¼Ìu˜¬…åZþèy{ÕÂb-ÕÊxònñA”󆃋/‰!af¯°£ °‹¿ú+èÂlãÏüæÓÏȉEÆ‹ÅmÝìp%£w’οú(X9rGç‰[ïLr˜´ÎEÆ[–k:]ü]&Ó¦P þk.¸¯ Ùs­ÑwŽZRʆ)-ê<¸™'è]Î, ‘:œçáp¢±èW’m: <Üåü}ô·A-r·…kÏ<ý›Ï,è¢]3€µ¼¼´\KåªV“ªXÎ(C 1Wà`iyyt™1™åó`PnS‹%`°pd³2pÓƒA­mþÙßþÕ¿úUæXÐ…ÿûO?#]uQLŽ:)wWìØŽžErãXöa;££Ìù³Ÿ>`é$’^IÑ=!1:Ýy›®á‡º0ù­­£¤ZbSZ‘&ŸÂ±îXÀúœ-á ¦4À£Lí ³Ê…š ”®ØvYÄvù¬iÝ2+â±#w®•¼dtóÕLÆÑ žùôgŸqý\ß÷ŽŽŽæÖýûÍ}­vt„D‘†–58x8° Eï?¼€µXÖb ¬ìÞ=è’ï§ ùÏüç~õWÿêÙg‘-\³àBý•|Xµ£{÷îÍc7°¬å£{µ,—éüo“ÎÏ}ldeᔀµÈ´°ƒ€ ð@åZMÁÀ¤;¿R“tÿ ÖÅòb2¿8&Fµ+dÿGXØy0¥ZÚäeÝ;2¡¶Ö¥Öˆ[è.ª‡„Ty÷2ÍR³·{—3­VR€²Ôl»$úp-Ö¿`íÊ0d\Ñ̨ÃL@Â_ýÜ<âÖŠ t!@–AÔÀŠë³rk°,wïÖ¤ÍàúµQL`™ú¤SNÁûØyÃÁÅ—„ÓýÁƒZmþÌPîö²Y¾‡ÄNaüöü< ¤pʈL½7X÷Ž–æçé*½×Ž j|g]–½à yIDg g·´Î“·6åÿèÁüÒÒîýÚ²ð½ÚòCQXaöðß@ºÏRYÒéêº ÞäTfû! «°8óóó€ÎPæšê_¸zY.§4Pk©YB¨½{ ðžÉ`Í݃íC¬Z¨6*“xøjh—¬˜H `ÍßŶ½†•°\[&.œª@@¦ù¢Î_EïjEÀrš†êèî·Z“•Œ‡éj¿&}ŒÎB'y¸>­àN·4?úaä[%`# À‚»ÂŽt éË`(óh)Ïþ«ùgÁ0jÏþN çŒpH¨g×Ää,a|r:ðµÐÓ–ph‡KK¶Ç-/à œa]Ï¢ÓÝèü¬Ñ©qÌÖ&†x÷Á<é'‘Þ °”44N7«,×ÀºfL vž¬çˆ{È Dûš“Á5_Lñ jÍMIJ¸à–\^ÆÅü]@¬ùùk¦öd»Lé`­Q]2 êר,Ò.ÿƒIaIÏé1`-@Ó.C-陟7uC[:zçÙ€à³Ïþ+ÔF€¥kˆí ”òH°„™míþ=ä¸Ô‰–ÂÝYØÒ=b£4‰5sgáÊ{<ÄöÁsHïAõBg»7Ï]ð!1N"²p ÓЪ%‡B9o8¸ø’¬ÿ› |ž:Ë}ìß÷îߟ?º‹ft §¸ç \à–û[O£‘?ýŒîÂhrµ{w˜QQïãaÓt®¤ôð 1îá@]÷hŽÝêœgŸutº&=FKc²˜Q—{”ãûd,voÒ_†?°,Ö ¥Ë0’•® X l7Ë n`b÷j+‹Ä-0&–HÌKм ¿÷°Àïãå\œ”\À¢TМQÜ£Ì>DC†RÜ6¥X¾Ä1hj•ÁvqS`ÀZA(G?zp÷èË™»«©öð!Â2¶”ñGj¸cþs½XÏ<€õôo¹€u­¶Äx„Y‡}bçØ–1=`F€,K˜k€Ëù÷xõÞ!KÈ<ðÐÚÑÝ¥yì7pè€ ܽKà ”rª|éÁ=ä–ó5JÛðè±èóÆ–‰ÈyÃÁÅ—äð." Pp`%x‡¼{w ú3uA^½@†‚sFÏüæ§?ý›Ï؉5(è‰ËË+8^"ÿÆ6½vZ½o¢Ø•—… p\Ó:?ûéOÿËg€z-Êrí±û%û­2!¯ËºÐ×µaY0U‚±‡Ë<ŸN€•N×êè@ÓòÃåyà=ó`%K8Zà³+´^ó‚{ó(P<0{0EmTHa¸Ö®9)-ÕkoÖÞ’,äGÄ-€Ia)IæeÀ¨K4ϼc^üRó\–kK’‚i^p—ß]"¦‰ú2–± Žîb+ß›§ÖÁbÂó 2\œ'ßòÂ3ÿòÓX2ÿX“:Z °Y¦aÛ]¬c¼ÙÝ}€i€!ˆQ?¸»´©®, ®-c->x`rSÃv¹{wYjQëYº÷€u.é0Ý/—rœ}dá[óyÃÁÅ—`-Q'û1þB‡YZZÀÂžŠ¦GsçOÿæÓO¿ðë`+ÖÆWj`Ïw–——qh†æF>10cì°c> j‡1Õ2[+Ûú`QçgPçµ……EY§y"ÀÓBnµL¼g™‰Ï˜æÑ2ŒàhÅ"¦‹W&Ò5º0¯èTXFë¾t„ ·{r×–<%ìPÆÌø£X̰…뮳Ĕ~SÒ‹W¹«2`A…-/“ ¨°‡h½û·ÆtÍßÑ/£:4íòß9íRî ±‘Ó,³îetw`=@îó`iž¡÷)=-¸N~±\Œñé_ÿÌÓ \–Ί/k†uP·wï ËBà[œÉñ¡ï¢+ìÚ2¥lKi@ –ç@ …]é6t~uÝ~hp«¬ñ$Xä-™×†|t‡¯ñ#lä+p«|ú7?ýò¯ÿ‹§,z’É們|ËHù物-kÀZ¡QÓOˆÑ² ù~ŽÃÕ©WjîÎRòõ#O@pZF²sOΑ6Ä\†°¸ÀéÖ’eYѺ°®ñ°‡‡.À%–°´'†Ö!`ñà‡›Ë˜û° xÁÕÚ³¸Rká™§ÿ%§T³9çÉl"ÂiþqWÃû2{ƒæïi°:rA ]׸zýYÝ.Ïè² S¿fëˆK`‚¹ ×i߀ä‘>wWW:ù°¨mžþ¿þò§`-èµtè3\Ag‚åñù-9™îÕ4ËÒ½¥¥eªO·tGGÓz@LMØ0èyhé™?²7b`ç0K X㉠X|O—»#ÝÏa‹ìº­—À¢G ŸþÌË/<ýŒ;iD¾vò¬?b‰Ý(¼ÐWAãêÞò4™f: '¬š<ÿ·°‚>cÊ7ÀÆò}¼KóÒÉçaàyA¼Zd†…ËReÑ€ES™8óH¼ ,jîÄ~€¦ÌsÙ ?ËÀVÐy·Hɘ”L íaíš,ºyñŽ»ü[»´´ä°7iÃRk¼*Ö´KÍ”ëEƒ!\ytÿèÜ6*& æ-\ðídÙ¤+5 ‹Zû™§_xù3¸‚>ÁB1HϼÙ @èüÑ]vŽ3SzÈ—i xùO¦â:8Âé‡?>”¡á}„híÃJ3¬”€5žd.kXæ»ÎæÌ£éÝCVÂÏjüŽ<Æ‹÷ò§ÙSRãGs kÍ£¿ú-9™Å2 Ÿî¢+ŒLáÞ]êkâј„:IëˆN³ê| Ñ€uìf‡VèÝyö¥yÈÙ /°¯ßÅå´pˆÒ­%Ó5º–$Ý£Òr|Ä«ÐR ]‘[à‘SâÁ×½ûóÿ×]byò¸ð` y)'“Ú™%”!Ü"î ë©Ý°Ä-BµT#Îq™f¾¨S¨ÑƒR¦]iÜËÃMô-ð|é]ö$"¾.1¶³TC4 ·Ì.ÄEœ)ä•ï¦¹í ‚ÖŽá¾iFàáC™2¬ñ:,šãCætÿþýebÀÂp.î}„#ôÚ-àÄ Û<^‹Èó pšôÞ§ID¾yZãõ¡Ã¬k%`–âéâ{÷É „nž\ðt÷>€ñÒ}–‡åµ>ò,á2/¦\"§7þòÚ+0À£/J'Œ™ ¦&r¨¾f~^\{~P·4ßîñR&žÇ)J6‹{ŒV`84˜ ÄpÓ}Ú”…u-¢ëè>ÚÎÌ?8¢¡éƒ‡5\ŽA¦ˆÑÄîó§Ì£Ý{tÅ2z‚tJ+¶„ ü"7ó4 I‹^Ñ#´Dy÷˜Ž¡2ijûG6œ×ƒì]c½Ø.¼aÅ}€\(X ¥œXÐ:——D åqöHœåóXb½@uqr¾¸bò½˜,^tas S`Å]M…KL–——efGNÈCz1Ų»"¬¶,ëæð±`«Ëó²B$)%`]JqkÅô‹§ïp¯Ò˜Z­¦½FfqâBM÷_ÛU—õ}z}ϵ>guj [7è°±ye`ÁIßä`9ªY,Ë5f<µäc>YrÍ<ö+1t-e%$Fê”°–zJQϱ.sE;µxM-óêµÄÂJ©ÓkYu(»2$tò,k¸( Ge(µ£ž/µÀ`´ÒKsudV³Ê[uRm½Œ8¶¬sËÏLê?Sž{)ØÔ@Í„Öôï oi^ø>PÊpI¿­ÝÄò —îò²¨;³\p;@×|òºÜ{ᢳÕA‹ Îsÿc^ÈëïjI§iˤóTsÊÇ ™|=•“ó¼ïäŠ-¿»¢=Un#úm ö¤yŸÃbRÓ`.ôÛIÞÈ•z×VÍm›Å„&”é3 ‹ƒ)]ENÑKrJ.::¿¸8¨'©{èC” ™½ðCƯ´•2\Ro]a·ªX³ þt©eu,¶ýþ?'|œUØ[̉|Y0ˆ¹R[\ÐCIwDi^mG ¶(©hle["€sŸ%L”C?0e^‹îâ‹\ÃdðÈ(7ÖyÞYuMhTÌžÉ{^UêE]N.„a][ѯ_›Ð‚¼×Â}%Ì üs´Ê«“õ}í¿ylqq ¶SÂEºr1ž «åÝ.?ŒÃ@WÎ.¾8€• '®èsoi~Ï˰˜ÅÊ+LmȇŒ2Äždíeè^J”ÊKí$­Nýeœ7†–r9o8¸ø’bX§½ƒ`¥ÞaUL¯yÂã' X92^Û'ê»D¬‚å¼áàâˇæ«9?ÿÙûïÿô§ðÿ§ô‹;$￯ßßîÿTÇKħíû?;RJ)9ò¡¬ŸþäG?täÿüáiåG?ùéy—¥”RJÉ XAP¯×ƒÀ÷ƒÍÍMú…þ¥° X§08ªû [Ú«û×ëëë:”A‹ìÖ}#˜œ ’qågÓ†iå˜ìpÁhžüì'Ÿ}áåÓÉK/%_øìO~lÖ9/ë¾ÍÓ:fœë%0õè¼nnê3T6¦ã­¯ë2“Þ  s›tŒ•ÏᤅS[wãR]’§@·“®[9u}̺7©M9Uν[n_ϔ˖Ñ7uÀiC¬:©õ’q°®ê”£:¥¾ØvÔeÇR%uš8ußÄuó¥{ ×a¢ÞMœ²Ø2`£7\|±€%(Ðøa:Ê(ÁXXºzðÿ§5y¶ãSï–h^2ö¦NÓsÓ`ðJ†0t’q¾ÿ£nÝ,Dn½ð£÷Sy÷ò“+ް㜴~Ç€óSò’¿ãäÇ—†u£uÝp ¬Ú1k#Õ)¼ÑyÞÐÓc#«¶†Tð˜¹gܰ9o8¸ø’,¼ƒ‰Š°|bX-sÛvS>ïBŽW·Ño'õÕ‘WØLð]¸¾i1й€ X?|ùæÇI>qF¹ùò]ÀL5Ý>ÑŸùÈl¼ôEÙáݘ­?Q7¹µHÑWtPiɬÑÉØz0w5[½žnµzØRq=Ó^ç%½ÄáÈL{Ñ<Û¼!¥8I%7\|I–¨Ûþ¸BC º<Ý¢ôà0…~A2DCês{“¾ÚÆ#ø±±êXŸøÂÕÙ ëã XÉŽ¨ûø8¶ï˜QºŸçõç4`åÀ`‰ É–ƒ,W>ÃÈâÈg^1ž›û´*/ dzjÓ=—Å¿Fp-/•Å6 âe©Üóœb:ê%ÏjxQMk=>~ôÞyƒÂE—a½ÒÜm6^mUÚ»­+s»cw^ÊÁåÁk»3í@¬ `Zø×À߯nsc½ª_]o4šu?h¶çÚm€DàqW)EmÀ!ì4Aähs£Ù|Í÷›³m€Ïu YðÄ+›V»Ò´stXO½ðÒË/<¿/ݺõÔ-¢X'-,…àØøJwCåôs€UHŸÁÄA4…ž½0Pº»ùcÔÜM)4ÐÊQ/bïkãõT¨i”®2:Ô¨+ÆfXiU:cŽ…Q ô‹ŒpýÚ²bµ*›”JQ#/óW¶‰zÄœk òXq*¯ž ã€gÀr&y·F¨T¾}•Ê\nkýãÿþïÿY‰XùâVsvn¶Ýš¾r¥=pbçŸGz“?¾½ÑlMµ+íÖÔn p«5=݂ߩÝÝ©j¥ œj޶ī4`5+Õ6ÆÛÝåØp¶ÕšíÌôU€éÍ"ÓcÀâ«_iN‘¦¹«©ÂÌê°¨^zŠ€ ñêt.x,#O–G@0ôKô| Xžî•Ü%µ!+}×VÜ­ 9tn¸XžÜØ6#,Ãð<ámʱ|å uåÃr ³8À2ª4 wäÜ)eŒÕóõ/“%]\VrÀãž ôM1“€å)?E°$ý„J o’ŽÄQE¤KÉ5œ¾’.H¨UÉ1¡` ï»]c<‚­õ蟽ùæßŸ7,\\qkwîc€8í+ívë$€å`ù­i€!€ )Ø´gÚm8œjìÊ.@ÎÇæv› |v«ú+>»s‰ÿO!ŠUábÔ‚q›ãWÚ [²Ñ}¿†P%,ø{ù©›Ÿúåßøå—?õü'N7eè–3ÜcÀ"ÖƒÝÙ,{óOŒÑrµ-ú°{Ú*÷”fX¾fXŸŒÕšÁa‚ ,ÒçRijРXÆúªD` $’¯¡ÌášX+LL• ©Jʧ,q1õ¦™­ïês/×ÜI×Sà¹ÙUn¶(–Ã8åÑÿ›f6w)*óRËËÝ|h­ã¿<8üÆ£ó†…‹+`y »»Õöî.û°ÆYÔÀk ?öíJuîê• zæ*X»À¦®À~U~®^™mzõ&ï0=àb3¸m¶ÚWàìîî,ÀUµJ¨5Û@nøf ¹j°>Ú¯kªhÀzéæM`X·~韼ô‘[„Xg,fXx ÍöOCAY\½«ËÀîîpΊq†•´,åY# ÁH2€å'2vFI–ø™L~,\/bÏç_#“6uòVYt¾â¥ Ÿê> ,* €N…iBå9*uv•á¸Ú³¦Á•ø’Æ)ýßsÔ{`e¨÷˜Ê÷Özüö¿üÎyÃÂÅ—a5bfÈgíé.”°6Å,`ȆÄh«B dºÑ`nE³[ýµ6p¥zRÁþ€éMïîÒ¶ ë_·*‘nµ§Z³tõ !a¨Øhì"ikW›iëiYu/ ëÖ­‘a½ðâ­ÜúäéV8$ËÓ>,,™ŠoÁ+0ck(ICðÅj0ÜÀb†••`yA`Q.à ‚Q† Ëp—CÈñd€ayJ„”ž"0´Ås†¢žV‚ayJ3,?ë¿V©•ªÏ÷³K¥–'77O· ­D?é3=˰ìÿ­ÌfXæGy©|1$|ü_;|ó¯Ë1ažXÀªû0›ÚhÎV`à5µáùuoŒ1!ù‘hH8ÕÞmîîNµÚS»Ífk¶Šã¼×š³sÀªš@ŸævÒª³@Ö­iؘj\X5w§§ Nµ:ÛšªVÚÓ`fèÖÚ€Ÿ‡øpÙ è…¬+ ¯ê°d±>‚€õü-œ%¼…³„Ÿºyë#Ÿ<Z™uX~rÐÌÉñ´x5œ™DßXªJ¸4ä¬LòÙs\!vᨸ«øéÖvï;Ðg,Ò¤3Ò`Ø~Ý©Å3I ³L¥Í:?åÃÒ&œ=~Óþ(íF§šåéºÏ”Å\Ïm›ô@S·ƒoë*0paØ“ŸâEúÆcg ]ôJãaR}j¢ÁäÆÍ÷xCÂÇÇß>8øÖ?ž7.\Xqž%|†eíÖ.oZ» î XâÃj!ôÐåMTÕmðÓª´?v¥M0Ü¥üÛ¢–‰*ÒÚ¥ÍnËêrõÑÏîFp›s°¬`ݼõâ‹0|þS0Ä¿S‰Y‡å>'ç'û<[Æ ¬åÎêj2Hç¤,=H=x„n¼Ì‘c˜€Ö'Z Y‹ðäcþâÖ*É=›:A£^§þÒËŸ }W¼¡¾>“„—­ØËpW¨&¼nƒÓŸ:ßcÕ;ØáñÞ<|ëÇç V,`m4§f+•ÙÙY :³ð;…kŸ6Çô»ãˆ\V©TQÉlu®Z©âÑÜ\®ÌQàž„$’ÚÌ §‰Qáo®ŠWp^HÕ,¨Vè2ÒW©Àvª¹AiÓCµ´pôùOÞ¼ùßN=ÏgZ‡•Ù_­ ¬gOo֊ż*ƒk¤ÆYi9ÔdÉ\Et: ÌzÔÌɯ!KG9Ϊ$wqU*ÃvQZ6(8ð“8^2´øCî8æê$Ë‚/§Xn†ÇX‡õø½?9<ø^9&Ì X¯6]Š‚€lúc ù°ž°´š¯PÚX/ñÒvt´Óßé\î°†1…Ìs.ËÈ3Ê,Î0À‚2å%=xäšBx••À>‹5´|éÅJöÜX´+©2oÉ«—Ô—¡y.²ÏË:ξŒW©…[ã"Îþi9O˜#ÎðU^´©¥1V±cŽ&®ÎFV„FÎþPE¼¥Ç€ÜYBXŸHí°†ŒuR¼*¯SfÂNº›r)âŒmù1Nõ”òH‘!¡Ÿƒ%CVV­Aþã.4õ2+3Ū¼QàädvÖf7§—–¥Ès«fÜÁy>-Fµ±ék±®%݇eßœ§üIm=c=¦Êʶô談å˜0[Š,jóx+–¶§ƒ8æ~hd{{Göðäö6ÇÍy ¥Ë¶M››ÄÍ,€£µÕµ5F§ÕÕë×W-T¹FÁ«Ãk S¦ Z?×](ÆiS ©RÇÞÚÒ‡¶ÎÜÝ´n¶ÌTîóâÎ,ŽÔÑåEç(âößBí:,Pâx+ur'·œ0½¿µ³µÒ¥˜õ•0§=BÎ#ÿ†åŒt­BJ ;[RSA1ÉIÄ-rVuÉtù¹=›„ÒZ(Çß98üj9&Ì”B ÿ¶¥tWÚÑÈ$w'Ó6a¼c`É®;õa9—8;`D°ֳn¬xZe0kmm$ËZÀŠÃ­íí\€,T¶b¬½0v¡(TTe®íÙû²„ç)!‹1CcÊ NipXá îY°uKÆ“Ñ\ÆH‰ãÐäÎjqáY 7‘f_N‰Bû›ÊÆÚâàÁÌsH(Uª-HÅ©V85êgשaXßùâïéírž0K îw:;x;ŒïÜáÞ³³#&ÝsÒ£ ^÷w÷÷é<Xˆ Ò~ªÇ ;C+ŒiT%¨ˆ„€µÆPETKx×uÁ«µ|‚uƒ–0¼Ð¤1A ~*&B†hÌ%̰&Y[ƒµnM¢Øå?§¬0¶¤0“Á„Ì—#“°AË(näBŒûš«uîb(Ü2F†òØ¡"Ç“iî“ʟΠسÅü–9­„.`=úúÁ¾SŽ ³¤0À ïôú½~;Ñ~·»¯¡ ¬ØÊ>c*p§ÛïÁá>p1Š#, ~: ®Üfƒp—Ä©í,&A]Çña R¨ç’‡ã ­d‚ƒÁ˜q  µ¯Æ1`‚b4Lƒ\±=¯}1®Ñà'­^üc®ŸélV¦ë;Np&W¶’†¼³CðeO¦À‡s® ¸µeÏsi¸hßXœ4ýg¦ [QlxXbàj.dŸ”®TÇ›Çæf`Žôý!Ù' ¼‘…ìÙ 9þξ^Ž ³¤8†µßŸžžîw¢íN·?ÕÝßÞÞ߇ý€ÏÎNÎA„ÂxS½Î>Kã ‰NLõö·‰g_C¬eb0`á©kü£àç:ýÑþõçtœ_¥€¥ [ò_ª  &A>¹ûsjpH¹Û8:Ã:‰ èª$b V \@ʰ,¬õìÔ@ SO‹ÒC.c‡” 좋ªTI\ñO)i!×F”HSÚ(6å¢ó8„£`®w«Ø=EY—úˆêÔ©} ¶gÝ-ç°XÞZÀúÅÛ_z£œ'Ì”Â+îô¦û½é^§Óßë÷ûÝ;w€gu„Wu¦;Mõ{]À§.Ä0–…(Ö…íÿ¸Å×÷§ö‰g½ ¡p-n»ÒÙ‰ãìÛ¹8í°¢˜>)õ=g¡ËF XJÚyÊÃT¤l±‹ìK¶¬Ø$”"Å6n8ÀF¼Qª²´G¬;fðÕ‰œYHm¨Bs“YM‚Æ<µ¦“ÁTH—(†RŠXO *¡@±r(®3WSú*R64¦b[)B®Øäˆ‘PMÑ¥ú®¤wTÄãQʼnEŠ+ÕlndªHæ-}KV9O˜+ÅQ—þ¦+½)àX½ÞT¯_©ô‘u§{] öÿé~u{ÖéO€!%b;ñ¬~§;]¨êOW«]8±PË=Q˜nêAÀZUkX–W¹€¥ÖF¬opK÷Ò¢zfFWÕ€%†¼‰Ø%¯¬Á*º»ó ~‹ S¹ë+ñÏ " \d˜A\ÃJÌM1‹c‡ÜFà‘}RJiv‰u«~8ç*v"hâÃQ,80ÓW'EˆTò£ñùës3 c ò—aEÇ‘­˜ˆë.±øÅÄ/ Ó€q %X)À*ç ód€µ·ø4Õ«îõ*{{€5 Xñ;èŒÀªV¦:ÝÞL¯_}ýõj¯GÛ8¾ƒÈUíñõÝý~ïõ¹\°‡ZˆcÅfÒ0ÀdH(?Ä«Ôõ$`™5tP(Æ(7ná'6 ì¤ÜS·ØÏdØœ¦NqdŒFà@ò´%$@Œ(,ËðãØÍÚ_¬ÎнÂnØ5&piÿc–Ca¥¡rä”N†)9g®4g d¢ÊJ%DFÃ… XNL‰¦Sm=šÁ&G³¼Té–Ž™…ZlŠ%D×5ßXh#‹!Î*v¢É˜Ó;xXÎfIq>,dNÀ™:8„êÞ^   ¨[ux@[oîêÕ¹oqö°×C¨êVqÛéU¯^éw+=ÒÒ‰­‹>£É ÃJü¨`™€ë£+ff Pš±ÕÿÃXS"µØ0¬Ø‰F«§¤Ù2‹<]'k<ƒN³69¥=GÆA”ZÖ˜Ô­½A*±pô´9FÀ Ç“2ÁÎj¥CcžjÓ”iíÊx6N|X‘ö5ű‹ùv¡l\íò6!0ÊLª$*íÛw4:óLž”eeƨ© ä=Ò‘%?‘“·¬_”ÏfK€µGÒÛ³ÒãMÏ„Á^~z©¨½žtÀÖÕÒÕÒkîÚª5w¥.ÕŽöµ£(ÔO³8O™¹‹-‹Y…™5Nãi«-9Ík $jbAhe/VÐ GCgù™Å´ÂÑqñ;k\qçVìNg¦®ŒíˆT®N>h#1ž…J dC!Fá°éŦš³é¼à39¡<'hU?’~J&L$ëØQ-6¾µ£gÃÝeŒÅ Φ ÛZ ?=8jeºóôÜ@ÅD²î[/B=ûä–,'fŸAJNç×B˜~:‹»“Ò•f/Γ¦[‰óà ã>o¨h¦‚€ÚqùÙÚÊW¦–œšëP[ 8€uüÝrž0KЬíN·Á1ä€tòë3óÁ#‰Ó˜²Ê€•^e?IÑϹLÀ©éç‹¡ôˆ¸hƒ Lxíï©…ž©¥äŽA½óV9O˜!¿­Á]Üé>¸¡ªH÷"wñ m@çâÈ¡î¢?ùOžf)°äõ2nWŸð?‡® –¯ÝQ‘åõSº¦]&^?—âŸîÆFÊyÂL)ò}XÑÀ›ôSWÑ’)ëÂ( ‹¬'*“LpBºŸx]q ªœ'Ì”ò£¥”r¥|ïh¦”€UJ)RÊyÂ,) °|ú– ~g}¿£?ÃÇ|Ž…¿M_Å ó±˜ÍMþs¿¸ÌqœãŒO¨è*vHèž›ïä_ÁâøUÒ ;­Óü¥¿Ãâüa—¢òuYÆï¾z~ùþ ü-îW¾]‹*ç ³¤0À’w›ò±h†÷S^e|PO7™ùðW=³E͇ÁÀ<bxôá÷¢ -\V‘Æž%Zÿ ;xº³ççOt{ú–qæÜr›ï#g„Q׎£;/ΤÚ<+m”„Iá<áJŠ•”¢‹¾CˆBÇøuB§aÖ홄 „Ô³NçÀ™Oì$°nܰÛñd …r;yÀò2?v:¢ƒ§;û0ÀrcQÄ)ù.aaUï'LêÑ·¾]VRŠJå#°PO¦ï±J8†BàmFëÄ–n;¨€'nç4ªçç÷œ@‹_¬¸ó+’oÈÂöÕëî97F6ÃâRÔý'#ƒ€•þº¹çgÇu´A¹-S ÀØOÕgŠùúq:ÃùGC>Õì¹~äéìÅ{y'PêYúNðÁùÓKÂ¤Ž¿ûo¿öÞy#Ä“ÂËÛlèÜ×¹eoÛ_o4ptØhl¼²¹Ñl¾bh?5Oû›ôˆ:èjlÂ5¯Ð€4 é,ðÖä!ü|ΚYó¾ê|.GG°Æý¾xÝ4à%7ÉO¸»ßh¼Ë2u{¾ùòv!¥J1,/S£—.†ýèÏ2§?ŸüB}*µÄáøŸ˜OŸ°9óF^6ÖéÓHÒ¦ÞùòïñíóFˆ &…VÐhÏ‚´ºo;wªÏ·§¾ßhO·šÍv¥IF y–—´!kLµøçkU·G44Öêšû>¬kîÃÏ«ö¥ ôå¡Ïæ1*ÀO9S¸_|ÏLuSLD)®Eu‡1J#Z¶J•……ô0Úp#ÒºI§Çѽ3›Ü t®œ†#D2ùñ"Ñ;(9öÄ›¦,ØÚRûpè<]¯,ˆ¼OçtEÐy§•)T ø\ÝlxT¿T„Txèéò`ˆª»MBõGîëW“@¬¤M=úÆáÁ_–c„XÍö\»ÝžmÝæ+À·`»¬«±¾þù„û~³]i5[W®ì"k¼4www›Æ«¯6€{½†a×ÈÑš3ífs¶Ý‚ 8ùj ˆ•çÇ¢!aòýÇköÝ2'~E2õÑ °RÚj&%˜ B@aSA#WlpŠg6%‚[hxž—@Îq"î²4ÃÔ‡ÂcT"µ‰u)@©ËàYÀÒ 9™ž¿uøf9O˜"«JCÂVûcWvr>6‡[àV¼O€Õ®¶gÛW$|wîc» ×nOÓ¶ŠÛj¹X… øô5Î+’ŸãÉlëh/žtÔItOÛM `iVe–â5:tGgãb»ôÍ]Ÿ™ŽR™7},¼H ×?ëP&=$´ùDä`¶ƒöíiÆøÊÃ@ÌåzCœ8fŸËëÛ?‡Êê—h8ì¤á ªõ(€%mˆfŸ†åz<$ô=&‹ 9‰žão|¡œ'LHq€¬ ‡pëö•« I€¤«W°pHè!#Ȳá¿6×j"³‚8¿‚ûsXu8CWÍi«ÎU°†™ÐºfXkB´ÖècÄ©VׯH^Uø¡B…ï›ÉYî ìa])Írø?1в,ˆM™Þ $0#>ϵ[OäxÑŒ&oY¢®§4·*„zžÀ34Oyžòu}Cþ¸drcâ{ã‘3[×\F[&kÆERoK”ãYññQ¶\àwÊŸ¨ / FæAò´`.©IœQ$]xæšL´ZʨŽÿúÍrž0)EÖ49É †4‡ªþë6@Ï î{im¤MÓ&r§fÉSƒ¶»»Ó¸WýJ»á×!¬…!mº¢Ý XİVí+’qbP×R£BÙ °”õ=AÀòÉ`X¾v¶¡²qˆÎŸöwåén ­íìföøqÝæÊ— 9€¥ŒA{?š<ò؉ž>/ìH9e@0rË÷}[3fR~°øZÌì¯sšÖcŒÿŸÚÀóäÖ¨I¼`Y†Öãw¾üF9O˜«5…°²Þœ»Rm6gÍíD¡?«5SE§ûFkjwwªÝžÚpÚuªp×7¥}~ݯo´¦g¦w[3èàjÍVô0]ÖskšZe¼"y¡‹þ®>‡€U¯Ó,‘_,/Éë²v&Ï÷•=¬+zžI¡—-О¬\íV·vv1’á, ·’ïüYoœ9éó€0y쥔ŸÊµïNÏ™²ï$šŒ¦h‚Fé©>[EÖ¨eÉ›žÔz)¢Ô¹òåÎÖ \ª‡Ð•¶ªGZÎ&¥¸YÂÏ·Ú»¸«…ĨÕú•öÇ®Úà>o›MøÝÝ¥Žû²g[4¬„˜¬Ã^L +³wð$ô& ×Ì«„¬éŸaß§O1¬:/}2+ÓËÆ‡.Èôêè¢ÿ·ŽÏ:ÀÔ}{@ýéAËsVº›…óf¦«7µ®Þ<Ïè%SK¡XðÁ.Ë>†,6ÓÉfi‘îâyš&¯ÄJôíëä8µZ >ë9Nw™V‘€åeÎþI9&t¤0Àºýù™Ê, ¾ã·Wæè j¶³ŒQ­V8Ž*r âéÙ ýÎÊyÅC|erc¸ ³Ó}0 y« °ZåI[XOdÁ¨.$x»ØÎoÅ.J]×Õu&á'ÖE­“gÏù;{•œ0òÈ%žùÔËÙ(µ?ÙG¼,†Åó„å{G­éÚ 4†µ´¯g W¯ßµj¹UêA±èëj?Û2ËqL/ì²î!éZOë `1›‘G9í)„æë¢Vòœd8).—ódLnèíT/÷²¬‡|<÷:Ï¿"_ž[Ÿž—Ðæ.x7ϱzüh™—ˆWdÇȬãòy¤X¸H´©ÿšý4õqZ2›©+mØæ#ÀZ[£âܸ?7ˆX‘[}Íq®›'t†Q,y[Ãë*Hp±½«Åç÷CËZ¡AK Lçöíã6CÄ2,/1Ü9£qay'/|"gøƒ>éhc”ÂËøµƒP/õ NÆS?Ãr[ Ø¡ó€Y•ó„))øágŸ´ñ×ñ&I#8XÛÜÔm¦ ]>³Ó㰣Ƨ)çpå¹Ï¦œWkû#}XÞðÇ­‹Xø.÷ñ$?Û?åB•õ¸ä›“õ%àíLöç–;ÐìyY.z™!ƒ.6oð‰B/Å‚¼ä}Ä+Ôá ¼¤Ò¼-ž“tÎõ™ Ÿ]l;˜Õ/Êy¤”o-¥” ,倕ÿ¹‘Q®ôñ†ƒ<$LgfâßJ(þš9YžœïÙf9{¡$˶yÇ-““d">Ñ™8y0î×—FT}|’è§“ ÃúqùÞQW ¬xK>„k¾ŠKßX7ß?ÝÞv>ôGGðÒg$w¢Ð|‚p'ŽèË„á6œ¦½múPØv¼ùfd|X Lèx_ÕNöµU™;´Ÿ„·¯üågüŠê~?ŒË2Ñï…¢õï8ßa·pt>éžÈAâSïûiÝæ<}öŒEáïFšO)fjvHNaN’“0u´“:1øÉk7•0S]F.Òx,ßzÍ73Ç©÷ÓI`•ó„ )°¶ÉÀãÄ×’fì׌™W9Ÿpæ/Ào›£ìÐú#áæ pYˆX6` ü}f X<+hY•^µ*kJׯ!ZdŒ‘ “ý¾±XhêfԗЩ"ù<}˜¼"[w‹Érä~*77ÃvoáøYFfßE}Üǣɚ9‰õ:W¸½Jƒݱv’ Fð5¡¾Àƒ‰ Ã:þë7¾öçF ¬ýNçw;w¢hš6"r G‘i’èÎèBÑ»û´OÛímæ^©/?‡ÛÔ=î>´ Œµ3°Ìªv U«‰W&óîÚÚÈE iÀÏRÎÔWTYÒI…©²°PÊãéãÈЬ°µ1ÖêÂaü4³¬cä-¡Bvì-Àh¦™{}ˆus¤T´P§=‘þIµÈ/Þùòa9Oh¤8Ö~·ßëõ{ûû½î¾m‡ýnâ¨×}W‡ñ–:ÔÖuÚw `â¾;;¦›m4´néô@/›L­ŽáÌJ–Ã"R]½¸¾ÊÖŒ aYƒW”„ÍØ23‚Ö®”üüERí ä¸g´·m‹±9Ðá4"slP…¡ñMF hÀÐÐè4<„ŽãÀèÞájÓî¼ÈD 5\aß2íª÷l;Ýöª¶mâ~‹üŒmž¬Ïm[­ƒR¾wÔ•â«ÓŸéw:S€0w€Wíïçêõ§öKÝÙÞít:ÝþT ª?ÕëDÞt7~"EÛ.Hšm»ÓFÕ¡-ð¯íÎêëÿn§ÛyÎm»ž0Ý¡µ]^×ïÃZ㇟W?Ë+Ö ΨՑ€¥ O*èžð)cM“¬òIRÆRÁ!˜´Ò#<²\¤(ˆ6IxH뎴nÐ,;g50V»ê°/™@(€…¡Æ=€U¹c2ºLP‹~"£EÙS;DÎ9,®´Kž"e!³âD¨~cªHª›ªTqJROÔ$Û☖PÅñ,îÕÛ9€uüýƒÃ¯ü—óŠ‹"VoºßêU÷zý~˜QþéÚîÇ8ÄóñN§W­ô;ý«WûïbÌ;þ^¯·×(ëôz;ÈÔ`‹\¬3ÝëÀjêtú#Û~4` 0­‘ÏJ¿`t-ñŠäµq^‘L]9bcÀUì5)4åF¦¡´Q²œ4²¾µkòA‡Jþx?K¹è)¦è8ƒ¥!ÖÄ3éÌýÌʉÓ:b<1 F2ë³¶tšÅ([Ùk"òÇAœ‰+¤x1·ªP‘eNzFž«ƒr¥¯MºJö°ìÄrãÒ—HãP‰Š¢o$Ó´Þû£Ã7¿_R,–â«»WA@êôæ®ÀÎT·×ŸîMW*½)€š©©þ~wº:ÝÛCÀêöææöú=,`e•^§;=7W­L÷»] i€MÓ3¸E.Öîu»Ó{ À°(e6t°w²_‘¼ªßï7°¨c+¬,}WŒ\úN/àįH¦¼‚eîú™ÜI+²6}FŠ•, Ì?¤®¥¨x(ˆ¶M”…caœ‰cÍl"7‚.«Ö è%6¤äGÓ<(6Y‘6¤”M[ ÂSZ°jð7†t§ŠÙAÏPKB|X°'+°ŽÿüààÏKÀb)ÎéÞÝÐ!a·º·7ÓëMÓ®ÕN°Ó›ÚïîÁ±¬½j¯úzµØ$Øõ` °$Û^µ× 5`AÄ^¯‘zŒX¼Â€ˆKãG(œW$_Ï{E²3L´Ï&^åGkŒ”¾q H‚L2ý³`1¨Ä‘,m´ Pšîaȶ½ëÇr×Wv¸çè§á¦,æ ƒ>¯“ä—þbY‡Å0Ày6TÇe=q¬ä—Š@Ù ¡™ÐÄP ‘ U®þ˜JWTœ,åÔU¹Xë⊌„*ñqÉ}Âx´”°4ZNcÚEó,jÓÔßà±n¼!!Œ ß<ü£òyB–‹Æ‚½}„)€—½êL÷qhX^%€…X6·Wäºzu®×E,êv-`1Huv°ö¼ö€›õªÕjA,£¸ +ñ£R€kkÊÄɬ°˜}QO°â8OÚ„ŒÙÇšsi¡c¬-¥Í\†;É þ“–,k`uÆ›–,!”8çBµ“(Œ„JÁ™7†²?p•ø•t-‰ùÛlÄ´ìe´³MP%ÌHFÒ®ëËÖ¡f_̰" V¶Æ ø°& ¬<§ûãÇ?þÊá”cB–‡„=²uÞÝ6€@ƒ¤j† ¨Š ‰+D.tjcÃÚëš+z8fdˆëÍôiH¸GH®õ2½XQ6`=§rF…vÔ˜ûŠäH »g¨VzÖ®(‰,`iúk/Š:ƒ:3–Jßï#e R0,,d(iP×CMÐZNKÖ†…õ¨A‚«–Ë.`~¤‡qfk²£Ç´sVìŒðX¯CÌàW‘þ¿È¨ˆb_$^±Ã¨+pL˜»¬äø/ÿ¢,’b gûúÈ—úý½9Å!§BÏþÎÍñÄÀ1^UbÍÁ–¯¨ì!êÉ@Ö &\‰qç@Ù^µ:Ó¿“iðq¤k _qœõŠäçl€}EòÀ²Þ\a“,ëÄQ8ý.N?ÔgÇ&ÄNffÍèæËŠ™%Ô GÙ¥ÝJî´ªÒ%ÁÈJƒF¬] `±öØ)Ø„y™Y9íòn(¢Ù‘™Ÿ øaÄ3— lT¡™'âÿR–•)!«±L¦òô¡`¥3#k*»˜Št{q.`=ÆyŸ7T\ )°pà×C:„òúUÙÙÓ!rÔKcÈÞ€àÕƒ1÷dHèêííö[ë!ݪÚ‰¬4ݸ¾:ÖB­5,ši¦>¿Ëêw%ar@zÆcóœ ­UÊZ÷­ÃxÁV,žY˜•B+£ß®¢ ¶'Í¿Îrba×NœÈ8ƒ*2d°eIVÈ×ílË¢¼ºN?1Êå ·X±£Ð<*£Çm¶>D¿®§-lI… ïÚrj3ïæ#ÃçtÔfu–ö—¥Ïà ç ÿcI±P \Ö05ÍRÁ ¾'y:%tbÆÙw~íNÞÕ(S§G#vºÓ;G sø¥}«@·ÖVo`­á‰ÁFÖÖö¶t"îúá„ËX‰Ugæ!‘HTJmž0 ã(Êœ°¶·tÂú¼U³ÙÚæçJ·)Ë‘,⤊ÝÑO"™g¶õ’üHVÛuëvÙ–^Œ¦Ë#º¶çà&:ùÝFFòÓ®ÉzÖUÊ¿ƒKØõ’ŠÐ­â$†ž¹ýǬržÐHq€ÅË?ôzÝ3HÎÕ×°ýŠÖªƒ;kköý¢´JD3€XÖÀF°ãvÎíxR¢KØ>¾¶µ…†ŠO´é§ÚvvøKÞ  ±Áoó£Pºc­;ÃâÎe§Jì/vO*oKžÈÛ&0×­Îaì-aU¨ŽŠµmŸD@‘ëÌCÜ|’Ëä…¯±*ã%‘©w=åH”ÛæN?i­ëšê74î*ëœ'ÔRàëeܶ6+ûìòÀ® ß…°ÍdÆÒîìG†YYêõ2ú «¡¢Å¤æAÂQ+Ý#ûŽ7™xŒQÄ)úª¼œ'S{”ü粜qò„ºCýø[zäxêòDâà ò—°ùÁúK¦›ãwËK4L>Ïc%4éI¶#s¬3LgÂ(•» ˆÌ_òQçI>Q:°pžð œ'D)ò}XC%q~TgÍrú þù>¬±e-õ>¬' “L0ý⪳‹Ôw4^›‘ܹf”Ê —•ÕçY×ñ_”ó„(š7Žþügï$åÛK¹pòýƒ7Êç Q>,€õóŸþäG?,D~ô“²J¹hR>O(RðWsÖ××ñ»8ô ]þòËf=°ß1_Ö¥8È_¶ã¸ëæû!þÎNñË2UØóô%aütÉÏ~òÙ^~ùå—^>³¼ðÙŸüÌÉÿš}S.ýwÖcü*ÐãÇžsŒûÒî·“ÓucþL„,ýÜ2ú+;É/YÁ©òëÑg¾ðÓÓyÉÌ_Ο.ßIÿ6±Ë~ÝMÓš‡zÝ-Oºìyu:^~ÎÞþnrÍ«œ')°PôA¿dÌýƒ¾Ì}.£žì‚X6N=ûÓÈWëÁû?záÖÍBäÖ ?zŸ>¹—Î]!_tÊ·ö’ •4§ÓêÆ¯qEG²¾ hðC”ëÙ²@6¶ Æ7)<øõ,½i—Ô‡ÎFäC÷®q$¯Qé%ÞPÀ*ç Yž(`¹ý‡îbꎬz–‘xнƒ÷øòÍO |üãŸHüjù¸ÙduäæË?|?ãss“,LjÒ€å–;`ÀBœùY¾BË?ÀòŸ0`ám%×¼~Aó„ç@ ,îH‰á›Ÿoè'p㙸u°ÃÖƒ [}•ëãˆòiÀÒÐéªcXuü|æ.‘/ú*lÑWÀª'?5{’ƪÊÜHI¦Í½Bv=9$ûËøíçÞ‡]UTpÛË·¯rž¥8ÀÚäOÔoâo£±Ñhl¯ÀvãµÍaÍdîªuêÝÏg)ò"Š€Åc:ÀùXù§n¾€…_°Nß¡‹éžY r: X¾W(`yÔVXúËÏ,%`V,`¡7äÑÿñ_íë˜æ qÞxqîR`5Ú³ íFcªÝžiµÚSWš­ééVs›äöx½ô4BrdXÿüŧ@^¼yó#ð÷âGnŽÁ´òK) ¶Ü™`‡V|Há´Å O攽ôx =|‰Bj%% †…A€zôʺ_„§£NœîŠ5c1Šø¾z ³ yFÝTWT?ÊFò|•¸FqÚ2(ϸÁ¹ìJg- ý¤•£×ãšäœ(]K~" eÛÅóåfÐúmû'/8EÈôÕ/ýM•*ç IЬf{®ÝnÏ6›3ívu÷6Z3ˆ]|Ïš(`­#`Ý|ê…—^zá)ø}éÖ­§nÝ<1V9CBèÖ› l0ð È =ìõ¾6 …†ЖÙÚøPúGëцhÔ´~¾`d ð$–ch4-ŠÙR -ÙB>,¹Z™|œÙ´ˆaör>´0ï®~eó‡`AÑ å;€eãûÂ:’å’*Užtc _žQà$‰[NÓ3íhl4-p1°JJ †ôÿþ̓—á^/ç IЬÆl»=Wm·+ÍÆt¥a{Ð`K† X/ߺõÒS\¯NÁ°° 4uf6 ”6¸ ЀåiC"ƒµ¶E†¡Ä¨4@ûñÓOôøXF'Êà–à”'¨,KñúÔb*D©TQ aé•gK‰)ÈC*‘K1pðPöD׿ô\îäùN=; dnž XžÃ¸ô4`qöTŠ Ÿ¿ÃúÒáÁw‘‰æ ËwÌXA³]å!aV»Ò®6›³íÖÔìlÓE© ð,°nÞ|ù©›ŸúåÏüÒËŸzþTpåVÝ =äñd¦™E P@q<¹s¼â_å ÃÒ7|¸D[‘Xt‰^B ”þhƒµˆ»tý0sÂ@†lg†¬Á!¡bÀ2šÀ ¶A Ùf@¥ôœS}yÉq¡²4É:ìWž­#§€Œ©ÒÒŽš¡ _Ó€zþB€õøÑÿzpø•w‹æ ¿wé)Va€u»Ùžm5›u€)Øk_½Ú‚½Ý]`ZuÝþ„†õ:Ö§žz‰ëÖ/ý“—>r ëãÿø‰!ëãú­êȰаd䡇?P;úóØ÷Ħã9–ꥇ–îÞÖ€å!×2 K€Ï3¾eLRi+*Ž+5ì:“i1`ùZ7‚`ƒ¡I’UMsLÊ2ºU–jyLt„öx¾3Ä”k]öå‹:%ƒ¹@¹Åòld d\2B4 Ë©Jïâ,¬Ço¿õFÖÇéÿòàðO7`œ·ǰíiüy™6ìµ° dwwºÝ¨Sñ'¹”ëS4$$†õ‹·>rëùOœ¯° Õ­‡DÑðNh“¶YwU -ÁÁ+6¢kÊ–& ®Ó=‡aù®&!\)7¼f°<¥‡¨“,OËÉ/'¨¸¬™ŽeX–/ 0×€&5|§’· !n;yÏÒ%í¦úì ÃÅþ ƒXXÇßþÂá[o"ÖÛ_<üò;ç ç-ÅÖFkêU¬õ©v{ják³±;=½ÛØ„‘Èí 63â!1¬OÞÂYÂ[Ÿ¼ù‘?uóÖGž?Í€†„ÿ/ÏÖÝ©;ÇÝ.7p=üQÆÝîéSšð Ò3s~;fÒž'3Kh~ŒnkNöPŒ?zª†„žf"&á3°<ƒ@Í4þ%¥4äjÑ`¯«Í35ÄtÊÓ>,ß)šuÛzö•o!γ¨cÎ;¥³õHúlƒ ‚_ –/ Gqð—Á¥}íàÍ¿¾ìcÂâœî­Ö.®ÄÚmµÛ­Ý]:ÂÝFcc}¢ë„Ͳ†çÿù­_„¡àóŸÂ¿›§,\Öx²Ü'È·mw’3/¥ó.ËX5¸p4Ãs5»© pu{¾žlôFÄW‚Á,§Wx{#N®êò//–öW &äåª~!X$lKÇßýâᛃî*`^ß*« ñÓ³"•ªÙ›«ÎNO57&Ú#°|Zéþü'oÞüäóŸøÄóòwZ†õ~ÈÃÏ“\.êvÓšî`’Y¾Ä"ÆôÞ¿;8\Úpüƒÿåð­Ë>OX`}¾#¸tTËÀÛÄUÎX§qY ʧ°œÕÓO¢›~€tór QûDªç‰Óñ÷ßüýŒ¥ ï•ó„ÅÖú:=šcEaDø*>z¬û|„Ô>üœp ŸzY?jHa‚ÃZ *ŧ"C‚õNša=‰‡/œ8??úæÁƒvœ'üÆ%Ÿ',°¸Öé9|ýø`ݾ¹a}=˜\7 ‚ŸýÝg^¾Uˆ¼ø?z?‘wÄäz꤫x½%`MFŒ9e/møOå<á‡å£ßÿûŸ€üg#îþ‰ä'ÿþy—¥”K/ÇßþÂï¿õv:ô¾vøæw/÷˜ðCX¥”òa’¿ýãÃo¦‡Çß>8ø³<שׂ”€UJ)PŽ¿{ðÆÀÒ†ã¼yøo/÷OXV)¥\DÁ·3|'M±.ýó„%`•RÊ…”Gß88ürú­ —þy°J)åbÊÛoýÞÀÒ†KÿOXV)¥\TÉzkÍ^Þï–€UJ)V}óàð“Ë.ùó„%`•RÊÅ•·ß:L-m8þ_8øÖåZÀЬÄú7ŽF ÇËc}Y'”<yüøú ¬É_z„`ažXîcª=·Îœ_›‘8]«qNxªbb* ýÙrµ| %·T{c%œ§2ª4­~d)ãŒóé®1·zã¨ÅumG)9þßR¤øÅÛ_:üÃË»vÔ¬X„ëd{;)!]@ýwggtô ÖÚõk7n¬1:­®^¿¾j¡Ê…0 ^X\Ñä‹´³…™·Le†ÉêM&φ9áÉŠ‰â­-s¼5"þøõAÖójgHÆF$†ùá¡£#OMèžÏ7XÏùšÃ8N&íž±’ɬÿqúƒ¾šù¡ÕK"IÀÚÒ] áj4dmƒÄ X¡Ôºþ瞆 ÃZ}ÎÁ£UK«Ö’5LÖÖ°¨ Û±ÅðIg>ЇWmÚ:ø¾· Xºe 02ì#¤te×P82$qQâ€ç0c?ýx;p–CÂt•: f&sÑ5ÈkÐ@—6@ÈáW/í˜Ð,¨µ-¼ßïïïw:m«‘€b ì¿Ñ~§ÛíìÇÑ(¾s«Ó™¼Í‡±fX".{Z»NTk-‰UkùkM†„ X¸•fôYIÐ&”Úæ¤¨F7Õ’¬³”GK²Ý aÞѰÔCçÿ@ø(@OiÖpYñNJšÂ³×cœ¨Á(άÇï}ýÔÒ†wþððKo_ÖyÂÔ`¿Ûï÷{ýì )ŒØ,Þíõ{½~÷Î^¿ßÝßïv÷¯ú gÂB]Çña­¥àÇ„èc i’ ˆµ_ ã¿”.bÚ8t¼x †Åж¥õÍÊ8ÆÏ—ß(yG#ˆOçSxÒë³âiUÒu•ïi‹ÝȱõÍÉ …Æ5a¼g½µ!1|ôõƒ/|粎 ]ÀºÓéÞ¤™êõ§f¦ûñ YȺ;ýé™ééþÎT¯ÿ{SÀ«é©îþ“W1`á':×øGÁÏuú£ýëk¸·Æ«2°(UüªIæïä7T¼§ÒÉ)7ž>F*«çIõRMèZÖÕMuêÖ>/qh.I—ó,ÂŽ˜­lÀzü臇_qW^ç _¿¬cB X1@NÉÕÜÞ4ìbÅ;;cqŒšçêôfàâéNwzo¯RéíMw¯ú]@,b*“ófmoïhÀˆbB…à¥LAW*Êa€¥",üQåZdýŠm@+&ÓëŠ5|ÚýŽr™BeÛ'ëæèh£”ÐY[ƒkKƒºžã õ Só–P šá„Ô_(³;Û±žÁÜÒ¹×4“ã#ú8úmýP…+,‘¢v Ä€µCͦ‡Á‰¸@+W)”z¤?E…0gu’Ρ¹DxÓžâLÀø ÅñÛ_:|ë²Îº>¬îtuºßŸ¾r¥×ë"`mmíŒuŽ—w{¬ÊÞ^µ Ýî4(ÂÁ%õÒɹߓ€µF,Šøó*QJ9`E€uc`™¾:±ÌÇT–èίÅRÎ –!X殯²†{¬;àÙúÎÞ¤v[ 4)ñ˜,>f4ŒåHx‰0=²~Æ>)—Ç© GÑàÙt‡=J£‰9jÀ²cްºB3JV²cD%U)©ÍØ`“TŠ4`Ñå¡ÜÄŠslެão¼ñ–ë´ºÌó„ ÀªìõfzýêÀ  ·âpÜŽM€U­ÀVµWy}®€ÕŸš«övpò~›o§c,”8¡éh’!¡ü»Rד€e8^&`ÝЀÅ]Ti~‚ œå…ÉÎOYØ{<FD‰Æb´1{Tl"0#ÁÙÆ‚eƒ6DÞqX8è‰$Õ3–ø°ô¸ÕüÇê +5É'ܘBoB`r}lJrè µ¾X†°¨Ê”)§¦Eö„i¶l†ÞR"e[ZPR{âØ”1V–ÓÊ´X?þJriÃež'L2¬½½én«_íõî`5ž °àÂî>V¿<­ ÁkЬH èºáNöG¥ V•‰“ X7°vè¦oi Vü$+ÀJšcí²äÂÜõ#!YÕ“`Xd¡a\`E¦‚8·+Š”öiÖ1cã< ukXcÞ»%µú‰B}Š9Ž,çZèh¡n6 o’sT²C@GùÒ CÑ"›gHšÖ‰-ŠEú°FÔ&–6¼óÖ¥'t|XX½¹×_¿²·ÐÓ©iµVŒCÂÎþ>i©ôúX}ÜíwžÀZ¬ ÀZK5`­¥†…¹€EC *Òϓɼø°Øhã$`‰§&Ö "V2’1c—XŒ2Â4`iÊã#Œu@6& Tˉ•žl³ +wu¤«6ÖÀ`ÙldëÁB¶.¡x­,œ%‹ÜU +NV¬x±Š ·xô*Xši?—­ñ˜¿øž)é·6\âyB‡a½Û« ¾ô®\½zõJuú Œ« Ò'-ý½+ý^¿W­öù&ºŽ)NVÆ,¡Á­Õë[y€uÝ0,3’ÑNãI– ¯h:0Šõ •†'vmȽ]ûŒ´ƒÍ.ÌFâ ³S\ÅdY¦Ú´wÉx£Å¥½q¢âX™ÒY–vÁé`Ìn#e½bJgŸÜP¼• ÊâX`&Ô3©y‹`\ˆ—q€…SPJXXd|lºÒ#“";þÃPWa,¸'dÊñ÷ßü=×ku‰ç -`Ýéõ÷Pz{¯óï VPaÿíâ5=â/(¡½=æjÐîL{ g[ìW"ÀZ¥uêzÍ•]iµFkÞ×äÄÚ¨eX XÃ*ÝMy\+‡úɲ˜2Ô¡Î#%[;-úd.V`0Ä!’]‚u¦²ððE¯tOV?¦2´ç¬‚—usN>BYÛ•ˆý…7p/3¥²…ybQ¶$xkg‡à{‡sä0,½x®" ÕèÖO˜LŽuOpÆ8°Òom¸Äó„.`MM»2ugü¾ý·ƒ—ÏÐ¥3üS©°"¬ x¯¤‡ZÀº.€¥¡‰x|°ŠC=~¼puäcÐXñÀuHíÑWOçk×°‰”0“­Ðl,²€e¢ {€•Uù '*vvða.úM>Ù¸m÷õ N{wK²æYOF,é ø˜ãá•nC™l:tí…¹  f:ëDír‚–º'Š•k§©·6\ÞyBgHx§Óu¥e°Ü1àòíäåVOgߺïÇyœúdê–ÎóH _Â0(«×sq™U˜qla’WÀå{Çž¯tžSęڳ/.þ$æ@>ÁSá”rr©{Aº7Øcž#ѳ•äAæŠôz{>JÖP2ÊŽÙŒ­SšÄ,±É>ï™XÇßþÂá[oÿ\þâ»o\ÎyÂä£9¦]õ¼q,7¢'c²žÔ°¯}ì4EIȯµÉ¬S ÕE4féÏ*.`¹)T[T(Y²“§!/Òu¤WdÆãú÷ÆìSî ,Ê MÖ`”sí Ž¬R'ê=Ž2㜾,'|Àzü·É·6¼ó‡o\ÎyÂÌ÷a\ò/·ë”'*EÖ•I&8 Ýád³|aeòý8ßP¿{ð{ÎÒ†K;OX¾q´”R>òÞ×ìÒ†K;OXV)¥|äøûo¾aí8Oø?_ÆyÂÂË_„·››¸W¯ë08 Þ/V@£Å Y'(—rP©0ÿEçžëèñcOê*\_çßÁ?ªH©kÃ<ê¿Aý Û÷=Ìû:ˆÖŸÔwâú®ƒÚÍÀ÷<Î?‡ÓžÎ6¹ŸWÛ7²Ë§ÏSœx¦—Õ¡LtžÚ§žÖéûÙé¹¢óX÷müu­_ê9;§­¿ŒúäjóoC†YØ£o~åX¾úû—rž°0ÀZGóë›Øquwà={< ñÀ½Â l²^ßLwïIHÒ‚'&“íyÉÐÓ— êÿP­—ݶÔrE§ŒWº·¸ñò…ºñJÆiÊa{å‰Ò¯»%C,ºg#Â5±Ä[Ž¿{ðû_ýÿÎ>ž¼XÌŸ°’¬ëÏe?ü|}_í7 °ࣂî¯p¿øž™ê¦˜ˆR\:EÜLYJ ‡)[QtA*|°‚û’2ÔæqtïÌÆ0¥&uIðð”Ý7[ªFÏmBå§X.Ó€c´(Gò’çtÖ’²…Òç3›- šð=ªÚzÙ‘òxr±ÒµË¿ÜB&lˆ5ÂÈomxçˇ_|ûÒQ¬â«Ùžk·Û³Íæl» jcƒ×n«õê:ì5ÖqÛ‚ó¾ßlWgZÍÖ•+»›xæ•ך»»»ÍFãµW7€{½†a¯½Öh¬ûë ‹ôA胓AFÑ€µ–|ÿñu­!¯H XÊ×`¥´¥LJ0AN‹L‰©òéOÛµ²æêZªÎ¡§íÓËÐí¡d£Eä8`jZ8UgøçæÂ#}lË-2Am²º} VúG¥Ò øXª„+†6ž>d\e„ Ü<­MpTêÉ3¬ÇÇã¼µáÑ7þ²¬ÓНkwîjµÝšÚpBÎÕžn÷ª´ŸŸš™ÁóuŒ 1ÚW¯ì"+k7š³W®ÌÍδvw[33-¸nv¶ÈŰ8dyÙfvC“Ó}u°®Er>`ÕëØ±ñ?ÙÒ„)–,º¾,‡@ñ¡sÓW†ð¾7Tw@FCyHh¨ŒÃ?<²h¥m^Nw!3÷8@ ®H)¸ž¨b]”cOùN ùQœŠà’'h"Ê »< .>ƒ“áEü+ÀÆõÁ´Jº6¹thüÝìMl2=a¸<úæÁ,KŽ¿wpø'ï4Ì™ X4$Üûµöl«5Õ®Â?„°F gfw·ˆÆ kNUÚWv Œâ>ö±«íö4Ä¢ÿs¸_m7 `‘81½»‘3‹ ¼"ùú¯H XtÇõÔ“:€¥xHèiÀ€ñÄDÅš|ßÜïÍ]_©Ì›¾Ñ-¬b,c–žh¢ ø*v¹€eÙ˜.ʙ͌Ð[z¥ÙŒ²¹ç6 ZìBàÂå <1*Ìz¼`ù¾?°£À !îþ×—ÛÇÿ§Ç•Öso=~Rö8€UxO!¿À·6|“—6ÿõ›—nž°8ÀÚhMœlL<5ší*ð¤_A¨zm£5=¸S©âц4ZS»»k «:Û¤+6^›j\ddku¿WÎLï¶fÐÁÕš†õj–ñz–â• Y¯H&÷;Ó.­Žfü3*a%“=KèÛŸÄh+u˜š¹˜BLéæYBã!+„$†„¾rf(|ãtÒ¹ ”å]:Ó~êØK¿S*Ð&à¹ÐãTΓ>‡þ° °Ud]€ì´2,Îמ6{‹pü…ÆÍ–œ%|Ò +ñÖš'Óâ+v[²C¿•.êÚ¥KL¤vkaÁ-ÒXÏY8J€ÅÏåÜ`^uÃ|Ç…¨5ý´áˆGs¼ È‘LB’æx~jè6â);o Ýúy͢ʃ€å@OÖs —»H3䡿ñŸ¨Ì>ý“†næŽ^öÐO‚qãˀƻ´áø[—lž°8À’f­'ži§í+Ü è•-uçœñjèPyxßyïž¹o "Ý·sšÙ¾^&ÉŸÜïã˜ýÑ-\x§xÀi…^}à¹ÃëK†`‡~–Ð…ÃhÎN.1$LÏõiÀMÁ6™´‡\Oz)ìö’öÙÅxãÉÙNó„—ë3åGK)å&øÖþ Åß^ºy°J)å&Çß=8ä¥ ¾qÙæ ,ü¨HÉ7—œ/Œ˜/ë/ŽÐG}9,ñ'ŠVaþâÁèŸáq_®O} g»&ò5é/¥ |‚fHŠq<*F–n[uúò3êñã8‘»Ç™ê­›¶Wâag¾Ì”ìX'øÚMœ”*Õd¾5¦±½÷õ^Úð‹K÷ý¸,+iŒaáÝ2#ó…8I2±P¶TÇs³äæmk‡¯Èø21ÖV˜¾òŒ9¬0ñä%3a›¯t„dKdq#e~…Ù­™T™©¿E±½-l¡0à9Ÿ¹7‰…±…©¢ò+L4E±2.`É[~Ðõg—lž°À!á~§ÓÅÏÒÓçà òpCìïøDïîcCß¹c[h‡¹u´xôíoï„1Ö¶îÆ;¹-ù©Z]Íħ‘‹®_Ï0Ɖ"–¶~×DìI‹W4jv9¨©E«<À «Â"8âOÕ“¦üò¯ÎK8X$#ùµeŽ¡«?C…섚þùÄV¼eZÆUIêµeóž?`ýB/m ÷Ž^¦1aa€ï÷ú½^¿»Æä£Š·…Iáß»½î»€BÝî>o¥éCbRQ´³÷ZÛ BŒsçN¯·O‡;¤F3,£ò^Þ>Î;݇ÂþeÂAaÝ”Ý!úî9þ¿TÙ±–¢0¶þ•±u˵Q’Ì2Ç‚±‰ôY);4$Ô¹A¤&­áKœ­8¾ÏH´Ü£k¶¶œ^‘l'Ü"u2µò>üØ0®eË_—UlÂMÚ‘-•Ä 'â$°ð­ oà[ŽéyŸŸ7Œ<9)°:ýi~™Vçð£N'¦´ÿnŒX6Õ¨êOõ:Q§7ÝßÝ¿s'Ú¾Óé`èt¶£;pò*è ©~þº@ÙÞPÏt]¿k~^ÍzEò„Ã5°Tâ/u.¼›‚‰@>ùPѸÁ,”¶ :L32â«ÂŒÑbZ7ÆP¡£æìY&½KEpQ6ï|l€~w¤Ž…à„ŸAC9¨¬è|DEØÙÒa$„+ ï'<‹ñB“-“'­kOjYRÇ!=ü«k‹ÏR]ó%—¨pÞ=>`=þþøð?HqÙž',nHØéÍôû½éÎ~˜–³®ÔííU{C½j¥ßé_½Ú¿Óëëôz{{ ðªßï@X¯Wtß·»Ó½Ng"AH§×¿Cž±!í¬ë:¿k߇¥œa™7Ž>7Î+’©³Fô£Šî™ƒÖO†'&JF‡v(æ lʽ]CÄ0u:‘ E¢;æ˜=:»¥EÔy"—“hEfx1HaX‹ uÎ%Рµ$K9ärJmg±”eG%¼¹¨HâÊ™‰» à¹&°]©m•N’àÖœ"{6â]"z ‡¬}â{Ç¿ÿ‡_ù/ç #ONЬn¯Â€ÕŸ®V{À·ªÓ]d]=ýÊ•9¬nonn¯ßÀâðîôÜ\µ2Ýïvñ°‡ ­\ k¯ ½i8Û¯Êmoá0s'‡ã$K£ÑÚ°W$ž%¤;nätìÉ ƒJÄÖÂ7ðH,ˆîñbäš°i+ºß+K"•5JqÁ‘-ÎŽvª, th T¦®Ðš)”‡}’Q‰‰ðKÖ¯bÍ]—”£XŠ­ d+UxŽ’T¨Zø_"Z,€¥µ0¥CeVyh¦´¥äYYlAK‹„¡Š"Èaáþµá—6¼÷G‡o~ÿòP¬" À†„ûýÞÞ\àfo‚^À ö«Ý ˜VB8¼;³· 7ÝÛXÂø¸ÑÃVÎVz ŒÔÆÜÙÉmg¬µ!¯H~îd¯H¦^«øî­yÖäĬH1¢ÀŠ4X HÈ–€C»¢¡ºã(+Îi³,CMɳ’ü(Íz"©59Š•) eƒ†fBC`Îõ´ c•Ðo8ư8N»ÑHW¬5òâa˜‚HtrKƒ.Å“Åð%M“œV¤ Yñ=al¡·6|(ÖŸüy X'€£*9Ýaàwõ VêêÕ9ÙÀګ¿¹½ŠGÀêvªà`+FÀê÷g` Ä«Z­VÄ€`嶳ð?¯H~î9åÄX‘&Yª(ÏÏ0ëO–=Œ¬÷Çœ5áÿgïÜbã¸ÎO”Nh² sR4ÿkYá‘¥ý™çv³¢”®ôJO”t«ûª€µ²xædî-×…™…W7Í7f³Ü ×ïDßô8q·Ç;;¡e«í³ÐÁ:Ð $´öØ–Ù}ÇqŸ“'ŽCÌÎNˆÛÙyœ©Y­Øì^çN?ÆWIí×>‘ÜïýD²€YÝ…T“¤‹ÆšÑH'm¼“L"§D Ùð$„ñѬªß’´5-7Þѳԙ£59hC2<#ÛÅÈ®»=p”\aúÔø¥¯Ü«¹ñéÂÝÉF¹‡5´À8¬Ö­ìütöõuvº¶6Ü…£6І»m<¸µŽà3ʭʉ°Ö–gáv±j«_Ъ_i—š ÃÞù—‘ëa«Ò<¹fB«Bí÷ŸŽÏ!‘ñ±§ãñ©9Î#D©fiùæIøø@{1[¥Õ‡È&”O^›Å™{b¼¹BŠ6Æ*¯~q‡4KÏõÇãÔëÌ'BÑD!>†,C}v¢ˆãé~÷†5€sçr§¦æÝâÙÜæé' X£ÏÓ ¢:¶jw¼bš¿z6™K&k˜…\Ã’ÚU¿ø¨»R¸®úwÕ›–£kL ­2ñ%°Ç4¯Çƒ¢„^뫸Zš–VåkÍq²|¾¥‰’±859Ž;q…¼_)ËkCÙ+°µÂlÂjW]a®Ž€!HD€¼h“‹üó¡^Ë :_3ž†U‹µÁymõ9ù‹6£ªÃ7)ü´÷ª~¬T{Ï7PD0AJè“&jÜi(ןxL}£A|³a×cu¨Å¿ÈÒ´c2@Ç]uÙ Qï;‡øjMtòªÎ—¿\FËüV—¡ªJbù´ÁòŽÉj‰«d¥Ò H5ù¨InµÀr¦~’›sæ§Æ7M?aßÃ’N¢§1·Î¯ ¡âïÖº\¿ï{XàšyB.;À/7዆>€–¯­Ìg¾-öMuT4«­uÎåÜø¹Å¥éS¹…MÒOø­ùâèò×·r_ßíK¹çî¹]iñÌxîõ⿌çfîÜí¼lŒû¶kùÖÏ? Ä}~ãw›hòû=÷ÍvðÕ†Ó×~™Û4ó \5džÕrläR˜#¶=2ÂwGø’\xÌ"FÔ*:°DŽ ‡V´•Å*< I¬¦£þlû ,¦óõí=pàÀþëv{tãk–Gpv§V%Öó Çh‘Ô ¡[ŸxÜO®Ó øìÖÁ˜\ÕÒµ=ÿ¼lbåËÉ7 ³Â±§Bİ*­ü^=~ýcµòscKÊÿ^«4ˆøÒ¬§¼ê˲±Ö,ÚðÊln³ô¬êä|À™¹ÕøÃW³Z àƒ6ë‰u㊀Uñ*jæµñ¨e³V¬Æ07jáÊÏ ó€¡I@ÛÀUqWŸ7®ÆRõ:øjÃßþë+ÿ°9lÂà€5‚ëÐëb¶±!uO0Œ|i?ú4é]j•è˜}hBFÊn¤Ve›¿`‘M·›ý>‰kÖ~,:´`­«FTšãˆ,‚Àc‘ïZ¯º Ü7XÖZ4,Ú0ñòʼnܿ˜O\£{4ÛÞÞ–I±R?”j93®û a­™øF0^KjXŠœC‡R™¶öölTÞH³ƒõo:hXûîcnp``Ë>¶¿e`m"ë`Ì0 ÆT¶%uíXøKçÜ2ӑDZ Rí1Ȧ<އ6&CÖVç k?yÁ6ÄãùqŸFÌ»"<Ь Ò}mÈ(—±>ÊPõ²E–áˆ._o½eÜ--ª*KÛ–eiÐ>6è1~åäè¥Ú¢H úó‰Œq‰"TXJ®m+¹2çmÞ‹¤ÚÝb*º«CÏ♉Ÿ\˜Ü$ó ƒVG6Û–‰2ðd3©ááa¦n±¿³gã`ª=›Í¶¤£‡RÙÎl6“f×Ó¨QD£©(c“ne‘Z£Ã)6bý8¶! Ýp­wd$BÀºoïþý{ïc¿û¸Öc"t"=Ü‚ƒUõ˜¡*§Aqlâ T ÔdxÍëÆ¡p<$!ü r¨v&ƒ§µ|¯PÀ{Œ¥U,‹Wz˨EY ž,™µ;ÞµBÀâYÖ($ò"ÑZ–9ËGä9ÄPøµc™ÆèʱìmݦãÉ ºL„$¹…$Åâå¯î^‡—kù²Çíu–ÔZ«H¥ÙéK³‹E§qjÁW~úòÉŠý„Ënõ1:ßÈÑ;Á+•mÏd²mÑT{_vk¦%Íö3™V¦s Çl¬Lt8šnŽÅXéT¶µ%“*š%½j•Nµw²c;ÕÒў°L¦ ¥ÔªEC,ªý÷!¸¯Ö a1`El|úI{Ј‡ØæûT%b¼æˆG]PÍB/€×"~üÐÒ{òXìD·¸F …U–ÅH!0 Ù€mhš\õ*€µÜ°´l­¿bq`Űº MŪ$-Ó&}Žkœœ†áÓˆ"\E ]“Є,–½Eš"ËâÀ‚kï[(hä [Ë"é6)±>¹/›—7¤šòF+X,çüó¹Üé³ß]øôK·¡áënáÜøäËãþ~Âåk½fwï5·«r²ŽÓU_øÊJWÅL”§­/MHÚá6šª<4P`¥à/ÝùƒlG&Ó\jc*SfØŠ1`¥ÙÑt ÕÑÞeÛ ¨d,M;lAÃʶµµf¢¾=5œÉþy_ò d­éZ*–-€ÅþÜ7°ç;ñ{v¯ W°"1õ`s*,¨2W+¼`[’45Ô°Y¤!Ä4“P™6X–!p  åZ…£€ZõŠ·a‚/F½ 9,¢•e½I™²ñz ì¦78\ [Ž\)ÒÀÄhÆ?Ô¼HÔPt1 ”'7 ;†Û( a¦4,‹k„^¹pß,žM¸3BƒFø:¨£¯NåÆÇÇsÏO½t~fa‰iZn=UÈËMLNNøû ÝðÛÅ/Þ ;w\®i-£Ö¶Lâ\³X4Ý•@¤D$)iZd¥ë²ô>f±<Cn âð¤ìÀ ¹TÒbI!´…‹aÎt\HX‚u!Õ2){®vz.rØ,`E XQ€ÌÖtº €Õѹ•¡&f!°RéèðH 5±èÛ¦3}ôà` V&…ÚVX4˼XR õ6–ßdfÚ1®a!°ÿðöoDb¡’õ„úkàMÂVšƒø ³7®Ev ©SõŒiÕTja¨b&A™³èÝ.+TŒÉ2<©4 IO±”IHµÙRtঠɲë)X|È„ÖúMBr4ÖÕ@ÿR×3D…ç­SÜå*š}¨yêeÉÖ¹71˜—/íd*ìm­ÝJ”±¡Ln ieyÍ1Ù*&Aˆ¹0bš\zá @¶kwË$\).Î^š~áùÜø©ñ\îÌ…×çë6j/žšøédnÞÍí¹ú%C„c:¡ï‡{>r ½¡ðl{—ºL³züo’ÏJé?zÌð'mÉ5ß»ì§°Í —v†˜ÿ§<ÚJ¡× ÿO Ò1É|ѼóþŸ¸³(ƒü“p¨{Æ =gdVÑ<¿Ýœ5Mó¦ƒP†$’ñIØì™qvÜ¥n)µçݦ«-ìºh"Ø¢vĬ¿§#1v”Iµ°X¼èÛ¶FÓLÃʦÒɶÐèÞ"ÅÒ·gЗŽ2­%»¤ IXe€ƒÖÁAÔ°öîÜ2¨ëIñWÿxWT¶¯X1Qol/°HÛá&¤äYM,©¥‹4,õúöË«aÙ>Iª"¼÷¯“d!bϵ=²ÔƒhX†¼–aÁú1*=dߊ±HRs5HšÅ‹Ç®,ËŠ)hYR[R÷@Ø›–è Üt ³VL½@lÞô%Š÷n ÔŽ›‹s¯]8CUë¯_˜¾ŒÐªN-wajâï&ÇÿÙ7ŸðƒîÞ?v¿2‹æCÅ÷L§÷¡âlØé-Îõ–VJŽY¸ú~q¶Çéýù0§Ôs®0×í섎9[tzÈyø{ŽYÜù³âaò¡ùo&Is¸Oñ]·çÜ͹nˆž+.l¿i~T¤„LerC…ž+ÅY³ÐS€t³½ÅÐGL˃ý{ðÜ Û‡v~ö]§wŽK½ÒD`δ¶µ¦£#Ã- 2ÃÙ–t*•ÙJºQÂRІeÅXóaÛÃL'Ãvª?ê ëÐáT+™„}í™áÔVö“béZ˜ÞÕÞA–§ÊxLDltj{ ŸزoÏÀà–ÝO®É!°lÕÈ»î´ævÞ–¤õR³¸mÉ BE/!Û“½„eP&ŽTT|ý_ºIhiç ª ™D“ÐâÚš:±U-~cÇ,KYe¤åì¢õà†lÜQQ­ò¶aùË2&ÊL`V¶‘i¥ •¡¡&zEŒŠr-y7½rù•ñâ”]º¾{´¾òª¬k…Œ®¥…™W_œz©uúì•÷À>¬RûœËã““'_ZòyßùøáÞ7HB3®ŠÛÀ"sz˜‚‚3˜ ð>+nŸ¾vÛÙλ¦\w‰áí™éØSmgñºØŽÓrTZÌ컯Ìï>Rrßa2Ð4¼ùÐÎí=S;c)T4o2ƒ%ãéB®”áY|óÎì”Wy(;OÁô7 ¬á ´™§RiøM³- ,º4÷Ë_:“á[é‹é(6;ìžôÃ#”Ë{ÀÚ=0¸oßàÀîÝ{ö°¿5 ‡5ؼóÆÚWoÆP!65ÇHÿÂiV•ñEZc»zL«?Ââ4–”dÛú‘.µR… ‘îÔÙ¨ÆD¬·‚ù§æh³v&ÄPï\Ãj®Ö8¬ò>FÃO…C§…vȯWîÇêȉ|ªø®¸F®ƒ8&çSœ´æß¾x&'µÞ¼výK·RSü♉ɉçáú8…ViÅ0¬8=KÅ¢ø`Ø•˜¢U>+ÎÜ¥ð£NÏb¡è0•˜.5vÝ–¹x³è°@ŽJ[Àšyùƒ 8uïÌ/z TNϧ$ŸI©!¦£|õ,}Á"ôÎüçÃ;¥ó%…v;· Í4 [;:;ÚÛÚÛÛ;¶¶ ^Þ#_-R'KÚÙ×Iûà»u+í·Eµ{í¿õC6tßýÔÀÀSŒS»ùßÚ€%Fºo”ZÍ<—êR†*ûë0j\\GY®|NækÔÊ“(iËs¨f…&„“±`©*0+C·® ®«¸²jh(\}óÒ4Ó´N¦uæÂëóKåZî[¹‰ÉSW¼ÞákNq¾Åà&£Aï«…·Ñ@3—Š€æÿêï‚ÏJx¶p™™„ÿTx“™„ 1î£æe 3 ÿ™„ç™?7 ç˜6ißî%ÉŒFßûe@¬îkKgX.Æü°p»„év2.Ê(¼Ûë`|×}Ã|Ä¥<2©W·3`y¯5È6¬¦ºêÀ²°FÔ\B½eJs wÞ`Á¿‰À²‚ ãåÀª¨|ªue‹x«ŸÛ0d«Û°®¼¦ ʵJåbк6ûÚ?žFM+7õâôe„–V“— çNMNœñŽ]ÜÙ½ š¶apÀí.ËÜ%hS‡Ð=àït1“|Â!óçÎ"º] »™ÀûHòÉíElŒ‡S-í¢Ë}܇ÿÔE¬G»{.™E–Éò»XV`»Ó¤tRFˆíc|w¹Ð]\)¡“žgÀêj°ì¡hª®Ã(0¶U‚õã¨ÜFÕ³¬˜‹(z 9°$•ªak5À‚êÔjºuÏ%¬etq KÔéu_Ç…Èr„&­‹^^³Q‰Æ§)]–X±†˜åZ_aB¾– }Kº\ó&÷hçŠT­^n íÃËÓ/LårÐ}xúì•ÙkÕ¨åÎå&Ëú it@Iš´ÇAWÒ ð=dàòŠot£.GY¥ê–Ô0Wîp¹Ë^%‰Î"RÈáúˆž#ôù³&‹¦làgYø»3b‹'šíÚCng:4OÏ@¡=HvÅGÙ¶G¼ŸS¹õ›î Äíûáo¾&}dC€EïÕõɨ ,lN ¬¾y©,‹ßÔ&‹ «ØÝÁøkWk¢±yß™ç²"‘:• ¡õúÙ¨5}é=€ÖîâÅ““ã—œ êóïk°î¶»õÛ7þ/wã··îöµÜs÷\5t…«ožiJŒÔºøöüÒWÌû—S'_Xú¶Ï€þÖëž»ç6sO¯Í^9‹#µ˜¦õâôÌüâÒ•‰‰Ü{÷€Õ ÓÖÿÈ'=k¦ˆ¥.ë,¢­óå?HVñW ƒ¸jÎc½jN^®š“_årC8’°\Z™¬jàZN×ð¥ç½×“÷ü(9M(Êæ:Ìoãõ­#µç.ã˜x¦håN¿rñï''Îé6¡·é¨TÆ2ÑtÔÈùVù‰U»ò~ÏÊ)ƒ]—pŒ9Ïr§ì0?Wk¹aŸ?xÀÄRôcttLKUy7L@÷zMÀzüñêÀ¢uâª9èÕèø•Ž®OPMÙùd€ ê%+­Ž­Î’ðŸ±Þ©“D"Wg-C±hìhðeÙd·:`‰ZÍ …Z§NŸœ˜œ<½(Bv”J]¼MžOôO$vijqWÝ¹Š˜¸q`•v¬nþÜÁÔìJÄ Xòñ? :cì“”Šçã,l,>6&'•þpñ5Æãqá Q4p$8Ú˜d•N«¿_,.(–Lõ,9¸K…ÕÖ°è‘ÕrÔÜ•ŸÅÒìÞ2,¯|b1õxYu„8ªÌ<²ÇD…PRÖW“ÉÊÀªÉ’xøå‹¼–­ëÌ—§÷E“ÏEB”•Ùè¨ø­š1µÈsã˹Æ}©ƒv«Ö 5j]_˜9ÿÒÔøÄäÄß¼Ã}‹¦sÇ,:Î2Ó¬œÛÌg7àWkn;·qÞq1ÄÜfÎÅq¦0+·îmHÅÓº.HPÓ—…nŽbãiˆï¸0JcbMŽH‰©Ä1†Ã˜.!60qÆçSnu¢©a%þ:©Ö§•~áQ`%MPã£GŸe Œ;ÚÃÌW×MŽÅÈ’É£G©ÒÁãIÏìèèÑç’šF‚À¢uwõWAS¿ô¨…¬ÇÕRõ£yÿRåÍqXð'*-<§£Qÿˬ„gyuð©¬r}g½úKÝêQ]&äʳð2es4^u)eyÉyýéÑŽññIòEâ*ËÅé5o…·½/ç;0ú‰íº‡ÍîwÜB¸gÇ‘w9¡™î7¹ÿ}·k¾»÷:ôi†ÿ›Ò2Ÿû?€!Ÿ0¢ªwѹÿÁîm?‡“t‰™Ín×;$#˜¦y»ÐkÒ„g]Ä/¹×ïw0?‚pÌÝb8ü+wÇu·¸ ô-Ó¼i>Þöš:0°€CÇŽÅçËkî€:¹_;qüø w–¡'*©*U\íeÊä>Ç-NÜŒ¡ŒcÏÉÇ•™”LBK»jVnÃÊ‹ñV“æ9Ù $®é®åª.™¾p@E+š=d¹%’µe‘ì`®…4¬¤A/^@²Ý¸¾š|y|Ù×8âÉP×ÐZ¬Ôýö¼?kˆQqý*…ËV0F? ®òûË’MP²Ö ,ÐI>ŸœcÝݯL×5/ý?{W÷ÛÆ•Ýï£(ДBQP‰üXôeýÑF¶¹ý;¨}j\&`s,AªiV tL£ º6àu³èníÉÊM¶±4…‹H¶»®²^(ó°E„T+ç=ô‹Æ€Fðˆì9ç~9¤h‰T¢.­ù¸sï¹sïÌýñœ;çÜã~6âLügu%±ÍíÒOº'^üWÎêø38¾Çˉ=\‹ÿ×g#[±¥­“ wâ„ Ûñ;.Z·?„²òü$Y¾cù 'zÒ]um'ºâzÄÝ%Ÿð²N ž«Ëd?Æù,S.Èrü)œoâù#—_¯!`ÞÞÉ“îýàn:²<¦8u°.\È—Š 9Â\¶¬|Þ‚=R!oYßä ù tår)TÊ_€<˜^‚|þkqÊ}“Ï/æŒàdñ²M\ìü@ vÖeHCi ù-Jy«°Î ++ã{ Äè ®$£Jù)£Á§ àÆS5ÔhË(‰6ò3G[ÞÀ†q6] Pp³_S‚±˜ÊcéKËž7'ž+«ròVk^–âË Á‹qd–ÔŒ?+q ‹Ð)ñ°š`O×Lý›U À‹÷©<µ-y–å½olm£Ý}öJÞúí+o_»®,GÝ莭zð‡NË7.¹?o޹›Ç&ÆÇàøù,ôð«:1öÏÝØz°ýhüÕuîsƪϷˆÃº#;±mP8 °Ï£[¨À‡§X}£ŒÜòvPU|’p_«ó]Ge©«cÞÓøVb 箢ŽpÙ–œº X,¡\%'ˆþ&_,.ª Kù˱…«í|1©¡|¾TZ„|y( [~ŽJ(!àji1kBÅÊYx¤³üb±˜‹i¦KL½“„ÅøŸ€#Æä™LÇ?Ðu–ÖsX¾«ô~â‹Ïz‰W4ú/@=6£Á‹ITm ¨Ìòai|OÖÉñ˳ò¦vp†’Í>‹+ê\Ââ`n«Ï‚Ræ²´°B-ÊÒÍIÉòFZRÞá’#³ ."¿¥€ˆË=²¨DV=Ù ¶h¡-[Ö/ˆ=¼:bD¨¤NÄ!‡¬àÊ ?[z?ºÿRì°jOÞÇõÔºî5œ ¨E7Çh@œBÀªŽ9‰OW×°Ü rFŽÖp-…ªëŽ ÀrV–⯹1,ëŽU]r[€Å)-,·æw7ö”Ö˜¬QÇu¹CõoO(>€@¡zL»X,ËK<ŒS9¬N‡Å$§nÖ7ùR87™+ŠÅb)Œ(•BC‘b¾4 ò%”«.Ú…b«PÁ’ …bh7LÅp$TŒDèÂâ¡@U!”+p¹ @¯ŠD€Sxr¨Âú…€uÆX§ØXIúßÁ¤;½ŒÞUz±{,a!`ÙXü\ ‘-ã-uÊ%Ê'ä¯> RRh²IH‰4T÷ ¾°¸ôi) pÈEžÊo…~ÕæiŒze'qç,+EHÊÀE¦ ›Ëž\ê!©S²2/Õ©ðØ$nÅX&åWB1‰ð¤|S5YIB°’Oݲ5Ð2ûâ'‚£a·§±öXî‡åkoÿ½9ÇvÑpgØ™8áýðå:wsF•ÎY¯ÞŠ={ùØú¸T ôùƒýÄÆ±W܉%T 㜥QPñ¶ø²7qb=å*á³¥ gX.]Œþ†‰.äˆ \àKó>ÅJë’‡¹È¡:ºäí$ˆ/žÓu¬hâ'&êµãÇñ¦jÑo©ž˜æÔmÀB¼Ê]š,r‘\ŽÃÅ\ ªxi¨2Rn°PŒ\ºrQ¶‹„|.¡¬€ƒR¥¡K—†J¹b’iƒ²•EÛ‹ ¿åB…ËÄÃÿ“>5uªA%¤Šñ„¤PÛ–x³fÑ‹Ú ¤"PRIâg^þ3%81…:˜rÞ6ïň”êMà 0$fJlúÌÈ/ïõC–Ыä}JQÇz0§<³Õ/A””e;™noÖ8¶EÑ€¬‚^&”2XúQ‰j³R>Ò¼Dß0©X QK¨¢L"Ïà RoÑG&O)­ú•Ú®¼ ðK°×Ñç=,_û‡·ß¾±¦S^&S„ar]þ¶N– |>ýµÑÑ¥¨÷4_°3L«»ã$},áˆL_Åc1šD[«&âkdÖ°ÇI÷ai„€iœ»äÀe'F à0w¨þ½Á‡x8/UE):ÿ}<ûŒîn#žxZ ŽŠÕ1^æÔeÀ²†"“C¥b+„³XŠ€‰ŠCGN-°"9T €jX¸-–Š“xµ ó?¼V(„ °"¹R>ÏSò?ÿ:¥d'½ã¸•Ôš!$L1#O;ÀRB–šÙèiÀ2Ƴ,K–9ÚéÜÖ€%u½`d!uSJX4pÏw°lËR¤tg8–WlK¶ÇÖ9•<&Y CTHƒŒ¿”˜Ýãue›Ke³…ìÆ$ø™ý(U9&¥,Ù&®r3yiüR#«zÜêþÖ>Ë{|óêÛ?¿ví=cUwa%P&Ü\€Œ <бäqç œÛ1ZïJ* B—­iCWrå%ë:GMÔåñš¶¥Yñ‘f Tª&M'ðˆ_×u¬ÆÅrî®ç©{6 ²ºX\Ñ+•" X‹¹" HUMrJX¹‚E9óùE‹$¬¢²àjE+„»œsRÂ*]€+…¿K’Ÿ65TÂÀ2…,ÆqµüJxÚXjÆ¢ç“îBY¶°,«Τlb›Ã§5`Yzü±n 49¡ª›´ AJ«L–-a‰œLO½iÙL46ÛX–¥+²m?ù$,%„Ò´5S X6/¥™Êi/¥ úOufÞy²Çí®–ü ýºG•Ð[¿])¿÷ókå‡Zl[ŠzÃÛ=1g¡pb/}Úþz+”C9 eŸ"ìq.*†rS©”£mqh(\z£K € 1ÈMÛ\#C9Üa‹ ’Ø {M·"¥VÊM*]æÏ›>xs•Pζ •P}%û°œËåZýå•Ê]÷PÆF}!êž„•‡(<8 ÿPdhrr(¢Òx†ÐnæyÃfî0?ÀÊ’£T “Ê;*iÚ‹š–ïb×°øW ÚÙ£·„¯¼,ÿ`luM£0˜šFð¾˜õåR¶}@–T MãÐ8 ¾a_½Y?7¹@5dn83l¿¤UV¶E9þEñ¼¿"« |–Õ|±[€%øì°žÿ[ùÊ;+ë?¹R^ùÿ¾TC½»f …Ö„ÆU…î’pXÉAI㕹Li«%M%OqOÛôUì%)q¥i˜´I‚S‚3[`˜Ý—„%û[HX~hÀž¡ÈÈ™í¬Á†/N»Îȶd! ¾ØtÜm¤¼.‘%ºõ…É[¹~õÆÇÎ  VµE–€(Í/0z¹¾ ;@c¹pÞ­Ãæ*ȉº{–m8±\°-t»QO•»…d¥ Î;igõcéW[li(œ.,ÍÃÿ.emíK8Õà…3eÀ—<›JNjK|0fR­žü³åèo Ù†qîsu¢Ò¾ÈŸæÇ¨³ÊE=‰=ý“ýmqk'ßÓȰáƒK]F§«à~Pý!òZ-ñ/He³eþ¬zOŒÞ‘J£ÙKÝ›e¼YÍ ¿”¼ØÅç¯Æµ‡¯„ÞÚ;•ò‡Žû Ønf ˜Ì|=䙲%¢4‘žU”åšvBVD o?7“Ô‡Cä*JtÍ$Í+æ ;‚»\?F­­Œ^ÔñTêX@X³n®Ö †™ãYòGMùzùü°”ýqÓúF*1«Kʶ´M5Ïc”êézX½^ZITØ=¢™¶‘ÃnÌÔn*¬^4F÷‘­žbã:hþ#;ðR{²ƒŽí`6ÍÉ&LuRƒÑ »ÕU;àyt‘^¯6nWÊïV½¼zýq€@Bá!¢4Çâ¿pQšÿ[EiæQÑ #6-cæÍQd³‘ýó¨ÝJP,hŠc±»;>ò©GnÖè”ó`ìþÒÈçÏŸàµÍGøGSŠGTß:Ùyaþû#Ÿ>§xÒèýUì1ð~û¸º« º¡X«O}êÓÓÓ»åòíuÏ[._½ bH®_ÇèqŠü,£4ÿRœW¼mŠôÌ£4?]¯’@ãÅo®Žc\çåÆa¾ÿ*°©MÜsN —̽%Œ-bCèüzd›²Áਟ¬ŽÿöшŽÿùD9<Ê3ÞŒˆ,}oó”þäËñ/lq^'–Ücãw(ÎôÝ*p_q¾¯R<ÄêVŸúthÉ}P.ß| êÜ«†[Žq}Ô}Í1£4SŠ{õÏ<¥ù)EiŽšÇXÂ{wh<ï: ù‹ t]ÞÅ¢Ã.FqŽºuT/ jÚsOùõ<ªÀü e~Š3½Ž¡êÇø×^ ¶¥‰ñ9K7R°úÔ§ÃJÞÊõÊ—Ÿ×½µëWÕZ£&¡»2ÎaÑZ cß>¥xÊhþþ1¯)J³ÇWDÄæ¨rEÞAÀ"?dr]މØÐõ:zº°\0út\ć–|juk‹ê“€EqŸ£›ãÈkÛMõé` 'ÜßüÈ¥¸ÏWM·CFi®ñÏ*JsÔýÁ× QšAM4"6ãb õÚ}îŠ\Ÿ¸·‘ Àz-öçQ h¬XÎvL£âCK>"ò³Yú^UBpÎÄ»˜ß;>~Ï=>¾äÕ¢z|uãV ×hjQ°úÔ§ÃIÞÆJå.Î\9?{«ü–þ(ÍQ3JóŸ4DivÃêx‹¯ÈàmÄž›Äør”¨­îÔÿ bCÓÃÛÓY¸?‹0ÒšO£<Ó¤»Œ,M«ºhZ!ò{^5 w6º±SÞ†ÔgFGOD1BtSƒú€Õ§>NªÞ-Wn¯#Ȭ–¯Ü\oa eØ.èË^ã5ÏR£ êÞïøZŸ;®ãçûWFÐ"â»n1R°úÔ§ÃHÞòõ«7¸3ÎÆ­·Ê{ 'ß/Å>`õ©O‡¼Õë•òG<öÖÊßV~ZÝ/ÃCB}ÀêSŸÑXw7éØýÅÕò/{­¯™Oí—€émŒè>`õ©O‡ªï—Ë·784 [ÎjÏK;P{M1¤}Ýáݹíú€Õ§>:rþµ\¹ù%)ïã`·œîÌ\ǨѮ;ìÁÞU1 =O¿êa<é^‚g°úÔ§ÃFÞÃë•rõ+çN¥üq¯¬ŒÌœØðþ'ý ‰¢G»ÃÇF)6ópü+´ï"×êÑåX/.íVŸútÈÈ{|£rýß…ƒ·výJ [NwÉÛ>1Á£FoÆžÓžb@¹‰“ÞçÜyyÂQñ¤{E°2™LúGéT&3=NgÎÁ_&Ý!M§ëu~„E°,åñXþu—RpËÓÓ™î./<ý÷›QÔíûGâ½gö‘®;³ ‰¼éVý‹ÖÿöÝßȇ¿/©Lªñz‹ûóý黾ޮý” ¦vÏïEêë.ùkë ¯ÖnUÊ÷ahà}T®¼×#,“j<2³ë`ÔèjŒGæ.Òäè’‹óo?9 À‚—ž¿Œ&;×Y·Ãû;ûééi#ÕwÒ£ÎoZÖé}a•X"9Õ`jÝ{ûå +ˆw—Û"û›vÈûEïa/ùö™õ†:³4á^•†QÎÏ*o.÷ܦ³Æ#3;‰×Vׯ6c[|­aTÛ†u“¥,•L&[V†·¢ëã¼5V£®•J§µüûB·å“°ºÖ )aµ"~¿Á7Üâ,e&µŸ]‘j:OçJµä” :IÄëÐÁˆ¥ ÷/tHúÊ=rËi¨#3W)jtÌ–{ŠÍÌ'Ý)B3S<éî­ñÞ°äã873 4söìë?êä7 ó `¥D¹s¸ŸA:—9‹»³™N¥°¸B•Ĩ9§…~wJ…Ð1P+Ù`‰Wõ @« °H%5ª7·ÆJ·[~ÞŠWZƒÈ~[%$¬F¶ ­ÐU©[O¥ƒ ¥¹d& ‡äÔP›ï4ز–ÍMùz» õàÕè8ߍܸä¹:߸Ué¹[ÕËMj®ënËèÑdÆ ÌäT™ˆÞû|k~¹ÃÁgœ‘~˜Óô"7ç1¬óì@hi.¾¿""“™$«˜¬®žÊow%3##"#ãÇ'¿ßȈŒŒµ•=ì)œÅa\ÎÎB%ý?åM@BKWNJ%9Ìt+Þ_‹_xÝ|&¬ó*È¥Úï† ¬xÍzSX·”í[SY`Qg rZ¾GU.^Xè­ÇÝl™·„UZ PÉ75Õ—?ûÙwœ–óþú¯¯š!·*Þ°†÷úÓÙl:™bOùlº3°x¦Æ7¦Ó Åš`,s4Ãnÿü=‰ Š× X™b[+ɰ|$7õ] IØuc¯|éÊÏéÃ#ި׷2z:Ì jÚ2 S÷ sÚüµÖÖ±½÷Óµèo-;— Æ‹1?Ä*7sßqfG3dÓïviJ˜}‘'—] ÃDkÑN³!!³ïÁ½ƒç§ÞS!xÀ…ëSñèB½X¿þgYsÂÉ/øþóÃO˹Sâ€õÞ¸qÜn·;mó¿ÕØÑ$Ôöa=ý½# Ò’Wû¸Ù(‰†g¡?™‡öÆŠB^À‚&!Œ}˜ÖŽ”:ÍS¬{º X·6Ê®d.øôPý{nPê™d×^‚@¦6xiÖÞßþYrMÏ[G¿—ë ºx?#ßç!?ë-Ö§ùüÅ÷³/7®–ó9X¬[‰ì܇ðÀÑ!¨…‚v 7ûp+°ÎΊ\ù‰¤zÄjÔ©Ó­ä/«nm®¡¯ûáçèÀóæ…Ö½áúO·F8ú²Ù½gÓ£â:ãh9ÍY '§Ë•ÌŒ)u}šóSJ‘ÂI>Ú§ƒ§9åKûù©¿LlÚ» ήEü4s?Õ/Ü ¬—?ýþûßûß³púôϵZÎÝÏ$<;‡I5c‘þÅ5JÃÔß3Ô“þ¸ÿÍ÷ÞsÆCØë]l0³²“§¯Qجn÷a×ëÑ#óó+œöÜõ&?Û:›T,œW¹Ö$`Ë|?²æÊ¶¤ÐVnÙnNžÓ°´oîì)`êÝÇ^V—yØò„Ø}F¥.øuF¨ÎOÁÑ›.}ÈJà,‡Òvúòï~ðâùÿœ…Óo~öß÷V¦åÜ%ñ‡5ࣀrÍâÑ4ý.ÌÎåÑ>ZˆÀÚ@,Xòik2–_Þ›K˜ï¼êìoíÃ"3ó€UÔ¿c–¹æ™Í>þú@A1ø¨r=.åååúÇ2xÛ«ýiÛ‡åÛk1k]4qQº¬w±éµ»Ò:§éì›»X¦Ôimz-í]:›¶ÌÞÚ…÷WŽeÍôå?Êw¸ãj9ïß«i9 õGk©å®Ë¯?úÉóç?Î÷V}ú§÷lZH ¬Zj¹ëòéþÎóü}žM÷nZHeÀŠSó/NÍlñwp/2ÿà4œO㌗"aŸn—B¥BmýDòŽæ ™„ùÄX²Œ·äÌõÒDq§™ðéþ7ÅI¶ñd#ܽ”çî’^ëLš=Hw¾Rêj0ÿæÒ¼kªn(Åmëåß<ÿ{?Í£éå_?qøÕrîšT¬tF)þ7¥žcÊiŠU\DfEÁüM1?bÎnÌRp([ÁQ!NÈ›uÄ’PÕéY¶¿¬X/ÿú?¼Xïp—Õrj`ÝX@«UÒ\$í9kZ+slvŽ´Z-¯«ÏÇ©ñÒJ«VW|Æ„˜¯eÉja|›íêb‹f²\6ÐÝ‹Õêªø¹6´Àb0u±ÏJ>0ÚÍ|"¹»Ëçe°*ÇÔàGUûDÍ ¾rí¤áeéÒ¤ `K¡G»(x¨øö‹"ç¸#ô©{´´Á€Mp„zŠWO¥?kí­öúàýÐzÀ²ûä,wÁZŒßÊÓyå8+Šý¥TZ…Š=͉ÓD€§ìÀT)är.KîSœ£”\„OãUi‚a±Ö¬^þí÷þó¿.˜~ó韽xþ“O½CËü|IuÀZÎ[¬Î‰Ùiݪ™4[­¤aPÓh65ÛGɼ¹ŒÓeÒéÌW‰heÉbÙêtÚ­æj¹„Ã45Ã,ÐŖ͹ÖÜÄc`Øj­ u¬á°ˆ;ÅŸH¶ß÷Û ,¬ØJˆp@`F ,€<À‘K4"†“ý±ƒ<õ u'VìÚôž*VX¤p^)¼¢"SÚ6ªväÕâLšŠfûXñ¡[¢¨@xŽ<ò]§˜KJhBÇJ€3æ%u©+K&<^ËìDAXÊê¨B`Et™”Ÿ]°‡°«¶'«X¿îñËõæöò¶V˹kR]§ûrn Ó\-–íùü(IFÓ]Ë~ #5.—‰96ÀJGXóvÒ~ÖNÌÆl—­¹]Ò4gW+Þ&íd12À Ëx6ž"–ôxÙÎzV7ó‰ä‡eŸHöÌÄ좫>°bi¤åä´—üõ÷96``TÒØK-JÔ=pº§~ÊO}åÌ=/~47X)µôµ>¯ë¤ÿR‡EP¢Ž¨ØBF2/•#þÅ[Àd iÆjb¤l ±*cÜ)?þ”%•f€¥¼üaE•K\”‘)ˆuCÅ}\üœˆQ_Ýà n6µå"z–Îè&ù·~l_¯›„/ÿËŸ¼xþãÿ§€K/ÿXwÓr@*Ø‚«är ÈÌ´ ¡P§É(NF`Ë:ó–!׃Öré€EB`Í^ó¶A^» †dTT| +ó£rÀ2Ý®ûDr°Y`‘f@=· ¬4Íà‰ªµƒT•èÒŒ 5PÒÌÙ˾à¿>°xXEg{Ó2ÀbåÏA‰RΪ`ÌiQ̪!ß8é﯅¢¬°¹Ä1ð¿Ô%#eMËÃ!¢Š5#¶¤ý®/XVy$`‰é-9Žàƒœ¨Xëî¿þå_ø‹<ûò韾¸Ór@*4 c²->Z`ÐÌ ˜ŽEmÐXèbFê€/£aÍ—6Db‚4 qÉÑŠLBtå ¨nkë Ub:«±d {1wVÏH4¬ü[»ª$vÀõ[ˆh%©gÔY[*ÿ¼U\`¤x0dVbÊÄuÑDL¼‘ÓISNš§aA> $(kéÞ6©ÕÄŒ³[îŠbÇij9 +õ,¼l?TFS•ëÚ¤Ø_‰B²Ÿ‹DzÅ2£®B›°hXçõüÅ~Zˆ¥ŸýÑ=œ–R-°àmß ¼Õ¼c¬8Щ g ~;:2>ÀÆk³¯ŽÙRˆÖÔ¨„CeÍø4!ÁoÇD6o·VW… >X]øÄqÑ'’ßpîÉ[€åzsY 8$°\'Ž‚×ïÜcC×ä¬mÆ©uq¯ “fã¦`Õ¼%”£Ô%ÝJþkU%wž•@#•Ž.X*=vÊjL¬yÙ·r҇庡ÄE´#û~ýG1½¹Ì°QEö=iœfô/å´2ÅÊ*!н‚MÅÜö“™]MFúµ8¬—?ýÞ‹ïÿo…ß»ÂÕrî£EX)°ÀðK@yö€wæâÂGIö\æk¡×}ÎÙ$ôj˜â3òæ>:µ¦KÑôèáéNµº¬!Ìc;qhäÝç Ò=í<«T4î[ÜhÀVÊ=1<0+G+7ÊŽ¢ßÛë¦_’œØ5J3 §ÛÀŒŒöÉŠ(Üh(3D‡Òdc¾yãw@{Fr±k⩼Lí V˜ÆÆg(ë]/7£Mù‘9S”ukšÕ>åÏCŸ×€õòïÿèùwþ¢W¿¾ŸÓr@*ÖÐh’´`c”¢v3'xâÈÛ÷~ÝNYhÆb­ÀMƒ``ÑÇùhn}´ïÔ¨[ÝÓG¬.œxd ¶ X;‹Œª~t``ù0°Àúãúíüš¡emY²0ŒÒ8.7an¬á@.,ç-Tíf€“cba>FrЦkAÒè>ñ¶À1QwãÖݰ-Œ&÷Ãq ½ùGC˜ÞåÒ;*¢Ù®Ù|–,¥_£šç¡6W™ÝëåÏ~üüùÿ— /ÿî{ïßÃi9 ÕkˆÃ?­$Ér) ½ðv¦F‘†uêq§Ûuß%§SœMÛ2¬Áȯœ%Ó®+ØÍÉ  ¡Â„e™´< PO --’¹›ÃAaÜ©Ä]ÐâöH²—%n‹ÛãÌð„ë!Bĸ16F’ÖADáó€µ*ˆ@‡·5tó#œyJ­\n‚N"°lZ(Œ›Ab›þ{LGîŠ{]«£¼Æüe­qXq}XÖ/ÿâùó•Œ …i9rϾÌRáçeü²öç8ØâÈ5ùÂp8Ìθ(žú°©•å>/#ßl8õ*Lj'néÇn‹w™tƒUµG]åóÆgÿùZÎ.i‚¸#™þ–·o|?1÷aEkéË´ùõüË^·¤ß­ì¢Qv>«I†±=–ã™(Î¥Ám#¯ì™\ú9£4¬Oÿêùûßû?K¬¾~øþwîá´*¿‡µQÒ-ç·ùñg{åÎÀÿ­ßÃÚYº¹ïaÝ‚ò‚ùWí/œßñneZÅån%̶(|¯½mN/ú½ò5_þíó÷ðÁo^5;^‰|n¾8úë_}R‘Ü¿éµÜ5yù÷ôâù_þ%g?ýó/þì~Z„Ÿ`ýú_>þÅÏ+‘_|\#«–W+/ÿïÿøâùO>*S°~ö‡ïßËi9 •‹–ý8;; aµ\LW~¹è…nm»ÚúAGZ‡üžÙõCxÕ\*' ae™ÐEºó¸’0,]ò«÷­wß}÷w÷–·~÷ã_yé£_»oïKþö=†…>ûL{ǰؗüùKÇæóÆþYEñSÉÈ*;Ù¥hÃðF饥¾aééµ´¦¯äOîﺸ|eÐó¯lLC¯çßOþÞ¯“æõ¿ýËßO7¦_þIy‡;|1ùßÿÁîå ¬Ï*ˆ[Éy}9£0ëiùoÿl/[XÎOÉ’…€«³ð“_¼õäq%òä­_|‚KîåSWÉŠN…âç^ÑúÖÙ|¹~ܰ×>qdóA Qž{(‚lþÚ>Œ×Rp> zEñ†¶\r mI‡Ô®]%Ÿ[•äܶŒµÀÂîåãØaµœ¿¼§ Öí˯?øP,@B®jx‘Àš…ED›ê~òówä+_ùjæWä+vStÖ“Çïþü“‚åæ,¸Ô¡¥Ã < XF!.\–¯`÷XðXÁ¦#Ü7}›ïƒï÷~NË©XT‘2æ[PÞÐeaUߟ[´>X¯°½0,ŽË\Q3°¾bAT¤]€%* WU¦aõ`ùÌ=‚oI® [uƒë`õ²KÍ^ç ;ee©§¬¦MµB@UO‡ÙúR}ùU£l\Hõåß}ïÅwþ²¼Oý~®–#R°.ú´À}í(A]ôûæ™i¶ççáùxüÀ#ÕÚ“6@Ÿð—©¦•·FDþ ‹l:ÃþÛ¬òSßùù'æa× âÕ³H*7“íÀ t¥ÀÒøˆ0ÀÊ®ô]ë¦âê¿F F¸ÿä£ò?÷wZHuÀêÏŽÌú\ ™&ØŸ5úAØŸ5§ãóñìx̧Ÿþ’áb$š'w¿1ëÃß®U'@ ëñÛ_0òöãÇ_4oññšV9°”R&9fK)3;hXÑ!º‡àâ|hE¤¦C ˆñèL<´U&ÕRãQÃ'Ì…ùÁѸ›TAf™ôzØ:îtLjÞFë«£IH·±^Ú”\]Öžu¡ƒæ[tà£ØùZi1bn›„K„ ïg~¨èOe.¦‚À+#|‰Àá]‘ñV{Q¯'_ÉÂöU ´¤ÿõ¿ùÎ~V>ÈÊ(`÷qµ‘ê€5žuf³ÙÑ8<ïOÆï}k2>ÖÕ?;ëORáxÖ>šŽ§''ÐÆúï'“ÉØh]çç {[ßì]ôôøx66Spéù‹-O³3ÖÞzç·¾`~ßyòä O_›UžIH•*4bᥡRSewj!s%$¢tha“‰' xŒ‹PGª)ºbTÐýÆ&­Âk:š·.¥E¦ þ(IǾ‚/6CÄ5¥À=wzÒž}É'Q ¥´½%Â(° 4Ïä<4LlI ªø‚\ZÞ h/åÊE…-é—ýãM=T0-çOïé ¬ÏªÕ°XÇF…j´[c£ouŽakt®þ¬ý 3`u:³éìÁɤ?;2îãã““N»9L¦ÍæÔ@í¶FÓý#¹Ê‹z_.–Õ;_@p ¯n ae€ESSåf57F§ƒˆz·± PZuè’µà ÑÒ4Q…N£Q¶¡ëPÔ?J°GEZi(ºiˆw­ ¦*ôó—jJîr>28>¦fÞð²¼ ©€(¯„C¤·]ØVàë`¸²ö )~ˆ°' )¶æûÍ›ÒË_n2øþù‡/îë´*5¬vðt>}É éhöåÎdÜ2Ð1`š}É u°öìø÷;Àh<é|éKf³¦üoÍlŒÁØ' hœfÍÉŽÀ2ï~áñ×ëßýÖ»_óF¸ò€¥=`0°Bm©¤*J‹2¥ÙbË‚k>sCÒ~Ë +fÁÀÂëkۚă ªk! Ä}X¢[±µoà Ŋuf,ÿל3 u e=q)Ô(¶ø0_Bcy„J “y Âð‰â–%ïIVyâç‡BNYýIdŠ ÂñãBÊŸ.¨mú]¹T*ÛÛÙË¿}þÝû:-¤2`éñ¬&Ü{FÓ2:” éÁÉ1éJã ‘å¹·e „Ûl;,6 gG†aíNË ‡r–wíbÖ×XOþõ¿zç‹OX×—¯x–V“ iTµ ¯¨ PBipJZ˜æj¯=ST*gZ’Jê2`…Ð[£­†Z«Pñƒž5%ºB¸õA/}X”¸Ÿ*+ ¡¤×PK&-D¨ê€…½g°„Y‚wT_æRÒ«ÅxadÈ“‚(ÌXy´hf¢V’w&´¾)VÑà`bèµ]0/¥`t¡b½Ú íRVâ*2­Azö- óÝ&ŸþÙý–R° K;ÉIŸb`µ¿<›ûMг‚ž1Í¿¶ñçÜ›}ÜN&f{ºtÛ‡F?›‚ h]&¢™½Ú¬¯ ëÉÔ°ÞzûÉŸì,hg¦â"°B-ýøh CÑ‚2Àò9âxÅàƒþ,ѰDÑÉ+”cíáI4í\¿ýÛÅ$¤æ€+–ÎSÄÕNÃÒ®Ý;`Y KSú´¯aI”ÕM}÷@ô1j?ÿêZ(VÅçÐ+ ûË”„ëÀ‡'™¬a…Úe6_ÃuöWÕã~-`ýægøÝ{;-¤2`õΧo°: =ÍNt&ýY«}<>ŸuŽû½Àø˜L³YãœÝqÿ¼15¸2Èš6à â´èþôè¨9™M'Óãã¦VQƒîEîOà-ᓯ=þâÛ_üä‹oÞÄ D`ýSÏï—á¾^Û䶤I±F ¸o\Ù˜ ÕBÛw~ÐMœy‡èAÅöõøï¬¼Ïf´½CÁöW…hŠ=æ.¼gcC`‰–HÚS&Ç\viïÊÚ?´V_#ÑþÝJ¾r†éìsAûF¨”§S/)•(W”¤£ê r¥€ÉR~D^Ô61m¶«+±µ™½ü›ï¼¸·Ór@ªÖtC±¦ M§FÏ:1´}ÚöÇãc‚Îöy§0š‹Î{ϙԳ.Xoþö“·ß~òÛo¾ùÛæïëo ¬w~þI/ÐO]Ö¶ýQHÙáÁ¦7Þî[Žêõ`ÅCŠ›€¤ÆQQVæâL‡ ÷[)¢ÁlIÐéÕÁšî(E¢œƒ¾^¤û&êÚ²µ™Áj9÷vZH…o ›Ç$ð}cØžtàzâ;NëXNãúá}ôv|Üj³¤ÍØc³|˜Ä‘îo~íñã¯KðMþ»‘ IØër èz5½¸ó“Ÿo"<%¦ É7xoVq×u±•vÞñÊ$["[›Ùßq§å€T9¬á€² X:`e&ÜÜH¿úª›šs«À:ÄÓZâ¬2P °pªwí×áîúõW"4«t³Àj9?úçW W)UOÍÁé9ü“wð\û¾ÓvÁI:›¦ïÊ\œywóa AT;ýnƒì5—p›Ð,Ϫñ&ùºf½X¤Tnke¿üã÷ïñ´êú°zÔYüÑ‘Ò'{æûD©DÞþø$ó­¤ÃWÔϰ®9QåÑ78s—DoÖopZÎý„õÙçç‹£Ÿ}òOÿãÇÿèäcÿà:òñ?}òªï¥–Z åžOËùÜ«–Z>÷òÿþpㇲîƒT·jNÉ:#vEßÍëŽx'yY¦ë¬UB«æ¯Œz}qË|ÝŠ¤·°jNÅ7S’äë\%½~­QG–ÞbYÞ<í”ÆÍmŒ¦åÔÀªDh·opuâ¡¿2]œ]ŠtäVcãœS»¼ø°$Lš–,/ϯ7x#†Ñš{[Ê̯å»Ýgy^¹µôþöYîÎÅ]e¬²Ì—'‡\´o/¹yÂv+ßêd°îû´ê€«YÆ‘]×+lXSwèê ¬ï¥Ü8yY]þqMÉÈÅZºÚ®[Hµëÿ<âžñ¦{êy)]–—ª÷«jÄD••‰+¯§´ª£ï4J‹×8…EßS/ÙEÅqÇyÿû²ed”ÎÆyû´õÓG~E©ü°´âµ;Ç#ï(—!ž/‰SjÖ@ƒ¸kÙÓÒ¹P(ÿnüu}×s:Í”Be²X´Zνîr¯Ô$¼\,B¶//M‹I]2ºS ç¤Àþâ2öª/F/–Æ=G¨Ýc]DDáŽø+-iV¯NOHMþêõYœm–×@®ƒ[V$®aÙ îÄ©—6ï\TwåÖ€”N‰ªreYhþñþ€N‘w'þ£ÀbHn;òb¸cãq¹ÑÈ»}5B}Æì㘺(¨ösƒÂûdÂýÈ>NÙ=fÊ>öÂW([€uß§å€T¬èr¹J’dû·–ËK*T6 Ssn¾ZÐjÜWàoµ¼”§ßhˆkÕ›²0îÉU¦y S1!ªA °F…+?{X:=Ýp²È$ôª'÷€T]7ýèeÝlq‰èÁK³‰Ò|ÛŒRé±M+*L#«BÙ•³+iYX¼^\‘½NMF]á5ìÙ-òõ—Øêj^Ú"‰)ŽyÙy¯›ÊæMä¹§.DD¥>`èRпgkd;—¢ˆIÆ©‹Ýoå&üf`Ýûi9 ÕiX‹U³Ù*-’UÃhJ gÅ‹ÂÎ5’«+C£øjÕ<2‹ËË«K#†f——ß2åþ¡ñtÔX]~úWjôµ¥‰ëÃˡCÐÎLÕ7« “U ppëÃSe ¤ðÈ(\]…Áñ!úÚ ¬T™ªªð7ŽÕ!•bV›t’‹Â†`)D{6eð È[Lt° t÷AÞ÷× L´œ†8£šTp:c! AEEh2ÒÅÅi2„=ºëTÀ¦jæ?û‹ARÅ,»+†– ')P¾oµQ¾2æo$7À¹yJc¼X|Ÿ´u9®ÒÛÖßÿƒû=-¤B`%Í•ù¿X€µJ.¿•$—‹Õ t®Ñ²itªÆjµüp”‚¿åb~VàïÒü€¾exe\W Ô¿H_ƒíòÒ¸,FܳµVAb¢a)úSd*%GâÆbd—-ÀRÔT|u0^¡À¡(n*О€YÔlbD'b“?Z.ÛXË«UûÁÉÊ„K ÑŒà¿%ä{êÃ"ต–u Íf`Y%‹Ô˜ƒ+cr;äÆ;`ű߀¥OG¹”Û­ ,Ž,%èíݸ¤Ó=¶Äi³ÀaWð-ÍÛùô{‚ø8vy-pUk¡l|KѰ” Cãg‚Û<%×T²‰;&Eß´&·JóÀ’@ )Ùc`UW¶«ž–R¥Ih´¥æ uÀ2*”ÙMV,£*A_ÕLBÒÇÚóg‰1!Ÿ™íÈðª1T%g°5zkÞJ8–r‰cgËc–ìnyKHOp¯Ç"–Þ™êª(§=âJXj X~¿Jì5ç|ô¬aY¦šþ8¯K:Á¾†%ýF|$ Ö°„º^Èx]ÃNq÷<î¯ËyK‰16}ðÃïÈó3¬H)ä’ŽXƒ£Ü²Ï›ãiI—áÍ%â÷Å¥rÏWË©X NAXp«örÔ\&­æt®û­•Ù‚>f\ek¬É(dÉjuòà·ðcâœC,G›€}ªdÒxkÚ·„ÉéŽß,èxÁºMM'Šäyz`ÅôÊ-¶8Ø%/¦RÖˆäÐiXÞ;+Ú-N›¼Œ¸7ˆßxî£fÁ‹~Ò°w#±†%ÝÔ±}©Æ)e±O6•»-‹fJiÌ}IüâÃݪ¼OŒé<Ùv¶ëßz‹8))+mÒF©Á1Y¤6+QÞRë+¶wâ-÷–0Ý3s¹ºX¿ùÛçïßçÕrD*4 ç(‰·e—$±{t*™'¾ò“HøÏpçÙ3ðg=,Fe° Maó8¬îÃìèP«HÁpÒÓìhÒn·pâN7;Òýà3N";l<*¸˜}»UÚcmîûåži¶{ÝT”Ž"—äØ9ÛqŸ|={.ÊŽ0¹ÛJýÑQÞ¨u¨KC?e¼¨õçÖÉ`°Aј5~_Y +¢ðw–ÛnxFIÊŒ‹·£³Þ¸Õܸ®}e€/ ÊÛ×§^OË©pXC£ÉÒj53bðÈÛ·r$‡­&ô{囿ƂÆ5ÎY`=êÚ¹ƒÝÓG@&/ =U§Ð_•è^,™š3®½@TÒ&eÇhoh(ùSÜ;Ž»þï½ÚÚÀ6¥9<Ú"µùæ õfD4ü§ÃŒ2Cõ³ Ái5Q.¤;+è°qÀÁ¦(²WeÅ3¢7ˆâ.£Þ£µ˜aRüŽ,tí6*Êþê5Â+—6¯{¿ZŽH…SsËj$I ò™¨4œÇ«ûȃìtO­ÒôÈB‹µ­rA +Jã[P®øD]ñõ•ÒæPdúɀ̓•ã–©-ü»—Aè:ÝS|Ù B<¹…fÌ P{°3û$Ñ  ÞñÚ´™#Óm²Z[vZ_¯hgÚdgRæg:ÊœBR„O4>bDzÚàAg¥Íëåß|çýÞûAXŸU ,©Òfò_ È7&7³Â= ­?;ÿ!_¤qþù³_k°”r¶ß©(^§Ì«Ó‡…fÊDÅT\ñ¿T ñô7Ã-Ó Mz¢Ø›ƒ)qfhq>w¬*äÛJÑÍï„gÚa¯qÏWZY£Ìéb°¦ëQ¥kº—=²cäs!"[³”ËùõG2n53)(¥©Eö"bÜÆñºy]AùsYÂ¥K›W=-‡¥âïaå><äÆ@ó°¬;&Z¦–仩oñ6)˜KxcYûÖÓ¡?§Tú=,—g¶¥(“íœÂ]â®æóP.ÚÔ+Ý’¨×’®í”ßÿ†0¶ú¤kΩW·ÒlÊÒÜrñ¥S—fêp壴y}ðý÷ëi9 õGk©åÎ ¬–óÇ¿|Õ©¸ R«–Zî¼|ô£zZIuË|áE Ã»±KráÊ3½‡á™9„½žÎÎp]š§äN«sžQç/ë…‹áÁ ÏÆËE(+2S@Xc'¬Î$„N÷ ^îGãµÂÍËŒí³TJh/ùW…kú‹=gV+¶+ fÿÀ‚®ÇoâÜŠ„œþ*V~íµ³b~ÑÅÖÓnÈGY©(ܘ×:È•G¦|\\Ù•¹óñaPÃõ´Ä¢‹îØ¿W›Šã ½•£J×Ë¿ûÞûõ´” ô\áºß‘…#Z*X{ªçW,qªpÍcè-–Vö5 tºŸv±Û}‡N÷€š€«š‡J@«©ëÌêîvW'$ã® âöýV•bYæË–ÕÆ5àu>ºFº$‚2÷¼³.µ9ÐgYî^ï|_)i\õ´+U Ö`ö2?óLg` ‚ôN(\ëƒä«¸ÑÚ0¬SË)C¤G>µTuÅÇéÖ/Žê`­‰Rhågj?g6" @Jü˜’ÉijûÝ …yAi Ùœ§|âýÜÄãë߈Þä§èXo‰ÉËõÝ‚¢pžÖ÷ª +?ô£ïÖÓrH*V°¥*R±ôÄWn©ÒÌbŸ¼+ªìÌAϳ11{^(M–Š:”§F=zôüáïÅGOYø½jz¸eU5kAÜø]í ¶ÃEo< ‚Ã,ÒŠù½»>³›vR¦&îª)2+kzþü³ùß].®ƒõÇJRܶ^þíó÷ÿðgõ´*uÑïŸ#¯­Jµï¯üÓXΫÙYŸ–ª÷ü†ä–3 ºyN.uº>2QÇ­Ùô7~ÓÄ÷³þtÖ6nh2º·„î32–}"ùá–ÏËH´ln ê°Ä 4´~eîEiÛ˜VraeÛ©}“¦`O…žŸ’&À |¶ö½OÃÊ"ã#ç 6sêuÑyß]ܧ”縦‹‹M)ìû4*„—’ Š %Þ¼g•=+[ˆ½ê:©/lZõ´OªÖ7ÇÓÆìx6mL¦†[Ófsj~“I£}<6:U§m¶G¨W°Zãñq{6=:šN&°½k6™íq³Gýññ±ÁÒø€ÕG—÷Æ_ûAgÂ%½XÙ¯÷9õªô~¶Æ†®–P<`á“ŸÚ \ÛW èΣj¥dKÞTXwàèWɽ°D[ ¬þA <²_ùˆéd7³¯u”r{§¡x ûj8G/D¨(ʆÅk…î¾­&ª<ÂÚüP¬Ù*¹f <Ä·"äëÃ>Ä ›V=-Ç“ê€ÕŸ6 †:†X³ölv4›™Ã¶ÁÐìË'ƒœ/u`;CÍÚÇÇ­YÒù2û3ÿ@±¶ <ƒà†gàwÒ™M‚iX} }>}IâãB¶À:Í›„…ŸH3ñÑ`…X·ýíÁċڌ-`…¨\i¶"PÌÆ(K aÁ–¦Jãø^±áö”ŒIh³IÙ"DX[{{±÷¨È`#Ä ±ª{¿ô PÚF+g9>-×@]I€e P(Ú'.{±[cãn@%ÄwWD`ñ!^×Að6M¾ÿÝzZŽH…ÀšµÚ'ÓÉ §Ón µ&“ÙɃŸ¶Áσ“ãqÏëxjÌ»÷`F³:‚íx '£uÍÚméVv;ݪóà„Ñ×s½ó¢a¡¥§È´óÀná'’K„Eš«54êªiX,iÊû÷òS5 ª0n­„ •54Ûé.Ñ„x„IX€ €Uh}ZG‹é…²z£wïJsL°°p0N_Ão˜wÊSwÿ¦“ò8àN7£=…)á®+d…+¬êkºÀj9õ´‘*u Š `ZÒ¬ÙwºU{>] ,Íæ¬äçf­PYÃÒK(´ý\·¬þq=-ÇIeÀ:ë7¦“ñdژΓñxzÜnš½óñqÇhUc£>ÌÌZ0 ûÓ¾K<7!&Íæ¤ß7[ã§Ý>ž5Œ†Õl·&cè;7>úgXmìÕŠï|zÔ†˜üDŠ”áÑiÁ[B^Hõ \—Ð8î,Mýª¸“¸Újdºh4™x¡µHñåµ[×säi€z=nÒ6´ôUbÆx&¡íˆ é‘FÃS˵XSÕÔ¯E/ãBk¡*«fiûžŽ‚†.Z¹UÖ„¤‹Ò"¯B/GÂÐQÎ&ï8‡Ôfå”7ï-¡5V­ŽˆÞüøƒÛV=-'#•+ìO ° ±Œ~ÀB kЇ³é´5ûò cp‚>À/:Mûý©õÊ2àf‚qz'8>ºÊ¹S)¼©92+Ã$ï ëm7+€çõÓC޾ò«i~ºŠÌ#)›’õ–hX!j2¡L_„EãQsßd.ÍÔÞ|¼õ©9þP3ïùÑ.üónL–Sèå‡/Þ ×@¦¸†anJGnLªvswÕ{)hXõ´œŒThµ`xU«ÝÂßv»ÓjµÍa§Óþ·ÇíÎIÎuÚÇèéØŠQ«Žp{ ^ÍŸè”o9OàѶÄS«e¶ óåO~îv=Ê"é4Ã)ÚÛ¤_uX›§èU\MýF¦½Ñ‘yHI‹–‰¿ùÆU4—°`”A“Ÿ×Üò‰Ñ¹Ýußëgt>ªÂQ›^¸ £æmh ®wÝ­Q°,2û¼XOó-tºô?Ö«åxR°zýÙ-Ë´ XvÐB×îyÜ·‹Å}[’Öz‹Yw*Õ¨ LÂu@íO¬”ÂÜe7Q„¯©¯qåmŒ]¦£¥S­óQoc¿{Ân.ëíªž–“• Žâ„›Û“~MBêy?³ÀÚI»ëöääž)^V”ùI×ÒRxa—®¼‡ìÂ’Å÷4(ŠÑÏ™Ü=#râÔ= ¼‘—â"˜Fè•\Q¦(ªXõj9…’Õ°F€«««8¾42ŒP{ÚAFhx\.ËÅeœ^^^]Æ&–t4^-†ƒ!ÔŠ€櫓ݰ¤3–ŸQªNO ùtj7;k­¥"ñVùˆò—òxcC±ÊKäˆaU¬È UA`4 9¾µôÒ¯¤%Z¿%+kéu÷¶™‘A¼­ÅÌø§ƒt`5´âPõ.]Ñíë/Ÿ?¯§å¬IFÃBµýj¹¼º\®VËËtW`AF§—É*1ÿ/áwùáåry9LI² 1ǵ[|7)é|OUÙçÝ·«YÈ8÷WˆƒÊOÝ!òô–Þ¿áò^Df»ë^Ù9ng•¹¦˜›¹>EJΞIê##œ“®á³ŸAŽÙ^O¦MäåÄÀ™€~’œÕÉæNDûæÇ¹Q.;ýÕöX¥~ïZ»äó]ñ‰è >°>úQ½ZNøÖÐhH‹Ë¤‘,—«Fc¨¹°«¦‘ÕÕ¢‘˜(’Uc14N凶d‡;Çwí‚&`Ѫ]ZHõÔ_HUV~î*Ziu;°Tæ/÷®¼šš¦aÒI‡ íshš…’v‡r³Ølà&c X‹ù¸Á‡Š¼höO2Æ»¦`©Ø‡…Œri§ãXH€¿#ÎcVp"ðOøP•žñFq3—4îÊáݤ ΂¿È&˦I"Üã\–C¬8è×;Lé>É1¥ 1ÝQåz·¬—ûüêÕrÖÅ–чV«UÒ™Ú$­d¹c. …LðEÒ4›‹Es>o·æs³·j®–å•g»T]¶:Ú¥êU€~Ã_§Þ¢Ëü½ñp‡¥ê¡¡˜š mÔaÒíªiL ›h Ú!7׈±ÉÏvºe<ÄvDïdÓBqÜ)ù$ïñþ--¨yÖÞ‹ñÅfTL²H!¬¥Vu1:—âÛg€%·Ñ}ÆîAùDâJI‚‡‹Š•U\)11²O9åŠe«ä’˜ >kó”=ãƒp<•#ËÖ§?©§å‰¬åQ»iXuò i&€­]CÀZÎ[¬%«mþ–KÍ’ŒBx“XmÙfÊÙ–Ш«²´ò ¶Ã[B|ÄÆ^Å>`ò*1µbz€ÇÜ‚PàF.Ï|nDø¼WNQˆU‘•âÃÈ–{»Q’Beó*F=ñI¡QØúU*º‹¢;¥ã8åÛVÙÊye=GñU0[è_Æ[ÊÀ’XHÅCeGyˆ¦4P|HZ©¸¤) FS¡yàÃÊÍB¬ß|ðƒ÷¿_ÂZ— ° jŽ’¤ýìÁ³ùük‡GÈÈ”+i·ŒIHÀJZÏ:‰Ù[5:í°‡¦`| >,V—M‡d0) ¬7fÔF££¢§·èY‡X±"¢X`ÅKÆ» BÂfÙzŸV6î4.òsÓ$³©ÉiVœ%Z4w>J•½ALšf¬&FB0/Ü&‘,Z2ñ¥²Ä§Þu2(ŠüV_"›4- ¬â7MqޱES«-cqjòw…l"œåcË¥8*¾×Ò‰Ñ~ ÿ>ò=@Z¼ÉEÞU³sœÔêO~®V,°þ—ç/þ¤„U$ÙÉÏ%óÂvÉhûxs¾(ær¤qQlþsuû•6OCÉ~^¦Ë_dðªîCùfÃéÃ-Ôâ/²R#\Ͻ©pô4J‹ô¶›ÇçêK~ÖžÙ®?š†kn×KP©’¸>mp}†c\¸ )q\\!Ý䣉ë£?úî¿ÿim‰¬=»v3’æíf]öû¬*þ[¿‡µ³tî™7ʽCÇ]á—›°=ÓÐÒÍÞÖ\náÛb¯«PÖPS¤Õrêi9Eò¹ùâè¯õIEò«W}+µÜsùô'/žÿYmÊçX¿þäã_ü¼ùÅÇÿòëW}7µÜgùõ?øƒÿðwu%,”Ê€a À¯ì_\ôœî¸ý3ösˆ„A¸8ð÷BöÃðÂ쟅¡ÄOaøô©9ý«÷­wß}÷w÷–·~÷ã_™ë‚„âÒï§!ÌÝw6›ÿtøÙg:àxÊ®WòG¡riÉöYøiÞæÛ±I¯I,D†:›ž Ÿ¶õ__|·ü~Q8{tè»lè¿`¢+¸ˆ®‚2¡$Y­¥Cg•.»œÎCGË&æ¯ÂœóóQü†BÙL ”W>”>øSžiÃH6»ûÀ2’cS|^Ô~òC¾˜®ÜŸñj9õ´œ2©XãYg63·fÓþ¹‘¾Q¹ú“é´Ñ÷ï 4°)BjžÍß\ÎQ/+,fcg"°¾ðÖ;ï¼õóûΓ'\û˜„XÉ{@'ÂCCUæJŠ­A@\¡&çBnvÔXð<Õ~øÃ9\?“â°Zg™æ¦ášL¨)^Ð6ôò&bËD`Ùtì+ôbq­Cå’MÊ:|üóøÆQ(%·‚{~¼1Ï4§_c¾pQ˜] `‚r’Ò!”‡Z…T˜§üâ ¤‡f/ç‹ËOãN½0´¥)7ÐÃ$cO9ÐË4¤—ÿù;Ïëi9¥R=°&íÙ´11pkvÔÝ 4%³e`uŒÙƒ“ ŸœtŽ›ÓÉdzt45áZM³5º˜Ëø2.æÜø½’ösFÀ2 zç .áÕ 4,¬^( ¡ ©YÛQòyß´W"µ[ãi«Ñ  ÆZ5q: iX=ð®óZ6lª¬2ðy¾¾.zöçš6L¥½díß°°ËÜ ´|ÒvÔŠ ÎZ&d_¨%áwÈЀõ&¸{MçUŽsš²,ôÀï4,zXð9€¹Í 3›”g‚8ÒxuÈš“¸GÆú¡nñPÛSâÎÊ[BÝÃòÒPûÕÔ]Á^H9#Ñ^Y4,-.¶+§t,=š„ZÌGÛå¢ËüïvŒÀÒòÆŽ¬)Å™&ŠŸÍ‚@úólŽú‡ÂbgAçú°ì[B›~Õ“÷”N%™J/G쵘Q¤\a6cs¥Ú“ÞH˜{'î xÆ}ÞÁßÖãÂóÖÓlÚ/)pÖ›Ÿ¼ýö“Ço¾ùõ¯›¿Ç7kù½Ì_,€faÐ[/á¯Ã,6Oa³-Üt]èd]õ`™æD/­}ýU¬œ ¾%¾pÂaIf  ¦0¯9íþŒ"!÷çyo}Ï^o“}Ãäf‰±ïò4Eeª·úÜå˜äUãàîK…ã°šÇ,­–Ù´Û­ãv§Ý‚žøãv«Õêt:à†'­/ð~Ûmrìtèœc-ô»Í~aÕ8 i¤û›_{üøk†SoòßÍ€%#ÝoKθõï7uñì¬ØÝ‡áÙîÑm‘`)!‘»JqšÜ@I»÷ôLmº‡l8;„¸4Ê­´ láê2°D^5î¾T¬ß›Ý‚ü^A!k¬ 7—Ðï™òd熯X8~v¿X6KW ,ø8ë¬@íógì ¬§gäó:À: ÷̰›ÈAùúªqp÷¥ê©9kÒïï‹K¿8˜óáÂõÇý²é2 ,K¥2l]X›&U*{Ï%Üô}Ö°-{ßãB’ŒSØy¨Ý zÎçŽ1ê]ý‡7Îdí¹£]'øÐœþÃÍr¹ô^5î¾TׇUðÉn _å «J˜}¾â'ÜQxÁ“Ÿ‹+ÎÅ'ÿð;o?©DÞþøé#·,z®îÇf`awZeí- ¬^XÚo|;æ¶þvƒÊ”N¯4ʲ¤ß XxÅÃÍ^´¹¥{5°¶Êçå‹£Ÿ}òOüUÈÇÿôÉ«¾—Zj©¥X>7Àª¥–Z>ÿR°òˤȂHr”?éü§©]4$ãomM–ò5Wª\5çám¯š“ÚUsÒ´úee(îŠãM‹–IºÙuÜ"€%Í.#]p¥¯áÖŒ¾EÁë½jÜ}©X¸¶³·ÝP¶X¼sæpî£-ñ6tî"£Ìjm#‚Ÿñ_°\—õ€õèQ9°(òÑ(=¼¸U«_fÖ[ñtçU&¯­H´~o™ùmñíâi'‘Ec‡ky¹û"ˆö  •çA ¬¤:`he\h벂øh”_iSªÑh3 †¯¢\M“J¥£Á¤tµ]V·+‹ Ê’©™%OݹÍ%d˜Iû!W~–¥ÙmúWtYBK†ƒµæ~Œó° î‘Í`Ëp/4Æq°Ò-Hlð¿¾Èëںά÷ä¼ÙJ$¹Dy6ÊoiÂÜzÏ»“l ]µÔÀÚ*š„— #—NŸB`ñb¹——1nMŠ/?Dm‰—ü¡¶Jc™Æ¿ñR+6g‡»‹Öu>í– ©k6!ë‘[ª~˜mJüI¢UÔt4Ì/±LÀŠüµ#p)V‘îS°ÜóC?NHUfáeJæpPÐÈ3·åeµÜÃ`e$^=ê"[J,K—Í^hóªöñ-£BÕS«ÖV© Xéår•$«¥¡LÄÕM8,ÔË%¸h¶Ãô2Y^޼Z6 soäµÊáe’\W#ˆ ô!UÜâr6úZIècétÓÉâ>¬Tš8÷ÎNl‡š[Aph›n:áF^[lŒÛD£(š 4PÜR¯¯ÁÄÊú‰Ý©XE_q"_‘õIwíâŠm¼ÊS¼ARŨ•Ÿƒ xˆqÄkØsWÆüì ÀNLyJ¹©l¤è-æ¼¶9®Òê¥ÖV©NÃ2 Z­’æò[‰Ñ´¨o-¾µ\ËðjÞN †’vkµX=x°ºD÷Åjž¥ÌPj±Z-.M¸ÕÂhaWépÑL–Ëf²—Å*Y`iRþz)£;jXŠþGJÉ‘¸ÃŸ±—ò>¬ê*ÖO¨øê ý¯Ðú‡æ:©ÂÆ ‰/2*#j–Þ+5n¶JÚ/y/Œïƒ"”hö ÖpÈù  ÔÚ×o¢s9]“J‘²½P¤)™h-|§VÃ!ÿ±éO’?"ÐaùH.¤|‡)[”M °‡.‡)¦^$Xü)§Ë&¦ÌS’ëê±X[¥º>¬eÒB`]®šíöÒè[í&l›€œÖIÇk™t:óUb€îÉbÙìtÚ-`xK@C3[ÐÅ–àxO—«äY'Y4 n–IûÙ³v²lÎQÃ2Àš·çmãâÜ äš èfÍd[ãqi|†e< ¬e<% ìx/7 X§s&!þó(F]67‹k63 +j¥Ó€Õ‚P› Ç|*re'e©.ƒÔÞs‹ó&—1CŒŒP’âkF:}Ó ,¶«$¢êxZø”£Ô>Q¢!Ê}*w¿‘·Ÿr¾È¢W±QFÀrEÅ—b§£r\œ7J kVµØUB¶˜mRTµTÌ/ ”ž¢­fÚJj‚y¼jÜ}©Ð$¾@·SÒ~p²2¸yÖ6„zð “Ðþpdøeütæ-ç>?Zâvµ:šÏ›)ÀkÞ60ƒoÏ$‹QŒïÌ6ËêNÕu–¡q8UžŸMÀ²J–=çâ€åµgVì€å·v¬X»H•}XÆt[\¥ =° ’Ì>êJf?`%M£e0µçÏæË%Aªet1£d%,££´ý \@¹2ÜJV ~ǵ¡eH•–¯d)âš*}KØÍËöXЕ3Œ4,n–þaœÃ™è&©ß|Ê;mLù ífƒbG0ÞNLB›H8ˆX‘r&S,ÝUž†Ç^ÖÆ.aÞÍÆy`ű»Pšf”Ѱ¬Š˜ºH°R å"•n/²ü93/[\‹íI½ò7ÌÁµ"â7Á0äçUãàîKµÀZ~{¹\<0tU=0ÛNÇ}óй–«ŒA4ɽ…û­Ô¨$ýyÇ€ÏNüv:s8×\]Êz°Rzá &!jXox&áÃ7¬ù÷†pëtË[Bõûp£‰øi~8`ñ7V=¤s'eUBzf¼VygÅý?ßF™®ÐAn ¬Ñ ’a ÊuqÏtI÷Ul߸)A¼ìTŽžJyý…žƒâI%&«”¥"öУ29q7:[Ÿ™'+Õf%Z™{KH(Â𤣥VǶ©’ޭѨ ›‹-ªµ‹TÙé>§ógÏŒjtòìÙóÇ(Ds‘dÍEÜ!L2Ïûœ'ËQÙPGÓ~†¦`¹Qî4jôT6FÁpÒÓºwIÃ9ÌfO£̶Ô-yá?*8³©ï`8ðÆ&¹G7Oðó›R䟧h 0¹±'ó³!òãÉeæš?ñç^5zÉÈÆ VD¤aÒÓ ãíµŒŸÑ€‡>{ã×¼1[2®k0Ü01¦eç5°vê€uÕhzÒꜜtÚ¼Û#ÿl~÷¨kT4ÛOQ¨Æb´¡Àå-¡!–ÌPu½ñ¢ä¾Ã@wÛ‡uxR‘ˆ *¹Æ˜ku‘«Þ›’–?EÚ[ꆰ·=îNLBp¨Ã‰?YÆ­ Ï„Ê CÏLDZ»3cÄG‘0Q803u¾¡ä¡ä"hbkZÆËÇ2›43NÔ p®XôæÕÔX[¥Â©98 Ô ¢JìÑ·—»‰Ä¹°OÂ5pQEB +£'u3JÍÚáÃÓÄê>¤™2ðì7…e7‰ìļZËÖ°¬N"ánœbÉï˜F;e 6ò°‘AIlOÇQY>Øü`¿q)ÿÖI»$ Fi&wÄh¤˜OQlÓK—ÚØÝEöî% –?×c¸Ø«ÆÁÝ—*徉ä Y¦ùX9íOÏÊ}+-8·á{Fh>¬FÖ¾‡uèO#ù¹·vá4vß K‹ü¥¿ôd€uˆ›qy”Ú÷¾k–½LÜ»vÒ¢ý´8šugS»\ÁËÎÒT¦åQ¡¼jÜ}©¿8ZK-µ¼6R«–Zjym¤2`i^Jª×Óa¯G«"Áb-´¼.,Ïuq«#ëМ‡3²ÖKÒ Ë°j‡ÂU^Π³î^™pW/¸¨öÉ]½ùŒÖôÓù´TöyòÙgá…·rqØÓx=\Ð[õ8ä• âAwM‹ eÿü¸­»¦ß0¼qºM´Tļ¢t˜»ú¿ÀæÕ1ÿzº0Œvûëå¦ù¼ ¯³ñ@¦®å³­¡–º]å=¾jÜ}©n]B»”’·Ì×YɺF™e“xïi~¡'®g²âݦu–Â,°²½YÒé~Jo wètgppä:8°Hî!ß5ÒÇ»4cEk?MNÐÝ÷_wUwÂ¥’[™,ÔÁ†üÒ[ŽóÎz7÷¼³.%’]Fn[r»ÞA•Ö ‘¶Wƒ»/‹–‚¤'›W´¿ö®pL«Ã¹¦ºêáÕƒž‹c°(ÄN~~Cx•!J ‚­€«\p¤»2 <4³è‚št^ðÝ]2 6¬Ž§Ëâ–3½ÍwíKK„ÚotAà#wg\m;¯7ù):Ö9W , £7 O{Ea=…Î{õB´?ˆëUãàîK•VŸ´`ÈØ€/x9TX&’–C-(bÄÑEyáóB“å«­kÒ°ÜH÷n~„ =ˆm|›xÊ–«ö‡Õ°Ü¥w¸ºÞxû/ÒšjZ&¿³Ë˜nJènÄ*S·dA©ú……dz3·õè#XÍÿ«6]öÕãUãàîKuÀºè÷Çýþ9¬[KeÕ”~Ù$Ì_º^Ôºü6£ËâîåÏîsW¡ä7ÇTqémîZoŸÏº °ò²–;kÇqºÄCuòªqp÷¥:`õgÇÇÍéøÜÔæqpäÆÃýÖQö…fÄ®oާÍããYŸƒøÆÝ-Xœ\CEÔÔéžÿ–ýDò5&?£†e®£Œ!¦LµTýY±:ÑšZ¿I'-\¯Âj¹râÙL2à&3îÅésq›ØÀûžMˆÀÀ¢«ëLÁ@Æ­¿¤p©´Ç™gs§ÚKÿø‡—7àH‡7],T=\°>äó¡q7á{Z^ô(6Qu@Hœ¬P…’¡&˜‡aæ0p7†þ!ç5n{\)teu‚rëUãàîKeÀ dzölÖœžŸ§3æós£Fáß{A0>žÍfIÿ=S*ãYg6›N@ãB 5.S—¾9iOÍþ{ã ¸ž÷'ãs7ÚÇcŸÎ¾t2Ås6– M(´&áÛ>‘üp‡O$ø¼íÁ2ëbEm!$íŠ5,E'JZJ PãÒId^(U·É$º—@l¸=šl3&¡Í&æìjш(œx&/Þå«Ò„¼5:BoZ»èt a´{˜h, 8¥g˳ï0”·À±q7 ’ âûÌÑ]±ÒZ?dVTj`í*•jXX-ÐdrÀjwZÍÉ7XÆÔëÌCƒ³>øžLOœ'fk€žO¦F+;ê[°þ¬óàd‚¦$År¾Ñ" ×¾8ÚõŒÀÌ'’îð‰ä@ZU¨ÊQP TBj®¸%“‰°4 ¶‰¡aº8øÖ¾ ÍvºKAk×ʱ+l®_ (äS4`®õNT!½Ñ»w¥9&,Ê%ŒS •$ƒ" ñŠÙ¸Â,‰˜¦ìJ„Ód‡C`ÛyeQ´y`U'uÖnRe§ûÑÔXu¿×7 ÑQ¿ß4ªÑ̰gº‘q›ŽX=ã¯Ù‡®÷£þ¤ýåÙÌhdÆkÜ °À°4ÖÄÄ2k@D&–0 {åŽû'’O7/óÕõõû-tåµ3',]¬À"¶ÝzöšRa¸­‹ãªäVü>,ß´ò5,éßQ¡¶up£å‡]ãÐG”SötXÒåL7Ê¥À–ÍjM9¢K¥ü¬#D}X!=:´=ž‘,]ëÕIuîçÓæQsÒ?ë7 dÎϧÉx¬°?mô/`{ÞŸS?U»5†Áã&™„'ÇØ“uÒ6†a£aô®V5¬‹ ÅMÀ¢oö¼%ä…T»¸.áö…Tj*Ó\'îMž¼”{Êg–v.Òÿâ âFEÜCVÍ`GgÚŽ¨€;ªÉ¾å‰ß𑦪•  ¬ÁÈwɦ[ ­*;6Z¹UÖ„œžÉîåˆ+¶:ý ph½“Ö¦Bå”7RR)ÍîZÛÌwÙìzÃRjÙ,ÕÍ%ìO¡Ï|<žÀÏd2°pŸÜ̺»·Æ»R8ñ==ù2;Ò{8.¶‹T$‹•8êÂêŠ"µXX­{»U³ý«i‘‘–Mt³1Ov¤»¾qÅù½îÈoé~¯'3hΞì'Âj&Ãü‘ó™ñžÎympÙzÌ4c’”¬‚3¹c˜‚^‹úš£zo ¯w_*4 Úö¿=6Òj·ÍöÚíNçÅœ;nµZÇGGÇ|N\ÁWû˜Âï–Q­ð„@¿Æ½mÌÈÞ|°ÁöB$å'êlÖæ)zWSÿH{-1߸ ÆEfæÍ%,˜Ú·÷ý°Â\§ˆ{ù´\¯8Á:Uá¨Í`E‘»‰C¼hÌÍQói²Ï‹õ4W]1^5î¾TÙ‡uPÙXŠ Eû[@•Ó°ng”;UÓ§¯“"“°·Ž…J:ݽ ÏY.—c&\ãÊÛz·¬Ùì§·Ñ›ÞÛ­q__^5î¾T¬³þØI¿ï¶ã5wÜó]Çž}/g4|¡Ð,ìõœIèË—u÷,Ü<ë±êéw[DW>ß/Û`ë:¯BŠ4¬Zn&þ´öWƒ»/Õ kÀÌ¿¸à*ÜÛV@™ÊÞóû§zGo­ã,èÇÒX}#ù³ÏäSO·Tcù‚‘Ê•KXko©u©¿8ZK-µ¼6R«–Zjym¤ÚUsÜâ"inõ›XVðrGë«—øK{,‹²i’j?‘œ¹ƒÃ‹äÞ!®¸¶ÐŽö¾Ë«ÆÁݗꀕ](ή@:t í ÝZ„ø3’üǩ]7–`ë˘¯mUA/Ö)®K8‚¤ŒJ×›®TìBªX¶5¦e¬–äZ*¨m¯w_ªÖPˆÃu9ÓÜeéTåM6Ò]›êº?Xx<ŠíÊÏ;Ž\ئa]'M{ @%Ê]q”–ÁùÚqû«¬W#kGdA)®{?Ûü®éÿu¨Ö°¶K…À //X´t®TTØy— #W&Ä@é`èûÉI|y)¸³MšÝXi‰IøèÚ¬ò•Þ"°ø¦íwÑívâ-Ñ|À$o¹—ëê«›üçÏ]ˆe÷õJõÆXÛ¥B` /—ËK[ƒRÛüâØ¯^ÆPÿp¹J’•ó[PLÃ4ÂeÑG/ŸáåêSãveãKû°r WÆbìv7 ô·@õ®ÚÄM*iêõaE©4ºf,K¦ËâÊ|ûQDþ]ÊH‹‚G@6zT…b׃ȫ¢ï›jÎ#JÑ`Ùk‹ ­5oËGº"S3"Ð%2ÑE™tGKdóÇ.Aos&Šdaz‡ïj”"93‘çØú‚«ÅÞZ㩟CòÉÙ_“jIt´ÕÀÚ*Uk±j$Ë«KÔ~†‹ÅÐh\FŒ2§—WËEá)èŪidµ0~>†MàçÃËËãøj~——WàÜÓEcµ0õœB_.–ß2i,Ò<°2ŸH>Í|"Ùûhéqên–‰S™*ªLbÍ_¬Ç+ ¬Ô¤“®B?æ÷cj›p–áÄM n2ŠÉ›•`¡/s1^¤‚›Á®±(¶i&A°*Á¡;ƒY”…´Ö” À;Jv"ï¼Í ŸÎEÖÍd„ ažG`ªØ¢þ3íé,g7l#ÎM,ÉÇ=È/ȶh ù‡e@[?…UV†Wƒ»/•+ͤšÓe’\.’äêj¹I’ťѩV £Y­–WQºH𯵹\¬V ø `kü¬L£{þ•@@ËÊXŽ&Þ…á•q2q/)¾dÞNðÚ÷a ¢h¶`Ù'’ÝçeJFŰà Û!*g¦šÚkA#Fa{¡æˆnÐBb«`#Š9„B8D™¦íÇ-š!xGmhOó‰4,N¤Ó|¬èô!:+Q]ÈÁ‹P‰²êŸÜ],çù„Š]üt-DnŒ]>x8,á-!ÆLXQÈH)^_ÙìKm>2¯R.uÊ-…7@/zŒ@ý¨Ö€ÄGM ¬­R!°«Öüdž4–‰Ñ´V­–N£±Z5Ûmƒ¦fÕDô,ç-ÖbÙ4~ŒÓr™4°i&IÒj7“vÂlÙâŽ"vÉWÜX]÷m™R`a…ĦA5YNÃJ-°P£c¥ üÑC›ž¤óƒTY€µ3Rb â&*†²Ícß$#US¼|Ìúµèˆد¢”#K*V:)Š xˆDßA¸*/”‚âM‰$Š˜LǬ4ARhäš{0.Ò‘qŠXÚ¤7)În£À‚c„7iEUq ¬W"Õ™„À«ù³“Õ²‘´ç‰Ù7ÿ ŸVɳ“dÑ4ûˤýìY;‰R³Óø|»9]«™Ì›«¤‘tž=ë$¹q›pÁ9¬d™"°@Ï‚8Œöf|Á~{™m@ÆÖ+ÿDòöÉoìò‰ä˜ª»ŠùÌÄÚ³™—TT4 ­6—JÃ-]"nä1SG¡ S#JEQP9ûÌ#‹ÄMÞ¯‹{ª¨‹í*‚ ©:¬í8$yG’¡ÈHˆU]^§>•Ü G N ¢³¬÷RA¹ ±€9¶NûöM9L†”lLTM­™º‚kVÃâ0ÊÚ¯UÕƒX;HuÀ µOÚ+Ã*¬v»Ý2 Z.’ö±&é0ZÕ|þàÙû€OsÖ¥¶ øIòAKC§•7:k}Ö Ò"qMîõÕa;Æóñ»™•¹d¦$.ëc²T<Лkfà¨{WtÞ»ÃÔwñß"ùY‘KC\üò†N€ø~ó.­nt‡…Źû~ î­Ò|­µU*ìto4IŽŽš9iµ;''èiÇóÍM’={tıe]aÛ`Á@DèÃ:Ý ¬Ý(3e†~c(_D<߯ X¾S\–;\sí«ÒY‘1æw,]Î7œ7s}XùÔeïBnËßP$ØV`EÜsÅše”…«ø*–—ÞÒÔT”­5°vêLÂøjY.8¸jY©,—0 š¢ü\Å7ühbämMÌɨ+… a°Ç0Š{°ï0OÐô”$)oƒµôúw5(¸›,°²°ÈûÍ—kíªqœÕ§r9—Å‘¿µÊr±@j`í"Žt÷+EöK14ƒDf[ø@NÏ·®Eó£2ÍhèbV¬[R–VÅW.™ü,¹x“«‰I§;šßfOÇYƒË«¹4gwÊ"õç!¥2JÏEr­8kàš¬¹{>´ÔŸ—ÙEªÓ°Ê¿åd'±¹š’óìoû6TšñS5°6¦±j!B.î*…ÓYI´‡ÌSw‘ÜÁ†z¸1}·òu´Wƒ»/õGk©¥–×Fj`ÕRK-¯ÔÀª¥–Z^©UK-µ¼6R«–Zjym¤V-µÔòÚH ¬Zj©åµ‘XµÔRËk#5°j©¥–×Fj`ÕRK-¯ÔÀª¥–Z^©UK-µ¼6R«–Zjym¤V-µÔòÚH ¬Zj©åµ‘XµÔRËk#5°j©¥–×Fj`ÕRK-¯ÔÀª¥–Z^©UK-µ¼6R«–Zjym¤V-µÔòÚH ¬Zj©åµ‘XµÔRËk#5°j©¥–×Fj`ÕRK-¯ÔÀª¥–Z^©UK-µ¼6R«–Zjym¤V-µÔòÚH ¬Zj©åµ‘XµÔRËk#5°j©¥–×Fj`ÕRK-¯ÔÀª¥–Z^©õÿ·S$‚þ¿nG #6„l ذ!,`CXÀ†°€ aÂ6„l ذ!,`CXÀ†°€ aÂ6„l ذé#Þ‰âó@IEND®B`‚nagios-2.6/html/docs/images/interleaved3.png0000664000076500007650000023143707436604460020456 0ustar nagiosnagios‰PNG  IHDR°ô$ tIMEÑ (NgÙ pHYs ð ðB¬4˜PLTE1=J R b o o1cp U,{ƒz')s%%Yx'¨R:³,Öo Ï…Ð*Ò‡D[§?o´j¢¶ ©´9Ì® ÄÄǹ$Ë´G ˆ—””ƒŒ””¥}{ ”sŸ”~œ”Œ†œ†ŒœŒƒ¢‚»€”œƒœÀ~”””œ¶ËŽˆÁ¢«¿®žµ­µÁ¿yÊÁwÖÆ¥½½½½Æ½Á½Åýӽ½Þ¸·óµµÿ¹¹ÿ½½ÿ)ÿ1÷1ÿ1ÿ9÷=ó9ÿ9ûB÷BóJç%Jï!RÞ5Jï)Tä3±Ô(dØItÐj­Óm¦Þ°ã±±ð°±ûµÆÿ­ÐÐ?ÑÑMÒÒXÎÎcÒÑfÒÚgÓÖmÓÝ‘ÆÆ½½ÆÆÆÆÆÎεÖε½çµ½ç½½ïµµï½µ÷½µÿµ½ï½½÷½½û½½ÿ½Êû½ÁÆÎÎÖÒÖÖÎÖÖÖÎÖÞÆÆÿÆÎÿÎÎÿÊâÊÖÞÎÊðÊËüËÒÖæÒÖóÎÖÿÎéÛâkã†#å‘Kì¤Dä€Wì™TÞœ^í©Xç}ꔃã¦lïªhä°qõ±qé²÷µ{âÒIðÑiéåZèêræÆ|ýÇ{Úæíï|èºÿ½ˆëÏ‹ÿÔŠÚëŒçç„êîˆúô‰ë  þ¢¢ïÁ”ñ¸°ÞÆœèÈŸ÷ΜÿÈ–ê×¢úÔ¥ÿÖœÿÖ­ÿÞœÿÞ­ÿÖµÿÞµÖ÷œéí˜ïï˜ò÷˜àï³ðóª÷÷ ÷ï­ÿï™ÿï©ûý¡ûû­üïµÿ÷µ÷ÿµÿÿ±ÞÞÆÞÞÎïÆÆïÆÎïÎÆ÷½½÷½Æ÷ÆÆÿÁ½üËËÿÒÒÿÖÖÿÖÞÿÞ½÷ÞÆÿÞÆÞçÆÞçÎÖóÊççÆøëÂÿëÅ÷÷Âÿ÷ÅÖÞÖÞÞÖÚâÚÖóÖûèßÿ÷âÿóóÿ÷ÿÖÿÆÞÿÆçÿÆÖÿÎÖÿÖÞÿÒÖÿÞÞÿÞçÿÖïÿÎûÿÁüÿËçÿÞïÿÚ÷ÿÖÿÿÖ÷ÿÞÿÿÞÞÿççÿçïÿç÷ÿçÿÿççÿïïÿï÷ÿïÿÿïïÿ÷÷ÿ÷ÿÿ÷÷ÿÿÿÿÿV=¥/²IDATxÚì½}p\Çu'z#âƒib¸¹¯HCI£!D©ÔËf‚OT&EòQ²Ÿìl\ƒ»®M^äÊ*÷Rø01øÃ•UÉNìü±¯\qª’’¢T\.WžwýÊÞ?¼.yëËbªˆJis¥À¼*9TYL©²h4¯ÏGÝÁ`æBÀ9$fîôí>Ý}ºÏïž>Ý}Û©¶¨E-jÑ!ç^ E-jQ‹ê¥`µ¨E-Ú2Ô¬µ¨E[†Z€Õ¢µhËP °ZÔ¢mjV‹ZÔ¢-C °š¡&“7OYà#¯ÌFf¸A¼ïyƒoOº×h°¨^ÀÊówN_çõ­ÚÉs1.)r’*@.Î'”Ïçk勼r±²ˆ\ŒmT;.>—O„æòkSž*f1Ñ-“³9Öæ”Ì>©È ÖyRkžÑ–¡{[€ê,è¬9¡÷å©ÿ?Q@­ÎÄ=H^€žE: Jó Œç€æ¹~ÊåòRr9¡¼Ëõ:Ÿï{üq;߃±äK—cÖ¹]É5q ò9I©ŽÖpM¸WòO¦‚ÈPåÏ2Ä4Ì;gÃUmø“q+ŠJ|žx¢Çúã]`›cq¤Ô^æ1Z>*¡¼l¼,Sì‘‘ÓÍ—Sí—DÙ¶v¯Ñ` ,³ÿ X*’+ÐuþñÇþü±Ç©ïˆP‘‚R-ÉKf +‚Ç­Ïá(5È)eqp@Ç5ª˜‚WF»ÈrŒô(X¹xUÓ>¤ûyÁòÏû ØsX yöäósssós}²¹¥HCëùy£H «Ÿ_@ˆËææ yË2¶ª˜“Õ^Û¥ º×h°HV>¿°c.Ò º‹§ããŸ{\ôáÇ~ýqèc†ê奎Ï-.Î-2âÙ,ˆ·ú­©Ϧ :öüâ¢MR iÏ“v¾y¶Jäýð*Py ­4¬ªÄ¸Ÿ[Xœ_•‚F[\((À2rÊ×°°æççæÒŒt%‰"%ÜÂvyÜnƒ ¦ ¸KwT>_ÛQ˜GËLŒÕý1QpÁ:ZXJŽ Xsó}}}Bh8åÈ Êƒgra‹;O>p¶õ‰`Y@sõC„sX24µé™)ìMì9,|„°(Ꙃ؊t¯Ñ` ,PBèÔ—®ÈîPÈq'#Eé*Šñ9pÅæèIŽ”ËÉþ+úúÂbÁîN9û-.Ò˜ÄpoX<ûòÒ:X'å¥Î ô˜ï/ä±úæ$^ úç#&c~­|qx€Å>¨ƒáWf®=´Aû‹Çlõ °…5 Ó‘¼/õã£Atd^(ôõ±Ï÷ã½BA‡£…5Gåê»t\}Ú´G ½ 9½.ÀªÐ߯îË;M Â&¦{[€L kN˜÷ù+WTïÁîS¥ÄGÛçË÷ Åxüs}O<ñ(Ì hÀý¯ F…FÈ«žK_ô9À<…²=þø¿í{¢À<¯w¦0§kŽ;6<Æ%‰ú ä-ŠäkÕ…zˆ¹yBqY¥uêúê_Èåû/]É'PÃ)5Sl¦¥rïQ[ÒæÞí‹edÈl!)Cc¶UŽÝú®Ì£ùÜ×vÍ@>æçúÁþéû· ÀêË?ö¹<”KˆÈÖÂ+1¶Ã‡Ý<| Ðí›[ 6 Žc?êc‹‹B¼ª»0×ù…¹L³0PŽ´ ç¯\Ѽæû 9Ñ0‹ ÛÕÄÊTµ—–®ÝktÙ2KtÕþ¾K¨8ó¨üØGæ¯\š#ÿr¾JžÏ?qøÈáûŸ=Ì3…ia]™—€AýwŽú/<ßû Eßá¢;/Ì‘gxöEy62SÈ t uzáÒ¥ìð¢< Øáçpðî9tMú¢ù–ùæóÀKH€Æ&ùEHe5˜¿‚Ö b.]šŠÎa ±Î}ý àŸAdˆ×gÏ ¹Ím€%ø.Šì¯9TöÈ· Ôv> ËA¶’hÈOŒ­p<öx¬.(é@Ø'øæ/× ªßXÚ~!„QÑ~†¹yæpбlO0CxøÙý{šìÌI¼‚0X€t„.$gQ÷<Üp>¢ùû y°°@:¢ "šøÃð>Ù<"½H'þ ¦ ÂF—„å ßÊyåÊ"ä·=ç 3Tìk=@K=t½Û³T+íROu]”Ì-ÎÅYo.D†Ó]ôÑY¯ˆ2©¯Ot”…+Сú¯\é“Ó‡}¿Óçâ1~d?(  4ðJ{‰,zŽç±3ð]²ì“þ¹Å¾ùKçÔô¨3¬P<Ï)žëoiT ,tj¡÷ý}¢Ã÷D}@Ya¨» 2žcïRòíKÈ7'­5òä,ô£ Hçús¤‰èÝ»t°X@ò¥þþKs ý­àÿ%Þј²' –ÔÈólV./Á¾úúú/ ±‰õaË\ù€‹|… aEËPÖ…s@_“,(>=ˆ a‘w?»|æÄú æ®Њ–À‡ ÖOJÀÚä€,š¤iañt»p òP?ha()$Z`}Ôæó²õúî aÎóÞëLjø}0Nìû»KdÎb»!¯|ä5X͹`Õ¤¥¥Ë=W—® ,Yt >9| °â*þ¼vcãŪŠ©®UUM…¬š¡A5‚YK×–Ë^,æ¡î¯.éÄתk Xè½tItT ѱ®ôõQažä0G&ºï¹gOÞœy‚»~¡½0ðµÍ‹ÎLê7ayô’‰gç¥|Î,ÁóóDWM!·ž.‰Óì€hˆ:#–+4Ä%À*,R}xå"+¹‘/¯vD †„ìi™CÛ ’‚Bãê%çPHZl\1d˜}y^(B9å †Ôìe#° °$háèò¨ª©ºT£BáÎÃå¹]ú"í’£å™j°.y²MhÞ¯Â$HR«I¯|Ÿ,–° xöœ€ÂBçqÝÔoŽj?;(iÍåY°êBon~±ÀCB VÔ'ø¯uP+èAÀ§~¡ŸÛNÕ^äU˜§û÷Z2'žÓͱz––Þîyµ§ç5¯÷ôìý±€¼ø›¥ž/õô¼¾ôÆÞž½o.‰ÿÓó#oK¯‰{ÿ/âÙ«pûMqû¥½——~Üó×Ko‚=tR_Æt=_Ú iEºž«•ÃËàâÇW‰ËeäÂ!KŸ{sùÑRõæòÚÒßìíéyry³‡¬°òR-àiÖ/,-èG䡿\Ðy|úÜ|â*•ÄÏñyèöÐá»ê“;&{•æç5`åÈjÐ<ŸÀ¼,(À<>鯠ë­_€0(Õ9žˆËS]àú ]…¾ XÂ(ò_ \`õÑ0¯T©ƒEj]Q* 1hΞ q ÿDDjfáóWDû¬ØîÇ=@Øß]É£K>Xð[.଺˜€%JX˜'«øCi° å=„XX8v–Ûs§Ÿ’œX„çWÐòé– ÷”9Cîèáð-¬]œqÍçµeeæÚ‡Ò,H8"F«Pòš¡K,Ñ–÷_2§¬ÕÕ¥ž'¯¾Ö#€¢ç•˯õ`á|¾Þ³´÷•ËOî]úÒ—–žìyeéÉGùD‚TK{Ÿ¼üÊÞ¥'Ÿ\z¥Gü=¹¤Rï}íêk{—ÂMHwuï+W_ßËá"Ú^‘~ïUæ‚rõÑ%™Ëµ%uÿÇ=˜Ë+·^ÀÊëYBêl}`,A÷»¤V2 pÁ•K¢ ƒYrXNjñäy>ÏÏëþ^`ÍkÀšG§8>ûú¥ÏyóÂ’'7á:‹g‘x8Bþ´M ¨îä¶žŸSK _¸Ôùr‘°úqž/‡V'ÚB™ÑVÃ¥¹Žd].±§E(%©(Àµv}X2'é·~aùæyØ&RÌ“¢ò5A KÛ\£],Á°ïJ!Yp…‚”²°Èúûi¸ KªúhHV¨0°ÎIH—“… „ÿ®¯OZT`Ï]égй‚cA&t”Œ‡‚. VÛ‹ ücý|ó b8èžW÷¨`÷f²£Ìk|D`e]Àzµç•ãÀK\¼!@ã²ø» Þ«oÒì½*Ì W{~ÿ%¶Í0 â.‹[x›Rÿ>¤&÷˜Hý¦Hûq‚Ì0œr½¦¸¯%Àª'—–°UY¶%™{!—%°À€®­ °¤U| ƒõ£êÑB˜‘¢ËÃûÏ‘GC«,]ê#;¤~p–¾Œ­< :„}²¸ˆƒcÉòÄ¥ŽÄÓ\”^7aùq  MÐÁGÎßðÉ-’¯DåÛG•Qu¡uCèÇTi0”}?Ò"ÙM,²ZXì7óü­™_(F/ C\.xŇœP†œ“ÙG¥ôæŽæa†\JóècÊçæYEçæ¨eæÔôA®@Ë)q«Ú%O9èe° ,}äÑ'xÀ?˜k£á'„-`̓‡¯€-\Û÷د÷Q ÷æ§ X9¨ùÂ<„`ÊA´9$€rÍ£;.ŸuX€A4O"¢kÚ`¦`Z'B¨Cdí@ºýˆ±PìÅ´¡œÖàû–·m`]»¶„pñÚ+{_(€‹_÷Ñ5¬¥¥½?BL÷ª`û ›«ü`ú6ò¤Ôo\Æ”`K‰°0\q¹|U–$ ‹s©2 î}õG?†\£·{Þ¼zu©^À€Ê¢Ó$R®°ˆ]&?ÇÓȼê«pX ô„“nc;&Œ>æó´ø§ rQê<°ù,,Òrx^ È# äI e3ÖkeÑÖœÅùEP\~a‘æëÀÄ×¢Ó£ÀÂlVrž€— ?ùR8V!/ª>Óç0³ï Xµ9^)ÀqqqT ý‹ Ѹ T(½¸Õ·¨ÖyŠœ jó³Z.²»ŽŽÎ/ÐYTax, KÐZThR[(I¤,7 ÑÚŠ~ø0Yp° «1°ÎÁx–½æ9€Ž~ò½#ó.gXHA…-ÛBÎr»áROZE `r¼C/º Qu® ŒW¹¢E/³â‹µm€CÔ¾¸¤¤è˜ ¯Bk–pm`UUг÷µË¯€í²*.¾Ôƒ`9Ò€°çKK×è^uIBÉ“W_Ù{í{žDÀ¢" ´\{U¤ÓCB ×CB₲ôèKœ‹ÔU@½ž7Þü}X_9Pܺ úõ¢™y22Øð EÆ9cåø€tÁ*VFÁ}+ÜåŒU¼ ‹ÆŽ… Xñ·ˆ4 XùB?"ꀕe,Å[¾]ÀÚŒmí3ÒU(䥪 È5Æ’³Åɬ Ë#õH,µ5GeË_8O  r±D^íÛÌ›m¢ J[XZƒ®xàGƒ5qå}ù\ÎÜ”ÃYH]v{ž€7AJ2Ãc»Æ ,§YlÚ~·†ÚPe‹ËÌ›7-´kMÀRVLº¶_Àz.°Øé~írÏ”z³Zý1ÞS©À“þ“jõ'büøFÏeäI1(Nù]…õo(¢¡‹ÝàÂNwñëWóK‘\^íéyE°ºÜsµŠqëvºsÇWO9û òqXà9x©ÄØå¶=T9¹sEk·|âêTú!¬,Õ¬¯Ïàׯ;Àí¼eNæ7`ÂW^-$*EÁئËàÍ;˜óy³Ì ´ª’¦Ä¨ÌJbJï­¼¢‹ÕõÖqÓÄP)²°"o¡H,‚bÞÕ.ߤ þ …¼-ZìŠó³JH’k4·¼,»S6;’!˜·a')bŒGÊkÀ¬×Ùl'ʰ4r¡Í²D_â—2aÔƒk*`ÕN‰÷q‡\ÃÍB_«Zá«"—%uo‰VAÈ»KKKvZã÷RÍbÕ”÷aÏTµÅ…g´-e$E.ËЉR_§ù%[OÆ^þu–*oyÎ)pMI{Š›/H~=•ñ¦€ôWAð2ûu*…€•ÏÛÆ÷aF˜,kop^9Ϙw.‰g±ó¸~¥)ÛO×–嚀•‹ƒò@ÔNJªŸÍMJ3¡-*°-hck[Q"`N,;HÎÈäRœ¦âÇ6Î,»¤¾a.Vâ¬ß+ª-ŒxRvÿÖ^ReŒù¨„I¤zòë]Lµ7Þ¥!AV.M¥s9û bµ¥¡å—S‚ÉI«ÐÀ]½ÁÛ  /DÚ oÉ[•M.x sÍðÒâR2äíÕ©5‰¿9«‹ßÝfD—­A­wºßûÊ´ÞéÞ"¢{[€Z§æ´¨EÛ’®¥ºƒ’E1ÇTjš¥¥$ié“c7o»ÖÊ­wß}÷Æ»šn˜?b¤îÒ…÷Öʽ®K‹Z”õÄõŸ]ê¼íxiéQ;~ f׌»K¯Ã®ë6pêIÁ›¥ž”mΫuƳHVyäyžø¤ëjuœ~â'Þå[LƒeoÈNÍ<Ä÷  øŒò_Oiª·ÎɈÎݪzãÑx㺶6Ér{Ñž¼¯C=o|P_{R$,ü¡¡dΉ4¨Û ¹uðË-Svù—Yù[…x®—ÄA•Á7³VýÅ*‚Ç|£Â’5“<¼²”ðg^<÷¨$U.ƒêz]½dS“+*•-`á"ÎkKú“¶AÓ7-ä¤o é1®¯Uå|¯.Ñ2QÒóÚe+e9A~×漢 Äefìk”ÆLOl³¬ÁÔž€…?eÿòt§âx €%o&V9¢¾é)«7Î<¥éر§,:f„K‹Ã¿y·êÅ ‚ l-ÀJ. Xº–ƒã*\V"çØ¬™)‹˜·K%‰•Ì,[´Êvî)€5‡ X2ñPœG"`éÜL¦qÀÜŽ€Ì¯®õ¼±ö&ãš)Þ®ü$-Æh—¯ÁF¹‘Yna~—lýêÒÞ7¯]¥EToÂçëh?ý5nTî¡-8Š'mÊ0¶Vx=Ùcæ €õ¨ø×ó#ú0=í †Ï¿æ­Ñ¯ã~èGm‹o]€Uóé§jUw×èäƒ.³£/ :š;ä¹ú7urRª!#žä6TFSÁÓá2¬wOæ3ðé©"ÕIXÑê¹ü9˜ZvË5¨æMYǵÌ[7庞Œ·[O1ÖEÕªK™ZœåoèŠörÍÛX_Spn9z;αÑÒ×h W}»ÑZ¸)É““»‰|kv´Dš÷¾† ÍñS„¼N{ý®ö<¹„›¢å×p½:ÅýÑÕ7zx[3‡ˆk\×¾÷uب¼Ôsù²™R€#ZXÈ8ñ~ç×hÝ;ÚZ"¿'EdLßóÊÕ×å§,\¯ÖS- XÔn^±(:”W|±n‡íˆˆ´e=RtJÍþÊñb©T2F!Ði<2ÆmÀðç½X¤0×èÿ"¯!u=€ÖÓcccO=uü8|k´°Ü$]’×ZÕbÔèîÉâ 5` F´!MÖ¡Q0L™ˆØFÐ)!>˜"äqdO=RŒC“Äæk M^{VˆÙ];EFÕ$£¸:•ëÆÐ.wm±f X´Á™öÓçeÞÈ›fèÎÕk×z.“åôæ+îí¹úÚÖLÛœeº«OŠ[Kb°yµ§ªRÒF檹¡Zç¹$ ó6ìKÄôW_íyô ØýèW9 ©¯Z °\¤x€%å2~®ÃÊ€%bS*ø-Sb±¿Ê•v›[-¢gcPÞ“­9¨ nh{Ö– ‡t›Ê‰?€?ÖØ©Ó§O=}|lìøSÇŽŸú§c(–Ì¡Œ_’·V4G]ËoæTS$:ÈS—# ËIºãhÞVÑœX<£*Æ¥a/™R0r8‡%D,Çæ¤/]“©’&µl: §¸Ždïš“‘$7ɞʆ)Ë][¬ÕêÊÔá/Üɰö¾ƒº'—~u/ÒB²°¤3ܸs®„w.<ÚЗ®Ueê7zh»ò—Ÿ-,Rð€Oâƒ÷Ua…}Ö”¾çõ¥/ÉOéÕ½|½NÀ*–†ŽK#½££#£dÕÔce‰†À*ŽvŽ´Áò¥aøGGájd´4¿c±sd¸Ô&‰^ÂO¸ûbiôèÑa(üÂð¡âÑ6ÏâQ(òœF:"À;µó䘭sçvŽ=}vç'ŽÇüêëða9ƒ o=Ø =îvð8âö»pÃ)Ë®ÍQ]â¸ÇÃxe![yT8Ü÷ 33Õ:B‰QÝ€u`bd¤CDÃCõNƒÓ½Ô;22Ò ÿÛ4Ÿ’àR#ÒN7ÁJ*õ>Ò!BFÚœ€UÖ>‚)"ˆ(G;GŽ=*àJ”¥½4$€°³ä–a¨ ÃÀ²©¡„8)N°ëÜγϜhÈECBoœ†.‚YX®|ÂÓߥG3ß’ÂpŒO|¸laÅì/ *êi,òr ¬ /G&«)C™žÖŽÇ@jðŠ’z\^Æ,†„P‰ÖžÇl:dÅ8¹¤Ì\*ú¶Vá>ήȑ>ØB亦,BŽGƨËò+³ß= ÖmH‹Íså0Òq F••yW¶ÊJU,ë—Xƒ·f®,¸µ…Џr~×n0²>lÞÈÚ4´dNuÍ&“,†`J©è•:Mû¥žþ;Tîííè >½<Ò Ü†‡;{µ‹oq§·rmG‹:¿@Ü…Ôl혢@oÊ%Ɨâù…¥Í?¬³jH¸.7X[OdÞ›C<¯ÌÆRY ¨HÆ_ƒZµ9~r°*,#RŠNOy—§¬‹ T‹ËU–ë9 ­!!)´ë8 e)'O)2ÝfÅw`±­åpå’,,Vxl ]|ˆÉ€å™ ÂŸ—ÄÒA+ÖÁ¡¡«ÜlŽûŽfo–4tu‰Ë ì•éIËÊæVb´rQ Öîî,Œ¬MCµ·ý¬‡` K¦½XX- •¤ýR µ(ŠñÛ(Ø=#í D#ø)0¨W þŽŽà‘‘a¬Î‘Ñ¢gÖHçQ¸;BFšøÓ î‰ØÀcDØ`GGˆ,q!K­‚!á‰3;O Úy†„ÏìÁ'úŸ€ûpQÄíÄx#ôyôh§°¬ §˜ê@Û xtrñ; vVIohHÖqR‚Α"¿TúšåõlݼóIZàp³Yš"€x…«›¤`ëX‰%z—zëÒ¸±ÙY‚¾óŠX Ê

    £goU¹ÚêIovXWZ, ¹X ž«¿qŸR@«æðÎ*׋䓶²Ú¾oç,¹šRõ`I¯^®±K–§‡±ªÞ®§òsU-=…í2G+ë2“Tܨì<[†ž³\\i9šïX‹îõt˦|Ì2›m‰ y¨4ºÜ–à£+í‡ËÃ5ʘ¼´A•<¢œ+ïéÞ½»ëÀÅ,¶êlÚ.o½óÿ{Fô­ÞÑ¢MB.?×2²ljV °Z´yiå{„‘µÿb ±ˆ²¬`- ÿé+9Rä;Æ#{¶CB‘?7VT ë@„5ŠmÜHŒ¡¥Úü,®a,u-I&óÎŒˆmÆ‹™*‚кÖñ“kš_aü†)”0”üͪ<à …K/uX£—m8%(¬"ݽ;£ýÐÛ€²,RqK!vËÉéŽ.㩪¯q€Ž¨#Eþg?¬Þ8½~÷z2¾QÅü|YŸÊaÔË—¥Õe‡Ø\I.µ,ÿ¢TAL"¬Z ƒX¨øåÌuåC™-}-Õ÷‰w`$‘òóƒ°Ñ,ïªYÝÚªýX:VË%uó§oT1|#¡jÉßçayc™ü@^[œ}•;ñ÷u1¢½J‡«–ÛðF›$–4²öhY@™VèOMsçðC ‡¦¦¤¢úVÇ ¦ÞLi§§§íNíêI$ø沆ÆÖ_™Ë‚iÙ‘¿Â…;>#T\é’Kl@H÷¢¨hí‚û 5¤¾dÅ25Âcä+Þ ½"oßm˜c§¦€œ|Åõc+*}õQõužö£ èz¡\¦8˜øûPü1eÔß·Ê’^`·•æ›,é̃å"#kÿs-#k,,øžf…ŸžæŽ‡†¿VsyŸ›Iw$£cOëH5;Ñ4@–œ†^l¬t—Oã8)ÈâòFÔˆ7å³ dèžê –" é)Sß¾ )AŽÏx-ž¯l•“`h€ŠŸo]äKÀ ¥æûÓSÈrJ·hhº)£Ý¼+á4Ið†”#ÐãS¶B.J¾F‡š²8X oÉ[ò„ÓË¥9‚¤i×ÊE0²¶×~è);ÀºP©Tf¨å/Ð7–\˜™‘÷pA<«;òÄ™¹ Íä8`%ÛYÓðtpkΘ±5çĉoÍ ÔhËW™ú‘2°Ÿ‹*¡i}Yê%ïèÁœoVã3ÜǺ/)šL;ÍŠe©·¡åˆ|æ-³3&l°zðƒ@cÚCiÚ¨\`a*%£@ÖT=¢˜% <(ŒÔ]¥oE—×4´ `%ö!°BY¥{@~ªzéýÐ÷;deX•ŽÞŽÉ°x.üBå‚j¡`‹•Ù¶ööÙöA¼¶™Xc3³ím³œ’m³éèð0Þá×°Ž‘›ŸÇŽŸ<¹ó´ê}Ý€u -,ÇqDfâ“T ~â7•ÃÍO£òÑOŠ/â&[Å'ÀDÚ Flb`™áOâéK6Z™a¬ò±Ý~¦¤|_YXÀ,pd&Mi{‡.‚bÉ|G±5¡0¡u” ÊÔYNGŸÄ%vB-pˆ`s8¬ëŽÕ:t­š/ŒòM«ŸÓ¬ŒÖ)P®BêPЇ+­­:HÙù°*½/MÀVRe¾.(»jf¶mrrR€Ô…EÑ.³"ÞdåF¤XdWUÚ'&&wT*dg±½7g ‹ÌLR3‡XÆëeNÂËðÉ ZXØãù3PÊ6…æ]úÅÂ!ÅÄØƒ_A °Î…òáuþj\m! ’Kò¦r#JRÍü0l؆ À¢šªjF,ù9e+%£†rðo€=-(Âó€!GÊ…D‰-€1ü)þùòn( !e®>æœ2ù¦ÀÇ=¬°`[uî4ñú»­OVÇÄl¥mb²mÇlûDÇälåÙI°«`M¶‚±å€5;SéQÚàðóÂtˆ€U©ˆ4ð{¦­]D€{’KZsSK[/ð;u²¹øE+POsÆ” X¤NT©`Œ1‰CJi¨È¬¤¹AŠ'­·Œz5œšSLµ° è œ¦UØHÀ"©°äHRÚ@X…)‹ 1sŠ‹E«dg‹†~y_¶Ùv2ˆŠÁSŒvë Gxã:J„ô°&;:<‰ôh¨MNô ð›Æs©ÝÒÖ+’Ïî<{¦™W$“B)À`ëŠ,61HQ K–Ô5ä ¤•eÃV¨fî°BVdHîã@G![ˆc¿y:jÀÂѹ5K5Žd“`q!d1¨Ð«¹F,$4£¨N N!–#«ÃÆ”ïK8’£iˆGC_F‚.ˆäKé³EÈg„M¨Û(ÆW–|¨¨ÿ÷¯°î^ýoo'Qjé}¼¶9KÀ‹hr¢£"l-6í•ÙÞGz°Äu ÀŠVY%v>':¡&Á¥5Lû3b 9Û&BggSGoïÄ„°Ìf'‘‹¿FK[€ˆ5Ö`…¡~è;¾Ð‡4þ èˆ =N…¬4Žž‚âaa¨ '‡µÅWÝÔ,ñ±&… a¶”0?'”EZ°( ¨OØÌˆ¼R°ü€Kå³($ïœ#ÐtøtÀòúÚ¯úÓ„ÖŸÆ#=t#HaoA´ã°@lit—ž*G¹%`ùQ¾!W'”)õ°¹'€µú·/ÿÒ×o'kÙ nÕÙ}?oÕÉÔš|@ àÚffÄÀ°c¢M ûÀ[åƒKÏÈʨ´MŠ^ãLN À#ÁYÑA.< «mrOXXb`9‰>¯`–~÷ÌÓú˜/p¼Ÿlð˜/°„Z…1€ KÉws$öEêOɱi† êëŸòNñ*Ìm¥ê2R&ðhƒÑå+›ËWŽŸP¹ÈÖ,‡Q±)¸2K–Žá,GVZÚŒ ¨S¾iañúO¼žò54ùX -åãÄé³Õê(Ü1egŒÁµI‚Ô Å7Ц°#G‘†uvÏëîÿÒ¾‡¾u7EÏô*Òû²2œ%l–ÒŒ¦€žÊŽÙ™™ÙŽÌ ÄjÃÀ ¿P ¦Ãqg*œx ‹>/„áŒ$†„Ø&’ÂW[¥‚\¦k43/kÐ©Ž¯{c©£e KŽ?õTãGÕ£K9¶å>^T –õ†Ó\­ Cµƒ‡S‘§*ÀÝ3¼oNí.áE<å&×yÉ9/ߨŸâ«mA¼fÉ—«ºÔ@ ÀÂõXr1X¼Â{ýš%÷ðùäͶöô9¼hŠKhnÖ än=cÕ¦”Ÿ±wÇÞUŠ÷ÕBjŸ¿£Æ¥oÈÅ·R¨\T ˜’¼G>wéÃúöÃûzùýÔ¹@ZEz¿nÕÉ °*;:’©½½]|öª_øÕ)¯z{˜´U.„ÉF.ÃB WŽâûÜwŽŸ0^•¼n +ªÓæÖ6㣌\LjP]kKfð¢ &léÅðÊ»%·žHpœâÐÐZÞX}ˆ÷”Ê3^³F5+Œ6Õ_ä3%íP ² ¾±(+²Á|XjC/µ…†¡LÆÂQGÉňm'žÅ—ò›R*ˆ¶ê= ž%¼ý—í{è«o§#Ö2¬"Ý}î‡Î°Àb6SìzB^š÷®ìÔ’`Aét"b€Åˆ£_èÞèÉÏM_©nï›[[¸óëEÙQëF¯>J9 hÓS¸v›Kê³Öëè:&¾£·žL… ™E‘€J° ÖHQ·fÉÍV6Ï€A˜ÂµU,·Ð¨¬ÕÞœ)]¸)œ´5øfØÒ—°#S&o­”›hó ‰ÅÌËíó=1`­¾ýUX߸®mÂÈêÚý±=~zÿ!VvCÂ™ÊÆ.- Ã4K=°÷jèj„NÓ͹”¡Ö4RF”ßղݟVxfÏ84^/³ˆZÊüܬ$×a­¾ÿò¾Ž÷ª¹Uç~[Ešáû°ôf“ÐöXßI¿â¿µÿb8Zý§sg²¡SçnU¥Óè#¢:Þ&Ö Ig“Ÿ)Ï -ò}JÜ™î¢ãý­ˆU½ÃGÞoFÖvyãèÊ?½› ݸu¿=³Z´ùïÿáýZ]ñ>=ºpÖ-ÀjÑ6¡ÛߨíxÂSu„‘õÏ+÷Q—Í °ð<œAy,^ á¹"CxVŽ:fÐ> †Nâëñq>G%vªÈZëVoe5$îyf u¡§SËëñññ:Žq•¼õ²†&Þ5ª«ÉƒÜ×GTj›‘ëäéñIò¨ú øÒ¹„Y–ø~%}þ¦kVõî[ïÛ÷ò[k ]¸çþÙ` K¥â¸Ñ4ÃÁ÷åñ_÷ŵ„¢(`ñµ7$F“Å#ˆUS9°žS G›x½Ì`P™Q—•€•©ð‘ªb µ+;R€e …‰uû[Õ\ñÎtŸ]˜`yåâèÈÈhQØ;nüPnÀ²rùEü„k7r.ÁX@ øÓ§+‰C ¥ªÞ€…[sžæ­9c'D¬S0$ò8Oc`X§™²æóÑø© âÆY¤ADZfQÞ–Nõã`ö»k ɵ£$œ ïjFnœ{ôÊ5K‘˜¥ÎÏ][<ëmáúÉÖ©zïUÜMçC߈•`•:;:Û„%,(aO©Oas Û«m ªýhÑÃk>ä !*ÑšâC®7ô¢÷âèŽbQü!ä³VßðªïžR›ŸÏì{Jm~nÈÂòÊCŽãˆLá{&^ˆB8ÔS)Üü”·"tÛq¹[w) µ_„¹ŠÌÙ‘j!S˜€% XK6X.1‚¬íŒ›Ò,ÊÜIS_G… ¦`ˆE®!AÉA Òå P°—ekäÉâV?IL:§¬ ®ÎÑùÁs4ÂZ¥¶ká$Ô"±š´öŠwŽ÷sZEz_lÕÉ °Ê°F†ŒŠ£GGKêS•+l¯Î£¥¡òð# G;;bø‹¥áÑ£#«$èE‘b¸44W#íÅâÑ6kd´4\B»¬vׂ÷aé×ËŒ=}jçØñÝYXž#0Òw©cŠŸ^Åq<ÒW‰@ø44Ei‰ ¤ ;9äûñPS\K9TÈx{݃0_C÷ ÀrË'7U:ÀÊî€GKèºç:å,‡„(#Ð¥¢ÿ *ÿËÆ1`è"ôÊ< r)/²a19„°,?‰æžÃrp¨9´h\)z—CJNm)KÇíf”j8×ÑùA ¥Ä‡Gm’Ò÷²‘#Ðà 7D”ª>Ç{õ¾:º0SÀÀ*uv¶–Jmíâs¸³§­³c„ktx¤·wdÃGÛ`Çs;@\›N÷@i¨t´³Té,•::ÚFvvŽÖXð¿cø¿gNî<;ÖÈûÜ5`A·w<°$‘â9 *†zHµpä'ÅFÝE†é›z@!¨ ºh»`Î{¦EäàMeR©²8冓àíb®)¾ëe£hX®„q+:fBµð¸À Ôdi"ÃOS`9áQàh±HcE%Ÿ x9R|,OÚÈËQB‘€å±Mæ%Õ­ “p;–©¨–—£ÅÌÖ[V¦j¹`Õéx¯êó¡·ÿ©:Y–0zé€!aéèHÇÈH[i¸}d¤ÿ‹kXÒ:ĝޑ^Þ.€KÜ-Ûĵ,DV#£"¸4,bw”dÓ¦48:Ý?¡ß8z^‘Üèt!:ÝIÁÕ¨Á5º5Ú3Žz¢—[¨kª—¥ž˜Šè š¿QY°\|š;ž¥>J]Ò4×1U3•ÈÂr°°4™¸±°\ Fƒ€,R ®é„Ë:ˆÒ5DäÔô%9eiÎz8Çé7Ç/3O†zj&€iGa4”ƒä )5`D@s5Š!À;eOä !ªëHT¬!ôfÄ¡»àxÿƒ5ïÂ[¾¸ÿ¾8º03ÀòJ½àt*w ŠÁÞÃ×%´Áz °à1#K§Tì”×â»\.)`vtÀzä‘^¬´)),ãЧ›8„œî X¢ÓãÇB%é\â1…•)eS]ÜÐ;£{×pæ°…E ì&–ùÓqMNø‘ª=8Ü„á-–—>ÆY§fñp‰¬'Ga–ãèb3¼šáµËe7ƒªë(¯¡,¶Ø\ Xn™AªÌ)•EŠŒÇí®«ÀÞ3üeNÙ0Zй°ÐФö’-oVp£œî«wï*„ºýuX?º¦ã½ªŒ¬ýÏmïU¤Ù ^ Ü$¬#€ªb#íG°Ú9ü¨©R©¯¶´—Àçé:DÊ‘¶Q[€]ú:Ýác¾ÎÑ1_Ïœ|¦qÄ¢!a™‹J:$Éa›§<&Ú鎇ËƃJG—C9up:¤g[XÚcI%.x®òs%ù« é Cß-Ë—‡Ž²:fÂÖÔ,.Éq•Kv‡iXᄃôв!Àrã€Åˆ@C8WyÁ<T®ž~Y¸ßáñ¶–?#º+ZÒÂ’€%1Α>7ÝšÔv%TîIsÜ©`Æ …ª´zû½Ü–µúöW÷í{è/× ¢£ ÷lïSu2›%,¢Ó½>*°°À¸Ÿà—› îÑH°ƒÂÅZaâ“ýZ#u£¥bi”R·ƒ&îu–ŠzkOL%%`?‰©>óÌÙ°´ag€¾ôµð@;“XñðAnÌj…¡6&¤Ê%:®1iHÎg9KX–~õÓÑ~écýò”AãÔr¨Èe ŽœH¹^Í’“Òè(Ç? ë%ÇSÊ‡å– cHRÖe¬D¥'*Ô§#KfxÙLÃV%¤dËX¶Ÿ”]Y‚—ô»%±¦ Ù®ºŒ« »ÿåß|ü»±Þú⾺ïUÚª³.ܾ¯OÎ °eLxóÈÈú)9ÍhéÅ­<8èâÂÑã'Œ£ê¯½p4Ù)Œ·æ|td¬•2ìH½â –Ñ’c6ÍÎL wMÞnz¼ȭò<æë¡„4ïò¢-¦TwÚ©:È»·h :ÖòcíÊN*V6’Èr1¶hÒêÿó¡C¿ñžB(t¼±Ç{Õ8zû®"Ͱv´w"á—0‹ðomj·~%¦iÛ ju×xãhÝ´9‹|Xl9¦Ï$¥iYªú¹rÖñÖ]è8`•²9ÓÈm© XPyÚM*«œ¸§Ôœ¥T2 79‹šT¬6°nçÐÁCúÔ¬Ut¼¹7V·êìéÂU¤ÛÔÈÊÌé^¤åT1J Æ[iw‹Q/y©c7aÙ€u¬pJ™EÀ‚•у)Š‘=ÕÚ>ã%(…çÕ§N C‘½„™@–ñ¶›®m@f Û×ÍÅ­åMЬ‡O–Â=Þh¤¶æ¬¾ÿ™CŸ×&Võmp¼£^ÄÚæû¡³sº«>1î¹)¾HO½Æa0òŒ£;(ÇÇUçTMéznêÛ±¥oœˈÎÞ@eüè¶Ö,¯aÀÂ&ŠðÎB)I³Òø­ °\¦YÀZ+µ¥°^Ùd pʪVoïã}íP«ïY Ö7×\ñδ½W‘fXî½þЧrëMã•ë•W}ò¤žï‘.­¾ÿYabýP9ÞëscUSu~¾ !kÛ¼qô§ÿýô~yQG‹6+ÝýÁóý¦±\ôî_Õ¹âI]¸ W‘nÀª®ÜɈ¶_·h«ÑÂÄ:ô}O«w¿ +ÞëtcU¥‘ÕÕ}~Û­"ÍðÔœØA Ö‘ öQ:i§éÔâRë~µúk™4óÒAò©9uq}\7®ÈEm{6^H©Mwøéƒ?køÝÙñ~»þ—·ßÁ£ »l7#+;Àâ£ÕŸT×§­E ôƒê¸pÏŠìijž9`…Vù¨„ÁÆaNÚ†êìúhÞQY„ê0Quö³8—0H=´áú@‘}«íôɨV þ5( ‚À8 UžP¯xÖ“^‹%!ªÙ¢øÏðÀîèAØ~h¶5ü‹K6ذޠkõƒ?&Öw 7;;ÞëšGÞkŒÉ”²,< | Î’Í€‡WúÑC,ñ¶a:œNB–!p¯}z¸<»7©¥7°4 lÜyÀ¾<ùÙ×ÝŸÏ#Vª²aS:”¬”ªØ-‰KÁ(iO…™‘`ëOGDâÇ.ôÏÀ7Â¥T}õG'kûúdúPBŒæ5=íǸëÞaA‡È@ö9ü‘xw¬ì’Y}•¹O›qj1kB¬L«ï ëÓïÕÝõ9ÞVÔÑ…ÛÈÊʰ¥¦Ug¦US/€h6ì`MÓ#Í„6ÕY¦Ì¦µnCË7:m¬cFòoê·,V´˜æû OJªíGî×ÐâmªºŸwå¶‘3” ÀÍßø‹£7Ä“$±á^ žˆS±³·¥ì€ö$õ€«X¾„´DìÑåãŸiÕlPb•„«Gÿó&b}ïë9ÑKnÕùímddeXðHù™ÊŒù䛂E=$™ffÄ/óBxAÄ Tãñ}»ý!6ü‰Ž2­X¦(P¶€Eƒ’0•2¬€˲)üаI|uR¦]±Ö Çn zÚd}sØl5žS¹­a]²Ö×;vœRšŠ+üI…åØü¢Ðegc´€d¡ Jçfg)¿µëî{¿!L¬ŸÕêí¿ƒÂ¯ÔïxZ~_ø~䟷•`U:z;Úfg'ÛfdÏÀ øNd ‹_3m³ân¥c¢r¡2Û69Ã݇¾6óßÌ^3’_ó7± °`³*‰o¼Ä_¿ÆWôAk–àèˆ.êÐwè¬Õ]›"¬@”3@ûɃåCø@î`HX%»Ñq¤Ž™&®ŠCÞqHŒuáèÍŒdÖ¬@ò5 ˆÊ#³˜BX |ÛYZ‰ËRÙÀ‘%¦?‡ÝW"\úë ü**¹;ýÚ( Tz¬&˜ôŠG$órÈ’`)‡\’2Š’¥M\UcŸT˜¬»…Xջ߷6èTõ“×…XêèÂí‚XÙÖlïK/M¶MNtÌ¢â³2;‹×„EU *í•0œíí­Ì¶wLV(bi&X„`‰¯ .•ÉöJe²ƒbaŒ-ýk¢w´LèŠF©XŽ,gc‹@…/$ò%N—ÐpŸÑžõÊ ì8„Õð ,Ú)›5ñX± Ín¼¸,ï€s·½G±ë)*†£Íçi€è¸Ö86“3zâr æê«™gääè$Ó<3¤°#?QøTÀtÄŽ!‹AO('*þ$Y;êI±Á€U}ÿ7|þ¿›>«Õ¿ÿò¾}k=n¬ê¶;U'3À `Õ6 ím;fÛ''gÛDH¥­££RiŸ¬L‹˜LNNvtLÌâÉövxÑŸÀ¹ÙööÙ°ÔDê„6€éw@,²ÈBmPë'tMÀ’¸å¬ VjHÛñU_¥N/ó‹æßÜo,Èȇ‡¹ÏJç¨'=jZÀ&€|êÒ8ö¡*ò”:C¡fT‚õ”§SØ(äùxmy„ŽÔfú ‘%äðéH¤ ›±A¾|h}( ‘’¢€à!GƒÖ’ÃxípíÁ¶óÑeE°ä è„ú¡ãËpˆ  °ä#±€¿™ö·æÓMºýÃçúšõ²Ñu®xg’ž¬í±U';ÀªÀ+’gg':&&¶v‰«Yñ1Ù&þÏNN¼$ì*1œ1_êὓ“íwâ‘—œÄOñÙû’àÑ6«K àÜ[°"CB'X*À©9(de”Z…º`ª÷VÈ*ª‹G8†’Ê%G?¬ÆjlHañŽ*}“€55ÅË5n•ÿU )¹Ð¸aüg¸udD#ÒÐŸšŸ”Œ¬H´P£•£QI¤¡„[‡œ•Ê^d›+Ѐl8³Òl8`­¾ÿ5ab}ÏÚAx÷[ïÛ÷å:Þ˜lÓòsÝÛÆÈʰ„Å$Fn`fðtL´ÏÎvtЈàädï#°„……>,ø×+b s ‘³G X˜ºr!”C ðÉ;*17¥né_Ó¦•úr"€¥~­À’Xà?Ê–Ð\QOnܘ€%Õ”µQBXˆ*†‚c€ªÅ9ÀuXUPÑ2˜‹xqm(d¡”´’4rZ”´C¶¾blÌKʱ+ L9( ‹Ó†d*±CŠã9zìjŒ 1µš’pøæ”D3ú Â*«à’—ŸdÙ ºûßqƒŽ´ŠGþÑÛëÕNÚ½-Ž.ÌÐéÞ693MŽr¡ 4Â~à5ÙV©< é¥ÞÊ :ÚÅ'XX„fÂxj›©´‰¨ù9‰€NÏÌ¢_€–°Ã„ÝÃÉZë°ÒËÖéÂÁ´KeCˆýL`Ò»âHo)RcR= G“i€%}M¶±Ø|‘}Y6´J}ªdÀ„~ É|¶°¸€Ž´°X‚0°0Ë·êNk3* Xl@)Ó)Peaä#©…<`d¦8‡ ƒÙ”Æ+ ˜f[ÎñCia…°¦]m±š„«G¿k¿¤áí¯ÄúËõ9Þ}¸L§êlý£ ³¬™083ûÀÌ̤p„^«âºM€¸©*G€ÚCp^;ffvLNŠOpi‰kL-,±@´·MÎ"µ=Õ -Àjz–•ÆW# ?ÌFÍ“ÉG+HÍäIG¯Ã®rGiƒ^ÓLÏ_É©ÂdQ>.â_™´Nâ!aˆ¶¡¾£¯ éÔ¢r*›ˆææx@(]K<¬õCòKþ0¶˜ˆ? h:d¯ûéC95bÌâYÞs™¥ÃîwvX¡=æH‹Næ’YEá!£kVÙØ›Ê¶+DëîÏ>}ðàgÞ³\VwÿþåïÕí³:C kvæ÷fgñOXT“““³x=99;;1Á¿ Ž0«„ÝwÀšÅý‰€E!Ñ$¥_•Ôٺ̎j—£\…½a¤7æQŽ*<Ì™(Z]dÖߨ„V›7. Qy4K°äŠJÉUn¯¡ŒÃ@ËÍ(¨Ü×ÊR©¥ Ó>}«ÒRÊi—‹Kq ­]š3ÔŒ™o¥#»ËšÞÌj&–3²šK¨ oJ"ëž`½{ôÏ>°×óÆd‹ô©:[ú]¤™VeG{‡0‚:RIXXHí5â˜ÔÞ‹¹£¤¶t¶€åoà0¡ðTŒÑvµT-¹®Ÿwh/̲ÈzG}ÿ^lí¯v4«]‚!o}°ô`…ê–É”ÒãÂašR¨µ5Æ·¤èKùÉ ˜²’–MÏx9¢ùÉþôÆ aƒÎ!{ƒNµaÇ;¼ðöCïÞ³µ÷CgX`6½”N2|NL˜áêþ„nÆAš­¤X±Ò≠7¦,{—HT%dý}99¯S$õ°ü¤µåÍ/ ŸNƒ'«jcÖ´o²µ?‹Ë¢·õ<¦(ˆHÛ·Fs@—yhïœŸšªµ¹Ðª“-W†+ÃFVõö÷põ¨NäxÿêºÝXU0²~™¬­ YnÍá H3ñ*ØÀ’–€¿±#Bµ—ÐTŸ4„1ÁÉÜå§óŽñËj–Л*i[Ó_£  7»ÌÄqñ[­Ë¡|=…¯6òÄwg&K7úÛzŸž0ŠÖÝ÷>{ðà§hÿVt¼WSu¶îÑ…Yn~6^íƒ:ƒ”@nÑ‹¼+ Ï„ém`'EF +%†f X±L‚$tº'e–A¶T™èk¶ÌæIn&ó:L­bZÙµ"%†™¾»úêžš¨Ø…õðibj…ïý¬íŪ®¾õrÝGFiË]¸mÞ8Ú¢mCú6èü ‚MìxoÀÄ‚w‘nm#k»ÖÊ­ï ºŸÍÐ[ õƒµh#èî÷ÁÄŠºØñÉ8ÞVþñoÕÙŠFVfGÕó^œÒ5äEXòÒÏäSDàx¯ÁA}Êoô@¥¡¡Zg$UÿéÜE§bë¡s·ðÌ2Ïsù ”3Ë\> Ï5cð׎hòqËQžòÔœµJ8ÔsSnÑ2êD·œ%¹¢Á“JçZu°$“TS iñU»»iq]ÍÈ8‘ÏÏáCœôý4y5BYôeñˆë¾{ôãß‹ñµú68Þ¿^ïÁ_úp+]˜ÙAª 2¨&CØË°OÐ^p SÍ&3«lžI¨b yµÎ¼ƒƒTé°Tñɧ¦«q\j ⓟ=oÈFšr—ÒÈjS±çìc=åqò^Œ»kóeDÝ=±4¤È;[°"yÛ糪y±Zrª'°æsJ}E kïr7”Rʬ0—,xÔ,|÷è¡ÏD–6Äú<ª°ÁÑÀ>º03 «Vï3ÆóUS³Rñymf€ïqO%§ãWÇ“RÖü,JŸó¼~¼zJUïòxÆãÛ‚ B&¾$©„wnì¶:ªžÏ・‰G±C¨¤ QN8nÕ-`˜j™$غ˜»ƒñ2D»q€³˜VÈA%¼4ƒÝ¾Gž)®-p||èã3ë#>æµÎó¶›kœ>ø3|½{tP؄㽊§êlQ#+;À‡“燼bÑãã/â·øiÛ SmÎñ„[uºº·œ‘•`GGFF‹µ^äCC%AÅqÙîI­=ˆ¡ƒràXXÒwëë xt:ÖØ©Ó§O?yòø±cðÙàðF•NJL7ågÝÊj 5`¹Î$,Zyû#¾=d1nvby`é»ÙUï#MÏø4IV K®´?rˆüƒµ„7H‡†ÃqàôË•¨Uz¥â¥Ê«^2>³Á/Ù¦n2`­ÞþnôÝ£H·¿ùо}_iÐñ^5·ÞZ/|ϰJm¥ÒèŽb±íh±¸C€×ðŽ‰€¥Õ. ÀÀ;¹SÐÉ“gvž¶ÖαãÇÌÁẆ„®ç8Ž(ø$þòÂúi~â-Ð;°œöÓ1j‰€%‚HÆ k:ÆÜq¢“’q-å“–CV¾UÃóK(eañ—e£v„è`¹b AQ;+¾MXCe3HÄ×ÑuŒö‘ä&5DsF -}fcqmš¬[ïÿæÁƒÏG½XÕU<ªð뺱ªhdáVŸn%#++À* Àni/?òÈp±mdtxÇèèŤ†Éœ`ÚyrL€Ö¹s;ÇÆÎ ¼jlDxL–P qÐB0‡Ø×±ûSçÇ?¡?®Ã·ÊÆ-×)Ë@ºð„žzú'„˜eíi0R|cˆ?GÚ&òôL;d(óIÕA,ÔuÏáènS&k– AÇ!þŽëñ/E浈î‰ç€—pÛ•—ô鹦5fFvHìOO¸e–“°ù¬5‡ay±I¶F»àªâRÞ¡l½DÖ³—faÁ<ôµbˆ…G~«Á©B ½ú£€šl(SÀ- Àê, À::Ü12Ò6<<:Z*‘¿á€uzç˜`<¹óìØ16fa RGwÄØú7¡’K UÆñ›ë¸2b™£µ“”F+¯Ãv€2ÛÀBPa…Pq( þrAÙ 8)ª¸£µØqRŽM!Tj*»S΂°¸–®CàêÊÏxª¥B°íi[G¥•f)¿‡õvl'‡‹pàüo±uû‡Ÿ>xð³±¥ ÕÕÛÜÄŠw&½ú^Ðz)3À*‚Ó½CÂáaXbH8<<ÒÛ;B€UÞxÀ:~ò Ì>ó 8Ü…¥uò©c Ö1¬¤É>·,‡„ô÷éo1ýÆû_ò阓SNlÒ°L…ç)7Ï52bÐãCB4UØÂR $’Ëç¼²“•=ACÂ2ñõw=¶qÊV÷ʤE)êÁv«Ã^;¨*IÉåIA{ô´‰¦\6ÒÖ*ËÅ zÔJ–13QÖ½wa!ñD€Ç¿?ä@w÷F-2¶ŽœÿO_;xðÐw>XIq¼ßmnÿëVÚª“`K£#É4ªæ 7Òé~ãÌSÇOŒ :q‚ž8ÞÈ2w¬èB+k«ZŠ-ß.hݰ®\Ë;ßK˜¸ü1êxLm¹ÒÝ([&>,S(ñ'¬ ³ƒ# jJ,& Û.rU†I|ÜX³ð‚à{85hIBMG EcÀ;7ßyáüý[·ö<ø¯|þ?½»¼ÁZñÞÀ“-ÚBGfX;Ú:ÛÛ;#$BÚ>*ÀRÓ óJ ©´®±'0Ms"»JêÓ€ÈÆú7?[½<•£I‘•îÍ{Û¥¼c è›_*‘ ôIQ“ŸîZ ôj÷Œ‘ Z€%!deùúÅó¿,`‹Œ­.@¬Üäü ÿã&x¶¤ï½ÜøúQÎN]¸éßEšÙæg؆S2Hý*•õ‚dsYhV¤VºKÀ:öT# F ÀrÕ"æéØ6ׯ«Îœ²ßšCò®~U66gÙ‡lZ¾þ1F°õ‹°þµ¯®=8Füü?Þdl¡7&7çx¯â*Òî­°:ãÍÏje¶n„!¹V~m`UoœˈÎÞÚÈŽý‘ˆÒ‡µ›Ÿ7©Ò×G›±ìn°”¬,ß¼ø[¿ü?:ø¿þk˵Eóˆwßÿ?÷í{èÍ9Þ!›[[â謋ÞuB¦Ô (ž¹b™Þtµ!V„ ê­gOgDô>,AãƒiùQý$8ÛdÄñ’JªïÑ ]}ÏLå¡òNÍ_’ë!K\á‰Ë¶RÊÔˆ¼5`Eÿìºê-íº^ 2°êS‹gJ[Ô,CòýÍX [+ MVî¼÷›±þ7pm™óˆ¶~ë»ÿWûú«&ÝX‚î\Ü/Ù.o½óÓȈ~º%fw[t¿Ñí>ðà×~öîO?OcDÃØzð—àU3Ėȯ—p«ÎÇ6÷©:Û°ªw2£{]“µ(V?øÚ¡ƒÏÿß*ý Ì#‘óˆ]]€X¿„Kä¯/ßilà¥3Ûݽ‰Ï‡Þ6€Õ¢moâ :Ò»ŽóˆŸ¤yÄ_ˆõ¯üÅ.#¾ðÎ͆­•›´ÀṦpo©X-jÑÖ x½û¡ïï“ùŒ­Ÿ_ÿÂù_~ L,Xj‰ü‘óŸ‡%ò  ÎÍ}ªN °ZÔ¢­Awö™ƒ#¾A§ºrçöß…îÙ³;>h¬Úª‡ôVÍx~T °ZÔ¢­A«·¿#L¬?KZÀ°ŠoL~ø¿üÏE–È#l}òâõõ[®ÐV#›q«N °ZÔ¢-B«ðz÷O¿—høÜþUx÷ÎòÍë#óˆ´Öô ×o­ÔéÚZy.ŸfbUoƒãýÏzÇ;Í#¾#-¶¶öìéÞ¿ÿÇ`?ô¿'#KD´¼"¿1@ý„Ë.Æœ?‡#¥é¾üʰf*33•Je&H°.’‰+€T@pµÀ÷ òÙXòq‡PÀ1_ŸÇ|8q¢AcKZXrܧò‘}KÊÅWŸ–ÖøamÃ2ªÐ¾aŸN۱ݴ‘ÈŸš¶nZCÙõe1Å•o–Fm”Æä=5¥pÐO4Å•E° á&ž©²¹|߈'X¾ùˆ0B î¿—.h3Þ&ƒ+¬Ít½€U½ý½çúÚ)´úþ—÷í{è›Í¼1YÀLd?âîÝûØÇÀÈ"8ÚtSüß³g×®{yjÿ®]û§Vví‚߀S» ü…•êòƒ»v]ÿp…ï¿€_ÙÖÌdÛìl[Gûä uÅ:@kš<%•ŽÞ‘v²m¦Ò1Q™i›™™loŸÙè¶ö§§°ŽŸ|R=sæìα§NÂAªs +pG ø¤2ür0ËÃù®ŒãNé[häãO8ªþ$ü|òxc€«êB(… RÂŽ#o`9 Àè'G‘l1†,?i€,CNBiØ„RZÐCXùÔPš%$­%• “\pë‘·´°VˆÊ~HEÖüeñCU1X]橚5Š¥$‚µ–ö¥âéàœcI#užJ^5Qñˆ®þí¿µÆIδA'õ,»Ž÷÷›?•‚=[Ÿz¶ûcdauí_&ÀÚs}ykw×Í›]]×»÷üÎuì  "¬k7„/ß9е¿kÿÍ›tÿæž®‹7¯7¹ZÖÌl;XH½½í³€‚ºº5©…O€5) ®ÒûÈälÇÄØ[³• Óö­×E¶&á kì¬*TçÎí<õŒ¸<Þ¸+ˆ€vr'Ä/ë옘a@i cde9ÒþrB‡ÔÜ!`“ò«VMHt­hô‹¹’I#­³€Žã$>ØÂ uMjâÛ:´ ·`±2¢: ¿8YEÄ~› …éBÊ~÷¦äC«âjÒP>(yú¡~`p“…Œ‹2 Ódw/ëêË=ü5\PøîÑïßNÞÇûWÞΰ8ýÏvƒyEC·B€Õ%†|×°v¿ó©®î›¿²gÏÏÛ€õÎ'»º—ouwÿîžîëËGð¾øê>ð»7›{- ¬ÊDÇÄdÛÄK½“•аfÖáÂþ;-` ‡„X/uL fâJ` –Žœ9`qK À:-†‚O`Ýyö™M8Ýéá¯#:?š¾„# Ø´=x¤!bÀÆÚ¡t¶°Ha~ŸÀ-œš&ÛŽ1€`£K% j–¯²ÌH;°Xå :À×УŒ!mcÑð‘–àWÖRB {^yÆzJ–D,ÉÔaH馸–Ü ´„L*)/ÂKj¤@–{3âMXÿ×Cp0jm#ëîÏ>}ðà¿y/Õ†ºýGÁQ…M®º|ýüþî.íÂúM Séë7 °ºötryùSº÷±kÏ.þ\׳ïtwÉûË7ÅWבŒ,¬@Öìlû„ø¬L¶ÍÎ@{OÕ'æ€}Xšš©L ëªÐoVà׎ ê8°Ú°¢–¶ K\‹!aƒB˜% L0BÅ:EOìVA¨Gd.I[u”45Ì¡P¨Ø²¡ä³ø"€¥G|°”–#œqˆ2X HµZ Å£¦¼EÍŒ™À¤–Ö“adYƒ_GˆŽ1Ö•Þ76µBŸP€Í1,6ÄViaéÁ5Ë•÷Kâ7ÀBe*ÙF¯ØÎÅ_¡ÏÒ„¬7‰G ëî7hóÅoÖ2²Voÿç´wÒ}p¼?Ü”ãpé“­ötïGc ïàp÷õÃÝçÅhﺰ¤–W5`uÝ„-@º€žåû7¯ÿ3x¼š;–ʬɶ™™¶‰‰öY1œ›Ÿ»?=Öñô™žFµ˜i›¬„¡àR™ßUÇäìì¯f+ÁÆ»8°ž>¥†„gž9»óǯ,z’5¼cƒÉôdißÃPä‘DÈ.9å'½Jì7vØÿâ0À8JIÀ¸Á$¾ªn*§}=¤rØ" A¨|Á˜†¦»9fUž®¸l4`…Ž1™fAYÉf–öBŽ#ל;r€«ˆ )箨j”ŽÃ• K·¯’c¯rÓKˆ’ƒvn XRŽ!/ —CY–ݦÀ,9Køö7ˆõÅ¿ª1¦»ýÔw"‘ãýï®\g㪫{ÿù‹ï^u«wù-ïÚµŒŸ7÷캳òÜ®_ e Õ\ÔP•ß¿²ëÈò‹»v]çe í…ìKÀŒÃMN UƒºqÔâBÒWðsr–¾3[¿W“¦ëØØ©Ó§O‡ùÁ§Žâ zÝ °ô&5så@ã8 »Rx#›4FåÍ€7&¸´–Øúoa’QOÐ!ä;•í8ÐieH †š&ù5˧Jý3X=*÷NëEgÖBR¹ ÞÚ»dîüâ H öÐèk™k\W5 k Wm2Oi­rþ”Úy_’bÇÁ2%»IðJ­ÃZ½ýW_#ëëï§YwßûìÁ´w¢}ïëG,1”»ø+û÷°qõÉëË×ะëüŠŽ ×q•é2xºVî,ßÄ¢Õe¹²t™¾VVázE-ýùϳ[8Zië`êÔ¾§º„Ì[s*;„eÖÞÞ£¶³+o ÀÆÔØØØÓ«©Ž73K¨t:0ΠÈwüšf(Ћ)ãÛSâ¼|cc“ZÜnðS´ –Y¦å£ÛF/J5ŠÚ¼v`ù¡¹„ÖÇÇ[ÂÊLc N-S@'–©DIÃïô;$-äµFÝÌ=D°äÔß@£¿±2bÝ}ÿë€XÿῦYw¿(õÝ£Èߘ¼~ÇûÊõóÚ¸ú©%Ä«é¡[ëJ««>L[dÅ3ÜšÌL4!L£ú FÖ,'ŒÐ ƒ°ä˜î©èÅúKõ{œ)Õ °m¤±¦§å¬j} êÍÀ‘˜z ¤LT¨œ32ÛÆàÝZÝ ) Ëäu $áõ”c\w„pÃÖéTB>„HS~ þé\kê8“)™Òè-O›Ãºb±j¼ùYãí4# 7èü ÝÄ"Çû·ÖãÆZÆÕ‘ý{è|°Ÿ‡S+7¯>¶»ûó›ìm áØ‘£hfæ*^]3{è…™±Òœ@—y5ï† £Î¨-¬S7ªA=s YvÓÀjšsåe‘íGP½‹`¨vf×z”MñÔO­hµxè¼ä”5;)gGæÖœÕ»o}Œ¬/§yÎk¾{#ÀQ…_|«~ëÎ;ʸ:ðÜ?ãvez,=ÒÜä^ö€%}6æÚäºÈ|–ác •Ó`ƒ ³¨þÓ¹3§NÉ€N»U5¼,õb=‹RäUÒG•ä«Ò1Œlk½wÊhØLåÝðk¶¤C|½)Ö›j­ôE×\W)áÃRÍÕÐ÷þð7ßN>%§æ»G±¾ù0UXb­¬,á/bØä"{š¯`@xý^#U°¶8­üÓ»7½k’ý«^ºµènÑ}H«·ßú2Y_I6²`iáÏÔÀ#:ªðêXñþáò;畟ý¹›òÕ0¯`v–Œ69·—mÀZ½Õ¬m7ºûþ×ÁÈzù[‰³}·aƒÎwk¸ÕWßþJä¨Â$ZY¹ùïÄPðcÒ¸Ò7оڿ„›âå}@Y–[.—½2|xø…Wü¨±_â…èžõS ÇOO|b·§[èÑ-,!ÞÅ· z*¡îýUκ¿£3¤kÏÓ)ø‰+Y@7&Kð¾šè˜7 Xƒe‡ éššë:–.;ê‡˸Ðu"à’’Tò¤:rMUùéèZ9,F—PÇ h-—ÚƒRšé/µc®Š• Õ7U®ðS0dž'”ëZs0áp>Xý˜µk*Ì5TÍ©TÔ53•.°sñ<’¬ïE”»æ_‚ïÑ®óoÚ„F¼¯\ýcF+!š@Ÿ®=*Áíû~u~‡fÈ(I¦€Už’€%y–®r©tK¹PÈMÁZN²®©\a¤$Ó”*®¬òÔôøøôÔÔÈÈT©œÏ y såœd]Ź.Ï.KÓò ø)äÊ3##åî€%êrà÷à‘­Çfï±Iýõ±M€[{¨+œAœDZ(à^áð –a[‡$û…p¨s#¾Tb€©]ÄÁ€€éê<^ßšnXeQÆé\Vê`N%5eßb‹ï »6r+Xf*XTºœ'3¾OJ-*&%W§®hs,Ò–¨p} |CÀ ¥µóÆ+Òó¡2 ›Û[IJaéùE…(­z5ñýd+0ɳÛ4À!â&«çHs~7Þ;Ƈ(ŒM æŒüjû]W¯=;d_A2T ÁErijºÀ<+_–?¥R~zZ*Š·LMÍL3`• òpazRÁÿ¼.™ªX„´ÅîÅ’ ó™’© %²o…„ìãR%ü¢ñ8úÈÖcGït.¡,‡ Š(6Z·BDÉ%>ãbv]ÔT{S„VÄ„½]LÖž /{ê| °pÝRB±×¸¼Çuþ•n„y#[Ó<0jÒ°g‘b¬ê‰@QT°+V¤Ø*°H¼ u¯*­‚_AU ïm_ÒeÇ} N…Ò)…›@æFy:D>…õl¨¦dý;fˎņ)c‡ÁL0SÄ :Èz…ÐlA áåò[‰Vtv“µóÔk¶=ªÓü!F®ïÖ7ÙðÞꢷïýÉ•”«w¿zôÚÊÕ}C5d”$KÀB£ûôˆäH\¦ å2q* H¥©òLᬠVð7]/L,厪h)ÝŠT§$ÊS °Éó¿¤b…ƒPl=¶Ž |´ê2 ‰ l¼¬â1`©Nê0`‘V6!ôiAÀ˜ŠŠ)Ô7ˈC€Ej#á`°TS*˜JÃ*¨¤ª›XVÓ³å@f7.«WX7ÈHÈ^‡v"ºwr7 °,d t\1ŸŠ¢hÌ^½DSºè²½KièÄ|‘8 f½ŽeŒ¬p^ûXX>‡_ ª¼| ¡ç¡ºüýÞùÃäï~ÖèÁ!ä&«—ïQLsñ „*ü†\}9=vÍÕ}€WwK8B…0;Àš¬€JXœCÀ’ð“—5# S¸ü—ð€5Só¼Ü‚r2R*¨"ˆ“¿§X†ãœL `—Ô@@E¡0_P˜¯¨°9ƒ¹H®hû”ˈà¸kM‰ßúŽt÷UL12uX÷#{O…¿¡J¨Õ}Ý¡]˜B±0Òi¨£:ÖÅ‹–P0ì„í߃–£µ[ͰØ~G $l†å8‚Y©f^Ž*“Ë´ŠìIŒæ+«Pß@ùI0i†eØc˜ìòа7t}Òó¤ÆÚöAÌÇQ€åp½H ‡ïÏÑ–áø6~Z«í¯ÜyðÎ7“ƒvÚËßÝM¾HÍÎæw$Åúa³+bµ/œÞ¹stÇ­ìæêÃë+©~«ÐýÕí^[]F…0CÀUnªXœš™šp‘•/oäŸ\’ ©<†ùÒ20P§G “FP%”K¶káÙåR©TžWùÈc#¥§»Öá#GU ÕûC ÕA=ŽJ•°âZß+¼¢´þr%ØÖ!,«bUBY¡l-4"õ&ç?õ•°bsÚnÆlű‹Ë¢¯Ö¥ Tؼ£ÌJ™3,K¹ââp'粆¥ÔDJBt‡mPJæû®µ×Ôš8Ú⤙šõVèꙓxuµªg¾èâþŠº®Wýu—ÒÚ_€ñF²©LûiIP2¦ãi!¼:­ó§¤Z¸çœq“…tN\êbÅZYùõ?üîè®]£·nSn®R“¢û«Û“zà¿Èµ¡S³¬¢D—š^$Ÿ].=ø '**Tý,„ªG¯£‡†eMÍÉb˜~·É'V38Ÿ.Âs–(ïl»–S‰yŸ×wvLºgþéÁ'=©fôÇÓœ+7Y§õ(ÒNë®tV®ƒÑ[wŒîÜ5º÷Ñ_]_éÂÅVž%¼‚¨þòS¥n’`mÉF@ò´„ˆ×$Ÿ²®e|¼ß™ÛRJþóˆOßqŒ}¬{úµn‡'?÷.sõ夳6q÷Ál›neȰÖQŸ¦ì<Ò½sùåƒcwv‰áÕ¡8`§y€Cgùåߣ¢·ÞíªÝ_a0¯aU3õ‡¥ðhÒuç\l%4:vÃltùbŽ‘Òbò‰°æ¥¢‚³¹ ëmŸÝ&ѹV˜í¸«é¡lä‘/?,¼–›VqÆÅe‹nÇþ\7ÄØ`Øm?×°ò3ÞM=×qTÞNøÚѲ¬i›þpàhè8{‡ˆI½GŽW"ú¿tå™óíºpìú²ê¢k}š¬z>‡ÄûY_}ÌRSsÚ—Á ÃÛél¨Ã£Hÿüçˆ?íK8A'„>6¹B¢öåžKƃüjãÕ°*„Ÿ£×ù‹Œä—Ãø˜6å7JÀð~ðD·IÍa7YàÞýàÓÉWV®~UE™·Ü\áøÑ³)¡ ÙýK…ð¶aT?;€µºr=#ÙÄ«Mù´¥ƒf©ÝfÜ7Ym X'ÆÆžàä¶Ñ»þÈrsÕiÅïIÙ­|Ý_}H›Q!ü§O»%+Àê¤gL™ô1&‰—mÄ_]ýBf2xD˜%ý‚Ýê£gÔ {Œyg!FÕ÷ «,‹=ìbú}¹»o¾ /Ò‡v§ÓߣßiF}ˆ~x-4@´³ †÷׿*®°û+«áU³¬@&÷í q^h+[Î÷­`U*ò»g'ô“Ðe X74ŠèéE’ă²zÉ^“òÎ:V(d›–gh¿õ¸âéýøyáD¡‡ÝÇ=¨,úLš¥:åv660]Á¬öò·qtU·aÖkjªN›&è\ÿØö!Ÿ,ˆ¡  ïׯxHéµaœC¨$KÀ²­~ðB51ÙDÿ…€–á(í†_7Q”£=ÒO×¹€¡ç=Šl`x`/ˆƒŠº¦¾zBeÐ1Ou=/t¦]1¾ÚŸaèPÌ6R%‰àÉoÏŽ"¯`VµÏDÑöBH$I¼DKb#‘ç%`}Òcˆœ½ŽÏõèy½3[Gµ4ºü$ÄÄé1åféEr“ÕjþÙWL”ù¯'‰†÷ÓQÃ;»¿ºBtŒÂOV‡R²¬z‹Š yÔ81ìº@DhÄaØU/úfô‚E ìz>é¬+Ä ¼|½jÀò¨cÄz¾©Ö‰“»‹—’·Ê_ Ý~À"‡²Yuó’B¯( ±á"GÑóçðõI÷ç§^&œ‘u£^ ãÆ®å)H‹çUytm„„©¶/=Ÿ »v»»É:wùÒ“ccû1´`ª›+$Ãûµ»ÑýÕUÚ9Ô a–€uãÒŸ´ž®éZ?«Õü`Q¦8œ¬Á:´»E XoszL-ÿ|ÏôŠ…^O:cÀŠèž©„ÃÉ+ÆÑYtpiS²~@GÙ°2&~TmÖìM+v6±YX¤4˜ÊëUO©ÿAR½§Áµ¹nTÕ£7&üX/ƒÀ—u¢|AYÇ#WºA€Õiý ï—ÚÝ£ ²/Ò~ïŽýcû÷o#¢éÉ;Áðþª ƒä®ï®«jsX‡Œ’dXõÂx!×Dü*ô¬åªµ ¨æë~½ëª%@ëDÊå#÷‚ưPkäjµj®†Ùr¸Ð½™`ÁTUþ‘¿¸Š[_à5ú]=˲ψ±±ö '/Ëé#Xk°‰%À^Ž·¤1Ëøö©ˆB˜šLÉSŸsY7x1`áÕ=@–…Õ‘ó_«¢°é éæÙ.…µŽE¥„¾ üaÁi|ªˆÄzF×/ëÑ[ÀtIàBÕËÇõÁ5„µ,3ö¸Â` iZ íôÄ´‰p¨úÕæî;ØÃ9xpø»w/†ý’bí½ûï®­tw5†wÛc2º¿÷ $h~Ê!£$ÙVcü™gª¹ÆÉ &‰V­V§e­vòd­Þ(TëAÐoÔy¹^«Q $e>ž!ÎðOž êÕ|½^-Ôátàmˆo)Ö+ý¤¿` Šp‡Aˆ®h’n€%°@ÿÁF4ÎpïçŽHyxE.A°àyŒžD! ‰ð¬"ñ~QÞ"€¼§€¡ ‹"c¹ÌÌ€}Vÿi‰°²@'.¨uÐ|ñ&˜<*0òˆ”`q&B“]u§Âç Ðy€ÃtÌ#›Ý!ìNP n°<‚nÀ×G[ |cTe>_Qp]szBÄÕË,ª5Œ-`x¹«ÇöÎÊõ_þîŽÑ];w핈õÄ¥îð¶Ê†÷ÓÊð¾Bî¯ ^}¸6‡U!̰Xµ\>ßh4ä²*—’sÉeA‚Ô¢Lq¨Z­Êõ*ìoTóypàW•lJžQ†&ϸE’0,HµR!#ë‡a¥–Â-Ѭ,À†jÚj¶M3$X² zçû °˜W)º§˜ÖwSîÛBW\¢¼}u/™vhCV¸_ó“âaä pßžf6†òR Óê¶}ʼn°‚ðŠ‹rÍ èé ª9AÈ­!&¼Ùlbú„R>•™­ÏpÎõÄGEù¸)p Ol@CˆÅéêëŠ|ˆn»!ëÀ±ƒ?ênói¿&•Bex¿ªÜ_±àÑ}C«f Xup‘ܨ×êÕùñùù\u¾0_ÍW%„Ua«>þLAâÐxµš§ÕùCÏÌKp’›r9þŒÜ#sP€%uÇy‰op¬W'KV E°ôÑU)d•z•ÏJá4O»÷«×9vQ °ÀPÏÑ{(b‚>«3~JÞÎ ’g@ Øè®@Š`©Žo¯?vbÃ]|N®ïNý‚èRç§€hKŸÎ™Š%é: ò+5øÍ ë+m“®påê,Á HgCšD°À×ÞS®\{öw؇èŽ;$mÚu"×wzöÕÖ+`x‡LW¢x… áíéB,mXó Pô’6I¨j4$Ô Y ×¥J) ÌÆi¿,L£ ÒËß“ °äIÆÆêê¦ðB?"XzÇú,…dÙØ@1€¥ÕÀ0`-„+ƆÅDp#ЪY(ïÀ,¤rÙ9PŠ(ÕA)_±$êþ”ÈçÆD4Œ0£L,“@P’Xú\†zl¼-`ÈzÆĨź6c¯Ï à ÔÓQò† a?˜bx¿nbuí}ô£¸É’ˆuðÍfOÄÒ†wv/j¾~2ì a–€UËU%ò¹yäVF’Iõ¯š«7@­“)æ² H›¤r˜«Õeb^ÖëHÊò’‰Õ 0Ê=UÉÃ$ïû×"5³+¬öaÃBÛH TóTívƒDÙ°XA°´åÅ@÷E‹¥øÉã°-°¡'#²Hã°°f¼€•-?LtˆÀ€¢«Œ•-Ï0¬À×(§É‘Ø‘üñÒºˆiÚ K“ª@Y©¬Ô}­Ô £¯ê•qü.  f–é*༰$lÓOhÆãF¥õöñ±ƒ5¼¯ØQæ÷ýñ¿¬ /Ò=@±î|¿Õ±–ŸÃ{ëïö†ñjõÚ] ^íuþ§)Ö–F-N‚Á*/Q*_‹T´ÄF.ŸkÔ$Ý‚0{`uK­¶¥ K0iÉõç±ò¹jcKA²,™´o•P¯²øJHæcÑØ0ñ`AŠs0›£M_¨âŽC¿·é/W] õ•P›rè¢ëíYü•P},ô¸¸ô«?`ÒÏ€¡‡>…\émVk=¶C)þÅëBå¯ï’­ZªØp•Là'®óm/ñ/6 ²-ð<)v¦®ÈÌP—Ê<‘l%°(*N$Tê øUž~ų_ÁMÖ( Ö»=íîlxÿÏQ¼b…p˜ V–*a£Ú¨KVTEö$µ¼ñyÉ“æåÎÆü<‚ò—÷H=p„—Xó”Î Ó ‹z/ÃËŒÃÒ“‚Ð`Í 3ßÏš©d®¯†çB†fê„ÇyZ3_BSRqG ‡2¼Dç-šqÆ AÀ@([È₱†&3z~ÒWÚöÕTÎÌêÓTk¶\†O…*ŽÎõÝ»]B½ÏÞ)ÓcF_\êE²:Í—FwîÚq+»“!á/„Clq_ͰU–y½UµÖçé¨>DÇôñ4i0`-Þ0À2ý#Úu²/XÝçîª÷>Í(Q} ñ*qî43,šÞdƒÚú:[ÂÔœÈME7J—T„Ð<˜H­[€ä)祜Oå¡¥ªöô(îÍH4)=Ón€ kãèÄ8:++Wÿý]·o7QæãIaÄ]»ØMVi}ÂèŒþ½eοÂL§æ¨‘ ™K'üø7°°;,0l”„&?'x°÷„g«9rë‹ÉyÛ;“qîZ%ŒÍKLàd7 ö,$M»xš¶g Å¾Jdv²]žg©uÑI:~„&×nZ37*õÄL$°(ŽÎ‰wþßÿ©Ý\í{ìj¢ß¶Nû½ã’bíb7Yé²òïn¿U"ÖnËÞuS(„»—I–@™Z"ÖerÐ{|þT®MHž5 ÖOÈÃÈÆøÃÒWÛXoJht·j&amyÇŸG&EŽ—´ke¡õÔ[Äé6¾ÄZK¯Hm|k»÷Ù|Õ^7¨A$÷­NóG<±oĠh\À÷¨,;X‚\—djÛŽQkÄ»úBøñ§CýËgÆãè¦lÊgU®_~òá±±Û¶¹úêÕ•.,}þÙ×v’›¬”DäþêßüçÝ;wŸQŽH!|vØ Ög°V>þèÊ•´èuk_Ÿòqï¡Â›²)7LЇèö½íß±|ˆv‡ñÏ£‡¥DOåþªùç8~ÓÜ$ av€U©è\ŽâD£ŸPÀœ¹¹¹Ð^™‰  °Ô%ªéDÅYýø‘£qyàèòÈdzÌQq£’ãÝ9–†Ž:f§užÙgåãT¢yª0_½C[9nüx<¿PzË1[Ö+B â³ºŽ¹m§k9¢÷à„Ÿm¸žLŽõÊ¿ÇE¹@{t0ì™ãôÈ7žÓ¡í&ñ~¥Fˆnß?6öðËÿOïˆð=ú÷Ï›¬Sç"N¬ ;p/Ú^~AÂÚyäa×¥B¸m˜ç*ɰtÜÀpuic‚Ây©¸‚Š'h`ˆON%·Ò°0T½IõžuS5‘ŸcˆÂ¥4 ÷;'žéÝ|o X&«í²Özpz—Æuí¨Ò…ùŠ^½¯Þí:©¥pÌK/ñ“À*oìmýåD^ñ|“JsÃ%-+öô›;ÆÆºÆÑQÒ÷îß¾ü.ºÉ:'Yȯ¶ãpöö’ U¸òUüBøi£Q’a ÕŠjÃá‡ÍP3añ'—ö'‡µ6Ea uú‰‰‰îáÚ °â05n½bH ^Tõ“hR d÷ؤþ‚»„NvêÄZôì¤ig¨¼³î}#,³¯ 9‰;tÝ9‘»u¬­HÍ&‚¶“˜o O+sÅ¢êØ®ÜSœcª5W,•Š£4XîÓ2‘K,‚£­*Àš ÀJ}/+ÀºovvöÞ{ï? 8uøð@p¥‹XáDeFâtÝ?šyà«éÎ:óîRß«‘Ùôí¶˜#Nï³IÑ%ßObéîÔ‘äêQöÄ>D¯w:Gg¹7bµÞ„Ívë]´d]¶HÖ'Wï~u·ÒýZçwïÜýâò¯á áÞ+Ã=d”$+Àš«Ë3åÒÓò1KDš„(õsÐåñ±gä±"±•byzº\D Åû-–dÅn1‘|P kö‡z`öð‘#‡ï¹—)†R%œ¨t'e3¥…ULéBaÅÇ€Jüº}uÓDJæX +Û® Uß½}ÔaDeíFª>¶KÕuŠ]o}åÞ@q `‘›+!ú;’ƒöNqtP:ËO;þ÷íN{ù›{$zÝDXE÷ ’_©L:Mp5óÝÿ²ý¦øB’`MTŠ##¹©"Ê-SÅIw“ü­T&‹¥\^sAUJ#…B®(9לü›„£È·$ÉD%<YäA©(Ae"™cM° köÈV)GŽÝz?¬`­²À†5á !dÖ´´VB›á4‚Z~üDÙ yÓ5Ù S~s†}“Ê>Ã$„dÝ:›CA Ïe0±‹¬n¿ÏNïØwe×"Õ“°nJPr…9*¹N¤*!TQPË[ñgdUq<߸dTUk«VI‚VþõCC®¾l´S>ÜÇ´Þ—ÚãSËÕNëu ¶úêE"YŸDÝ_ºá}ôV‰b×{å;’ѽ42=³eª$eª\ž’ÈSB)"É·‰yÉtS¯Êå"ü!û*ÂÃ*榧J·”gUˆ¯MBЧå¹p^%®°î{`ë‘Y T<²uö¾c¯’lZ½å`X²÷Ì ê ŽîNÅ‚-<êÕc¬CÖN“ÒÞ¬ˆÙ@z+eøŠ&hEèt”IÅ0¼ Ê8ÝìN€Å›“;ë§htV§vDß熓†jîÝÔX˜ú‡ÇAµ#ÔÀÚt9O¬/¡PQ襋éRòM±Üw­Ø ‘‰U A_¶bu][±Ô4Œ£sâ힆÷NóåƒcwB:I²Îâ‡wað‚rB¦ÞGo½U%vɰÊS¹™rnËT®œ+—J·”gFF$¹¥é‘’«§Ÿþ-©2B:©–FF¦¦F SÅÒ”\+Î1`M•ggÍ …¼Ì#'¡®<2Ö °fÚ:{Ͻ³XÙzlv0“»,ì 6Ð8 5èýìØ]ÂÖ Y¨¥Z!N  6#€G°ˆihÀÜk(3Å.héprgš:JTˆÐÖ*ÜzE–# SáªšÈ † ¬FSø®'M{uªÃX§J r„© WÀ g¯.Kè&xéÂóR +’¯"sêT:=32Ú·8XWGÏmþrB:­÷Ž£;¿^±} ôè’¦sñü)E*IV›Ü_}9’kûõÝ;wíØñ_o’á‡YÖ$Q)?=ÇåÈt®45>=](ML`¹`uG£|i|\"’L=Mÿ rY.J•²œÏçËå™üT)W.–𘄫[f8—TÃÛ°,Àzdë±ï#øȆU¡·ñœêyÈt¨ª‹BÃÆ—¼¨è¾ÄÕX­ïb„‹Ú)kny†©ÁŒ9ªXC¤ruéY¶JˆåÅ´ë^´º JWÅ¡ò ¸B«{Âm¹ÏŠÆ(>T±4?Cx¹tÂ8c [±€‘“ëªÅ‹v9º>1‡–£ž þs9_GÙ*¼®ç)°€]¹úe«Nóí>âè¬ÒƒoáPp“$ëÌ»ÿuEÒ¾þà÷,ÿ&–dXgJF…RiüСq 5E¡RqìVXÓe¬Âø8- 3E2ÆOçf¦ ’yÍÈ¿q Tò¼©Î¥`M®~ôÀì1­n}h냳‡ W X5î9î@‚Ã!@Ì d׈²0õ«è ñÃotbd`¹"X,êY °Øš0Áœ ­c… ¹[&}‡5V ¬"¥›bkÚåjrC€…UX1–*Uq„ XŽc½0XeT\—ö0`U"]b³\{X¿”/–zi kØ¢Ó·U.™@Àº¶oÛvö!š ýÄÑÁ :O0°u.žƒ{vܺm[Œ_ÁÑ[wìÒ#Þ‡^²Ö XÕô€ÑLžkº„6,À¢â¤T Qu,== Ç$›ž)íVy,y`èÕøôŒÜÌÚ.± ‡-Ø3 €uÿÑ­IÙú¨„n=räð` îÂEbP™›XÒ†ÞüdbrÔÆ ’>æ:Ä”-Ì©h-Ò‰–R -ÀrlåIu)VÁ*”·‹Å4¬..` e`ËBH%t4:ˆê4eV*Ö½‡ïŸ•rÿý³÷Á°Ñë„WVéý¯üzDt·ÑÏñé‚¡¡5Û†”4¸3qØuÔðÔ×°véA[×ÿÝŽ;ÀéÌ+"¨Ds/¿.녛Œ•`mÉ(ÉçG:KÒ©¸ä¶ô,3—pði„ °Tƒ…6‘Þx­©ýNý§t4º“ºé¡tYuBΖf‡Ú@ì²Ù¥¼¡*sœnÉ¢"“%ïè•Y÷+ÞpÄê°(ŽÎ½ ïp¬|â}Jµò˜TûnÛûéBPGsŸm·^…P…oÄÊN%T¯hôU©›@Òxòb19%þ€J¨ X“±Gm–Æ«'@kÀ²¾kµþ~&OZéÝ-¹u¬ð9¶ o¢G ç¼c)×; Zg{)ëÝîjc…ÆÏÇîØMN^sõô¬I7ž&;¡g9ÑOOë4ߌÇщ ø=ø$z‚GWWÛö]xF‘†Üd}¢æv.¾¸ûæ0¼g;ùÙn ‘Çšø˜'ôŒÂ¹¹Þ ¢Ë—ÂÕ+Çf3’c6`qCªèù}6X;M/`°º‹c+)¬°ÐßFe2X}AêÍXî,šñÔ‡ô9G§))ÖÃï´;«ÊýU§½ôbÄMÖõGa!8nè\8-Áìõá7ceXØ,ðòÜeW¢kš‹ËÛ6œ?Pîää$,¸A€Çž‚7ÇÍÅö‰e7Agüa}題äK¯òµ£åOü#‘å›0iéî‡î…·ÏŸ˜pVWútw"Çé^'pú·ÎÎ\[]#~|ºƒñ«°â¸Vý%•¿¡!N-vãÉ赩ƒG×ã×µïò¡çÏm€À.4é]ÿFòReˆ•ÅzvòØzéY=á}"œNÕ¶¹–=û"šoEß{?5ªžW_*a4ŽNj*ÚðÔåöµ»ØýÕj§}ñ5p“µG¹ÉZyÖxÅP…§–†žb}V<Ž^ÿÅd$¿¸9æTmÊo®€á}ìø{Ý8ô=zçþº“ÙÇS[Kè&ëëD²®î“Pv–lŸ¿) µ X›r³IëÉž¿»‡¾GOü>8b¸KÏòi_<¾HÁMÖ *„¿âÙŠÖ¹Ý;wÿùÅOûÞzHvQsú^±oº/ ºæW Y‡JØWû2(=¿>ko åÕ=e\ä ²,ÛM,ýö¶Nó­‡Ç>ÙãSaë;ÇÞ±mÛvÛ=ÃjëÝÓä‹´õw ~Õxƒ@Ãû°Í°Â¡ñtðïX,AÜĦ‹„ñŠäÄq0u¯æ'ÿ24º?teÕ”uMº_’u11p Þª ’©§húø'Õ HƼ}+oŸÿ%çØ§P@éP9̪k…ï'rÝØ½&^¦kùB¹'Ö­*O¯tA,¿xý«üÔŸJ¬jØ Áp­Á¿¾»[§ùí;{ºók_~bllÿö0^%‹|‘~ï6©†\Í€áýáF¬ ã..ª§¥žâ/o,j_ò3…ýÂh•O C€:{Q¥X”}sõ££ñA ;ðÓQÓ·&–Ÿ– ¸Æ7LAaoZ[V‘Ÿ£Ç7 %ðTÞ´Ëë7{­ V½ŸHù“®›po k)Öª•o8;lÉ×J-öb‹ƾš9®bjúØWíW¯áµ´™hµý÷74¼ßÙýSáõ¼c¿¤XwGc v.¾ñNÕ¹õÖ½¿²3¸ ï™=.Ù/_…󅇩Z­‰Ñz¦É‘s=?© Ç›¾¼A8…Y¶;Œ]Qpr/V/Ô%?Ä{×a‰µÚ“p³º÷G:¸¥9^ML‚xøå¤¼CvýÑŠ# «Gžªƒn¡•£²`ýÄÝ/.†wDÊŽŸm.ê\ Ÿdê ápAþ,ÄŠËá¤Í©ê…X篣Zû–öåÇaŽNÃûÊ•}Û÷KÄúi, ø"•ˆµktÇÿ¦Síó»‡Ýðž¡Jø³Z½bžð¢n-òêføþ¤Ä—kfc?÷Zíg|̬ZR.,"—þè{ïÅ©9÷Ý~ݾÿð:˳Õ1O} Êj^€GÌSÍTÁ˜i¸¾•–ß̪ûzê¿»" êJ‹tkRôz`ª„x«„–© Þx¥šCø€./`>ˆl™—žÂ‡ šÆ3àfg½@Û vý%Ô‡ª'J·¸°Ve¦%.¦¿¸®zöÖXÀ>=ŽÎʇû¶mÛ±?Ù¹C§ynt×®]£ß½B¬N <&¿2Ì#Þ³cX'ë\£Æu¿À ÔWxµhu¿za¼kÔ ‰Öï¼HƒÀÞ]käj˜C(E-W­™ÆçãäçaòóQ=ùy qḭ̂!„Ä\´‚0$ˆØÈMZê4r‹X”Ù* NÄE€1¿[UDú<^W¹Zµ£®ÃÅLëhÆEÀų]Äóc@±VAôd£Ô¢Ez‚žð©|X#^à){–Pú>c‰±ÒˆJG€­*‹ªòóuxX©ÔR<&N‚¯ r¥—梯^ò?e\q”¥¯ ·ña/X•$|Ý’½E PÜ&™Oû95>Ÿ–u õì­ °:­®qtVžÕŽß?ܾûÖà£áLxÊsgù Þûˆ&öiIv «ÖÈÏçë5)'Ož¬I %!L‚R ØT–Ì«ãÏ<3/«†ûk˜¦FR'©äÍÚÉ ^Í×e[ûæ¬ókªuÍw°îp+|÷2Gfl}ðÈ€³Ÿøhº4^ÁMqŠ ûa îä4ÐÓ©t×⣌t”J¡Tg,•ÐÓçÁ÷j»«r'TÄci½‚‹Ë KŽu©-°L‡Ä?MÒ °¨d A|à‰ß3"_<²cÛµÅôDÔ óÝÆ7üÓþžàëÌæ«\­bdp– ¯ÔÓ ø £(¦éÔ}-ñdå.š'%ø¯¹Z;~±Õn·;Þ,§[Ä«Ûnì§Ç§ñ¬<{û¶[wÀ×Â=çC$«½†÷w‡×ðž`Õ«…j®ÑÈU[|¾Z« õZN®É½´”(uRV5·Ò5$ú¨£jA®æó9ÞÊm©ûXÈ߀•©ü °ðG<Ž~ܸHV@cÁMÀÍÐ'½1'à=°›!¨O¬LÆÁ‰H(<ìá/Œ‚,"Nž,!ô€´iÙM 0×HD,dXB#¥ê޶¹x]€¥zyˆY.82" ùñ ãdn¨Hâ"ŸFhJ«œª•êD½ è$:K«&<¢PDs qÍ©W‡~:K¨ ÁeL8‡+ïUXjʪ€Ï*ëZ بŒ³{NyåÜÒ [=Ýô¥ÏÑ‘xuÛm·í}öºå{Ô2z÷»à&k÷‹KaÄnÃ{v*a½0?_ÍU綪r½P¯Ï7êÕùqÚ=_ÍÏÏç$`yõqP e¢FC¦Ë×ëò@ÂyóðWÍq^ °¤bX•×U~2e}qqѬ‡¶ÎÞK.’­ÓE²bXÜ ™])•ßïša±zƒÝ!à×8Áuœ€_ë~À‰ÖŸ! `)4³žâùÄP3 î²ê,}åDd‘øæ«üˆjy™ƒ ËÀ¤ÀÀck»V …oÿr‘tnêä&7dH‚êZ9V7Û¨Dº½a”FU:¢Çàãð¸6±°<•‘~åX¹bYU«¬lKÄ{õÔsä²®Qó–ÕzIíÞ³çôÙs,]lµº‘-Š£‡#«m{Ÿ] û5ÇaøûÞ_¶—_§_³shŸ“%^Ç Öø¡ñ•„ †\—@$AªQ— ÐTEÓ•ì¨r¿¤U’‘AŠyJ'Á© Vól<`¬þ3¬ÅÅZöHn¥ó“ Kw:¬/`݃€ˆ5Kë׌XÀ°|Õ˜±‡éW5Ó&á±nØ*¡VØØ(m„Ù uWÎP6bÁ§*,²‚!)ñ)[,Ùf•qžš ™”v`õ=JÉg†¥!ÉcÀ]PÑaq fu–ïwQ ñ[¦îu|v€EÖ6?Aoú-“ ‹*f°”9[m*`Q7e½.)ØâGüB°+°yŸ0µ¦.OðÏOÍV `ÙÚsô`X®Í}ýü `QY×@±H%ìüüW_|î”Z»ÙJ²lµ!a4޹“ÙK“ši‚ÎåÐyÖBI²ÐMÖ†d‘áýµ!5ceXõ[VêõX¥ …|½v ›òÕª$M`G’C”€µ¾&Ö[dºœL}ÍSp´ ©åŸÌ vU·Ô‚ÅÀتUÇüà'9i냿zåè½÷é@ª³÷c U W2¬Àþ§-4ÄnØ–¤>ùiµQ%T†À(•¦1²†ç¹¨/aBX4ê–Ù D ¯ã›…ÊŽì[ô¹îšñ¨oëI3x<ª.—ÇT†Å¦˜jzB!x ”ÙÈ×¶° зhU¢QØÔa?W¬ç ¹¯þ„Ë2°°áŠÉ€¥3ôÃÒƒ/#Oï³^S}ÈÂ<7øJØi·[­‹K?8÷õÓ{ú [­xvõ!Ϲi½ygÄÐE !Ï!ì´ÐM–M²†Úðž`Õê€WõFƒÿ$M’€Sm€=ª ö©q XÀ¡T*Hƒé¼Ä¤SÑ®*¦›Ÿgò…»é¨\Ö°<X÷ÞG¡êgg9Tý`Vw,ãäû‘IŒjitݬt[õÌY‰tEÍ̉^/ž¥ú.åëehæ¬ó•s×ÊÖXÞ‚‡¥ËD‹jvÑñcIÕ¤XŠúT¡îѾA#"èVבcŠ…/nr¥K‰ÐseZÑ_'­ŒC÷g]jM€eÏ%ì´[ËK¯¿úÒ 1²õFˆlÅãè\#¼ºª"°¶/?5¦}‚|ò!(„¤ç²›¬ÓÆMVûá5¼gXȃ ©2>®Ö(U·´¶P:s¶‘\ÍŒìòi¤û}³4hxøt4ª C¢ã6z‰§èñŒÉº±÷/$2ã íìÒ¿[†ø †æ”õ–(À²º§gN¹ÞùÒ Ê ?N8Ç aO­ëixjÄ q˜ÀO=+þð¼¤$ÖtMæPáGìõ« ZSíÕ‘\K²- [gcdëÕ7ÙŠÆÑaw}VÖö{2ÁSÚ{ÖÊ¿ BhÏ!d7Y¯jK;8nØùâPÞ³S õ!²t‰8Sè/ãGb[óæ•Yuž~X40‘‹Š,W¼°®èQÜŠ­è¶kMÖ±G·GÖÖôiˆõ«ûôp[÷"=§wOuô®°‚`™[ö’1¾¯Aðá"ßHÀx¯û© Sx"y†îŸëÙ‹¼Âo…(Øz‘ù‰Ã³b°ÚURËà  Ö¯¾ô|Œlý>#.¿ÿ±±;U…WvÍ'Á{–¢X¤~ ÎÓ¹ÉR†÷¡ô˜œáÀQ5êóI mÇ‹ÃR@Ŷv\(Ì—Õýn¯ðĦ{Që^‘>ß'ƒ¨ ÓžÕ›[¿uy:'-k3KÙ3ð».áú^õÔ¾**íxø0VOxJÚí¥n'Ò³AÊ‹¼“¢%‹žÚõŽÖ>‘À Ò§æt:lÙú F¶žé[?þ›ãRç£8:×Ð]ß]WCHÓzí\ŒEÿ÷í ñŸÙMÖžó̪:Ë/ ©á=cX¶ °Ô}f$l4“0 Y~È&bl4 Ieh΢OšV?~䨖ÔʃGG>^µ ·cÙE™=¢iõÍ%Øb” KÍ5T56hVAÂVµ l@KÈ;TŸë®ïUÛ¢“zï V ¤ãAt™s?…I½žu<±ê‚ÀœDò ¢Y&ÔÒ*=©Áô+½z’­wϽt&D¶v<06öÄ{ÍV«y÷ö¨û«U¶sÝIƒ>¹ á¾k±œ[Kì&‹HÞ‡0TágÅãhçã"rå£Áäã!äÁ›²)($[í(ÙÚ%ëàó/~ <Æl¿û×Ñ܆¡ #ÅJR)gr“µóÔy¤j4¼Ÿ>Ç ŸÀÚ”Mù&[¯œ9%u¹]ŽصkTÊŽ;Î/-7é;¢NŒ³ß”HôI¢BÈ9¶^WàÌ! U¸ X›²)7¥×j]üùçþêÎ;DZXKÜóÜ‹¯¼¾´ÜÒ˜…¾GÁ±ÃÕèÂP†‘\$CAçænT+½éËÙ¬ ’µõÝr×rÕi½wü`rÛŸ½¾ ¾G/ŹøŒ­ÝD¶¾õ­?ûS”ЈwôÞÜé´`z5¹rÖ+rÙÂ#…äÄ™ŽãÇJøiszÞ› `Mô_ÇTÑ@Ÿ$TuK¹QÍ®*‹â¿£ƒ Veƒ¸`R½l `9¸ä¼Œ3ß@Œý |Bkë«û€_EÜõuš?ŽÅÑùäŸ@!|te?#¾œôɯ£|?,½öjˆlí”ôŠë=â½ý·§GGO°<::úùϵšßÜ3:úÂR«ùÝÏî9×nŽ.5GG/€¯›¯ËS:MXÛóA»Ó’é–:7äÏé×›˜Çß®YÑŒ–;9é΋ÅÉ~»«¬¹b©Tœs‹Eוgãï¤ÌÈä³á€uïììì}„â B±Àºqˆµ‘ k£e°6DÖˆWÛ¢ü ¡ ïOÙ¨ ámàe´³ü²ö=š"Š×óÊ‹–e ˸šé´>?ú­ï~þÂÎï]h.¿2zú½WG?ß<7ú»gFÿ¯å;¿ GFGßyiô›myM¹ö­Ñ=ÍöߎÊ<Úí=£ß}tÏòçG¿÷½ÑÏ­°&*“uŠå™r©H;úãZ°&ŠåéérQ¢ÖäÓý•8×eÀâ0_÷A€¯{î9<;h˜¯®¬ÊÛæ·ËÜ'Kqè<·_Rã(ÀŠUÓ?/JKCg-wÒEÂÙ&ä—¥ë•Óç1'{’¹²–ž‹xuû£ÿ‡œH¥âÀ‡Ë’b=¹Ü5cE¶–ÙÒˆõA›ktôûšíæn¬ {F_ÝPò§¥æ»£ŸoçÎÓXïýDÂXë=¹u¡yvôÔÎS­Öèî×/4[MÊc­xeò¡¹b97UÊåóåâÚ*Ú­”F …\©TÞR,æfŠÅ-åRijË–R‘!,["XXTï¿©¦½²:11'„M–•ŠZ‘M7+í·—êÙéšMŒßYᜬSHìýrŸ£óQW¦õØ|%NÖ­'`9”\:)›³å»|STN¹ßa¨uì²qr»°"´ê„vTbàÊe:5ïä 5GCX×ä'aw¢û´…£~KüêöÇþ5áXû2Þ5býŠB&Я·úUÅdëÕŸûBÖÎ=dxï´¾9:zv©ÝܹsôsŸ[Þ½w·vïn¶¥"(ëë¯#`]ËXç$»°gÏwî¾Ø:+Oþ[©Hbk6bÀš,IbU,MOçJS3¹kZBÝôt®8uèÐT17]žÚR.ß²¦|Ò½BÕCÕÏÂúá²J(°»É%þ¹¸âP›w*\!i”pU ¶„ÕñOò4:Qæ$8'SvWq0K\8°"˜áéü4ãs*VNiTLfDT{­¼¶ã:¢’… ÑK% °ÊB¾Ö>zØT •£«A·"Ìax-@µÁ!ÜŒÜçÌ…*£aÀÃSJ\‚ƒfïn¼òáÞmé®­Ú—NX†wúBxMÙãä{´?Áp=Ëï}ïy0díý.Ÿ×þà…ÑQPü$5`jÀzýÅ`Ž~þ¿K•ñÅŸ|m÷íœ|¶Ey¬y^µ,É­ò¹RyüPAr£é‘Rß*œÔž°ÊS°FJ°¦§F$tMM•¥ni>·mœUHÖì#[¿xï½³XÙzlv°8ª °wL×t9ê*Ö!§Âouµ¤ÔªCa2HÏ”Çj¦VÐ通j9X!xP3a:b*qBÀ2wâ‚þ™œrÍõ€åDK0r:ŽÙeÔ1Xм25f‰ôÒaÎÈÄQsܳ²‹ïIÂ0â°ëhÀ2giÀ‚«àüâ0ä,³V¸^AÀj¿õ{o-÷€¬•g%iê⊯õ¶Ôüþ`ÉRß”ë;ÍÕ>E’¬ŸŸa3¬ Êåróš$µX%l‚Jø´l]8m©„m`XRùk–¸µSBT«yá'»G›”ÇšGÐkÀš,Îä§p¯r#3ý2#À  XnIBäfÓùR©0=2]˜†µüH•KÒ Õ˜¬ìë¡­³ Xl=vôþA¿JÀÂn=!;·fWs"ìôî‰0, A¦HªŠCý%Ä=°„EáÚÌŒÿc¦¸ &TNê:vfágà ˡŽë2Õ¢Ó×Wß«¤S©D¸dJ‰´uÔÕŽKÉŽiÅ¡M×ܱеhASE¿F蘣ÕÌ !¡ƒ\Ò˜V&¯©áyÁÃr¸~ñÊê‡`u.?~ðà“—šÝ:r/¼Zí4–žDû­bþ0Cúr8!ÑæõO±k·žÝþüè÷¾EF÷åVóU4ºŒîï½€F÷ ßDÀú ݰ.´:Ÿžj6_ÝsaÏèëß#£»Ìc€¬J²¤é‘©RY‚M¿FwXs¥q0º—¦d.¹ð5=R.Ê&47Ñ_nƒ Ö1©΢J¸VýJøÀG}Å$–¨ÌÍÁ«ÞB%—ˆöm!26¨Š­yé“Íaa”8G1,,'°xÓå4VN¸°®z6.Û°XÄq²1º+²&? ¡ï­Â€à²%‹Gj.þ D3µBK<Æ”‹3•ÃÒz´°`†Ë1ÄÊá‡îÛÑŒJ¸QÀRZþPÖ½slìà‰7»,«½ÏvquL¶*0¼ë/„JZo§ÌÞ‰£UkéÜicr?sA)’4¬áoA×ûíϵšÿ ·ä¯ÖÐ\âa gqXÃoÿ6\íߎžmwä¥×Og3¬AÐ#PìÖÖ~ç&@%,Ω\ò²hL7~t€ì—½ÿèÖ‡¤l}T ±aYG°*bBp'e­Â¿BÚKv‹JE# ¥à ¥’SV¡¹‘'ΰT®¢Æ/ÕË´æ), OR½X O¦ž½þof€ƒZ»E…L}$PÕ`q!ºKfQ •UañDûŽÊ›a¥ï€©¢Œcúy¹ê-iñ1À²¾l|ê‚*aó+±$=z? SV¾Ü¯VÛ—ŸÂ9:׿l+„|œÐôBŠNëÂù3äúoç×pPƒ™Sm†ˆâxÑŽ=pTžØÂ#ÖÀÑUƒF³8*¡f ,Oããòÿøt©o q°žF£»äTÌEâÞÔä5UÜøù-X‡…¯„G<¶†6l”bJX™”ocÉ•J¨I Gø²¶¾«½Ûù /*t¢­% ‹5èfZQº”¹Pè¢ÕË*Jݾý)£;£]¦_ +®²¦!ÃR'ôMÎB Rûë–£¾£R)¹N¬¨Ö×XÍj+ °ž9̸è'Rÿü‘q¹Œ©ü]s(„lXËoŸ8$ë‡É$K»¿êÞ±Áð>vü”à¶íÑPÚö{ÇÇ>ÕÍŠ€³ôÝÓŒVÏ?¿SâÕ«Câ(Ù2ºO‡¤Œœž¨57‡F÷"葉6¬‰Ji!eq"¼&ÉÐTŸ$¥rbÂÁqX‡ïŸ•rÿý4x´÷ÀÑäÑð÷¨£7²™êÕ¤™œty`Xš0q¿cçí¤§@œ8Š¥”·ËóSáÞ¡äê—ê&:œƒêKÝ!Õå™ÔD–&3Ò½Óºür:É"w2=ñJª~èÎï©î½>Ò”äëø{éK’«s/ì¦ù9§_ýÉKˆWÃâ_Ƭ܈‘|nK©?³»Ä« kK^›±%—LÕÖX=š…LçÐ\µÉpÙ°øž{VJ©ÝÏQã°z¤[s¡o$`ÁÍ£¥T×VH³V¥;`eRЬɊâÄuËýUwé4ß~xìáýÛ·Ý7ôLúTòÐI®.~p–TÁݧ^zýÂtØðj6¯ Xs80½¤F©¯avN~.Õùa):úcC¢fÕƒ-àÕ5ÚdzÓ˜0“Ÿ êôN)ö­{P%œ  nØG‚ÐwéýIó3»Õž-Ð&)oÇ>wÝ☑îñüéÄpN伞¹$kqýÝŸÛóÚog(pC6Z—¿H²”û«ÞxÅîüÞ±ýî•Ø;ø£¤!PÖÒ+ÏZíùúkË­ãÕ°ð«to }?0ªèP2gºz™NHÅn‚=×tmL±Ãü¾Œ;|…PàÊ±ÙŒäØ•U®€$]˰ðqLFò΢ê^ù4˾˵Þ_6€•- E&?K’õxœd)¼ê¯o·/ApÕ;âC’‡6tÚ­‹ohrõÊR³Ýi/Ÿ¥@ÐCƒW°˜n«‡à&u•´º–Ý&M“WEäQ84…AŽpTþ… lTss.²xCéÕJ¸ÊG—þ«ˆ­~ü¥‡2’/}¼R-”c°Èš}l=Û)€åR}…;‘êLn%’ÿUÑUãÅ`„œë„ŽGks­å¥žÝ.IeëýgìTú„š¥õçÀÌ>ZÚ@×KÈ×*Gê_¥ßúê¯>]ìo® ’d,v×׿’rýß¾ÿØÃ qЕò›¡ývsé•SL®Îþà"|l/Ÿ¼zmxøÕgÇãèÊ/‘‘üòú§}/›²)«h„KÖ˜þ\ˆüjû]}ò+2JnÜãqtÚ—ŸMÐIƒ¯½Àäê¹W—¡ÚË_:¼úÌÖêÊõŒ¤Ï×צlÊK˜d­\¹k{’;™T¹s÷>œG§Ó ùm_|÷Ï5¹ZºÈA¿ÚK§‡¯2,_KÀ?— ò›–n B§¯®~!3‘7³Î2­QìÚËPøOygx?ª¾7¾Z~Ó$€jKó´dÿöåætuwßxµòU2ú ü½ÿ"¸ü8úí¨É‚WgÎ-ix’xµsøð*CÀ P|ߣúKôÇ{ô:=7}À:)¼Í3kÀŠ–À×ÿ2êýrÅÃ…u ”Ì‹mxç…ÆË'ó†}^(ßÙó­<|óDCw`åïuÍÛ ßÁb¸•ô:ßTKBRû‰â?þh¿ÚÓi=kOøNü k 1À2$ëÄÉýUßx…s·=úkŽ£=ÚzûNð=Ún/¿ö"“«Óß]j™ˆªí¥S€W?¢ Ï(Y–|À´¶¸zœž Pº!¨V±¸¸¨V z-6`tm¶Xºw—õˆ‡½?`¼"YXPפË..྅ha¡Þ<Ü*ŸªM,Ì‘ÿ2™­·©/¶b6}ÏÚ¯jÕÓ¾<}ÇqØ€{òb¹P ·5jÀã8Ö'=«d A÷¬i·‰Ì[…ŸÐ±:Mü\8vÇŽíÛn¬¼ºŽs¯v:àÇ=î }ÿñ»çx<ûž3çCë‰_=7D!ŸY2,ÓQÌ“—¼³‹[h û ¨ê÷¬"l˜—É®dmo`yÉßK(gÐ¥VˆSxÅI<}I§Í+z)%¨»%ôÓuÞo«Í!Ñawî?NîõýêŽ º@ ñ¿@µÂõå‡ó‹BW¡Ô kãÛRI&¦ ëo-€_ëþzÿ~€¬—/÷mPºŠNeàƒw§õÓãc‘8:N»ù“ãÆì;û‹¯Gg-¶ß~ujñ*CÀªÆ ¹Fc>W[´ÚÃÉߪŸ Hy‘:b-W•(U/Ì×OÖr}Q7”…h’-¤ÖÈÕjÕ\ _æ JmHjíX0­–ä/®âÖx~`WÀ’9 ÙDý¢Ws]—`ù²œ>ò'ùK%ð} >ÞR¸>Qîct”G; YÇád¼N¾MÆçžå«|-ˆ¡òhаâ{ÁV±DLê²¾ÐOÿ›¯ä~e¯ƒòë¤xê ŸQàëóñ6Amóu:u-A_  &¸–¾ªe¬J®}®·@oê%&ëf‘X×ÿ½ÛvìGKÖÛËý!Ö ŒØRL[?ŠÄÑ鴖ν°{×±±£§Ïÿ¼«Nëµ=Cʯ²¬Æø3ÏTsÕùBy,ä²ÞhÔaë¤dT¥òóõ hŒ7ê|¡Z§„u”šdT°<‰'e«¨ÏçëõjRÁÎFwa€‰aIØHe£XoÀ°ÄÆ" u¼€@ÊS8 ?²‡{Œž¨J++°¾‚Õ€ð ´Ø…pÖ”·ÏÛêÙƒ—ëÛç«G-•‘õ*†°¸3À‰<Íz­q>žÇ]èÆñˆ).ïÄ«z Øà_œ“k05yö-Þ°àü-ªªtÈÅÅ(©î X ·Do°Ò*!4láé¶JÞ|_}Û Xp!^æw:Á¯s:G½ò‰#q7e€ ¼TÕ_ …ÏP`u3*ÁZÊ+ßBÀ¤¿ÇæÕ›iA¢JÈ`)RÐÁX„ O½4ˆÂN¬ Þ£jŠþ‚œ ?ñpQ¯ß=p;MV„P˜ ¤]Àl‰ŽB¶ ¨6l"üëyþöÓH,t×·mï?\þ!X²>þvóA!Üv—mÅÑ‘äêU5Yðùã0A'>F ðj÷ׇ¯2¬:¸H–*a¡:°%±«0?ß‹jNþoT矑¼J*ƒ‹2å3¹¼ZÍÏSÚùCÏ8ÉM¹ÎnhÀ’È7_­ŽÃ±€Q E°ôÑU)äΨzö»{o `ÜE5`±r„:”ê\Jûán¬uCBˆPÞ1ÀÂN¿NÀZXàa ¾Ö[Õ¡oBÕ\`°þ3Ü ÑVm˜¥ÉOÕŒ¬H2Ã’aPIÒ@Á­ c%B ¬…ÀTµ|g-.0}|±€Î¹Q€¥Ý_ušï?Ù'ÉZyœÊüÊìÀ8:w¾½ž,xùoÂáÀP¯Îô©{Þpɰ$c’š›T x óùF£P¨jå¥(ç,P eJ Wòß<˜½@‰læ `ðìúÉ ^%•°ùÈÓ õ˜™Ò<é/j¥D°ôŽ/ôX ìGÙ Òýæ&åÆ,ÕM¹7* °Ë#Q¨†röq–Aìh|‹÷ypm *H£”§°Aך%“’i¤YE„1 ˜”VàÛõ ŸUbƒ§Fwµ4h<[’ú B3Ü ÂhÖFpÉÃO²l 1ì!÷W®”,ÿðøA²due?¤~Õž²qtŽÿÍKz<ûË­v+Á÷hçâyÀ«³ËÃɯ25º£Œä5I©$&I°‘D)/éU½~‹„¤gÆëµ\UV È—äXªæ%w’gÔs’jÕiYC6Uk€Â(÷g“¼ ÔÉnã°Ò+¬öiÃåƒcRÙa;“X¾²®P÷ólénL]O'Cm2 °”­)L×_dBO• Y©§A•LàÙ| ÷y̰¸€B1,?ðC˜å…î]sEa GèüéiiÕW—…‘/XXDLò‘Tµz¸S0^ñQF(T­‰ËzbX¬ÅÁ«0¥Z£Øxµ}{´’$ ÇdÝÙýs!)„ö­NgùoêvÑdÁWÔdÁw$ÅúK›buZ¯îf~•%`Õ¶4j2·Ôj·HJª X­¶Èõœ0SÕ1Í¢\ å h‘[jµ-Õª\‚IK®Ãþ*¨rG>Wm`>2i>•a!ÀZ÷WBì4žÖ4¼ ›nž,² ý%mT¸iTBº>3êUþÌ¥>¦ ‹¶qQîñ‘IkV ä>üƒým}ØÍ•Q‹Ê©9}›c…P™–X­õ²KYö0fL”?W)ÇBÙûé;¡g,_| c=W—l~gƒò1¡º.¡dS!sÄЦ6+Šà0¬kä®ïŠ"K@²Nô"Y1…& þäÅÆØ%ÉÕ•/uTzÜðйˆxuvxñ*K†Õ¨Â÷½Fÿ°ªóÕ®WçùyÞ‚4U¹Z‡MdX µ‡—x6%„“ªt¦ü©§~­Ë|ਯg9vN‘Y3U³É{ÀÚÛzÊS`'Ð%ì–7ŽJÒ×X¯(ÀR#*U®¡Üy›þ ¨ ª&#ªTz(âç«YZ¾•g †Ê_ãqñæ^蛡ɘó «tĻ•¦'±öÉ5·Õº¾¹ÏÐMn4`±û+Û½h§yéÉî$‹Â/›¸^Yp ÖÁ—ÞµOk¿îÝ5<1^½2Äx•`Õ·ä ’´ŒÂ2Î;òùB_’ÏÇRn©û©O:[Àò6PL(¼î1áÿj ©rÝÞAxèd–E^\4ƒXAþ$eN€IAå÷ì™: ø(Ú¹¨3ñ5)T;Aè «=•x‘µ3e$-SÏE ‘ñ!®žUFf dV£ªZmIt%IÖ›]IVø !F$;û(œõ7!0ê4_c<‚g¼"÷¢ ’`Iz_óºÉ|òñyó;o¶Ò6êiª7`¤{qkL/XáY"Ñ.¡îßSç͉ª–—4¶|}àÅèS;lèLÁ¼(ÛEP€e½(<û &NYòÕt/”w¸6CW ©N~dJ@·É…üåÎMy´+ךV¶¡€õ âÕö»®|éjÖû]HÖ¿Z ¡Ž,ˆ“¿÷cŒ£vÛwùÄØÁÇy„ó«¡Æ«,§æðÐ ”ÚÉD¼ò7°ð6V#Ôs í068Ù“½ô¼cùeõ•ЋS•´)€énLáã´Ë>9^=ÖÔÅÐÌå@¹§ðôDžøìÌäÚ ôÐ[/á((€©'f"!Àº î¯nôZ>$kÒ$+zÔúB(“©È‚»O¿ºÔj7!øÄãᯂp}v–‡Í}{¢d9ù™uÏ6ضÛyŒI¨MzÝSnfT6žoí‰e•1`Å.âo¤ Ñ=éb\vƒn&êf‹,L]ò·wAê-¦•-è•(qŸm»ëïÞmV8+]ÐO>Šó²rµ§»>eÉ:ø”eÉ’ á¶m·ÿ—å%Yð ÛCû2Ù¿yëø% çµç|kuØ%+Àr9‚žkÇ! Ç0rôÞP8LŽ"±s¬h½¾Ëä5Ù-â½³úÏÕò@le-òÈdzÌu—ƒH%‡Às0, uÌÎH|O{Û±2³R¨¨9½ÃFÅ ‚ÁßaÜ‘'Û`ìŽ|àÝ˸æë9 'Yûâù9NZFŽ£Ú™cjÂÑ{t®Ž‰Qï„ à8É׌”Íu×_¯¡§®pçWˆWÝÝõY$KS¦kû¶m»õŽo=o" ¶Ãž¤ˆÎ±¬à{tì/žJ÷¢ ’`MV`é'{öÇûr\÷N˜GfË™€f¤ ËÄót»Å¼ƒ@ª,U.9jê=]Â¥vŽü캓a¤©Dp©KKŽt´H>V?¡ûWáäÝXîN8ßÄ.“Rî²w¶`Å=«[5 tÁÈIéx”ð“r÷vÈ9p7%¿”N×'E`ÂÀB÷ ¯z…C1Y#ɺÔÈê´ÿíö[wŒŽZ‘cçP{;ŽN&èÀø=ç‡u:Ž-™1,SëX\7ûÉ:¦!YÈæª¨v*Ò1&ŸSäAQuç’kB&œ˜ ÈÏ ¨LœçµãÕ½:T½Ãñ4Øâ‹:Ú²¾$õ£Ü%¼ºU¨zŽÇG“îOŒÖ€~Ç'„[u*fеl‘Ù¦ôeE~q¶x™À¯©Fâ,x"!ßH2Üt©Šì]•ÈÂ_óê8‘r±õUë*»gè¯0–à[8Wç8X²:­ÿ±CÂÕ.3Y0/uZïÄÑ :cvíyí&àWY„º/NV `ÍMp÷«¸“ŧáyONÊ&279©ÂPÑ€¡ìÝbÑ{óÂÓ°æRËÕ€ußììì½÷> 8%—ƒÉÑ+«„R®ص‰ÓuW‚Z¬î¬TŽá„TÂì„C§ÞkkºŒ¾çƒ@O¥­J ?}Û$ÖÐV,«½}àHëÒSL²–/œ'´¢É‚©l ƒ¨Z†÷Nû݃ÆìþþðÛ¯@²¬byzº\4V(ýpå£,ã¥KëÜd˜MYêŸ\N–J““˜ª¯÷†NÀš}ࡇ˜=|äÈá{îå€*á•UR&Ò@ÄIÙì» ‡uBXØ;&¨F°Èò\¶ºa¥³˜c•ÐI¹Vظ^Úé¢i:½+ÂÀ­ÙweJÈæ,×n%P;ñ—^¼P ò š:EŸTøü~—p#“féd`²îÞAÀb¼z¶Ïð˜öò[ ì»w™È‚]ÈR»ù×GÇ ¾G¿qé7 °ÜÒHa$W*ÎÍ‹ÅIW/!6}±”+`åËEZ—jNþv›š4g»*–·áOîF™ìÝ˰fl•räÈ[ï“\k+À–¥®I%t\!„Ä X¢¨•Ц½ÄCÐ'Â;+i›Â”Kî"¤L˜‚Ö)Œ¹Àª¨Œ»uŰ-B×\°"·a‹SÝÎO,>Gƒå.ppR¨{XT3"T®m\Å3-#¢=—¶B¸¢gâýQ‰''E¢El±ž©åþªïž×^~ÿ?€ZxàÀ®];G÷X‘S¤sâè¼ÉˆáqvIÄ:øæo`MOMI0*–gÊ¥Éâ /¨ÊÓ#3%×:thªX™4­Ê3ÓÓ2ÕÓ“¥)@.80l&'ÿò°G(F–Ú\ X÷=°õȬ­GÙ:;{l+¬à ËáÆC8Ô1*ÐB-Ø’G%%|È4{Ú)›²é4°é >Š=!TzÙûå9|>ÎU'”ÇôºÃ{„«’¥cuMYD,‡Ó ê!ðÀeVŽkÝŠë(¸q·è8)Ÿl‹Ÿ‹u`¬AiUí:UÍpmµWU?®(< ð™á¬èLÍã£5W¨G£óT»æ±%•š«=“¯„Úæ»ºòGèþj xÕi_øþó€öûwܱÜêô´Da4ƒ°ý.„Çù3ô=z3˜°²¬2°§ÒÈH¾\*åò¹rijd '7R˜.U°ÊSÓããØ`9—)òq9sÞ-¥biz¤Tš.”äžÜÔ œÓë¡KÀúâC[g¥Z€õà‘­Çfï¥/†k¬À莭ÙEÀª(Àr°Kp“u„ƒíYa™—ºLÂ¥Wµ#°"on,ê:•;à-»mZ{ `É)5ÄTH¦&Lì–]f,„Ëŧ‡ ì2Ô«ò›MÝóåÉÈ—økž¡7ŽÂ+¾‹À)ãÚfÎ&4Ô™+ ……Lƒ*?/,AI) ë3þ²SA suå®íÛÖ€Wz² (uRö¿Ùã½Nû½ã!ŽN§ÓF÷í§~‚¾G‡~Ð(Hv6¬¸H–*aqzº0=+Måqe×G$`UJ¹U˜Çò^—­O®>v­¼ê¹²& ^ºc;Æ.Tc²zœqtþòòëè¾}©Ýi½“Ð~%CÀA¼*KÜ‘”ô™‘$kº\ÆõV¹Õ4H¾È€•W€•Àªá ,™MYÛ41,ZšÚ>:zÿÑ­IÙú¨„n寄Ö•Õ¹ R¡Ä$vDfXܨQÁÑ RIž\ÕÉó¦‡îT4# Û~4`)b0rŒZ©TL‡ˆ‰Ê›Š±ÓØ¢î ~eÖ XÆNE¨¡ŠK £ÊŒ÷ea€Bé\̰ԋIƒ,eâ–Ãv+z&ô,4`±R¨K—O–c^..2@~‚Êܶ+ªvÀ +s“;L Xí]u“›ÍGA•¤H`ý,Š£ó0ÝùÅåN‚ïÑ¡•¬kÀgªT0, QÓ33`£*ã:QÊàLa$?3=‚,L.Ù®5 PW.–Jåbi@«ññ‘R:hÀ:<{¾>xôØVÚ°õÈà «2Aû\¥Ð×8ëÍ­Œ%^êÈvC¬Uþæûhh )6˜Þá+»ÜË*°X%t*†a©“‰¢†5(õ1+Ó ›Æ(o}\~u«Ì.3,BhàPW+®ã +è3‡a¤x=A&ªc·"•ªƒêÐÑp/Ï…i^‚ÌÁçGY󵕑!‘@ÌG™ßš³t{X¿„FÖõÕÕ:ívÓž,x±Ý!§2þôÛÇû%YíKaàçÉCMëíãc_î#‚ا-YV±Tž¶åþ_³$ŸSÆï„øFK™µúу÷ž¹ÿ~Z³mHIƒ;‡;F O} ÿ²Gº[eËĆU™°StReâ˜Y» ‰ÕVR…%!vžˆãë›ýNÂ@àÔ‰¢)¦¾ÈlÑLl*1IÕÚ[:­¥Wž3“q<ûµ}·ÝvÛ]·šï<Ñ'Éê´Þ‡á¢»T¸‰Î²í{tˆ%+Àzº´%7’ÏH…¤EøG{X #]à;5žŸÛRzZ=ÛTÀ:ªg=órîµ§æXc¥Û¥ÕnÍØ¿>$2”z°ÑèNê†-‘¼×omWõ½u¯ÙH×’Fö‰x§ïL¢"Oö†XÉoŸZ¦=õ¬§ªÉ߉^½ Â6Û‘›4@Óïý%ÀÐe&Y߃du.þGø²xðÇÊnÕ¾$)Ö“ÃìÍ$;•†Pu WÂø‰“ÝìÐq$`Ý3Ш«DVú$ël ­œgºëƒÐuÕ_¯ò˜‰›°²íd.%L(ËZë§ŸûYO~Ñ}éÇC~D>%éXR|ÅŠ,¨Æ³“Bøym¾×Éê4_Ùc!þƒ}…¾Gßú¡ YN~ŽtsÓía¤öD|77´MM(Ï4Æ?Éî XWŽÍf$Ç®¬VnnÀâ±bð‘`#¼5¸›€µ‚3̺@L»µüÚ×™\=÷ª=žýÚ¾mVÂ6“¬'Þi¦NÐ!÷í»¾aÏÑi_:A¾G‡[²,|Øw’¦’?˜ælMÔrÍ,0˜"h.‹j4ÊŸƒË†vw.}ö¸®ZýøKe$_ú˜çNâ|í0XlÄŸ³JF3¸µÉ®—ÖA]úPN œAÀ$µgA}¯ºn4Ï~˺Ñõy£ÿ²è;8"/ aÚ—LØæðdÁ•Ç@!ü'«¢Ý|ç»Ç´ï\|¾¾ôþS8G‡w’ïÑa·b}V<Ž^ÿÅd$¿¸¾þÒlʦd'0äê< bعû…èdÁ•÷‚ów;vaË"YIù]<‹á&–›— ŽÎ{*Ê×å7ÁMÀÚ¬Mf±" î>ý]°³‡!ÂÛöýKø”æ{O1ÉŠ#Vç"…ǹØé´BqtÀ÷èÁùÐ†ì¢æ¬A‚`}ÇÂdªnLH”.±Rnº¼7²È¿ÁÖpdÁóâ:ºw¸ýÃhðÂöåï¤X²ÚËg¯0ŽÎqG}žx¸­XY†ùRÑÕ츕øôîÀ÷{…T¶CµGN§p£Ñ˜,[£{ô^6ð5Ss—ëþ§Bóy”;„Ëôź‚p‡)ÏcóßÏ‹[Z¤SuÚK&²à¹¥$¢¬þkì@»yé©$K…óÚóíìà·AåÎ||j¸'èdX\ïV,ÜEÝy¬ßÔ¨¹ ÉÐeÒ-Fò×é¼ €a ™ jÀqX>GÎÌ:²o2@`%ÕÉz„#|r ÕL~ú:>ëg@nÄ3î) °ðüÀ–ÈdÁåäO~×î…ðê' ‡Iñ+…WȪ¬8:ͧÀ¦5Ô+s†µ{ÑΒ̱°á,`XrÛ'c~Úy¾8jžp\V Ê½¸¸ ƒ£/,P…"RÈׄððV¸uû°¢Vr X‘³©B„…¯÷XøåPYøUâSÝ.tK»ñWWÃÏ‚J GŸ"^äž<õ¨©ŽBwÌ[;á–µ™›Â¾±XÐâ»·˜þÔ‘ª`BdÁ¨B˜âŽ&Á’Õ^:«Höû' nØ0#V†¡ê!–<Öɓܖ¸Ÿ¬Õð6NgÚµÅÅÒÔN€)M»`=pïáûA£»§æ^ÇÔßóýP[¦0è¡Xå~`”ÕÀ¤L)&ªh¾J„ª€§þcï××óýP^g´b}mÕ}ýž òÆ«Dr]§Ä‹¡PUW¤B¼Ô§‡G=+L=·_¢ŠzU„Ð)VSÖ£Q1ìC&/üòP¯? —öSÄ,V a<{x²`Z¯‹! ¬ƒÉ÷¢a¼"RqtPCî :Ù©„õÂx¡ŠHtò·ê'MÃX\øY½‘Ëç5d½˜.Wãw*@,/X¬Uóù\ÎÄ&V(¹Ù-¦>éŽ>‚“Ÿ>h&?±îA†å !då’Â’Ë$U‚ø î·— ‡®i'ÖÊ^©N_«ó Â#”图Pµ¨Ž¡Ë ;£(¡¼*•³ñ’IÇ{–uÈMÞ%®`Øhœ_™KúÂl,X7~ « æ&7±ómaê ää·‘Jøö# ŠÓ•Å¥ çkM—Yxɵ¹ÑB€eO|áµåVÿì n ! ‹²dQ¸ÕöÒ)Ä«PŽGçÑ*Úðø0OÐɰƟ™—€#YR½?'OÖ€Kù‹ µF®Z— …ÌK¦{¦Z; ¥ø>,åþÅz~~~~K½Ž<Ëðd™Wr!&Õ °À½Ì#ä^æÈ¬Ä«/æ^ Q:.y„Ú½>¨4x(P‡x¡ŒÔÉÌEª-®Ð(Êäð«Dð4u~£‹^‚Þêêߣ# öd9 CF¥}™bÚܵ+_­ª8:8ñ¹Ózk¸}f X’Uåªó…zK‚Lcüи, V'ýŸô‰ôë…gæÁ˜U­ÂR2¬Å(’x àV…ñq T’€U1—T› ¼›4`±Ow@¬YB«ÁV¨¡ ¥Œp PÆ#@ƒÆÇØD¨¥:Y ìSÊ’¤lOžÔrY%TÝ ]Bõu¦‚HAtÏ#ÈSg‰p0ªL°ý[¿]9XHMþÿöÞíGŽ+½´Q™YYIˆ«EŠZõŽCJ;+€yò ;‚ÊÌÂdæƒã‡i»·×½£A–ø²OcfÇ iv%´ùÌÛ¶èÙ<€X2j -Ô¶ ª®=络K\òIVRç#+2âĉçœ8ß/~ßç.#C_2,¬˜´,çtºèQ 4Á¯ÇXZ"èàrü¯ž•äê?]Ydƒ…=Y_ÿúÆÿ•ëP—¼Š×ÑÁ¹GÏïR«wQ2¤Êp ÃZ·2P ÔÆÉ`$)ÓèÂ}Ų$`U”k~  JÚ€#ÜÊ÷/hÀªHkQ‘4å»ÐÛT©>ç}ÔK Xf™¯·`™¯¹¾f+ac *DZk߸ڠJÃ+6¼(1¸Û~œ>ØWX—Ð/dp%ìc#•6DÌv e+ÒV—Ðßì8ªT=¦ Á,ëD—E˜Ø–ÉzãËVލ¢ÒÀ""ûYDdèRµE Xºj´ ž$Žo,°ðï‹­Çõ˜ñJUëÉþþ§ WgÓ„$Çÿ+¬«sûÿÌïÏuò×Ñ9£:çwîÑ}XÕš2åF=GƒÁ¨VS ëg±ª•Q|ÿŸH“0‘gïÃv8R6 l•oëþ°‚+¬ÈKÁ¿5T¦bUVN߬ˆúa½H ©Þº´{]×·±æôaiÿ Ú™D†‰~{'æ Ù‚œ8B{w´%©œÉÀÞDÀÉ &žaw_Ç_¬„1 ÍŒëE©9ݵŠbÌ~‡²î‰A©¡Ï Ù†Qn¹o " º¼ÚNK´c‰RÂDR—YUœöš‘;,¥b}+ä Ù–#§KUŽü8‹»®×V}&¯,¨äsè2ú«i¢JCï?<ûUµv¡š?9—cýõõÀ‚éÞo?<¯]J¬ûÃn¯×‘þ•äI}÷ua‡x‹¡&’Ú)×ÂO·;öTº÷Ó}žlýAÀºú¢ZªþEXªþ…kßšó+¡šÀûXE40HêFDžêÏ„4Ëtn‡®5”ˆÎ'°õuŒÈÎ?BF?ÑÝÆõÐ¥ˆ;LÚ_ìc¾3Yš±¾WÁx'ì‡¤ÓæŒÑ­ç,¬ï³X÷+òÙåC8â:  1åàrö­uq(H×iÌi‰Øª\DzÓDA=G9£P#ÊDßÔ¢5äËŒ[Õ%t–..`M+_ü!t ÛNÕòƒ_݀υwÞÏ›'ëôð]£#Ïœ||žç- °†kùR•b™­‹÷67s©PÏ®lCŠõý‡æ¨~£ªÓ¨âU×®Í9G2õt4JnÄ9žŸ¾• ³u•›ú›:ÞÞen/L·Ÿ|]×(n?Ò½ë“)QY2],‘ÈʲüÛ‡dÝ@ÀRï=ÝÁÝ0,-lЙ (³C*ÚÏ˱µ=;³ÒVJ™>íj¨dd€/Žó@»XЇÅWƬ®1øò8©ZÒ=ðcÛfwlÍÖÝÃ_— °6ê§c˜g`A¿Æ¯}ŽìˆJà9Z5lî#ç¡öó‡[=‰f¬/”Aøµ_Nõôø/aùÁÓ“Cü\xç½O8Þo  æ=¯tÊsº«žËèJçö%ÿô–Á(êËpu¾Ñ„f,!€‡3Æ­oö”ò÷ûŽ$4F-±U¶Úìå5TfX*EîªÒ!½Ëå–aYy lÒfå,ƒ? ó<³Æ[¦:´d5U‹‚‹bÆÎŽa¸¸ÕÐk¨Ãú¢Zî#%í[iG)Y›¨(CÐ$ì«IS«„S-¹ Ó!?û}5#ÃÉñÁÝ Y³$ëDMçwçÑñÙéÑ»Ð{ô1AÐl²¬ù°¨)ÅèVHŒgÇròhW»X"œrƒ¯Œ“8I'go¤šíÙg¯ÞÒrãÖ"ò*χelÇ—¢=-N@¶p±6^¬+r…¦—‰´¿'1Ž“ªå ÊÔAœ›4Íaj»03¦AY¶KÌó%™ &Ù+­¢ÅÙ"CEIî•ìÓÊøSÏ(/]ío˯ßÇ!ðt¦Õ60Ÿ™Ê $¼ú_~Žurð’¬÷3k¾~przžç}Zf=ýì“’ä³sùœ¼x1‚_§1 ¯þòçܪ%Éz IÖ£t×dVožž½g/Oq®Ä–,/+&dþzrÌÓ#À«;ax²ôœ{ô\Ð)s™/XG-¦²ÅËY ­ØÇj*w—€ùJ¯HPŒ-}N-ÄcÖÝÅ…x:i.f:&!­…2Ýê¾Á„ð`RÜÖš2ÝÙVc±V~.q½/{õ°ùjgâinc#OXéV§S¸Nkщ1Ù.(öT qO’étí‹(˜e4#§4²kýj’•ödÁt~ëït^è”Xð ¶¶^¶¬½„#n\¡9Ií)í¥v݇.áÍ@`]˜Ó°Þa]-¤zÃrº[ßgw»ßøäL-AjëAÑúÀ©eË1(saS*û’`ÖÅ/šž›™‰PÈi¥h“«Y´vc˜§ÖR:ÅÔÍT*{¿¦²«/»Uhß+H?® {]öúTÞS™ R×¹Æ\4sµN#8©Ì!N‡üì~ž>qrø×L²\È:¡utN`€ÎÇ“Ç=v)måç ³'Ÿ.ƒŠ|È] ’žŸæ£°—V `ÑÕ-+b¦Plg±Sê֠罪¿Îó•н_u2Í¿¸­æè[º%ëåä3PÄ?ùoó 3#ÖRõA1vÌ.ˆƒ™b¦rÃ9 Âsê™wî4¡yµ:f z+$Hýº•›¹íؽ,8Ï^ÏS©ÚÔ_Oÿðêßþ<§×•!YGîäXëèÃ$Y<×ûy’ÒK-ˆZ¯Kn…k@°jÍDë‘Àj¡f³±g™…[ÆÈë„D›tH½ÑÝG¯ÎÂ"­Ö“– ëj¦ãè\rãÛŠrÚ°óÎ3!l®jÓÅGpvÖqŽ IÅì*@¶[0×ÅcDg9ƒ ùåHÃPNÖŠ‹\X—ƒÖ}]{e1–å]Ø(”kkO£i_Lû…–›øq~÷„“Còd½ë,RÁëèH@;Ÿs–fJF¥pˆ ¾-`DÄ B0å~£ÝjµeÌÈÖÔb¢œr}mÕeªÙ¥ãëp/ÝR`N÷]54g÷ú.Œ"œ{hëáô+û¦éÏ8†meMé\Ê»6>a'm+—¥hÖ„ò)ò4wOÀÊ[P¸Âu`cJ>æWVPðáõÇs¯ÎRÛiJ2KµN–Ï‹—päÄY'+$ëôèm5øùàèÑù Sžk¯Ñ¬´ŠùÔ÷R½F£.ùQãžÚÃcXy¾¹V[«4UD Cµ·§Îž>R×6¶í‹Xu¸Z…ÕCººÍàI[ƒŸo\º.¹Ö¥oÍɰ”It„2YÜò޼À¦Ž‡n-4ç†ãR›t΢Æö›+Ì i?à[9ФSÊ,}AØÂ,çi§(:–Š‹TÄñùæ:ÀÔåoˆ—ú²@8eèü⫵ê·#ø2û 4 32¹yÍõt ÝBœ„g®ÖÓ£ƒÃ££ããÂ!ÐÓ„'?ǯ0Êá¯)’uû]Û“uÜêíCøbøþ¹£XåV£½Öª4Ë’Ííf³Þh·öN»©·mÅŠ$`µ¶›‚ññl½ÙÞÙi·á:u$å^c§W5vÔÕœRkm§±ÃzÑL/³«f¯Ð‡%$¡PÊb7? ›¤ö«³!7ùÔ)hûV»Eå GñTT2Tرo(H×ø&öÛŸR¯X ðR¹< ‹J6y¸'Œí'\œÈÖ9 à 4þBdOœ>תka•_]bø4¾#•„õ\DG8"ëI=S“fXlò¹Î+ÁeVˆy ÄÔìܪÖã?¿sç·ßùðÑAþdîÓvåå&ƺÍõšö¯Ù$‹ÖÑ9xøÚsϽ~îè”XÍÖfkM‘Ä¡ Û;µ5 :µµ¦dSUR©Êívmm»Q—€Ukµ·+­Ê…ív¥¢À©RÙnn¯Õ¶›íêZm§ºV•éTšÍvåB³Þl­5;Àß$+«szkµVsË4WwÆÑ›/Á~‹V' XÂB‡`¹§:;AN –šØ€º/h< è5LM00)ó,ôa È€V>ÊÌ¡Y°ˆÁšY˜ì §¼¢£Ã…&:²ÚÊD†Šq˜éä–:·œt’Ÿ·kã( M=P,ªÓÐ"X…yíæ•óKyÝ$ ˜¬Ù €Ø cŒãß4…€©´;[åfU¢|!§;#Q‡˜‘°Ê/È4xëdÄ@•+ …•BÃÒIÒ#`\^’ ï¡ÁxvžÙ:Ùn¦\ªþ]²<Àºp6ë²H‡_9"õœ§ªÖ³Ó“ã㣣ƒG½ûÖÜɰ­ÿñ7žyækÿuq¼zö§Ã«\’u÷>|C™†çË‹U`mWÚmiæa·½ÝÚÜ\Vµ¹©‘¢Oj þ'kÛMâal‰I5É®¢+pÕ žJC¥«B(=¯aÔRÖµ]XHõæÍW.½ ©`͵jNÇqÉtôNÀ¶¼Ÿáã•zëÓ –=Ú±aÜKº­s˜Å‰¬@°c\X7Zw„`ëËV}·" p«ì¯„H.¸¦ô úÁŠm oP-p@@ž±Ò u]‚¿j4ƒxúÃi:=;ÉxšU?ŽÅõll@< ¬‡®t''გI˜BÍÕÖƒš¥Z5ŠœJ¶õŽË¶þ‡ßýÝß}ãÝ¿÷%§ý­©ñêÌx²n¿Í}²pw>”›»ç‹b•ȰZÅ"1æ ïï´J’¦¥xª[Ã5µRýîuk©ú«óØ„·¬Ž£ù]Ìíý|Åw>„æ'W¨ãǤÜãÅôW¦ôß÷)ÄäL<þFLNÜî½.øe’Ÿ)C™§Ë®‰…à›ÛËaÎâ»0¢È–‚-ŶîÞa²¥€ëö×~Xô%§¯ìÏ…<@Þk ]’k0N$Û:8xø×ÿFñ+×·•ù’xzòïgÇ«3íÉÒ$ëôøon?·~û »{®è”64ç^£A=ªÆJCoœ^X…ÑݨÎQðJMØ=Ýçú(˜µjŽÝ»§ Ÿ´9Êÿ‘GÏŠÄ•Ü~ãA>-˜BëÒ=ÝË¢[6Ã2ÈT€ßÓJ¸NÂ3$™ûžétr^)Ù˜ÅÚ îÌSÜÜjÍI¶$hý³ß|æ7þ›ï(ßÖí̗ćÀ¶N‰_ýéì#IÖ»¸¦=’,i&n<÷ÜþL†œ«:e «8¦ãŸÕqçT0†[²]„u>2ѦÕÅ0¤ø0CÄÙ§¯ì¢|kwAyùSžz"‡.Q¦ÛbAîsøÓTsµØ•“.KViÆáÙÙ”–àLød«‘OO2½sÏMÅtsq¦ð™GÆiدù;_ùÊ3ÿÝÿ›ëÛb¶uðÔB÷ßûÛy8ÑéÑGoX$ 'ÇúÁú9ëÚPZ?,¬ù4`q˜½?ëq:-«ûLpöÙ·_.I¾ýÌö‚åÔëóçwÊã #1sÊWBúDÞ/+ÿ˜lÇ™P£ìúIËëÿ¼«a ã4 »Œþéb['àÛ:øèÝ?w¿$®ß^ÿúW¿ú?xp4å↎œ¾{Çx²`çn?d= lÊ•§eÆÑÏñw%É/&õrñâåñ výC»Ë(ù¶¶õu)ë¯ç÷’Ÿ,§G-O¬£óÜúùš{ôi¬³ÏK“']/^2òÅ/ÕÂßK-ôì°­·^[ÿ:¬îÌ_okêÛ(’Ež¬Ã“SXïK%vŽæ}jË‹—§X>Gƒ°pLÎéÉÑ£ýÕ¯~õë·5ÛÂ1‰³²-I²Ð“õÖÁñÉÑ·±nŸŠåË‹—s/9¡+§'‡ÿúÙßú­ÿöÏmÝÍö’Ÿ’mž¼‹Sû}pt¬–ÏQI¼un&Æò€åÅËy—/>S_Ç!<ýùôr^9½äÇΑI‹HÖÆ[G?„ëo?¸,Cÿ\}M<’{¯p|rðÍË'ÇóòÆ7?>øàuºX^5`ŋȂ—/"eà¥Éc/Lñ “1W;7MÚKʲ—$«Ÿã BäWÿra¼²‹Ø}I\Ζ; 3ÖÉÁ‡Ï=÷ᣇ—?üðò†Ú¿¼ñàÁåo>”{oo¼%ã®?÷áƒõ;GÇjRøw¿yùÁƒçî¬?øðòóåV'Jbü™A ýÒ.þD°ÁÀ8š5½ï(°LâûËÍ;T7Ý0Ö—'Qæ J¢(÷l6í²Ÿ€J¶(M'ÜjKÙøqö:7’Ó§('1eÔ(›p”‰Å!³kŬ’X¿þûq_g_nbÈÒý¶´oË ÖÇ'ˆXëëGLIÐ’0Åе~ðhýö‘¬õGÖ×ÞX¿½q÷ààùO7Ö<:XÄxu‹žP?Ù%ÝŸAU5`íËõ„kãò&'¥–,Cõ¥pÓ]ŽDITøžúîÕÚÁs«^ä\é<OŸ[¬¾ãåNí$ æ? 4ÌÆ±›ùÈ*N^ZQAHfl$Š¢¬Ï{ é S'cªÇ(šœØÕš’±_¯¦\~pèÒ¾-¶ ׿ƒp#éðDÖúúÆ–dX°Õ¬÷7îÜ^ -ƃwyã;¾½!üÖ¨K"•”ý>@•$[XûÓÀV[ °*¸‹žEg—ÃX–Xƒˆ–ùzÕ€¡bd4ß¼çÑþSçóuÚœb”Ä% kZ†aIEf¨É&-W…jˆu³ì"¥¯Ê˜®sƹÂÛ¸ Ynâ,ÛŒÒòk$J%i k’¬q!.çõì¿Z^©{ÀÊ=‡>ü!zÞ׿yd–m®¯ßù‰âT XÏ]~þ›¾¿þƒ·7þúèøãïl\þÎÁ¡ü“±À"( âäþ`8¼?=`íƒZ܇%jï¾J'–É ~fy…+v›å2 ‚رA™é¦lcrëœM:XÓÆž3ˉÅÞ´ag›þ>ÆXѤ¬DI¬+[ïEpmî›6õ"¬·Èy¤¶A ¯å ‰sÑý1Öƒðê{Ë^ÒFõŽïupf­ßyûcD¬‡7؇õgï?CðÎú°$;»»±¾qyý‡‡Ç\Þ8Væ‡ë‹õ˜wLBùT£ÊàþpT« g«èxXÛ¬UF£^e0¬u‡ƒJo0U«£µ ¥º°Ô—ô#a޾A{ø£‚&V,¤Îˆ~±\ÿEŒ7"&  ºÔ!ä´Ф1+VÐc…€°"Š€€…‰É (•…Á‹ î®t ó'ˆÇÄÚUG*^ßè¿0ç ~,¬}È*FŒ¦‚qb¬ˆ>`>£„j ¯—õõ!^¸`õRÅQ}P A-Ë„#ûPµ\u¨‰À¼‰%´‰4`ýªø !áÕ÷—ŒW§Ç¼qÐjãîûÜ'! X’k=üæÆ¹÷9Ý×NNnÜ}tðîúíGÏo€ÓýõË •XŠ FÝÚh8ª¾¹9L¦P‹áæ›oö*½nu8ÚÜ k½Ñ¨ÒíÖ†÷¿›(Cñq–&‚%a#•b“K€(ýÉ2gªöPñ©îH9HúQDè‰B჊"b†U ^"Î"L;eJ ÊÈ2dòœ C ›_+}¼@áï+ËW »”^eFp+,JDh²Ë%1Ý.R8Œç"ô™a UpŽˆpùX€XC%…ó!Ö2Õ5Ua$DÖ¼,£Zmùâ÷³È <=þ·È¯–ØùüÉøÜ×oß}h¹Ë._>:9°º5<pøŸžc}]wk¸,aéäÝçÿŒvùò£ÿ`ãò7?>ø°Ôn ƒ^U2¤Þæ•ZWÂN«?±’ÕƒSj1BÀê)ÀºÒÕº½ÊpÔ뎤yø˜œîE€Å¸%&ƒ•XÐPM[]bî°"`øÎ°ˆW1Ýc¦Õ'5%Ý ^Y ÓŽ¹,¥¨»!+¤×´¨pøcáB÷@¤™!´À4;fNwÜ—{Q‚OG aÍ Dn 1‰ P`_êH!fŒ(cN€ÙÆÌZ¹Zá©$Lù¨) pŠH,§Ûxõ‹¯u=ýù_> üj™xu|ðá]&Wï¹ëðœªî VÇQùCå°ÓcX(L«¸'Ëè8{ czo^éÖz°F÷¡û+™k(¡N™„Õ¡äZµn­Û­ ‡ ï/áÑfŸtŽI(R€¥ÄX£LBÔª˜ŒÂåfžPŒ¬Ê,d:¤q˜ Æd¿Äi':%½„·9ݤˆêÄö.òaÇA &fÈ«/³þ'Iz«Óc ê`éË)‘D³$aå/I4ôp‰˜šÉOŒï&¯|• ć³”&áÖ¯~ï+_ùJ®Axz xõ§ËÃ+ WwóÈÕ“°F£j·»)™Öæ•ÍÊp ÀªuGƒÁP–«Ú¦D¿‘ri ï÷µ%¹Üm†åüˆ`é€oLXŒìÊXšÀÒf  X}°a|XD7’8ˈeÚ‰ XLJÈr†(ÖA©˜Yú‡4(¡+.NŒ'i_‚/J–I?Aó-°ôµ%øØèXÀôÑ{FD¨E¶¶ã­´Ïâã@AÌVäò Âßü9‹øUÎt}%I†\ͰîÎã¬Êp ¼N=I°$l 6}M`Uzƒ$ô*HE&3º0])ÀBçÄ“,×*œÂ‡¾‘Dpó4¯ÚeežýeÚo•,í[1Fºh±”8¿p6rô”D±ÔL”±»D‡ÈJk$#22 +‰5Êir'öD*}¸µ®dš6ÃÒ¤*a/•;Á¯•Ú`Œ¹îÀ‡ïÚOˆáÚ€U±_L?¡%ôÇ5xõ÷Ê ü§Åxõ£å°žÓÓ“£ƒ÷™\½ñÁ9"W)ÀŒ.{½ŠÄ FÓùm@{”Z .Ž`. FáLe8º¨ðjé]„Ó€UÊWBt$¬ËË{”(ÄœƒØÆÂ@nIQ÷# ãÏYc*†¿jWÞtÑú¦¯„ü±0¢ìâ¯þ€‰<‚üŠp¥É¬ÈÅü‹ö§¯KI^-®ŠÀÑ| Ê1ßö‡‘K|lLBSzÙó61¹2O¤\±ëW¿Wð…ðôðGöôíeãÕÉá÷‰\½.ÉÕ,‹>^ÀJîÄHz¿3MŸÖ¨7•æO¥5xl€U’`?¬D÷r:k.'óx'}Ïľ?wyŒ¬} KÈç29mýý­”’POwÎOÌy‹8ç }Ü‹œ²`ÔØ*¤.ƒ.bê¯äʬxP©YR½ˆ]G§eQ^¬Ê«ªµŒTØýt™£òJ,ëû|F –ù éGº#))Rš õSƒxÜ´ÙÍÞOÊeÝ9Òþî”c!‘:n?Okä‹]ë |Üí”à%=nQcUÓÓ‹?Hì÷¹ÇZöÛƒ3˜±°ã»¾tbعª•å!/³ÿ+˜bt}ýõwÏ!¹J–bW½n¯‡?#ðaM÷LTûrFWSpÔ!`-ÍE(™a%z H²\ÀŠR€5~ì.¿ùqD ëàUÎàaͰ صŔ-ghNªP郜ÜåeÁ“ªu "æqQÁõ˜ÜF‰!¡2!0D-“s‚TÓ–çÃRaÞBÄ«ß.Ý<ïž«<ÀRiŒ 3|$Ä¡9ÎõVJߥ>ûËSüeŒ%Œ‰7DQù-3S{Ij_þH¹ôè`#‘½Xðd,Å.¥Ÿ»6 3#WŠ0({’¦]4L;2Ðbß%rÓ´«#ŠcB§éÄ)B˜_»yÃ79´À÷Wöˆ'”"ƒðñjöéE'á•E®^;·ä* XÚ#¡»O-8ø™"ËéD4iÕ¬2C–3–.Ç,u1»€Ó=¯Ø%Ü6gâª2 ƒÉº9[Y‰³_XDnGYoÒ¤*™.ZÎù$ïlBá%7NŽ•±à !áÕËžNæèࣻwÎ?¹rË‹/çBN ¾žüô§]g‘äêßhrõè<“+§°¾øì“O?ýD‹Þ·Â¦”ÏÎ÷óòÔKAHxU&¿’äêð#ýYð½ƒs±.Îx) °:RÂpOý[[[KöB8 §T$>Yñ7 i§×…õº¹¶.#:ÎÞ^ØÉ‘­NpöÙ«·²rãÖòêgg!äÿwx›– |60Öu&l\:PÖž*ÿKfÏâ´e||2Tóa8>ýéD¦¨d1-Ø9Ç•3&_“ʌϥ›fw •ˆu&à’çæË<ÁtZæ OÊÌÌåÌŠTÔ¥È5qúö?ú«ÐÉÑÃwîàÜíwþâü“+2KJ‡ðÊj+-ºe=û-ü­j”Ⱥ  Æ˜–SÐŽåUgŸÜzAËU%/Ì+·>93mÑE—Æ´` ÂÎDÄbÀB`v¢¥Ôʜɹ °}T`u° ÇAú\NgI=˜œËTýæÜ)@AÍÙ!V­ga*˜ðÄË­Öç¹_%^=[æô¢§'LJ½Ež«×Ôø›Ç9‹Iy€%q D?ù8÷ô±~:NÝnäSÁ–CÑdv²‚€•…©9pëÖ§gVnÃŽ†ÍÀzA›Ò¾äéwAŽr1 2iä¨@Ỿ +í’tÊÔ÷ëp^¾]óÝ7¾c «-'¼0_éܤZ”Tú6åT°Ò¤/þ§<ƒøÕ³åá•M®Þþøp%ÈHy€µ×h6{὆ó¨Ãzco ߈vêõ{ÊîiÈ0µ  ¯BèÒ€¥bÈôêÊŒ,,¸Ö‹»»»/¼pýšÂ©k׿‚+¬€r2# ¦ 2âV wÓ'‚ÓSߨOc1-Y&f!˜âŠ`Üñ¸j.KB,e>“2OOþêÊ›¾]‘«Ÿ¼ÅŽöw­ ¹) °ÂN£Ýjí4jH´¼ÞlÞÛÒFIJ…qê°5O ¡aËâî÷d wo‹ÍŽ0¬ç­ÉrU1¬-‰2{›:·eÕ2­¦ gÁê`²MÌÜC*òP>nê+™À¡Ë‹Wiç<Ý0•RV°H/)z°8%§»@Å9CÙ¹ à+g±1Æ?N‰à&]}ö•É© !3&«Nþª}¨9@Ø©òVæˆk'´ª:ÈM:'×¢³(Å áëúÖ–ú–qš÷…ðøÕŸþ?‹ƒËj“+Ò«Þ\CÀª­IžUi7›Úrw[íU$ëÚ®lÖš2N«½ÝÚÜlmo¯­mKNV]«­IÖÕhW$ë’L­ª®nÖ›­µf³¥®ªUÚ; à‚1€µûò¥Ý«/ì*ÀºùÒ¥Wvçs¹À Eè*HÀ¨L*ƒ>°š´ÖÞÁW4™"a¶ò¨,dd°éƒÐ¯zbT©˜{ëM\ŠbÎ&Xúî\‚puÂvª#…Ätk¤£#²æ ˜šãJ¢¤›šóúN6˜Aµ‰V ôcÃJ7L óò3¤g:ùXy ²×錫ùiEU¸‡€vξøïŸùÊW\ƒ–›XxzQ‹\I¸ZErR`ÕëM5Ers»U#žUmËŸ¦ä]- `¶Û­Ö&V³ÖRÿ6U,õ¿*KÆ’üKm›XiÖÃfK2¬Ö¤³-cך¹Î%òaY€õê¥Wn¾ˆð3—‹ûž6AÓŽºƒBÔ¸•ë7¹ }Ó-Þ05a'Ô  [ƒâU‚AÇ ÂŒ9 ýNï6ÆèŒm Æ‹ñé§,Rø³*ÿ…XOø!Wã-QÆŽF$þ Š%B]"ª¸@×£Æß 10 PQ)†ô^P\ ßúÁ…À¦³9ѱ¶ðªBÊH¨“æìñ t6 •ovk+€õ˯=óŒkžÿe9xutðÞŠ“+Ò¾JÀjIcX‘„‰Hmɰšœ$ 5%^Õ®(ÀÚi*o—+¬ZmSÁ\aok­µF'&áö6¤S“€uE^¿•×4$`ÕÏ>¹±ûŠ6 /½|éæîµ9èV €#{¤&‚#@@áv.‚ ã_V'€0‹ßP‚®ÙÀº‘,2[ˆ’0`±1Â@Züšw ´¶— 8Ý*›@0…ü@þ©pŠ,2ÃҀбXçÓ€¥Ù[¿´ÅZ ¬7€Xù¹ê´I¨sÂõ«ïGýt˜Ù‚„`…ûÊ‚PhŽFù/¡>õǤ³/þËïü¦cž•0}»"Wóàæ;ï<\QrR^·†¦r^Õ°ª h$aj¯µv$Cª(x"†`U[µZ;; U†,y²ÙÙ’&⎯öŽJGŸbgQ&a]Öõ[—^–réeeÞ¼ôÒK׿£Xàt—mtaoOàË€!À7sZf›è8€,„Ðaâ³%t+ÒÊcV`GWË;˜vóK«‚,ÑI#år&Ay§M¡|Rö´?›˜Th¸ .‚™*±5a£Õ²ÙvlÆK˜¢ª*¤Ô…,ódœƒ@3,DÆÝ.lÇ[Ð![ã‡|7¾@ÓèrêS÷ùõ¯þ‹ãÀ:†éEÿd1¼Räê6‘«V—\”ìÃ’&áx  ªµZkGüm)†ÔÞÆ8À¡väv§V«îеmökÁÕíf³ÙÞYÛätä¹5i&fÞg °ÂPš„×vo©¯„7o¾rIum¸47`}znð–E“0¤Ï|A‡z‡^Âü´ÄìtÀë³``¼ME_ ƒNÈŸýدc†”Õ ¹åkŒ#…»5°ha— ‰öa­åÒá}LÖW<ÂŒèˆÍ.U©sšK5Ø_[µsP=\³ø‰B¸ŸjûlaAІëÑuR\ _ð uKž‹Óz°eIÖ*ZçGóã•Z}ëÑÛz忇Ë^(zéR`5š’OÙr¥µˆä_Ývzn±l©AXŸÜxáÚõ])ׯᄄº^›Û$üô › vðë¡ãúäöûò¢Ø§³;s»9fOÓ ²{º[y+Ň•JNÖJn'òT^D©µlo)ý5±¸#šíî×dº¿É`PÔß5S¥Ð¡0(ФË2—„{¡jÃA°Nþ£§µVn¾s÷#µ¸à“ƒšr¤,Àº×¼XY©â$DxHdz _íHåbó^NGA,3–pþa„ XVc¥Îœ¹í10]= †´åKª õz£epÓ^ÜÛN’ͲÈ-á¤.šAêêÜ‘53"-vÉÜG¸éMu¤d«øé—#Xð•Ð^ÎkÎ9€\½ûšE®V­Îʬ½=Õu*WŠÂUgQü™æ2ê:ZðÐ-ÀÒx5çh Xv› ­nèÓ ®[ñͰ¢üôã˽Æ¢´5¡C>(¦‰¹è è³³0œœª‹zv¯°2Æ”nÑ<çu:ÎÞ©(Öã—añôíóâÕ‘&W·‘\= xUžËzêðÌ-5¥]HGú´µÍ´7VÁô2RÎ>}e·$yÅ,α=üzűãLRëykBã7€•ÃÎ?`•ŸçzÑdç°pÄ“‘“ÃïÏm*ruà«'3¥Iy=Ýõ˜9بÌ{n#SäBš!ÜÃf¢®ØãëöÒÓ‚`¬Ð¾>#òI×Õ|Xß~¹$ùöggŠžCÎöL™ŠþP¤2lYå‡ßzƼñqîõ[[ò½à§œïÂ9Šª°g«£“3÷æ{d¯¡:u…,að½:üüO/…!-¥Ýa&MU`âtÒ÷ËÜß>î`½ë:°ê¢Ní¦ÞÉ0χÓí1œºÜ9åÏ«Iq¨Mêñ¡‹ˆ]†=K¡h¹‰Ï3a±å¹º}÷}5Eû“†™òäi™qôó¿ûg%Éß}þ¤ËâåK/§È¯æXnÈÕ{¯Óú7’\ï)ÚgX°¼œ;9ùÛïÍ7}»E®6¹zJÜ좉 ¦@à.BacÖ\€«â˜Åؙ긋”«¥ÓUA"§YóS• ÖËó[>—U2?ÕJgR*\ªï™Y1º(mGñ_­Ø,ZÕT¾oclÖÃΞMcŽ]#qn*º½$Øf¬—åH¯$)=Ãm «¯o©¬YÏ„_´%ûÉœ¡Baùa,äWüÓüWYrõ´âU‰€u¸°"~´(ƒz*Ãáýäþ`0øV„ËÀÇØ$Lû—±ãÁ•|¬>bS\ú“/¼Cs^¼®æu¿víúµ+²Í±ˆÉa¤ Êidh)D¬8 cF•b+.)XÄÿTì2ԋ̧* ½ Ø&¡©ãÒVV'ÀŠ­dûj¿¯vQù‰aFQzÍwʘ› ›¯"*j­ß‚†ãEö%ƒUdjÇ@‹ ú®{gX긟›ÏýýˆZsŸ+Ú/°b¬SäWÿrêéEOON¹º½"+7/*¥V4¬mÖ*# I¨èw?Tz±†µîðgÃQe4°4n!}øŒ*ƒA¯2ØÇ¦Ä¤ýh\;Vz©?ßTƒŸoéÁÏsõs'†•!d‚m‚;C‰<Ä­Ž#`M`’p ÒüZüíŒoJ(ôu´Ï©Ú Í·Å»QiFoy(ð&‘ªîÅ KèRò»¦ÏLT漟hŽÚ‡çg”[埘U¤¨ÜÈy,›ºÔ7ÕÞO€GK@&ð% Ü'B(ÌKCžÄ‹)ifdóƒÇxJä•xµŠ-ZNBµžÿñ«)ïôäð#š9fãõ§›\”ǰF›o¾Ù­ŒîÇÅ´°Utê¾ÜŒj½a67GÃQU–<«"€HôRqcfhq<ìU‡Ã^mx“‘1ÈÔ,VL X×o^RŸÕô2/í¾téæKsŽ~¾ñ‰Ôqh÷1nq“­B¤ Hq”âÒÄx Á†ÎÒa:I:„8™8Òש?R¶X§G ¿sá\TX/èÊw,E)žb,FBÌ¹Æ `!óŒë•mYãxÇô6Ð"t!©r"ª;@`Á€ÃUQµãÓHøBƒXx Ì#=UyI¤!cüNÀW…ˆÜlf˾bàbñZL ´„“ÿøÛÓ/äêý/ ¹)¯[V<¨T«½Ñˆ¶•‘”JM‚Ô¾„´+£QOîcx¯Z­mnÖFÏdÜbhòŠ C,뢊EŒl?÷CjˆšqÔLàwã¥ù'ðSS$'‰ X¤åUí8ÀR*¥н u!XÂW4Q&xmG*èO Ê á×,d–ú ± ŒÈU 004 AÏ…!%d€Ïë„§ú>‹ FÄ2¯hTµ£ö÷c¢–@ƒ„Ím4ŲÄ( OgBõ U¥_ \^u¿ 7˜º®dÁ¯ |*šN©I8iźbÆG¬Ø,õt#¥Š9ÿã˜íÌuš …ŸüÕ ËMœ>ü2‘+òÖPM‘<†½îf·WéukÝnµ+! ö{þŒ!kò,„÷än÷Ê›] NÕ®‚¨Í7åi™B<ìÖ†òoTév!RuMX/_Ú}§H~eÁ)’™aQ»$vE&aL B3,z‡ jyDž fÌ Á"¡¼R°ÏolX¬¢ÃÂW<’ â\ün|•¾sŽ*(†Õ9=¤ZQY€e,füˆJ%¦vxú¿`ŒxÀ€…b?mFšx‘Ý&b p‰¦!ÑäŒ)+15ûÔO˜-"r Æ?¬D0+3ÿË,è÷"+âôäö·žýÞËMœžžÙÈHy k(™“2áF’6I$ÔÔj5 Lj_š„ʇ¥àJÂ†× –ÚÖ$`ÉßûÚ$Öj½Þæ•ÍêðÊþ‚“ÑËOn}KÖU,…X»¸`ý̈¥VÌ ‹#±X‰@+Ù€yû³$!g±¥Ã-ö´°ãE}jBÀBÅ’E–Ih{X˜œÅÀbP‘P³ UËXœP²h.ÃJE(c°À4Ù(<X¥ÍvÐAÅ[K¨ìυúù®°˜/ñ8bP}]›ôNÑ7`w”fSXŠ„ndˆS–-g1Õ’ ªõôçßÿíïO3TùD“«õ×Þ}ôå W å:Öï+^T#ÀRô¨'Öp$M¾$VdÀZÂ{R*ÃŒ\Êð.ì÷`Ó}8Ð’Ø4e¾ÅЉÄá-|#ƒdGæèÿ\zË+æÜýlx‡MBÁîaÕl§’6_ 1–~Üú«mTZ? Xg“Çþ!¹Zÿò‘+MÂÑH}ôõ”ç©'­¼Íîh¤– êõðœúåù«BôV…K³’Q¬ÛŨÃxÌwÂ(&ÀÊ,U?Ÿ×uµ aAZ"ýÙ^wBÂð8±âYW$úBìE”;´@%ÖCS F¦];Iê¦ܤFÞÀꛯ„ø] ³X^A–Mozf|"±ëª >’ˆËÌS?L9xt‘.'u8N?¾Jdî0¹1ÝþlqÄérÖÜ4ì<$v Ë+âÚãEy®?Òž«÷¾4ž+#¥Öð¢äT5õG²¹Ys¤Z­M%Õj&æÅaÌn÷ŒôÓÓ]uUF¯RsºÏ5å(VNWt¿Íœ“Qî%QBŸò[¸îéžsC·£OdßcŒºp—Ó˜Ò6—,Xgy?• b#‘3{qŸó?xEE÷qŽ©7^±÷ÛÕ2±£¼\EÙ gßíÈ›ó¼K"XfœìDÀ:9zøy®^ûã_ÿf>)°}VÛ™=ÞééÚ‡]ÙÄÁî¨ ¼„ò:” S³Cvk ^Ï}·íÛ= íÞí©½AX¥?‘£éî‰ÑD-qT ŽrÎ,ªc9óS9t4?;ÆägßJÈ-gjg ‘æO¢#ëi87ÉÍzTpìŒ%‹& ¾˜µ2¹%¬Ó“£ÃÞº£ÉÕ—Êse¤D÷-_Ô€Ÿ"éÃ3‡¡9)˜º:b`±zueNÑœ‚w´ißјױ l'ñucu9—$8º Ù[Yú¥V’C12ùÉÉ`?q-J Sˆ0ºf§ýâ å„fÞ$‘“n^þ¢œ'eSž|÷9ëu`*rEs9ÉH©óaaÍÇÍÖZSÂW£ñO°š÷BÉǶ·åŸD2¹mHë¯QmÖϪKV•iT$Ôµ«*•É€õò¥Ý«8ãèÍ—.½²;'^`íACï¤ñCh(X‚[¹†¡ßçÌ*@ÿX#-Ñ€vÒôŽÐ¼b"˜¦}·"žE€¥´œÀ«§;êu(,¾‚9šÈ „˜ Ø&¿V-¹€t4 ô,n'“*¬,+]E°˜¾rf(ýœ°ªDaqm.]ÎÎŽß}Çßxr•'¥V³Ymµª°]kUšÛ›­V­©«ÖTæ ™„››‘dìþ¯É-rªJµÚn·ªÛÍJ»Ñ„s{”Ê8 Ý)’_½ôÊ­ëóujÀ’jÊ?²>BiÓ…Äp÷3ÈœDÈPöÛØj„ZqÉß#¬8œy¤tŠÈx_ý Žßa ‘î ”ƒÙžû•°Ã÷G<\T§¶H³¤Õy–D‹hâ1Ì+!ˆò *J1;´q_§e_ò Œ¤®E,DD†Ën(–y‚2¨ÀÝJ¬ÂÜt;üÑi {{¢ÓÙÙÿ­ÖB]¿}÷}O®ò¥\†Õ¬Hœi"ÉßÍ+W6%Ô4vªÛ Éš°‚榌WoJœªÕ6i»Ó@g|«ÒnIæUÝ‘ìkS•¯í¥‚겕ÿ¬õ"7iŠä—v¯9]²f,lܪý*ʆD”PiÀl Œõ×±ÞÛÚíÌʈ®_aâpîÓ€h儃˜¢ X¡15ƒ10d]'üÆ€`)# €~!Óu›húúâ°X’ ÀÉBd¢lbª  T‚Šæ\¡ ûö¹¾°zº'’+¯¼t;X¡Žû„ëèîúúí·z´*’²«.™“bDÛX;U®V¸ÓŽ<׸-ÅÄê¡:'‰X«½[X,‰a•yZ¥×jWÔo«™íInI]Öõ[—^~—ùºùÒÍù—ÍA“Pi™4Ÿö°Uk_‘>F%#†’‘‚"8‡íPY“ •+“PhºA"è˜û‡¤h°˜‘…*¦îÌvJòÏ(À‚¼äÇL›ÐìµG,ëFhæ„$Ǥ%µ%ÇCjÓM0¨cÕ@ÙÖŸ†úÂWGˆ ÚÏê50éjŸa€ JLíа¸µ•/ôU·†“¿ãÉÕ8) °Û›W$w’€#ÙQkGâζ$G›k’[5Û;Š/)SOÚ‚òìv³±­À¬V«¶wZkkÊ[¥¨”"\j»£¶ŠaµÖj;;*•f£¨õÀ÷ÃR½å,¤º;_·¬º|ÙJ6ç~%$“,Ez#wÈq ,Ä#¤‚ßÜZ§Œf™†ªo<ù™l¿öÿhRp!h†¥ïV¨ `•ù•°ÃeS ˜µ°/ˆÜq†\:b2ý¡¾ãAZ¡XlNò÷QJÙ®£O V@ʬ‹•5Gªk…RÃUüsEÒ©ìÅ•‹ XEOÚÀό˙° í†[YH œ>Ûî™q#uL¨ X–:¹e'‘¯Y¹¡c¾Ÿ¦:Ž–ÑáÝ•5§s¿(̺5.2­r†åè‹ltºWSáúIlÓ!ã†0=ƒ)or£ˆ¯Š}Žš°Ù†cT%kWÞÌæoÙ™ ÊšS\´¼ñ‚Åç'pH>,˜1Å rn[xï'gÒózÒh°R`™q`ÖœXˆQõ0Üù4ܨ ž $ÓôÕx=ô†:Ý­­½zñO©ÔÏ>ûöËåÈ«ßþ u|‹3.ðÇ£ÄòÏ鯄n™ìxÔoæ/ ÇîŸÕÕ€q–Ž3û1jV¸P½ä§?ëùœúšêžÓÔ_Ñù²ùÙÂaO V@ž–G?ÿÅß•$¿øüI—Å‹/ò´ÖÙŸ—$_<é’xñâ¥HJ]5g^IwM—YÖwáU\¾Qš,X˜yÖJY¹´{}9äI£Á Hy€¥WX±V\S+üÅf'³˜g[»ÙE>ícŽ™³hŒËï• XÙû.Sb§öJXdÒŽJ]U]¥[¸Xµ—¹%J<`M!K,!ö*½X|†áP÷ùÌ|*€‹.°¸éu‡§X‡Ø‰[ßh?Ǻû¡àÊÏêX¯b½ Ø ©&sæq\ùì:È-ÓŒéå_´~—!“Rõ‚² À‚æn±¨ÄÝËû¤Rµ1Í+B"QªI8csžO!8F°òÒž ±ŽÑv›¥,E-þ>‘aQ– ˃œÇ ht§ÈÖR¢ëþ`0@z€•û†å¹ËÏÕ#ûœJ5+ƒ-4M¯¦r ó'Ó)ûâ€Åˆ•­®·\[x|ÊQ„€U¢=hê{ÀZŽÒçÝyvPwÁøl—n¿Û|ØË) °$ õ*£ÕìçꘄÃÚf­2Þwb¡VAî":=Uô\㘟îþÀRZéGþÂ.}ƒöðGM¬XHˆ°ÿ–è²Áåäe>ñ‚€0y¨¶ªbdU@‘¸1/­„‚‹u ^%v$SS;1 Øb ƒÙLy¶t?IÜüôÕYy/aŒ,žãŸ¤’Zi‰Ø ïcýƒ)ãy|FNÚ}üø¹qqDÌ:laµyØÑµœPí 9&åp -ÁË)°½j·:Hît?¨ŸŸÅáÜUl ŽAîËV4Ú|óÍ®D¬á`€T ~îÃù!ÈÔo<ìU‡òYB€l*”Þ¨ÖFö“þ†(Ä-ºÒQÆ–Ð`%@#Êož$àgŠA}@K+¬ ýÄàX„€¡fA„$Î —2¥ EBé“f/^–Ø€zh°ß‡ì9å‚< 7„¨Xƒ-àõ*÷Œ£ÎËršôk¬Ày, F1ë¢jÎ,¡GÁ5T ¡0p†‡T[">!ªËDxÀz2R`íz5I±F•ÞhtaÔ«V{ƒa­6Täž Å-ò*¬^â$úTkxVWå_…Ž*‡÷°¢Ÿ ñjN¯Vë ÷÷#ó¤Çã–˜ ViÀⶺd†•XŠ 5ª)EL4`áÉ1q&ÌTm×:kÆ'~²˜±†&!1Oý}¤#îJ#˜ rA@Í#¨[ãH3ÚÁ]S@é›$¥ ØOG·`–†OAw!Vš(Ou8oå>¦ëM]›8´Y! sª˜:aÀBš…`Bue¥•Pl‚°^côU Î ›¢±,¾)ÜL™Ö1p´¤d¸ò€5”gJÚ¬ÕÞT‡#¹/HAXmSV  \W±òau%­öj*–Œ×­ÕäÙ^U^S­ÁßjC6 ¥Á©Bz#•žÚ— +6nͰœ‘,ðI€•ð‹Ÿ àñ«%¨Äj‰ŠEJ¨­fJ?Z8òšý~QÚtD$ÌoÌ€¥ù3ÊÀú}«~B8ašñ$ˆ·HÔnTR ˜&^ejÆ,¬,º¨±Q XÂX?IìÚ#’ù"\Ìä³ æ%Õþq’öÕ•Ö¼Lò¾ŽžºòEƒov»Ò”¤–:ÙS K†$gêUT âáY\=• —òÜ~"K«™›žÚ¯`±Œ,×*œÂ‡…R°U`»t—ÓLm$b°= Ë@Ÿš„ŬûqÌì$ËœØ$D RG_,¿±öa@ÄÌ%Gv—Š<þİ.…0¹#ãÌE%+}flpÀÒJá žc‘ ®´t_¦gˆVä ä<%"Öß]0­„)›0/ˆìMÂÇ,¥Öð‚„•áèâpXQ^©Z­:\è)g“âOUɽ$hÕ*ʇ5¸ aKye¼Š4a;Tg{2vO1-ôX. "e VÉ«%ÓWéÉUd€êבò9€µðWB»y’”SZý±[~‰Šùk Y[J‰"þÊÆ ‹®$——õ©0ÊèNXF\W4&!ç¹Éc®bç["´1¨¿ÍŽD”}py‘«Ž]ÕN¦ôWÚ%´ X“¥<ÀR<¨fd³æÈ¦>ÆXNÜ¢¨:Þæf6Zeè<é²ëq‰XEÒO«4¿iû.Ï$,¨œdÇ¥Èç ?}ÌU*oýqŽÿÜŽ²9cMBú N½¸wŒbÝ ¡ŸÇç˜û-üÒš‡¬ÉRžI¨è”¤PŠ!á¶¿iévSgº9±Ó×:ǃt?¬§°àkŸ;TS+Nœd¿ ¦T l°),̃†¬¾¨>Æ+¬~nGô `%lXI!`¹Ú×:é[iþyXORÊsºSŸÏÇ&ƒd_2\`=¶±d9€¥U½H…ìsýqjÛ#¹çæY±c¹×”ñ2eNr (§öz¬IÊs&A€‰ÐÝß}ïvŠ ¢füY3¶ÊcèPõêåTn†N¯ï]×u®0Ì•ö-{{âú«ßþyüÊÑu:øðê¿á]ôC×쟺I+qû%ÃÜEÇ ìv_;ø<.6ÄlòCg§s~÷-Ÿz¿×áþØj\‰º ˆ¹+æ[£³¿Œï»ŒºÌ“.9Ù­(~¿f\žlêrCç³rþ÷R—!¤ñ¡ëŤb½›B k¼úè¹—¿Ìû<£7lõoõä?®Ón·3^ »Ö_´ïü ó_3Òý —önÖjµz½^®7›Mß÷ûûû‡††ÆÇÇí-¼"i]ø\­Vñ@|“ÉdÒé4>౑ÖgJûŃ Ûß߯œTÏÎÎjµ* ]oœáûB.ß'£xxxdxäSÏôŸaô]æßõÓúI¥ ZÆçr¹æYãôôd°½½½··‡½i-ìÄôô,ÆÌÌÌÀÀÀ/@z<ðàààðð°\.c2xW¡P+Å>çóy<<2òy³í0,i}}}cíýÑÑQ¹ZÀ[­~ØóâØøÒÒÒD©4;3ëž¿ñóøØq¡ìÚÚÞÚÝÝÝßí¾ÙlÖoµAQ µµµÕÕÕ“““Ð @]×®-=xðàË/¿Ä®€KK ÕÇ{É8>>ÞÜÜ|ùòå‹/ð"U^voiMLLLMMA6‚ÀÆÆÆÌŸ·ü£† ýüùóÇ?yö3˜Zµ^K¥RÐð{J›žš§ûòÑ#üsT%Øg8ÿ⑤®0&ˆ­­­×¯_ÿôÃ÷ *({­F+• „dZ³-²koïÈ÷Ãbqÿì§™}¹È¬û¡þíûÇýë_±ñYx¨  o\_ºÿþ­[·p}±XŒŸüyË?bõ,ìÕ«W¤.|n´[ (1ºT=Á5×®íesééÉɹ¹¹Ñ¬~øÏÇ1ÓÝq*?  @Eßcüí»wïÞÁ"ÂOA[tFX]C‡›òðÏVËPÈÌÎN'œ~üÐjxÄ#^‚͆ì=ãKÚ]`¥0ê`z-//¯­ˆœÄK!Ó u}’°µèß#€Šðw: „Æ^§3¬ àMëÀº¦§§wvvÀ@ÿñ3üíØgÒSZ$¾IwS‚çz œãã£ÃÃ}ì»to·Z)ï´Ú-õÃÀ œTë{»ûCGGÅâhüî@ß×ÛÃ8a;ða[oïîÀý¤aÚrïcûÅþ®T¼tjpxhbjÊáàààog~_:ÄX' }Z.‰MÄ2ˆÜj4±ÑÍÓ³Ó“ší—úׄöI«›–º¿ôìñçxßn‹c°\™ù:ð ]|¸,Jú 9üU€#BÜÜØ>:<¶žï]$µä]Ž‹gB(AË’0¦ð(]Ãóp8(~¯…: ;vÚWþÿâf|’ ü²a¶;€S1Æ!.l¶xº©Œl+ö4£ÒÌ^õ§^Á§—PQºÙ—xŠ^è’l€å/øOšç…Ž×öC0ºÐå7CÄ×É ˆëÝ»÷kkëï–Wm»hº*ž„@?¤^<Ê-¾Çeø§Dc‚ŠÊÚÚ 3ȺÏi9;Î)&Ø2×Ëe²™LŠ?Äa[( ñ_&•.äûúrÙL*ÊÂqþµ“¡.g.aðñ}Ë÷s¹,¶’–m©T‚ ðÙÞŽØ$?5œþž£C]7º¤h®È׃’Ë ½°=ã94-ÃiûÍm|2ƒé»yó¦çf¦¦Šå\ó^èú~«-ÙÙUJ±JÀ®üÓ ]eŸbìáÊV‹ŽJç_Õøõ#—Ëx°5°f]/,CaŒΠ4ÏqAWKKK 333}}}ÿ` ÿ÷ÔNxèþµ‡ì‚fÈT&üUé$žfEAÚÄ FšA¾—Á\ÆÇ““úñq›ƒõÍnbr,ñ|ãElé0©ñ$Z¾—Ÿi€ááx®lê~¦®„H Ûôõ×_÷÷÷߸y],Þý}6pÀL[i/êº}û6ÈorrrhhèSÏúw0.IFwzÆ»D…„BWô¼+é”W¢µû~ˉëD€÷z—NgšA ‚ÔU¯Ö¸ÚÅà`:›î$övÒC1ëÚxžP¬h&òüT´9 yW(dKÿ0Ÿv³õa€¿[ë ¢ðî¬âà—æ‡ó¯÷dÊì’ý?Šqt-T¿’G$÷ÛT-\¿¾•objòÖÎM¨õúv Ì‹Z"”F «ÌNMÏ*Ðþ> 7ß;WPîFp ÊMIyEè·¯ÛM¸‡G>ño^pg³YØB™L†J¹í´]huâFwD‚A¦ÁèÚÛÛ{ùò%v±¿¿¯0u™çÓo¡~i’"²Ä+ØtH£‘±Nވ祽T¢ìʾ†¢åzýj©ùÁTI‹TäÏE„”€mâC÷øÒ"9Ñ:÷}È£9­crr?=>H‡0þ)Y†ýýbrëƒ._ÎÕ—`´»ºì’â£+Ràe‘xQ’8:f¤Þ)„%ú•kÓFç1L/â’‰RÞÖ[vQ £èPß]DQ*|:òÔ<3lÂZÇ•#o˘››.–F†ûÁí¥WÐTµpTÍ^D7êb·ˆþyž”ñ/ââ?©V›-߉M|MN®½R©›€¤‡‡‡ Änz>?÷ƒ¤žØBð <5ð:®ú[âQü›¨ZH¤›E¼ÖU´ òãÒøx¥Z™œœÆ•P!Ê ¡LVɬ{{¢¬ç«þ¸^‡dæáñ½>u"ýë’—SÔE*ùSŒäüªZ­Ñ;­jt.Ñ€‹5b½6ýhò=ët³W éËGG§ Ñ{AZX^-yE¦˜!¢µ]Gf˜ò2L»c‚k&—Ä^ç }œ[÷dÌ»z¦%Ù—¥{‹¢ƒæPÂ9.Øëœ+Cv™©l5¯Ýnì¿}ûvb²41QSuÆF.Í«¢™¦â9‘lX¯!8’ºpxGßßk"@Ä| °;<8@±Óûûû»»»øpppP>®Ö«0 †1¨šÔ~µÐ”€yµZÔE¢‚5R,ô0ú'''øž˜×òIÉÖ k L´±½½ýþý{|Bc>xvš¯£OjÞ899 72ù ÙÙÙÙÕ¡ù+'¢Qû>`˜Ó1>Qĺ€r=%†ã%"]Ðᄽµµ5€ëeî(³Ïúräg¡?ŸÍˆë?%SHcƒqËèðHB?´¸ý“ÊÆ0–~ø¯¬Jttkk ?Ø?@ K¯ÐnoùMeÙò¨l:òùÂÀ@_Ax.€¥¤Û `ªÚåYR!©á'¨½û½ã]€;tFoá÷F39ßý"T1ãºÄ(“–Ùàö­í§O.•Æ€š2ãRɲg<À5–˜‘^a”K, ÃÿRé”0)#ݬ.ZgèhRÖþ¼{÷û½¾¾¾¹#ÉV@è3`T£÷b>}ý!õ°“tuò›AÕ°–b§‘Ì|aaáîÝ»‹‹‹€>ø~›0¦k·'‡ã÷ (ì÷›7o–——_½z¤ìb0ÝØºx6¯XÐqçÎÁõ±1ÌleeÖì“'O666`±Š¿U-RÜ!píúÈïËG_àucšŒÖMÞP1‡Ÿ~zòÃ?¬¬Húhó¬Å¬N<ÔŒŸŸŸ½wïÞÝû÷p=݆ N—!µnGÔKP>è ÄLÚ­—#t\€”EF 0,yLGi¢ˆ Ô+F+2H„ž´_³wÖÆóJ6?ÞþóÏO™N‰)—ȧg"Á@]š#Ñ2Zk&%ü=¯œ4Û' "KˆjzzffæöíÛ` wïÞOÐyâCO¥¦£ÚsÅ®ƒ¡â/sgUÔ¤(ÄŒÎvΪsƒ(H+1Þ„@²@8ñüùóùùyÌàÆ†Ò8­ä•Ii`Ë‘wµêÆ1Óí½¯±ßîé™q,Å7ïkZÖ«/!9ß¼y…MÝÙÛåÖ¶lCy„*¥ùŒò0É8qC˜õ!ý,À[|ÔV* #Ãc€õúÚæ×ß|ùÅ_ôõåTm° 첨+ˆ TñâÅ‹üø ĞѺ£ ñEFbØi°L¼ ¹­¿~ýúüã³gÏÀ’ÏΚ„¾bîJ¯¬ ueÓ€e J—”u)-ØS þãÇÿò—¿¬n¬žÕ )µÁ㸹-žûROglÕè"ÑtãÀT±ÑXàë—¯°À¶/p.ŽÑÊÀA~X5eu߀Ýáž²xl¹ZÂ#`Ä·nÜÄ’ggg™VšKçkÇù¤ ^•÷++€óßþú+$ñR@X<ŽêU#kQBè¾;T¦ðS&+v>z]@Z€ <œŽœ¢[v]4:²«[ߥ+Ê¡me¤wb÷ƒý2çøøÏ¤_@t`‘ß}÷$¾± Bºšb‡¹Œª ahatjñÃ%y€rwïÝÛ·Ïž<ýé§Ÿß½í-lg¹Z .¨ÜöÏ@d .Y)ÀëÄ„'§l `Vx&þSçÁþŠHWpGfT垦6Î÷ßÂÀLI¤JbÃNø2±DÕNO™hË*UÐ^ x«üX븅Ñ@v‰¦ ÝÖ“ ]pCh† ‘‘!H³XƒíØ{{˜ÃÓ§O±#›ÛÛ­v#=7•ãTÓâVÁ–áÈ ÈÌÙù¹+z WWWÁAþüç?c¥o^½ÆüA]Øî|&KÜmë BäÉö cÍõ‰_ZÃ.¢Æª–‹Éà Xæƒ@c@qÐØ%F{P^½~ýóÏ??þî{‘ZÊÂÚ`Ê‘&Ä鬨Åú #y(I­g‘ùïíïøÃrǯׯ_X>*šÒC3$’•ÆROþŒˆ®†-'ŠàKS¹‘“ I˜ªŸÖ·ww°©×®]ƒ6?26:=ùÂéÆŽAc¾GÆ^ü«Ì! ›éÉ'ðw{s ¼óç|þôÙÊò;0žÚI "ËaÔËÓ÷ÊsœŽC¿ª¸TJ‹¤|ÊÓ˜'U¸S*~B^,¨µž–c§.á^Ø!è¥@hP;„hû¤ðñ wØJ [  °œF#PwaS÷övÄzß—«æ CŽë·[ -à$äÍ›7oݺ‰AXá*Jï­­­Í<ÏÇš™Càmµ[xðs¦œÁs.é’B|bu9nÔa@3S,’¡îW (GÏ¥1貂Im°@ýOŽ«®;¬ ‹CÁŠL<=<™¡¯^+I”{üý/d¼…CéÆí‘F¤”F‘-Ú2þpUIWðŸJ¾'™w­F³Åâ9P[! Ðð4ÈÒK¶;ñMÍÐQ ›þ+0BìŠ\H‰ÇÙ7ªõâjj…K‘kR@.“ýÛßþ;`(ôSÜã™4è8“‹Œ§ìr,O/ `ñvÐi[|AŒ§ïÞW·;’ œÖë¹| 4|ûöM¨U6ˆð`p,æu&C%£¶]¸¼“pH*œÛÔ9µLF¨ý¢¸¦AóÎ| ¯;Aœ6­Þ¿”—â^´Ô)ɼênð³ø½Êb@¾[yÿìÙ3ØÕ,À#äÍÖx}T2m U&ŸÃ?Ä·ÔhœœÔbËÐaÚ„¸b,Â4€ÐTYéìÁß»wïv3Vñd¼ºbµ5UƒVKä'•Ò1XÈIs¥éé±âž–ɤ`ኟsÿ˜ ]”Úxìt% !è-/br…$dZ ñ£©Ë±$='@5ö 2—Ce¨oâ ºøN‰J¬æ)}¹$hçµÕ÷+? G%|´°0×j Ò4dÖ-ñ&„êÍÂL6„¾¦7 ÿëÀñ5÷/¹6ãk¡bS?;m¶ÅŒ4ï ÞâH´*Q²ß)KC °Úgff ©b>š9RÝ WkµÀ{{;Õã²Ä—[‚ܸ7,nâûç/ŸMLC[uAaHäjà/ëÁÎÿ1øm£)ãlü†¡!i€54,¸šMhY¸‘n€°“}àr/L>!%Ú¬|æ‰ –'$Ø<=þâ)MçÒj³Q/€aÐHd f^óz£«›|+3ÀqÀ56ÖÖ±´•ÕwP}_>›Tëˆq¥á/Ç…Ž•Qfä…›œ´3¹,6\zŸµ°Bê®)”ŠÒhO,D ²ÄºX8ƒ]‹E¨LZÜ{{++靖,5Ûƒ+%–vüßþíÛûwïÍÌN©µÒå¶¹½õüùs˜ø €‹>Õ–½îÓ€~*•ç½víÚÜÜ«r~u™¨ŠÅ6Ò´íÙ3L—¹¸Óç€è4Ì8V!¢uYj­˜(èÓx YK1$ý'8tC¿‹wv; º¼aÌ·|(H)UÕaõR¾,«jBlíÈØ0€uïÞ½‡⃄³†† 8Œ¦úÇOj5@¨ þbeäCªDÄFnll@×½w÷öÍ›KݬÔäá/Ýî ãÄQrþ„×°‹³ÓRý[À’WWWñ–.Æëu±iJ3›xÀftàQ ïV(¶GšÁq\–ÙɉjЕáÄú9]g–g©#. Õ!aE?ýù‰x $À½½µ+æ–Þ-^úD4›„¸ží.§fgnܸ€Ãö·‚ð‡´é;aqÊ»ž©ÖÕá™ ¼Óy8&¥Ž¹>¸—®J¥|Ö¨LëÛÊæ#‘ Ä644póæ¯¿þúÛ¯¿™šžÈç£ZìÑöîÎüüüËùÀÐ5Î$­yhxè4¶¸¸øàÁH>6öù…ÔeöC}²ÅùùÅRé•FWÎ,¯>¸í6wÂ!¿Ô0±ÄéYTbö[õ­ÂùAÃoÕVÌ{H=&/™|ïÁð°ÿ÷ŸžžÕ$#‰H‡LÐIÛ]µ¢l åÇÔ}cæª×Ç7iö$9+Ü…2­,^lÈ ›‡]küïÿþï;w'Ç'x“6ä² crÕ§æXÕ«„ËŠ=ಀªA3j| :¼kp`(“Φ½ Àc ÛlŽbAç#™\ö‹^Pè `ö'U (5f3öG^ìö=|õÍ×ÿùŸÿyýúuLlht¤P诖˘ Vê+7y¨–žÐ•'AÓH…f78Ì ¼ ´?3NÍõ”,X ‘Rw€XÊžüZ=®à-Ð$%+EC‚|ȨÀrõö훸ú‹`5äšâjçzz,¯D]=ox%Ä÷ÁþQ»4š ¬Û‡ä`Ù9Å4¡ˆN\ Ñ188\¯CÊ9Йº¡O·M·ý¦4äð!(à X­‘ÓÓ3;ñ_.›•eˆˆ¾’EC©¥‰ˆ=—ÇoŠã%;À9Sbhg«cíç\£¾°BD•¯-,  º CÎ › iþ|ugK"‰äÐÇ´ÇŽºôuPÒêÈ„qL;Å#œQ§éåNíK¿‘ˆ@__ì|᫯¾b墙®Ç„!C-ß>©T›­f¡¯ äêFi1Òå0ò3éÜÈØóôØXÉ>ZNH‡”œÏŠ% Å(åx¾DêT±P÷|ĔӸ&­Ô”ŠÉO! õiùÍëÍõ5x•È^Æõð9z›¨ÂÈfæfï?|ððË/ðxH›ÝT@uƒ£#bs¶Ú'ÕúIYV‚Öm)Œÿ{Ê£Þ!‰KŽX@ªr¹"j[GÇÖõCRá}Žª Ùß°†ÚÚ‘ æ4šg•Ê1Xÿ‹gϮٹiUF ’œ=19.Œ Êþ+ÓÝ*Ñ̾¼-©.ʺœØ.ì«54s÷î]IP8Ûº]´ Þ.ˆÀ\!ôÁT€R€ @¥Y:VÛïèùÒ¿~ýºZ­â!êmÓ¢Už5)Êh›ÙÆ^ÏÙrÃ: Ä4ðÛ «G¨ë´N ìÒdÜ’Ä©Q9$—RzÈEN9ì·XêïßCh///³ùvJ“9¤[O**¡]ŠÁ,oú†ÌÒ Šhr5éÙ—ôv}ˆ†6Ý š;¢š ›œžúÃþP?©ïîln—!UÕ6ò2ž¨R~ t奲žôtÊÑÍ{É~3/Q RUðª×‡çŸtj+%f‚/Ú÷Öt@Cß¡wNb¯£ÀÂqÌ€óÃC3ós÷=üæ›o"qjU ^s‹ Œ˜îB2Ô€˜H0ñ˶5V®Í]œ(Ê!p°ÂÓŒ[œ‰ÂôoŒkŽü”Mµâ?„”®V*ØPl7^)4>Q”ÌìÑ1©š €¢+•.:ñ'Ç}o»lý—P ñAŒm]]YÓ’Äçf›¤eüÜN,8/™ÊÉÊÈã ›emI…Ôåx!L#¬„ÉÂSr‡«„äy®!㸎´0A˜î•o½&æ{l[WÑgf³â†žP©–µÁNj/É ›ZQ‰Äfʬ‰'ª{ J·¡‹ãýýƒÝÓpb·2½¯ÆU`Ò2Ôâò$\6::7; ½¿4V4f8ð™A2_+µ“  ò]"¿ 1úYiÁ{q†M ž¨ÂÚL‰:$§aG©´K¦®ÈJµ ô€mµˆnLÀ³|x õ)ôÃŒ’_ZýøI¤óÃMåÒ9ñòI.ììÈhq`pتîÔù8Á„°ž›]X-½ÜÚÝ2¯±È°C…*s&Žu0Ç’Ï£_­¯¿€ÿò…>± 9´ÚJõ]ê`µôïC½ÄºFdžñ8¨ :Xm¡7±5i¦_,ÎÎÏ]’åxEñBê¢(XXX,.¾ƒ>²r˜àдËUÓ“üK|ƒ `–Ö—÷&Z…u2g72GraŸ<-ÓtÝÈ€ö$•vŸÃ Šÿ#ñ½z,ÔÄwhÁ»{ÒÿíòkÀúððàððH=fÕy,JþîÎ>¬6a *»D?ŒƒþþŒO1]Ò‘˜ƒùkxñdØIO®Æ7Ç ”,s¢SÁ:ܨ¯Æ^JãÇVñ"ïi-ô‹|ó烱)xŽbÝ8é,¶‘¤°Ív´HÊòÈÈÔÔ9ºØ)¦eI͏vŠI(áyeIÆf6ŸRËÏ¡œé5…¹ƒk¨õཇå#yŠc´YZQB }°€Þ>==©Ì {ÂóµÔzrggOP.]˜Û¡ HüÜo-±"q3îïhM@žÕâDͤ¸LAtZhm÷ïAQÇîà¸Ìž·kí£©Ë‰c¸’•ƒé$RHüfVj#wd„¬é¤ LBܱ:Ð4Q3¤hRWCý§X5‘pÓÂ…’oÍAxœ«†}gt¯Ð¦+d4Êó•°q@ØÇØ£Ÿ0~þ2 ߀«i…+ɬާÙebªA]eTµ:5¸âÚ2è#…Â@©$ O@̦mczE®«°€‚ F p£«·‡âQ,¥¥éÙÙÑâŒÓ†º—ÅC/” °¤0%Ú•ú%ßJÊ¢1S{b$3ŒÉF@Œ¹wJ®lfhdï´×(†Ó3˜¢J¬L ó$âÄU­näpî •ÆÔéÆ+ oÈÿ „ Aü@b,>lR±Á…H4—R…‘išØSž²˜Ú‘™‘ééÙ¥¥¥wïÞmoïֵˉ-B[ý‚ f}Ön:š]¶ð„§SSÕ”¶í;{û2Ìxl¿É°¹§MoM]ìóÎx(ÓX™äfê¾È©ÐRfÌ@*—]²8lZUŽE{¦êéŽÒ;"Ž¨Ê¤fØÂÊFSË!t˜}\¤ˆ a£êåtr°­ï?<~þü¹$LùMͤrå Õï­ô,X ¦"m½e«ãÄâУwš‘Ùn#ÇÌŠnƒÜa¯ü J’žÆR´@ Ę̈ªEÄ)æ¼§á‘¶j‡Ìø†Ñý±5c Jô©(UU;{’,¦ óÂ8œÅ¹I5¡BÌžŒùÀ ôÉ)ƒÁ"Ò[søäsœpbEçöNͶ”b´:3RÛEÁå ŽIˆ(ÔæpÀClk³Ù6ÅŠ`¯*ÓdÇß–îq aÆ„b†˜±H.ÊPÑ”«šÓIdñ5@’‡ÖqùÍ›7wîÜ=|ïÞ=H3H°ÙÙ™n:ºÄ—x!uAÐà~ú¯Ágz)HØK£Ã`yº^±8Š9C|i.ö¦ˆÙCPH³×h‘ž'ª3 ©¸æ¼Åaa‡cБ².i_iŠ‹|¾À;{1¶ªcimmmEÈ liXª‚ú؃7o^AËÕ_wyDhB§©Õ-)á^YF!„àõuQž‡+žBÍLã.ø¯tœ m9*Œ ¯£ý`(Æ3Ud ê PZ·+-pMÌDD–;>È"%mM”UC©ÒgC“¶ß1ÇÃȆ% ÚT__¾Ñ8 Ô¡ä .†&ÞÅh„&ˆDç)[!û\_¶O²=`kµÚÌ`ÏfNÖÓ‚7ˆ´t\K_0å|ç>ZhΦ@‡R:™‘…„íN_8?Y–ÎüC+#IÞŽýÅŠ>|X©D­J :Áîb?$¥fµ9öø)-¹r=ª`®¦0 (E'¤Þ%vlýì”ÅàL¡C)ÝB˜%ÂWÎÅî ©‹uúÓŸ^ëƒ7Õ.Å£P^¨à˜ú°=z$Ê•Ö"‚P™×s>)›ä‚Ñ;‚Õtÿûí@ƒÈq5·Ø̃ZMÏ 3ß SÅ´ß¾} Ã7ämš’bÊ3ˆJÌòÃCUÛ|Åof¢¥D1â·^;ÍD.ÇŠ þÕÇåªòKX'ƒƒý XSÔ³mFìðtX’ÐΤpbÕºç¢1ÖkÄ©n¡æN:†·{YœAË2mLv3T~–¸j©©Âv&Ž¥TÇÆ¸ÄP9Ö¶Ç\;özlx„¦&8W£]s"ýSöîá¹´ØÒ³XF·ö+œJxo•À' H#ê1:Æ šžšVë=¤Õ4ØÚØÔ4+ ¦½Œ¬»@Æ×¦/Qh$cG0Ï Ï©!!8pxss´•LÛ}vVzGñ<ò=¯ü«ÍM éãÇñ\:ãø} õ‚^\8]1%}ÇUvóQ7o.iµl>::ÐFóuE2z&€ ¡§†VŽŽÔLšá%@©VF~<”GÈ‚’ÊÝsµ0¦þïÿþÓÆœ¥È_Ý} FÎMóõµ’H3ªò¾ôyÎ1¯˜—ŒALĹh¤EcÁN*tŒð‰pövXÐ)%9(¡d |;2½ '¸¹$3É´Ôa£‹áî\æIí´zR?mHèB;ZÅ].|â„$J3®Êæo i£gRÁBº°s}¹È˜’}cÿU)zؤP¥Ù²¡Lß*=«ÕÁˆðVì˜Ó¦ŠBÛæ10hå¦ÝUÎ0ÁeE! !DE}9å^-eO¬Ûµ0÷õ<¼½ùùÅ\&Ïò ¨Z/Ÿ¿ƒÀƒ1Ͼœœ´8! C×[§€ÛgqÌ3rhGS: á2¦ÐØÃïÐÐéKt.Yê2&Ííx|+Ðtyy™F¿»ãê#Z;Žq‹= °‡ÛšÒüïÿþ/ D @5¨øJf°Ø3xoÛðNö-ëä(Æðd[v±Åo‚{º(iÿüç?3«ÔÅÇòh?}‰”ă Ikn¤«Ym°.ÅöƒýC˜Ûêê{ùH¹Ôqµ"fFà0]=6¥¤DÌ $ Õœ§–öobÃÄÓÏAÛ7Ë¥P%DŒ ^SbÏŽŽÄM‡a2Ò!iû-ˆX­=še^‹t1ÙÚbO›…k‹ö:MÓ±Ä*]WÉ›L1#$IÔˆ¢ Kë ÜXùP/ñùTÓµÈLÌÃñ# áù5‰dÈî¡Éò'M­Í1©„±Ê|ìK”k28×± 9eÆØ>ñ¦ ...Þ¸¾¤àjÉõýCR˜’:Ö×7A~žä¬´ô6Q¯(ƒO–‰ëñ=èêÆëX~Ïr˜$uÙÐ7Æ-7ùüÆ:´„{¨$éTÝA^lƒ–PÜ“Æ(­ÖÿøGÃfóœoœˆe‹š! ´%æAY¢|{®‰Ï°n\{ŽÓ%”!H <þì€<Æ„ãXU…¿Ù¬d 4_~ùåýû±U´yÀÍ¥F=Ÿì††qåòòP—é`W(‰Slµ^ VQ®h¿¶‹HÈ l*lQbÓÕ}eÀQ‘…¬AÄ T½êÉÉîÞÞÁÑ!bÚÄšgá p¥|\…1®$z @)nZ±*'oi¹¡œgÝn;=‡ëˆ8‹×óé uëL‡Éô5Ó‰ÎÚžÌ!¤DNÑ?›³‡ª@_ÅLF»ÄÁ$ò¨Xôo©’o­-‹ÜÈÒ ˜ªKwh.µè2šBGÄ3Óö] þ¥k×÷0)(7{=Ñ!M –_¿xñkáñß''•È1Ón;ûÐWÌL‘Ø0:ù@f`ßï2Ä_Еé¶G´N0ã&ê©›·bèΠ%'-îy]ÇÊ»ÓR|:êù®ó¦“Ø•.É5îZš&½ƒ/2Z;@ öƒðþçnݺ¸3)2ŠõÔ¸`ltì¤Z¥á^0 u ¯vršä@Ýo¼66Ђê¥ÓeW€´°à£kë⮬VLC+j}¾°²²p Å¡9c8îÈ5˜NÞjF­N¹º´HÂ”š©­–ø ãÐ|o‰[˜2ÊìGSî¥qxôÑójD&íÈlk^«ËÙ ZÚI­Æ5ÚêÔW&"N-?•šŽòÑñð(³Š“vZ—äèÚs»Xº¶£!±Ù¤µBöeÝžñ©‰É鉩ãɲ£çz³c7© ¯î0#9ÄSÓZ“¶ÇMÌÖW†bWÜÅe¬º(h•ÂæÊåÊäsÔ•pÁ¹Úù Ô$€‹ØÓXíJ ûWm~2¾´$ 0ðVž«¯áØÌd²j¼Ñèk3êõñ$_5ø Ý„þ µV²×ÆR PXpAý81Cj°øêz±8 ̸uë$ö©'_ÐðË’Ú•ér¥º±µ ,&8¦ä)€Lº”Ѱãæi ÎÙÙÙ»wï–Å‚’/¬!ð±ül¨Š:ø€o–ßΛ ¬íEᘧŧÈEYK´1 fgfÅ}_«K¡Wù–äXÌåI]Ž:úž>rÖ<]ÛX§bÓi™å7ïÀþa*PKç$EÝÅŽè”ÓK8˜Æ ³Ý‹8+ˆ ¨Ìææ)»±Ú¬{ÍÞLétöx8üè¹,h_bnŽ\ÚTkPjϤ]lhü®??y6>!Î?X/)7ˆ`KsmeýõË7ø[=>Á:Ôuj‚~hL3¸ga2ø#·/qNtGÛÙ=ØÛc÷‹³ú)»ýVƒC#³ ó‹‹ó3s³»¸T<°ZÄë Xá±Ø&éÖ\®pÇE÷N§L¼ÄøÛ˜ÕùAw|êÂ#€4lï ¶mä£Ý·øM‡S³ldžkã 0oèH_œÅ|¶aš‰‡&©9ˆÈÅP2mYM?Œêá¨ö•à^ õÌ&?z/˜2/GkòÛ9O íP׆œÃ.ãåëW°}ÅèªÕ´»‹è®šRã‡Qëã¨\¿3«Ê¾,àØ V½±%uòõ“šjn!Ó0ÈYÎ@X§â˜ÝÞÞìé‹2¾%édÿB0Ëq“ii}]JmL_SÌ;Ç&ÅÝõµ±ÏÁ¨ÅÎëD;Ír5tùߌeHï(^cs‡‹Iâ¬v^¡BhߢY’²¡ÍJ0 ÖwT./ÌÏã.vßÝÙßÙÙX~úô鯯f]‰!Œ;r³Yº™ €LÒ’–G±š+½³ÛVÞ½§Í%¿zâkGëj]à62*ØÛ÷nß{pÿöÍ[“RÝÜá¿´âÀ¸Ù1ÈLUÅb‚ÑéqÔ×oúÇgñG™ÆV!Îy-Ó†2ËX]kÞÊt‡‹Å³7n­¬¬-/¿×€g]{µÇù0štFQõ±ú«eÉíÔïd°ˆ+Èé•Ñ{ãFòæg–ú€[ŸÔ*;»»ëàgXTqtLÑN2h÷€yOž<“ ‹ƒ}2©ÞP õ!E%á£-\»%Q¦¼Ô2¥Sæü§ âCƒCͳ†ØÐS3Åâøêû5q"¤"Ï“ìr!7L¾|x|ttÌè§£Å)ÚníœÑ+k—â[Ïo©g_ ÏPÈ@z%¿y©…\@|¿St«ÜV­¥‰âäôÄèh1Ÿ/Ä„Í ¤õÃãï÷´Ðµõãã#^! »gâ‹êZ~÷f{OZcCoܸ1>^´s¯8®E“•±Ê¸¬Áׯ£Ùay¨—ÒvI½Í$-ç¢\Œv5t,¯†Ý]$Çj93Bz$HËüŒ°~ôè@‰à1ç®ÔýM§4ã„Êã~Øeê×Âvž;‘8Á$+?걘D*sÖK:nº¼¼<öý÷À‰jµøB—Ðä†3émôV#?{öb}}}ÿ0*é·¢j™0í-í¦õà :¸2ô½0œHøìÏ€!D÷­[·~üñÇb±ˆw…š®É
£–¹ƒk~ÍONZ<-d¯‘؉ÀQœ=Ôä}[êE67·5òY3žk{2Ìrr­Þ¯Æi›j€!˜4q(±(l4V±Mk~^šFj8ˆ1›¨O^üÅ÷ z ½P×ê*$ÏbÖhä±6œÙ;«EÁöN^‹j°x(“-õYñ`¤1” öGxýò•Z´`K_úì©VÑÜ×Ú©´³¿sçf.1õ\®Ñ8•Š>íÑ©2¿Ç·‘+´Û3˜ ; üÍÐ~VÜ£sЫ¡4ú<˜œOêÂûì=p»2qØxjeq+R*(a|uv¹‘«+ò;Psˆ%^‚ Ž´¼•i3gê)Tté&µš-É&ÜÚÜyöäyã´ùîí{F¢€Ú£¶ }icc º™ú÷Ï¢–oQ1$—Ö?…žä£yNÛõÏüFõìääô¤ÙnÔ§ýùs§ )ŠÕ!€C^@ÇÕ÷+Œ¤ñÒÖò^ω“3ÄOÛ°@Îæ3ŒÿªOS |í©‹l‹sÂÓöu­=íÇ}¬ö½ãôÛ{AÞÄæ<\T'U›<@ü h0Æ ¨¤×YÐ!cc#POFÂñˆÐÚ~“½»írR,ÅÎPa^X&›a蟋«¥VÀd Í½{÷=hq ¤Ò4 )&\ÛØ88ÚÇÄ3*ì|eÙQÿ9=ѦAý¥±¹+ »±Œ½89©°óÔÛ·o_½z³³³Ç9Ø>˜æÆ.,eÏžI ïôÐŒm3X¹Löø¨ L,-ÊÊ˽‘Öd6ÀQBûPH°UØoí°y¦UyG9%6/R¿‘¤}ûŽ/™-)©–=sšÐ¯ö÷ Ük7„œmÈu|Äú3¹³ýàÁ0ô“½ÝN¬Éø´|C"j¤»›™›}Ž`pkQÖ‹ ‰Ë‡ÅTJ«)2Aê*1Ù¸6HO;´4b¯½g~v".ÜzÛïjG;1®]»FsH²[A3ÀW‹EµRN\ŠÎ®2 V¾µG4‹âó‚ nú®Õaƒ?|øð믿ÆKyØ’=%Ö%ÝITä‹hMHI‹›jkÐ,ø¸Z¡£<ãH«NWª–·”M·SÛ‰ÊN²sssà)lbØ–s©SþBêrb1m‡JùÙð]áµÓ亇y7¦Š¢{ƒ§gœ„ýBñ‰Eޝ@[qÈ€á7švöÈ“„¬àêèË„Aóì4›ö$¾©­²q£Râ3‡Ø H³Ìpc˜4Ñ»Òér°}€ºŒëK`i–ñÔ™f=lÄ"Ù4ÝÛƒž`”Ëžé¨vÿþ}™’,‰ ì\I_m7Ñã~`ìÅ7 Iì;àÆ¡'HPl¦u€ÐxZáj^Hìq'8¶¶ÅÀ¢õùQ÷8BS›Ê®Òÿè`ßoœ‰£;%mF!»Â4¨ËÍjEp°Ñn-(±X·S M3üöÛoÉ  ŠÙ N[ÓH´Zúûx^>Û7>>>· çëܺugznð‹Yȇ¨ BçEèO^gã-à½"PÐX‚GáÍL|1y †{ò-ÆYœ?QÖ œöÓLA@È@€–ˆm•ôßóGÕœ#39ò„< UÒÌjOg¢ô|u-4iÌ3g Ô…ÿSj%¬zW;:áJ¬ˆËÄ!\>ViÙpâlé¶Öž“œs ©‹}êÛîe.œ;…ç_“vQ·)?ÙPѹTd]F]„/@Q z”I84˜ÍLzW 쥞ÃÌ`ãÔ qé”u‚qS._dºgܦ¥‰q)˜U;Ç0 k©öýG7w6¥¯‹ækêIw­´ºIX ¹5{Hk–¼T†Á:Wëhxî` pw‡{õæõ ´†³ºLC¨ô¤]^&Íç _û‡$¾Y,õåòêvcúã¹rO»…íˆÆˆÿë¿þKº¦ŒÿðÃ<·áèXÖžÏJYM:+íë&Jã˜Ã½w¡âOÍÎÕ*ÕêÆÎF:—å¿Øž°-eÆMªŽ m ]Ë"ßǹîü„@AìE¢€²Ñ~ã~¶•fÍ}Z†´ÂÿÄnÒ2¶`¶xþ³gÏ€3bqÿóˆSÒjõ— = š·~?xx"„CH.ËaYº>á˹¹(Ò_|ñÅëK7nÜp,}2ÁÅ@„†•@Ôö ëk+@§“Wõ)—‡]±ß£2rg ÎÒý¤C#²Àæè'牾ø @  šÞÐÏ6(~‰ÝEY`}õÕW¬ð%°÷?AFÅó®ƒyW$Ï_µØn¿Y÷ °Á¬Ðã^‡™Ù-§Q¸žH³–Ø»ÚH,’Ÿ˜ Ø$˜.ØëÑ&ØYè›[˜×º Hº5×kHº«ùo¾D¨ Ð&U ªY6CwïÞ‡n=22ÁIrÖjf YOŠ=©ó+䤣¥T´d‡GnݸqóæmHãKZ´‚U›ì»Ñ‘Ñ´8ÿ<Íò¤‹íîNwY‘üâØü윴^»}ƒV LÏ­u9)³¯ ›÷jg¸ÂÑ MO“5è…ò,¿ 66–Œ´HÑC ˜—hŠÄÙSš \x»Y—mu'E<7²èkH{¤;zÈ&“Ëõ4P^U©éÑÕý s÷e<œ¨$u[nÔ¶§sà#CÜK›¼í™’Æ™ùôÉOëëëe=*Z ^W­HÆÓŒMÕ™ÍtÈ 0s¶%2“¿ëðpü4ºUÓ+É®nYQ*ᡬQÅûè‡0¶¯Ø' ðP`¹«s^5OH-{³ñd<‡¦²:{Ì4dc&à o¬©ƒ“™0E'!C=ƒ…ÁÁ냃Òþ2*Ž—$¿æí²Ä7ZA'‹Ç,“.Ž‹Ÿ³T$»R.5¡6ômèor ñøV®¯Ð?4¸½»%-7ÌäÒ™\®¥ÍÀ FÆÇÆïÞ¾³8¿0Qœè4¾ë‚¶wžÝé` €À®b¾Öê y ž:9>^ÓDÀËè“8fÔ@Azµ§%$9rYÈìk­)ONóL2 ÿP›LA"¯ÄL˜sh(ŸŸŸ…ÐêÆ{"M‚o²Ñ§=BØaÔÅÀ½q®PßáI_Õê1.û c[¿þú[h_°3$[CçlŽ R)Kñì=Ú4xe¦Á {9aÚkkk;»rb²ä1J–Ó‹eÙ†ýèÑQ=0d‡/€Ò ÈŒù³â‰² ›Åþ‡ÎÇôEÒíð1À BƒN!–rП”» l†QF“¨ß5 уpÞÔ %OËþ@iØêÁŒfš·ððåH£æ pnrfú«Lš-i—¯½•î»{G•cec²Í¹¾üШ P¹@¨“ÓSD MkÐM¤©‰ÕAâQµF],Ù‘”ô<Òz–|a¨`°ðúâR6õâ9ô1s© ™@9ä7˜“xs&úú Úý« Õœ’à¨×Ô ñþœ9œf˜&¦B|XVdk1±˜ºPOàãÕÔ±Àu쥧ю~½~]$nãSB'ìɹIŠ€$ÖEŠ5h@Ùˆ-ÆÎnoo‚ëIšØì,»ù/,\Ó{-ôÍNËþBbòá&H¶E©íãàP¬zžº»»O]†9uuÇçÔÒMÀ|xœ, ·iv&û£©ë¯" …÷1¾Á<73¤©«j†à:FpõÄE1Vöi‚•X³§4nŠÎW+Žn+Ú¸`u‰^Ró„-¤º&7>5 u\øYYÅží˜n¡£%áC3³ótO3‡¡f÷ðÉLʆ:ª•óÄZQKrrX}ße“ç$—Œ¿°"äè§]ÙW蓲÷câµ#rÓná-'I퇦êtÊ»Ø(í««¦QoH¹®Zâ™ñÕ§§bJªN¥E‚ùA«´¯wÇ¢PÏq¤w«c•.S¿™þPÕ {O/Q áøà·Ïó×] %-ÀsÕTõ“Åâ8Ÿ£Öçtü®Q3ÛV+m_£Dk@`»{š‚È@.;U±bÝôñgäW4±zSW|öS(p± `.Œýg”Lf½âËìYâ*BÄ\ÍÞÈ0>†ƒ1 ûüùË·\²Ž¦§©³ZÜANšâ‰ Ž›V‡¼Êëù]ÝÑIûÉì¶Ÿ¯ÃUçZckS’C[nq™ÒutUNdç9Âl`v놤2³Á ·¨Um⌼t¨íƒ`Dh£‹*«ÜÀ¡€2CºadW°(&¡™Û1ŒPªæìšl  P‚¿"buÜQñ5Ý6‚}ûÁÁžª?ly›e~·9wæ+ç.”ºæËýýCšaÌ aï^ì¬qƒ“·ò ·žäpÑ‹>8ÎuÕJh\æûžyü&‘´qy”ÀdZÙ»{•až¬<㨃Q匰¹6òWïÃ#ÎÃŽô„£Íè¨0¾#7Ni·Ï¸\ýHla7”{,Þsû¥_|D·’=äyÝÆQ7i]öðPº…ܽ֓£¢Ù˜äûï¿õâ%65›—Ž+Û›[ .X;ÐÊ %Jqt&Í|íÙpCí·Îcwvv6w–——WÞ¯IßÅVÀæI¬sÓ‘H"+SSÉá šÝ{Ú(—ðiçîÓsk.R.=7±{V‰}¹Ç®òVôw?¶{6>_Ž™—ËR}µ¦ošÈ1Â#:Ý8ÜlrÕø™ ˜^ziÌi vMi3ºººJU˜‰ýv–°c¥ŒØ¹›-5£˜,0YmÏÑ/£[âoüx&£ £n¼®ueÏõ²Xˆg×K —†´C;:3l}u-:¥R« ŠÊÒõë×®_Ü4ÕµÀ,GÐäúš üìé󵕵êqµÝòµ¾Ø]®Éb ü¶v.èï+ÀŒa%EB]O°y®7Œ;v£õÕU K„ÿåß8ç &øG£òÕ¶‹T3.Æ¿u±Ý©ž`Ð<þî¨mÏÍù¾ pYÚ²$-<Ê4½0Þ|S‘éjém*ã³Y§izŽ+¦Zø]ºHy¸œ}F}SÜ„S7q±Ÿã\?÷Ì0.Sì½» ‘éTˆ ja°¤ŸõQBÌ@ßêÊÊÂòòÚÚšœ7 „ÞÛ7+o–ß¾|)9ªJ~—€]N’vSlaCód[v„ç)Xt²8”Žì¸ŽµÓ)Í$hñ𚟰J§ÂW§Ë{™lEFNW¸Ñs( A§ê ] j®¼ŠìöüÜu°5<ëyÞE—\º»/‚ÄbW]ë¾ÔÏ*&ë¹t¦¥ífs¹ÌÑAyg{#ˇpË©iµ¹µ§½ÆÅ¿ìn( Û„JéŽ×Ò=d½¿OÊwaÑ]»v­;NÕ­P¹î•*”þî£'ÖRj]4Û_ü çR6qÅŸ~ÍHÚ]2?/u€´xæo±q™1ÔÇp!-[Ùc|“9Ñ<…É„,gHˆT5åÀU ]2{WÃ8D º%'&&`“u˜ÕÍ›kðŠóðέ­-=0ÊŽ¹­ìC°RˆV?= õµõÂA Њ¨~ ýž4û;âJ¡ž<*Ê3''%±æ?þã?¾ýö[;Ûó×h5ŸÇ¯i[Ëbríû÷ïå÷çÏ÷t˜$bs˜«Y'†¢l#´iŒ·óhóDñ¥É•4zÔ¹ÃoxàžCŒ‘ØT*á¾ÿ ƒÐAsssׯ_‡m©ÇÊâûvKRµÇŸ'íñ5@•Nyì˜M{ÍS­D ƒVÓuÑ.Òs \ÍÁôÚm[:Å$'›ÉNLŒ/--ÝÕÑ]h÷©áñ/=Ò¶–%ÇËJ—¯Mž bã9&%tÂ@¡6éî`r·Ì™ÖŽEi®fOÚî ~É<þÔÝbÀ˜g dH?ˆ¶_îÙ<ð·3Ì”¦§§y"<¬ñýûU:NEã{li_a…Úô3$Àí­PMŸ ÏsMMˆƾTwîÜùæ›o¾üòË[·nÙ¹¿Aàü«H34ctT0‹j˜ùÉøÓíD›ÐjàÄ]©œNÍbšÕÄüKaE’#!1MžRÎ̉˜g¨‹],™+xQãÄßæ®ß»wïô´¡½2`XåòqKëÍBß÷¢ÈVàKξhò`Â?:tÇ•Sp­v\’7úsS°ëJ¥âÍ›7¿úú ¨…vq„­M|ŸpDÄ`¬&èýšê0 ÅÒ]jƒ,F ›˜5ÛÝ>ªŽF^±ò HÀ®ÑÔI6ì{nZ‹ÚŸc(Wj¤UrŸ™¡Ãjmû¥Ÿ€=†Q¶a...Òsî„bdnll²Ï1.ˤҮÇRÔÀ BÈ¢L_tö!̶=’‚‡©W%­>ô9’c:7'yz0¾xÒš˜(hxçcŸÇ§ç|†@bì%› ª˜™™1§û0ÆÅ–$0JÓçÌÕ›$)<„“,L°w"‹í©ùWWítctã’x¦f‚Iß¾}ÛÄݳ¨“ˆ™°‰óÖ§g&_¾x½³³£=Æ´eªË\¨ÍËÈ 4HŸV2V*8™Dp$®WvY |i 0??€|ñÅ·ïÜÄ~ÍÌ$Kú~³ðù—É»»»`Dƒ@²5¬†Ú4L!Ë‚, #æ YÝÀ„X3¦€u4Öò…¬nÔoÝünkPF4d! YóÈjÈÏêS@Ȳ KÈùBV7êwé³4Ö ‚) dµ|!«#ý LF4d! YóÈj‹À50dAÖýwå cå«-#æ YÝÀ„X3¦€u4Öò…¬n° (‘»&ñ\Õø…,d+«!ìª) dY¥aÄ|!«»Îê™ÐnX3¦€u4Öò…¬nìݤ̹&NýsB€ý‰Ñ …,dÍ#«!†•ÓJFL!Ë‚, #æ YÝ0ä4ÝýšsµŸ°fL!ëh¬å YÝØõ“mwmž/]Ôúo†tÎÆ÷:îÅøSçÒ ¹F/Ë:È꙯²žÅrÉ|uå[Ô•òuaYq{µŸÛãñpÿùøøxþ}{{k{¹æÛ/å\û¾Þ'Õ9°†nO#k|þçp‰óµSÖú˜¦XÆÊ—žo÷ûÏ*Yî:½Q]µ Ç’UÃ?žßßß“O; (ö1;O§°6ld YGc-_ÈêÆ®]@ëEK¦}Ü#‰X.Ê=©Ñ …,d]@Öýþ­s—º~¸íÐÉÿº¸I´‡žR×ÕÛ³ Y;1_W’õ«Mÿ¦‘µ›wPrhrW¨PFþ£º¢´f|L!ëh¬å Yݨß´¹;(#²…¬yd5¤þ, ¶Ù6‚¬×Q0­AøÀMÑéL!k#æë2²‚íË êû×üÏÏey¨£o€¡) ÓYu°ß œj7›þS@ÊùÇ/Jwµ?_¥2Í÷Çe‹ Yµ1{–›å|++¶ç_mzv~ß¿†\íFC8€Îc–æ¬:ð ý±üqZM¸H‚×WŒ3ï­ä àáKIIOŸŸ Å—qb#z&·Ö ‚³€u4Öò…¬n”9€Ìê–¹\íaDƒ@²5¬†pD L!Ë‚, #æ YÝÀ„X3¦€u4Öò…¬n° (dDƒ@²5¬†Ú´¡FnŸâc Ydi1_Èꆕ]@_@ ‡ÍõÙzdÍ ˜BÖÑX˲ºaePQ$šîªëψ1³,$²f“Õs‹ÀM¾€Wzˆ¯côÝéÚ *wáe”ëéfá£ïfÊ꙯ƒdmË ùj{‘”¥/ºË—á@²âHös{<þœ©ôñññüûööÖ*öR” ·ÆbµÄ&¨Búï³-£ßÖûÉGÕ²zæë@)ÿûí /–/½¬o÷ûϪôFe-_Èj(åÇÏ¿ïïïɧ†vµ*Á?YsÕaãUe1„¬Ùd5¤xТÛS‘íd "”Nb§P–ÃfÚc²v0b¾ÕÊEà#6ä´u*Õ>ÀšAÐÃÝ`bÙ kùBV7j¦€¢£ÃÛÌÛ$Jü_}Úê6¢AÌ, ‰¬Ùd5ÄÜ. ! ‡¾ø¿»[WóHKO£©È«–asYBiDzÞÑ€øÃoMtï¹ï·#[<ÿd䟙Ræ‹)  "}%§ÑºékÄ2´&«!õvT?Lö«aÊýÒoßÃ6.®«Éž…“+§áåéSÖfJÕ î3æ@èKÊåk#Uê¡÷"²F_›Lýö%%ûÎñ¯LG!»óÙáþ2Œr*©6ò¬º·³Ó}xDw”Cy`k   ÊY =“H„!Œ…07cé!Ìa^;¬¥A9¬L5D3A0"Ϧ¿Uë¿Ø™Z2³7kSÌühØDp ë¼EÓ?Æ"ðòÕs—[måüþÂ8.DÛŽ¿ÃÖ@ܲkîäž204€žàйqn$ñ»u±…G.×&,ùJ“xê’Ô$_É·ê2Äs„ÔE²ß˜ &ézõë lMÙ§Éڲ惆Í’qÖ|Ý"a‡¶þû˧._É·*Ê9ާ‰T¨[“Á=±íy½U2šäËZý:FÑYâ¡’o¤…xêr—,–šC™òùÚŸž „L•sé:–>ƒ;w:44ææ ÷‰X«_‡Â  §þ=ºôͨ"žVfÔêL½&­.=•lp÷x«†©•‡kNÑÄþ”¬Ô¯>àÊh2‚38Ì%ïtN/pZÿžœ®î˜JS@ðBÃöní…ÙYï:·4®Ýú_CÝ0¢wà ¸1¯‘±üç‹ÉyÏêÒ¨+çæ­?êoS@ìœ[l{×?'cÏ?¿§ß-ÇSAO]AµŠ'Yu{oâx*ÊÙgÿ \ÂN„úÕ@ˆªß-³Õîá­¢“[-â5\ <«œ›GÒ¼²“¤+Õ¯Ca `Rp“‚˜”p àï_œ*8œ—M?À<¼ü"Ìk“‚˜À¤à&0)8€IÁL `Rp“‚˜À¤à&0)'ÿ&ðív[/‚CIs÷µÑþ÷ëõ7£g>3ègm3¿k€¸”ìæj-‘ömãw:¿Ê-¶ ÁZvVœž¹sé<ËBŒ[‚¬åœmh^÷9y '®Ú,Vjôꌠ'N7î¿/‚GA!PbÜ6~‹þRnl‚µl’z¦Sˆß²%ÈZÖ„Q–°‰)  •ÖúŒGäW8WCÑšxË‘A®mÿAî.œÓ=3îQ“¢3á4Ü~\û7µñü÷æüùzá»wÿ© è¬wü§Éë&¹^P9›åp"·/‚ë8#.L.›·Wv–†AÛ:þµÔ7›‘Ô o²=ÄmB^K8\ï³q°y'¾Ò¿ü³7ã‹øæóïúoóÝd$š\Ë×ÏÕ'3»Yç"ç+¾Ž•›Ì~²@ä§a ۆœ»ŠRµ†¤—T#àl@¶‡MkIK4l ×ê/d*×2hJàäE`_m®·ë«Óš _&åí!»\ÿéX˜"ŒÉá«KFJ°íŽa®ó•S·>xúPO%Õuÿ-ØFR›B½¸<~Æ‹¬e—P–à2µlV€L¼ê]ÏWÑç\×|oÁq˜mâTiÒ)Hî|Hnu¨+ #¶Ïiäš¿ËP¯ƒJÈ%$ Ê¿öÝCuœÃ¬Äe¡ï.[smñäÝþ8»QTvZ4}O?,WD²X²x_‰qŠEs÷š`Ú¨ÌXB²ÜbÛØß3>¹Oôà4{ŸýIîŽ_R…îo<|‹Ÿþßúg¸wÁÛkvvonõ;ÂvÚ åÖõä(añŒ!É’™Œ#I¤Í¶mÄ…ÓÄZ¬![µ?Cè‚åÊA Æ`ÙSŸæì¿Ô®9¨<…³f¦%ž6kÌØ¬X³„Q§€¬aM¯`lV Z‹À–1²0!Á(Ø`÷Û€³–`wÔ ‡ÂÀ¤à&0)/‹ÀGέ·îð”UyòCŠ5ªê8#e;»ƒ;~<¹Gú4Ûøq¦m˜8Kø-¢«%¼8ù›Òj³x¾ç—Nó¯VýÈ÷è P¤Kg+½º‹àûÍ?žÜ£Á6–³m#x«A~t²âÆú[Bb Hó­öl6Yqª¦³´ :äÄüéü“ÛFòÄÍ;­¤7|f²‘ª-¡ •kÕ§ó»çÏ‹õÚ]×þ!¤ÿwyí8øïúOc)ú4Ç¢qñ[{èÐÇ·s:?¶Qª¸#lÃÍ?œx:?– z9uÙg 5ÀŸ³!žæø’[? ?ªZG‚î•õNîw Çüw]„îo e+³/þÐ/™ÔxHX­ž¶]õØn¾ÒùHþ ´˜ZðÔ¿#D"2¶‘TVîÎÑød¥öm@¶ÿiÐPloŽ%1Kzß¿f“v²oyD¿Q¥I‡¯$w'X9Éy]eå`¾èIÚP2ždâãbq¥¬¼Å=eMÓYDRÊ’WwÈÅ«½Åï”Å‘…ŒmŠnlJ¡É¿.;9k)%È‚½®=fPsD¼N]QRO“K|¼ äÝähoÍe&GÍåó—’VÛÈ™AÏÕþjY Sˆ%h„`L_Wþm¾(uDþ@)åµwšÏ«¶(Š—ÿæNx?·’Ç<ìœÎ?·mÄžuOkÍŽýܽ2XÑš–pè8/=Á´y´´02 % üû¦áBýÜÛ-|+˜YþÏÁI¶£)»Å‘ß’¥”»—yÑIß9µæbHú¤Å3†\$KÔŽÄÁrIÅ6üÂOÎð wöÛF ÊœÉ{q:?–à©R¯÷øN‘% ¿‘Œ¯`ZÆá(€I¡›ÍHŽRÀ,8€Ia `Rp“‚˜À¤à&0)8€IÁLJx´åß €†$~€oƒf áþïÿþïìTÀápÀ¤° 0)8€IÁL `Rp“‚˜À¤à&0)8€IÁL `Rp“’øAw>¨ÿã0ëMáN驢‹Ê8×`B˜ ?k;)͵{QŽ0ø•¡Ä\€ÍÂ9ކåäAÿE9ß¼ 1t½.Ò‰9rÍïâ¾Z¨d€d¯v§'ØÙJod' k¹&ÉrJÎ~œèªIgQ­Ü!&Xì§ …^kx0}áרx‘@¾ÈMŽ/ÑôTiMŽ×6‚¹ryÍ#—xa¶=Ù’v˜3(d6fÉOLm¦Ü͹å“âµ™\±o*(WΛÉÂWMË]@®®Õ/w? Ù¦'vV]¿a © ‘¾tyúEÙkʤ:ñÁÌR.ƒÉÌÆ(yEQN“鉕(û¦‚âûrÌà³íô½ãj4ݱU\]ÇíægÍým»” Ÿìwà误ÙfôJܯ (˜RÖÛ\»Vzß±ç†r[d·¹Õ^”žóšïY òå€Áͱ±U#´(LQg_ß±HŽ-üÒ°³ø`Ÿ¿Öwù•Û‡Fž€rÍeQf;Ìêèon¶¼šÏñêúø†1\m79n›’­•~PngH@¼X·Ì´E›I’‘ÈÛZ‚4$ÝÛþ/Kן“I•ñf‰ O…››6³GAšd³`e˜špV¥Ý¹kóÄ#&!÷í´,¥ßôgôêÊÙ†šðÓb}P}Ø\[é;ÀœÃ¡l–ç‡DêÀ¤ð{“‚˜À¤à&0)8€IÁL `Rp“‚˜”—Ãà>>>ÎN´äï¿ÿ~O>bpYž­¿ð4qôÛÛÛÙi€È€À¤à&0)8€IÁL `Rp“‚˜”¿öGÑ„ûýîÿ÷óóS&È=+`É·é¿q§¡؉¡) û¹E-¾,6G›½ûý<Äe¹(¢Õü‡ ÏO“ÖßId*i1Vhd,ÐWOš—¶¡) Vù w?.´&2Öl}ÉXÓW€+&U@ïý,û³ ƒ$ÖôEƒ+ƒ¾Š04´¹ÅsyÕ®\²k„Kß`’LaMk¦cô54VÀ’ÑœS?³¯Ö@k24¸caM_V¦€æ¡Éõ~ÿvv>f)…±@_Eàz“4ˆ¢ýÚ­?x,Ð×ÐàÎäÚMyT`ܱ°¦¯@o¼MMßü ¥3Ðû ¼K¬U`\ôU w“ÄçççÏ’~¶JŒA¨Àc¾†p&Eíþþ‡ðT`ܱ°¦¯@obƒp­¹Ð@M%ׯ+Ö*0 ® ú* ¥ºé|¾è¿„ký7'vâÉ"9Iñ(Á‰ÐäE¬9Tà±@_Ý8¢>âþ¥¢g]Ú>jWLî+É›Á6G­Œ¬:þC+ðI.í›R;ºØhpG¢•¾2]@Á|zÜ@+ë¶ßõ^ "÷V21.ÿ©û¯ÒùCÍ,+‡¹;–'šJÓ¶³ûe’½9æ 8¥ÁMjv§–2Y_ Ó¯¤‰¾ŽKj¥ðh;(eš³˜µ •{Óq§û‹GæþË»Aœ¹À‚ÃÈEµ™ÁÀi F´|ó8‹ª«Eš ,ûàRëÇfÇ•&óè:4š|í ¦¬¡Ši°0V÷ÊmVo‘©qît‹õâ’> ° ¹zÇbà |†@©¦ƒ¡€ß| ›R”^ÇïçÔ/Š`­B®i¯‘ÒÃÝÜn»¿©kx`¹“ë:¹¡C\Ýö7²E3TÁü§ðe» ôÍ›),Š!ž³4¥L¶ºl_FüÖ|@ýñCŽJ‰+a0Á’lLývÖ_X¢&ØãVTc•÷l U¶Sî•d]Š‹ÅKÞßÓKòt¢…Úž+/ž» Q™¯œèdÇßyô¤.’ß‘äúšÆ7XÖ þ µ,fÐ5I–XN)qîr6óúèχ–9óNŽqc—ƒ˜ü¤îgr WÏ¡£@C§žˆ_{ýº÷ü+´þ1šô/ƒP¥'ö=Ey‘“áçN“òØ ××Ýß8N—‹äÚ‰çUÜíyCŸß˜d¦|Uf¦~fªúcY~æ*aììˆÞÍ¥JŽ3™ò\!ºðËsž0hú½Â¼¯úJ–¶aPš$}’ÿú¯¿¿~%ǦAœ¯¯‡7“ÉŽã×Öæ«#Íÿ,uÀ?jÿJã€dERª3hìNÌÂæðé=Ì£Ü5‹ûPAøÍ*X´öß Œ!”~7ér6w²ô©lЃ›E}…8…Éî7·Œ´Y‹؀«™\Jyú1P½ ÜLÿ`ÉE´¿Â"–°CZÈ&¸ðHâ-´ ÍÅ¡ýý˜Ê€ËÒeZÿ×Ü•µhE!õ˜ŠÈtûzYÊæLóf[ãKÜœ´ÑÒÏø'Óöuñoƒ[´_ä®”oyž5nÛÍ ß—iDéÎ5!ý…\¾i6KÔ%ÝÌc©7×Õ¢f=üîç¾µÈß³â—9€Ü|h£­N¿– ³sD²ø¦‘¨Àb>ÊnJ{;ÈM¥”jMñ¤rz”¾ö—U·×ZÍ4©z¿²¹«úW (Î^¡ãq:Tà±@_CS¹ tó&@˜“Œµþú’±¦¯{cÜ Àš¾hpeÐW8€Þ7ˆ•÷‰^µ'‹ôûq¯ª¯I`ØâJøˆöÝZu»’¾ŽÀš¾líÚ\Pr ȳ¶$5b ÁÇš¾L%Æ è«C»€6ãñUkMÍzMv7¬iÖTb ‚¾†ÆÊ. åÏüEØ xlp™b=T`k†¾d¬é+ÀÊ"°ÞŒ4? ¯q'î,k§¡º‹åûRôV…ÐR›oi"¬z½‹=FRWÎò[î§X”… ¿ÄšTê† õåŸÆ¿4âöx<Ü>>>žßÞÞZÅ^Š~8™ ¹M‘;ÑJüÕÿüϧò~Ëb)ᆠ¹Wü¿Ýï??ÉT]$Ö¦Z•@²4bMu0§Æy<[_ýmµÒ°›¤³¼´üøñüûþþž|zÁ]@ëoÖŸ ¨ä¸ÖdIë?™ÖV¨5Û¾Œ·>kú °þ‹`¾½,Ë>`Âä%÷hª…„†X3¤Ü!L}Q¶ ÈÿE0w³I‰­|nµyshØ`éïL’ý¸kZ3•ƒÔé븙.ôUDñ6Ðå˜_ËER*ËP—°á&a/X9Öô`eИ2f`¦cô545k±¥ÐëèÓàŽÕéžÖ–”j¢Á kú ¨üàªth+WƒðÅ×ò¹û×[¶€µ |VbFéF ¯"j¾˜™g5¨8“ÇGcöô:G¥Š™ l Y›èkhøà­ú8õ•’ÑŽ¸¬*C–hQúzÆY5}àŠÙ»-ǶA@€5}î ›7ë–w"8€ß4Üè),œ›‹d^Nìµq~œ~Ö±ÍN´K˜}ùoµl{‚Ø i%;Ö²c„ß ûç:9:‚q\Sä&TÝ…¼á¢@кsÒê×<,g9ªÐ¿gÛ¸@bÑ‚sE‚7ãW®E»`òož”¦¹Ãot¨b.\älõû$¹Zqh£Aœþß%ðŸÏdŸló;M–ã:˜¼ï$ÆÇßÐAÑ"áÒh7eWÌœ”ôpîÛ>ã(Â,™Z—Lêfš7|_îÿÜ…ðÉZ„ ~`K“¯êתϻ¦åõ‹ÔÿY± 463(—ü^ÿíuh’ªQþvE²dä~zº@2?o§ÌQE;¹cUÆå–ûåÁæØúIÈþü;@+œs¸ïËmîP¢iß{ð½x–ÌJÊçãß’oÛÂ|/Rþ“PÆ÷ýQ@GÜŽiCË[+)úõoÉÛî]Ùrš.9Œµ%²¶ â|,UàA_2è« Ï‘ú〢6ä~Ÿ‘°Õ¾[þ½_hÀE+p3hpÇ¢©¾6WìJ±âÜڽоkÂøÏÎSkØÖÊÇZz¬a­|¬¥§5ßî÷oí·kîÒlÝûã!ú[Œ5%=¤‡ô •ž§øÙbƒé€rãöi§*;<ëf,=Öʇôéyíõ7iý;S@ a‘®Ê³éoÕú/v€kµ‡éÿüd.Œ›ALuOHé!=¥§aÓ¿bÅ,º_œ×ÿ*½ePDÛŽ¿ÃÖ@ܲkîäžZë ˜ÂÐzbk`ÉAÓmx¡IO7üŒ[ØnÌòYHOQù]†qùœ«5½¾º¥sòúŽxÁ`g*=‹±±×1R21X>Ê”tkýMÕ¯þéa (‹¯ 3’Û‰Ô¹t•ÙÝq)陞¸i¤||éÁužiHJ?«p’ H–XÏ”ÄrJùÌYß¼àú¶ÉÅäµáë9ŽN¦'Æ¥§/&Ùg91=Êž(Ý/œs äíÄSqzº 1©ï8€¸dÏí¬i4ݹoŠ;½Ñ8½»¼ÖLÚ¹Úöõ’°Éë; sûF,ãô廡±Öä5¦­ï¬¼ ¨<ùèh)M8Î`Ùÿ˧¤üì$Êò$õÀ ~Õ ¦#ƒGš©ºné1UbFÒ“S\çÒHƒFÒ³xëœFê×…ëûì¿ paøM`H€˜À¤„‹ÀÿâìTÀἌhúæáeÌk“‚˜À¤à&0)8€IÁL `Rp“‚˜À¤à&0)'ÿ(üív[/‚CIs÷µÑþ÷ëõ7Cg>3å²ã_'ó+”ÀÎÂ91×°i‰tþ*7§ëßiþU’° ?gYˆqKÛÆV–pò@N\µY¬ÕèÕÁÑø59¨ÕkXYÅw„ÀP„AÛHˆö4ëÔín=Ó)ÄoÙrEäî/,ÁÄP2“g'ª%AŽ6sw™ì'»± ã[KnÈ8.¥uaN’År„ ˜pn¿®ý›Úxþ{sþ|½ðÝ»ÿÔtÖ;þÓäu“\_¯†Ü¾®—H¡.Lò©ÿºIA†²Ëàú³I ú6 ÛCÜ&áõر׸¾T0{¶ìl%gã,`óN|!¤ùgnÆñÍçßõßæ»ÉH„Äë¯ã æDHªR¹~ ›OÄ™± ¡Ðr%VZªÖô’j|'!ØÃ¦µ¤%¶„Çk Ì].ƒzK8yØW›sq¾:ý§ÉðeRÞ²ËõŸ®…)ÂøQ~s~xž_éžF®ó•Sw0÷L†(»ruÝÿþ¶‘LyR×CÛÀ|(²–]B X‚ËÔâi?ÎÐf*±âdüqЮx¾Š>§àºý²\{y#GœSMÞ…± ø.!×[,Hð¶‘ÌfQ‰]€êlT8F,a;yרg˜5€dæõþ@ïÒ7‹Çeg•˜5«Õ÷ôƒÁrE$Ëy¶‘,“Ë[ËC±ã£hî^L•KèÆÉ]Œ —ìå!Î’ºs¼ñð-~øHè? g{^Ý»0´¹ë?Ûn¾n åg ÉQB\IxdöÈ‘$ÒfÒ6’e˜›L–Ì(¶‘Ë‚ߟ!tÁrö c°l ¹@s§È¦cö¡íø6‰g„Í3¶+Ö,aÔ) kXÓ+ØÛ€ƒ–0Æ"°eŒÏñ]˜`È`÷Û€³–`wÔ ‡ÂÀ¤à&0)/‹ÀGέ·îð”UyòK‘5ªê8#Û[t…Sàý0¹×õi0¶ñ%B²Üg"¹O¨–BÛ0q:?–ð[Ämóó áë™àæ²e /@þ¶vÇ™6/¥Óül`?ò=:éÒÙJ¯î"þj#³ä¿€^lcÑÙFò¾ð%„Þ6’-ÎA©Â–Ìç®qÑm*Zo ‰) Í·Ú{°ÙdÅ©j˜NMv8Þþéü“ÛÆÎ3-vJ_,m¥5“T×J(¸Ø©²Ê5€êÓùÝóçÅzí.‚kÿŽÒÿ»¼vüwý§±}šcѸø­€G“S¼Ûaçt~l#Éz4P7·ífN<KXz! ‚àáŠçžÄÓ_rëôGUëHн²Þɽâ.‚á˜ÿ®‹Ðý ¤leöåÂú%“ ã†>y°íÑÎ 8;0PYü7Ðrà´‚§þ!¡±¤²|5õºåfŸ¯ÝYòöà? Š£i°„H›>`m¤€ÜKÝŽfíÈW’»¬œä¼®²m”ƒùF 'iCÉx’‰fè’3¿›ïî!è›{yL«ÛÔ^}×C Û(úÈéñhr}—œµ)–‘Ðûþö¡æ(ˆxÇBEIU<5N.ññ¸8>ÅûÐE—dœJ›ÛŒP>¯q)±Ql#wüg›*XÕÑ6L – ,­õÞæ;€ÒÕE ”ò‡Ú;ÕóªÇ$Cs»…SàvNçŸÛ6r½«ƒæ 5;>ôs÷Ê`EkBÓZ‚+«CçŠÓëÎ9[¶‹ GoÇ…î4ê_¸Áp/wçv ß fÖ„ÿÆspAR…íhÊÄßnqäÚï–”¦5¯§uœWŸl[¾BexTŸÎmx…—a®Ø[ÙF ÊœÉÛLX.¤` X‚¯J½Þã`E–`b# \€þËÚ°Ž‚˜ºiÐŒ¶ûàhp“ÂÀ¤à&0)8€IÁL `Rp“‚˜”ð8èþ‡ŒÀ)$~€oƒf áþïÿþïìTÀápÀ¤° 0)8€IÁL `Rp“‚˜À¤à&0)8€IÁL `Rp“’øAw>hðã0ñ¹¡›Šp±ñäî'_Âñø9݉2…~x—áÅdñ¶-se: b9m£Žž•Êo•”uLRŽ¤è¾žÛ/_¬ÿÝ_vu)Œ[ÿ%óCl~©&/Žný‹|?¾¡@‰) ¸YIö=[uÁúWã{Ž.³n¼b¼k¼‘5ž<㜼С'§†NlvWÑÆ›þ!&Xì§À8í"ÀoÓã™n¿9Ž»ÃA$òªCÝlU6Mò–ÌHH¡fN¿s™ç®…rsÓeÉe¡ 6e2r!sE$‡_ñU6ÑŽâ&[hã\s41Áôwn:;9Kî'cñúÑËîž`œ¼ÍŒ÷5)W¦!ÇÍ£¨Ìs×uí¦PþJÕçB.©i1!fØOû€€~Iy3ÌÚ Ôµb¹îä~§²31ʘ›´€B6ýRþ}ù7tØÐŠpî {ÿöÍìÇÒ±§i°A¬Î»òÅŠøéø4§À±rJ?÷a•‘/ù©ÿ#²`j.;pèK[“ë%3¹ï˜u{€«R³ 航XÔÈ^£-p k…:4U›-¯æKºº>þãa̤ Õ^¿aC³u$˜ØÉÍóÄ ‰YÍ|C[´#eóëÜ8ƒAJ7 ²„2ÏeA/Q.Ÿdùoª¾¨l•:2â8FdÔúsVͯp< _¿6²ËÏ…§0ªéº h?£×y0†šðPÄ`#€Òc×’¾3L\äÐuGì‡Z0)üÀ¤à&0)8€IÁL `Rp“‚˜À¤à&åå0¸³Ó-ùûï¿ßßß“\–gë/¿X^«±¼çGˆmZ›˜6ã“3³ÞqüÕXqÖf}¥hÁ`*f® sj|e½ËùÒ`?æÖ;–ÿ+¿>D•€† ñáp úççO9Ìó¯ \/Ë Õ×1Ò4ÌÜ žãzw ½ß…ý?äkÓ¿Þ¡õ¯p5f® ÆÁ¦9 gBìë]ÙÜMò0#´ÀØô©FªÙ3rJNl‘qâÎû’r þp!W°¯Ë ÷å\^­8‹ìéUô‚eq§×!›.aöõÁZÅ£Œ!Èû@£Ÿ5ÙA»ï2‡Oº wÿ×ßÇÎÄL àp’Ö¤5ÉÔ–ú^°ÜÔ¶PùVÑæqñ”@MGr#û;µæ7Ùš| –÷šíO}¥ógüßõ¯Ÿ5WV.¼2¸¹D Z_ßÓ¸GþUaE˜æõNà_’Ú•õ-7(îÝdœ±±Æÿ]tžÃ¯9úD–âWÚ\Mp÷“ùRænÉvoÃæ Ùpç?OÄ'>&n˜âämEÞÜÙ,½Mu$óRíÀ”cÄæö¦^%¾-yÛœw®|’1yLÖú¤èœaÇf $¯!æ¶ö'ÐG®Iu­€o%þã…Á} à•ج!¿ܾN¹7Ï%EäÒœKdî¿ÉG.mɲuÁ>È©ûo²»ç‹[G‚·’ñ' MÎfЇJ)ØÅ˜ÔcR³±ââW~~3!²ÖbkÏUØþƒ‚‹¥¼ÁJÖ&!°wýéÆ~‚©äÊÁWG`ºIÛ“}‰¯µåµæjSЪÄúíR¥0ø—gù®ÿ–¨³™ë‚åü„k‚ §»³¼Ó¦Žscÿ(1ÍV>':9-ºý,Äe(ŒÙ“­¡/+”äe10g¬åø"ˆÄ×f¬Ä¤öã¢H*.2PM2ž@#që«)¹Ü§?nã„6=×råbH&,Ÿ©¬ê…×s²r½œ%ª\¥ n\ëãÿ&[€ ¡^”K¾ ŒÒ]*§‰ØlVªMãŽe%÷d™‹ßuX–¨qO¶õ¹Ý"ÚÜfÞƒ¬ùÁü.Uhß÷—$-©†/Wi_üX{‚I_Ç–kýs…–, ¹f mwÎr‚"’Ó Ñ…ð_y<”ÌlCðŠ<_Wš~ þÑrIÐiÒyÄ•åG»Y›¡žjª ) #€z„ŽŒ Pr¸ïÄì¾³lq˜¢&IxZT¯J‹hó•ê^Þ¡ ãÏ=Ý¿ h3ç_7k‘’¾w\c®û#,2ø>TŽœË½Þ¼r}n«¶#bû¥Žâ–º9î÷‚røØK²ºÄtnô3¯ÔTÃÍvJCu_¡ÕÆp¨ôã^ÔP3Zÿ6 õ¹X_”ÐUS?t½¾ÿ5 2ÌÉÌz§!ª†5€«1se (¢Æ¬Ó>W]€qÁçdfÇ¿“Ê€·éŠ*g *Ü̬wZ¡jÊv匬Õ/zkb“ƒ1"™9û3kÚŒÃÊ€3²æS@~mÆ÷SÄÙ)‡43W†™Írf½C5•S@ËÁ*ÀçdæÑÏNjem*Ü̬÷i3¾Ÿú_s×”¾)fV @ vÍ\ëÀØáœÐUcë(ØÏÌ ¡33³Þiý«Á\™+ @•‹À¬€A0Å9a ¨šÊE`ŠÛ,T†9™YïÓf|?õg`„™+ÃÌÖ8³Þ¡+?°Á9¡ ª†Eà«Ae˜“™õŽã¯p5f® 4‚E° ®¦8'3/€ï„]@WƒÊ0'3ë}ÚŒïg×/‚xH0se˜Ù&gÖ;T³wÐÒ®Öé`R3s4‚sB­¯ÆÊ"ðêTVdu¢lÊgNfÖ;Ž¿+@©BýDç´õaæÊ0­Ò—¹õÕìúIÈuƦ­å µþ›!Ýt“?ïÄÅÐþð‘‹y.&©Âqf÷s{<î?Ï¿ooo­b/En¸ÝSÙI,%½¡ëí1Gßî÷Ÿ£¥Ù#êýwÊÿ÷«ÎþgÈÄw¦BË?~üxþ}O>5tPi·=fòÓ)mš€ÞŠØµ h½hRër­¿?Þq«ÄË–¹OFpN¨ìÕÔ/1û¯ß ºÉ´>`Î\ÃÌzÇñWSù%psr*LÞôí?šÓ,æÌõʸóàû™6ã°‡ú]@›ë±ÁçdæÑÏN*§€üß8; ð•aNfÖ;­P5V>ƒVÌ\hŠhàf®u` Á9¡ ª¦l¸á¾O8Veædf½O›ñý”9€äÔ?þÀ3WA€"*w ÿ8 LqNèƒVÃ"ðÕ 2ÌÉÌzÇñWƒ¸3WA€"ØÜÿw_Ïk´à<øfITMñ. ³ ̼:33ë}ÚŒï§ø, ¸¬ñ ¦˜¹2ÐQ6Tz4@O0Å9¡Z ‹ÀWƒÊpa„õ˜™õŽã¯p5f® 4‚E° ®àœÐUckÐæ"žÿóu1\J`NfÖû´ß¡]@›ñø&>³¹Ëè‹eMþüÏuŠqf«"ã×3¹Ñ±² HSu‹1*œ!AhÎU+{‡o0­,—6î›3E›º_ŸwÖcçbÕzYË÷¥I˜½ÉXq‹º(_î-‡‘ìTÔ÷ÿm‹ûÛÐá݇ûÏÇÇÇóïÛÛ[«ØKQ6ÜB˜µh ¦AìMt&+uHÏ·ûýg¯qäÐøýÁ'R’¶äßÔÛ•f“ry‰ïWXø?žßßß“OÛ¤œ)ºêd®ÝúCê{5eÀƒ8MŸ/BïýföÓf¼6OÇ›Yï¿M¥ïÇÊ/‚ó_Â.Ï81¹¤^~B —ñ³“ Ï€}N¯L›ñã¸Ò,SŽâm Ë1¿–‹Ä¿¯T®·ÉÑ}ç™ÿN¬ì‚VÌ<p.çÎìÑû@óɤŽÕú›*í6_¥€k3³.fî N›qØCñÀÌu Œƒe^y[d"ü³cúϲ\}¾þЧ€VÀ<Ã)h¨fNfÖ{µã75s Å‹ÀóŒÝ0‰v’Ìcœ1}¶B.Ñ[uÕ¤aåºX Þ¹Ù©Yˆûרuƒ¶ø–sݹHϲÃ#Ú ;ßi”µõ¢ÍG¿ß—u èt†SGåw`–™{Á3s´ÞOéhoOx®þÉ>b!Ã6ЫѶÐÔÀC«GQü̃Gñôl‘/Üú/8=¬ÙçåõW}®¾êœžòø¾?ŠI©ù,cy H3*ï9‹ª9\³ùœ­2L ª÷(Q tkàÄ©ùÒóM;ƒø—VEoa ({ŒÒÁiëßp'ö‰v~~Ê›Çö¯3è•ñ¢,œ>v9=Æa (Mö““T?%¸)Ø\2°©åµnéùý#ºdüþ…œ­´ÉÎÏrÆý–ýÜDÚ):)%ß_‚µp%Tm;ÅÀ`‘›ïÜÈÔí€Ö„”%&ïË;äÇ¡¸ÝÙßS¿ÛüjˆGo. ^—G÷Ïë‡OÃtº“JñušŒ3öIJÑÉŒM.i>üó‹Ù¯…¼¼L"‰yßL^õ7 øš’\å®ÓÍlVÛ4ƒŠ›;±õ‹`ýq‘ÃbwXÄãûrûg#•3ûÁÍ{å¸`ýO½–ÝÊ efƒ"êÇ÷âí^ò/‚1€´]D©Aë¿…f­U?¥i…vŽ_™ÙÊDk—ƒ-qs2³ÞqüµØršyä03 ô›™+ \”Ç÷ÿ5ÇXW±6Û÷™ï6 œ“iÿc¯XqnƒÐ¾kÂøÏÎÓILSÈ;yŸo÷û·vÛ55ýñ׫9#æ¨UšGÌ{+Èû4<}ÀÏŸþ]Ð(?5þÉèÑÙ7Å­QšGÌ{+ÈûÙ©8<“þÿš´þ‹) †°HWåÙô·jý;ÀµÚ3÷~2FˆmBFì µJóˆyoyŸ†Mÿаè~q^ÿ«ô3û¸m;þ[kqË®¹“{:O¿ C#è  ÄŸ8ÒO"M7"üuŽÓ™9ûó^ñú5ò~å쬟 w;y·54µý9Âw†­lsgßlëß?ï—×µwS¦Î ͦÇÎùpÍQî¿vì€ìwÎûb¬!èŸw#]àÎy·¦tFÛÄÕ\×UÖ®ðÔšYôÌþZlfÿ¸¼[ÖøÑy_DY§wSΠB¹?uS£þ:˜ñ†¯Oöís¨ê—z¿|ÞYHà}¥/Êo}~±ØîööÌþÙy=-ïñÓAïòn F!¾FãÓ§sw‚×õÊö­Ç‚‰ô̾Ïåón ô>gÞgÿQx€ #ÿ(ͱè@\üV\tKç¹Û9Û°€›8ñt~,Á/ÆCAp‡pÅçlˆ§9¾äÖèªÖ‘ {e½“{Å]Ã1ÿ]¡ûHÙÊìË…?ôK&5æÎÅìÜŽÕõJò‘ü$ÒýM>õï‘…Œm$•%Ü9”d¥öm@¶ÿiÐPlMƒ%¼D{xûþøˆÓùãÒfý–¼?TZ¾¬°X\QœÁëq׈ÏüÅÆ™*[·sœ?åXå=”!ÎÓë$A.Κ°Êž¯Î<ã24Çvç k‚aݬ|®|Sù{ƒœ¹yS„U¶žø2ñÏ“ùFŒÊ•aÜód—¹rh3Á°>Ýÿn  ëzk‚qõÎþr‰ã±½Ø)`ÜK$Î <ŒCR½Ãaäi 2L *Ã" 2,Â?•c§É¨ ó§r䀌Ê01ñ*3*ÃÔ|UŽ˜]se˜™ŸÊï³ T†©AeXT†E@eX„B•Åúy³ÑÂ&´QY¬g¸ ]@eX„j*ïÿü{°îEeèD©Ê¿›˜ÿlv>ë ³eèC­QÙu•¡;•UþÎ-~¥øæ t£¶ÊÆ™`¼Ÿ«¨Dƒ ÆužËО&g0Œ¸Ã1*C{¸p ‹P¦òïcâ"ôâá:ÊýÂБˆ ¼²ß£†\Ú}h‘÷¬6ŠGe9~í€:rƱ™Uf`Þ•¬o×.úÖ2oHc“›•íר oøR 2óftø¾s»Â¯!ó6döuË_ÀY×>\Þ„ìï:OSú½9dÞ>&7.þÞ2¯N~ëR™W'¿{›Ý¬Q¼g=›„Yègr‡ M"ó¢”ô¬J•‘yQŠ~íÄ”5Ƶ )Ÿúü–úF.#óZþʉY«Äµ‹Ì ÑÝänuÆ6 )–Ô«ÌÀ¼¥ÝØü.ºj{úÔ42ëgˆÉþ±dVNy®¢2SfÝTøí?ªÅ¶ŽÌZ©Ðun¤+®Û<2«däo±šTef*úûØæýP ÌÚ¨Óc ªŒÌʨÓ[ï ­¼çã·umò ªñÛ@fÔê¨uUFæ¹D*5ã4Ô³nõôî@øQé« E_ø(ùßø¯²Voò@åR˜'•ËAæ)ø× óÌG•Sæ«’¿%uI‡Ë€ÊuÒˆÌÃAåZ‰DæÁ Pù¬¾¥u›Þ—?¢ÿàà§Âk¹H•#Ú9+¤ïCiݦº10•k‚ÌAåº ó0P¹6¸<T®óP¹È<Tn.÷•ÛÀÀÜTn2w•ÛË]Aå†00÷•›‚Ìý@åÆ s/P¹9¸ÜTnsP¹ÈÜTÎÌ[cjíçF r~Þ‚Êé r~Þ‚Êé rvÞZN/P9Ÿ ‘ó·W•c§’·¥uQy]P9;o¨<¨œ·ž*[ÑGìÚ5M¡ÆV{» r~ÞwËõµ¼û.{)-µóU!¥øíò„vB:ö¨‹Êfi•+OΊT.¨ÛIåç£ÊC¹»æO9Ï££üž—Xe¼ÒŸ‡£ùÛ­è&~<{Ÿ`$´“§cyÝ^*ÿF^ʽ«,¡‡ÏÌý,y¼/®¥ÍouRòTÀ¨œG–ÊòVî^eûÃJXe«fH|ã©›)ˆýÈws„ÌmFýß"yiHj«ü[Pù€’ŽêÎ!iQ•Ý„Uêý’vFÕM ÑÛ`ޞܖN0îGeó¢²¹ ÜÁ­¬…<¾ìÓΨºéÛ‘Ûñ¶JóÞë¢ ÆF*W:0àÛÕ­Ÿ®¿ÿuUÙ;'ñû¬w=„Ï`˜ÅÏ`Ü&/em|Á’­¬m®rm— šË;?¿oi¥15mÒØ©n~ÒŒû¡Ím:mkP9/vTÎHÚß[•#Ï+Ÿ¥+Îñcë®g2*g%ÍÛ´·6ÅäÚ*oŒü.Ÿ ®OÎÐo혬vŽ}0NIç‰D×½Ùš‚Ô9¯|FåÄV¯£rv;ñ·Ö­›Í›Ê)…а^oOwâ/‘¿dû—•œ'ï c÷Úm[Ò¬îµÞsÝü¤5ͯÊ÷}ht¯RÌõÑ\ÚrÖÄÕ5ñu¯»ý\· iMAå,øØ×6iYŒ– „uQ@-–ÂØ z¹œšÀfÐHÐ[le<(‹Í ‡7Y±¹ bý ­Ž<=ôÒÌs÷ÅìCÑþ÷4'nkØ\Ÿäyuj3îe‹œ}‚ºIù•è\—>*?7SRy&•ÓÝĿЄ¿@s¤8]å‡fZìCцëf2o[Ø\‹c2iÝvcÝr=W~i¦¼²äÕí4W.Ú6WáðÄu {‚ñÔL‹}(Úpµ$o›ËñUþ t•ï~“Hõ}(Úp¥ÖÙ6rQÁçmýlÖLI娺-óWùž»Öû»0¡t•½f"OÆ=ìCìÛ i’^ž½êícs6á3ç¯I¾Dl&öÉý>í;´µ ¤©oØ è 6C{zI†ÍД oNHf€ZØ õ%6CMÆú„ÍP‰ Lâg(f‡æÙPÈdö`3d1¥8SîLͼÊ`3$0¹-Ø Q¨EÅNÂPô(‚Íp6;´í/tB¥Ø Š•P¼ëPí2`3ü±„ؼ= )°P(ÌjÍ{²f¿¯<°psƒóF¬ß×ëGféÙ s8·e«Þ*ØÍدk±yI6íUl^Œ­;tëàƒ®Äæ)‘ÖŒ<ìBëkéBò º°Ï~jɃb¤é±UO’õÐ…äaèBò°=»ð·,n¿^ÿJÜ·±J¾RkŽ?äU% šéùqç¦S$\í­ôñÇ«„ 6â–Ûå]X­uç¡ÞÑI1Ï ¸?`>— ·ïÿ±ËÏÿïó頻Wúóp4~³¾y—ròû{׿¥ ÿ "/åÞºPBŸéêYÒ™f>þÁâ*ÿ—ˆ1y¸¾¹·¤«Ê¿‘ê¾ ­Z¡7^‘züçAP9&~‰êÁ„ÑÈžÚÙîçüP×ÛËñµJŽNõòp?ÞŒob'7ç‘æˆ÷£‘yéÂó•1TÖšñ7±#Ÿ$< ¸5Úw¶eîº0âÀj©Ü‡jóà>ܯ «÷áÓ'÷ï\×ùä~– r·®Ã^•õäá:NïÊ_Vn§±'ã¬Âö3w«EÙÊynzPv7ùe4Šýä~Ö¬rr‰”Tþûq×7ÃTN¨W§ Õça{“_?¹Ç÷`Ý.Ô‡*C4uÎ+Ÿeµv!yPÏ[Æê«úq‡<@*­S¬¥ ɃzèÂ>û©%Š‘ÖŒ<@úä iÐ*!Ê#ŒGÿ ÚAå/¤A9ÂX_Hƒn¬jw•uƒÊ?È‚nøêÍYP\~î *«•OÈ‚f$ô°)$A5¨|B4#7[B#÷O6•ƒÊä@1òøl7È^äíé^ ²^PÙ•Õ"Ï7‚è•HZ$îÅ6 ²V$úÕ&ðnÖ *»­HÊË@e¥¼ýî³ýº’7³RPÙ•u"é gûh•IÀHÖ’¥Ae•HÙþ½¬T&þ5‚e«‚Ê‘²…k²û[Y'¨êFáëDŠ—.Èîïd 2á¯ÔX¼¨¬©´|1PY¨Lôk õV¬*«Cª®Y‡½ßÈ*AåÄw^%R{Õ"ìý>V *üHƒuK€ÊÊ6+••ÊľÒl­vPYÒrµnPY¨œÜÒ¡kä­CJ×+fçw±FP97´…#WÉk”PËÆïb…¼÷FJAeM rA\«®’ˆÎ¨SD#û¾‰ÓµÊè•Ê…Q­¸B¢:¢^!eìûV*—Æ´b܉뇚¥T±í{X‘½P·˜"PY ¨\! åÂÖHl'Ô.§…]ßÂúˆî‚úu€ÊZ@å:á,µBâ{ EIìúÖ*× f©¨’ÿ6E§•u’þVe'gÓƒ‘:P¹b$ë­¤ä·+<3¨¬‚´Ü·,=/{‹ÔÊuãX%f}$f¾mñIÙóý«T®Å1ë#5ï­ËO *+ 9íí+LÈ–‡"m rƒYéIïQc6Py~2rÞ§Ê\ìx$Ò*· @}ÄêÈÉx¯:±ãœJ¨Üj÷•G¬Ž¬|÷«4 ¨<;yéîYkPyvP¹á¾kX™Éî[mPyrrsÝ»Þxö;)•Ûî¹Þxµ‘éþ³ßŒJ¨Üz¿µÆ«ü<¨9Tžš‚4©:TžTî°Ó*ÃIe‚ºëçjt¤*)¹e|TÝQt‹w†`õÊíö•»‚Êíö•»ò/k)38™ îÚ¹š$X} òl¹š$X} òd¹š%X}tÒÑÔ¦w»Ä;K°úø¥øµÜƒÊuMAÝiz·}¼«Tn’«Ìx' V¨Ü$W™ñN¬>P¹I®2ã(X} r“\eÆ;Q°ú@å&¹ÊŒw¢`õÊMr•ïDÁê•›ä*3Þ‰‚Õ*7ÉUf¼«Tn’«Ìx' V¨Ü$W™ñN¬>P¹I®2ã(X} r“\eÆ;Q°ú@å&¹ÊŒw¢`õÊMr•ïDÁê•›ä*3Þ‰‚Õ*7ÉUf¼«Tn’«Ìx' V¨Ü$W™ñN¬>P¹I®nã}e–`õâ•#«ò5UMÁê•›äê&Þ„ A*¨Ü$WÁx“6©|»'©ü躣(7¦ ¿(›Ô¬e4뎢C¼¨œ*·Û&]‰ÎÚÍ\yDÝQÅ›ÄèHU¨ÜnîÊcoÒF 7å£êjÌUT£\ˆ’ª«,W’¹’‘Ç—sÖEâ>+:þè¦$¿£êêÊ*7'6Å¡,ª»r®FǨ˜’Kn£êŽ¢,^ù܆ñï‡ýߨ ' VŒÊÝrµ‰Ñ1*•ûçêïµ÷ÿûdž`õñ—½óøvÿÄÜŒ4êËÕeRpóäv‚q1ÙZÿ÷ž`õñ—Û¨áO¦©«5WªAúøtÏ÷©y$%²nèIlݸíΕ«¸x¡9ß FÞH3¨®Æ\AsF}t+©«1Wäú-ìÀj>.Âüܨ|(,öÀ¼ r¢Ž}e«³ªš·¹ážõ¾gêäsH~«¹£oFxuRí¬ªF‘ʯá§›­Ëb×Cå  rÙ*ÿ~º[õ„ ÞżûΟ¹µ³ªš{67\_eï7¡rÞŽ}ÏWb_œÙ63öln¸•/õP¹œ÷cŸIè£`í¬ªfÆžÍ 7TÏ{ ˆ™1`U¼ûLÊpªUÕÌØ³¹á†'&Æž˜ r1ïÇ>“¢r¨vNÕ9{¶ \hNı¯ìÈ™WU‡Ê áBs"Ž}eGÎܪ3^ûzßç)wãÿ#üV£7sGVIEND®B`‚nagios-2.6/html/docs/images/network-outage1.png0000664000076500007650000001543407436604447021127 0ustar nagiosnagios‰PNG  IHDRͶµòtIMEÑ 9s.t pHYs  ÒÝ~ü PLTEÿÿÿÿÀɰtRNS@æØf™IDATxÚí‹¢ª*EeÿÿGß{*Ë*(°^cìû(3X˜,´´iˆAz±|v¸çãz®ã¸¬ãY®)vóµÓ.빊âÚσpÍÚCÇv*È›—õ\Äpíç§A¸¦ÐÍ%«àËzÎC¸¶óã \³v ›·{ày7¯ œ.l/Ý^zy9d•—¯,LžÖ{.b·;îÊNÓºŠ´‹`ÿt·þOû‰gõÎùé†ü›qäæ•wOV{Lë7¥¼áVËš9ežŸ»y”™pŽvÁÏà“µG3ÆLSÞÍëƒÝÍ{6…üvÚ[éhC±›wç5dÞà‹¼›Snô{°Ú”²oÞ¬Æ÷N*vóvå0×y®;ƒSö©ó³õ÷úb·©ÄðÓ±›3>ºåæ)WÕoË…¼ >ɺù,§þ6LGï9Ü”KŠ÷Ü|UÓ¹—¬²\4¯2›¸9µvs&¼ ŸfX§ÚÍ?/Månn³ÒÞXãf ^YLþ–ÂWnNkK?vsÑ'TÙÏϪ܌ŸÁ7‡n>ØmÚ¦åÕû×{ïÜ\r,3;¹ù¸¦¬†å[±38dŸ·¦nnžö™x·)•¸yôu凚<‘uóáÁìbÇíÃO¨¶­µSîáâõÕ¦³ªŽ5LûH<±I '¬>´ÍçÏÝ'ÊùO¢—’óîw]\æ›j'²ÒIÈ»9{šiŸþÖÆÈrWÏar^¿7÷]ÍïÃ#óŸlÊÅà‹ƒ%ô”·Æî=ûœßoÊoÝ¿3SÚ´bõÚz÷ü™ïÃZüpäæÝÉßMÚÜ=:(aÿ8o¦œË–ÞÝqüÚ‰Nh˜»˜f“¥Ã€Û\-äÀ ¹³â`Ì à¼ àŸt°%í^M¯gi³íõßÕÏž®^€¦º9M«oN¶§Ì¾?“ßsðtý4å÷Íèiu°¯›çW^6|í°Ú6M w¦ßƒ´,7 à·¢^¯¤Ó÷ï³íããi³m:róÇñßÂp3@gVW-m ˜ö6L³S¦Ì>H¿ÿýžâf€Ž,só´Y+ºy÷žü“´}Š›:ò["oWÚûUõùJ;—§³Oq3@¾wÐüžÝJ‹$½= ¶ßö)cú-¿¿%~÷]žLã*8#Õ"0PëNÜ  Ü àÜ à…—;+Ž™q3€Vp3€p3€jÜüÝòuó厸@7¸À ¸À ¸À ¸À ¸À ¸À ¸À ¸À ¸À ¸À ¸À ¸À ¸À ¸À ¸À ¸À ¸À ¸À ¸À ÜåÀ ¸À ¸À ¸À üª€p3€ÊÝÉïPè†Ü à…Â`ëSa  àˆtúôÃÀ>4x¡âC*éPàr3€p3€ÒüÏôý¶×ÉÐKšJ“.nÐÍ{ ½ºìq~ôMÈï¸@7Ÿ•öòæÏÙq3€r8 ༠à‚ïAô„¡,³8 ö{ ÖÈ%c4€=m‹Ÿ,qž‚IÐV(0+~ÐOiâ%Aè¦Ê¢ø@+õé–  ‘›ÆÄÏÊx`J4€û?¨ ‰IÐÒ4t!~¤±IÐ2tñ~N7Û‘ FÒÙqø`ÌF‚èÏ0Ÿág€® µ  îÂÏ2  -¢žÂÏÍ·  Jœ¤# Ã(2‘’iÀ$êü£-#¨´Žº @=Š]£72…(7Œâ©@&¼b!FaÌØÄĤ ‡-‡ØŠ` ³ÁúcÕVãè„ég:x€¶Øwƒ} p’ٜȸ'xÒP‰»|æNÀ9ó€÷9ò¿ª\ªXñÎ_޳˜{Ò¿aî}¤¿$z áI)Æ0""“B¹9€NðOªE:`P;XÍî4ýUý™ qˆçæ:3ÿ™ qˆçfr3xå5X+!ÍîWn.LnKÄsókù\ö—ÈÍ`‰xn~çæ"3“›Á5nþîo™97,³ÇÍ`Н›/wôâæon¾:ý•ç´ÁñÜ<çæË¦ÈÍ`Œxn&7ƒWâ¹™Ü ^‰çfr3x%ž›ÉÍà•xn&7ƒWâ¹™Ü ^‰çfr3x%ž›ÉÍà•xn&7ƒWâ¹™Ü ^‰çfr3x%ž›ÉÍà•xn&7ƒWâ¹™Ü ^‰çfr3x%ž›ÉÍà•xn&7ƒWâ¹™Ü ^‰w—¿97—&7ƒ%â¹yλ%äf°D<7›‹nŽOn;ÄsóË¢e›Áñ~Uîê\ööd˜tÀ¥Äss™í †8”Öäèw¨Ê²2¿C¶ 7“›Á …çƒÖ§Â,N0D%Üx'B‘NŸ:d³ôö/ün½N0D Ü1d8Á‡Š©¤Cm$˜¯Ž€WÂ¥ªp‚!áw8Á‡4ÿ3}¿íuòÀéß%‘¯sÙïo{½¾÷5å·˜"M¥9ÈÉà.¹óÇÍ`’÷’r¹¶ü=˜æk&_ÿ:ÜkÁï¯o~Íÿ¾ó´Á‡ÏJ{aæÙÎ3{ÜïeöÎÌigfr3X#ÜI¡p‚!2ñFr<Å‚÷;Öàž,"iÿ,Çs”±Q3¸g—›B í­f öÉbÿ#;¦jpÍaFr>°Tch°ÊÙØõ<®£ê·\æ!·ÃúJ7†[”ŒXŸ£:®rpIqöq8¨K•ch°@Í8õ6¦#kÔŽQOc:²vpÇ­õ£›!}G;†Ü™>FtlõàŠGYÆÁ€~¢Cƒ&žŽGëã9º~pC“Übz8·Ð¡AžV£Ðîh¦ÀM3ŠÑÁܲ04HÑzìYË´8 K17”{´††±ôq¶F2­æéš= äž­€¡a½Ç™•qL;€q†ä ÃxD;`hèǨѥÓ`š¡™Bù ÙZ3zLiôF$?¨Âm¡¡ R#Iç¦5À,¢YAá–l O?Òõk‹Gº~0‹Š\ !M±¨è°†šQ£%5¨é0‚¦£#Qè‹”£n5§ !¬ÂÑÖE ãD:&éú­ÄªP;狆¥µM´vh@óè‹Vs¨Ÿé¥¾„%­û"<íÝã±0&D¾-N»€-ÌÌïiô•ÅVÚÅJB/æ`i$¤aãö_E¶Zf~  ðö…µY}”Ó¸y£aÈ“½…$kÉç5n>‰zàêÔ¬×1a'£íct‚G­ÃÂNFÈê, ¤Z¤uùÑQ=º¥ÞÆó7UýUë­,__*0ïæÎƒµ¶üêé¢{*0ïfró…ãñCïï3•Riëì×`-Žÿfn.>æT˜Û^Ó‘áø¡ón~Ö¿²¿›¹¹´ü;ÓE÷zMGv㇠̻¹ó`­*_cn«˜ŽTÆÔ¸ù»¿"¾ƒµl¡}?7,S“ÆãÎy:²?TðuóåŽJÝ<ÖËÓ_÷kqùÓÍé¢{}s³Íø¡ónîßöz]3”ÝÒ¡üMMyGÖ.ºã‡ ÒT:'ëììô’›KËWzÜYt#$ÅñCï%Ör­•æ{ mrµÎÎNï«wçøÿæ çì3ÍÙçnnΗÿ·,ûS“ÚZtð+ÚùQ²?TðYi/Íüqóvá­³³? É…Ùf»mÌ|ÿœöIùK3(ÍmŸC……™?ßšYiüPõ“$œn Pù®í¾ñæ±ßÁPÈ{ý9Ò’榄¢{ ?©àÕ<Ò2ïÿ;”–z²é_‹Ý=ÇÜ/ô¹ƒã¡ƒ¡ˆÜ\mnþN™GÖjè…‹†{ÕRw¯bí÷ªCM㣃¡€óÚÌü=àêìmVZÆGÃ5}i¡»÷1¶:lч“†KJçeõów*ÜÖ¼íí⥃ኪÔÜݱµ8UmV›† êgcµówª~¡i%Z[ÅOÃ9·¿é(x]LíÂM7_“ÂQÃ9úL]w§¯6«E]£8ê`8ãézJÕzì2–6±^–¢¨I|u0œÑ¤§ÔtwAMô좦I\u0ÓnÖU1—ÅÐà~Ú ÷ꋳ†c÷xw—Öÿ4ÎâzÄÄYÃ=æZÑù»¢î‡‡‘]bjŽ»†#ºõŠXwWÕû$Ⱥ÷Š5‡»†<ݯޗT¹ÿýš:GÖ¦5Üu0äÐû»¾¾»ÞxßðÆpØÁcÔ¼:tþ¾U×½ï½ih[8ì`È1´†Uf Ík — {ÆÏ¦Cj|òÅîoheE.;öµ{÷j•?ìÔÙÓ7—”ï´ƒa‹äÚµî§eûX«A¬çe;í`Ø"ÞÚý>ûYÂÐÊêÊuÛÁ°FÇÌÙ%Š6—4ß±wÄ»2Ýv0¬QÔÆÍCiTÞØ¸mÝ ž;–h›/›ÆÓ®¬A×]µ/ÉwÕ-Ûîú¼–A ®Niš÷”uôÎ’M"k}¥ßã×WÒ®;~(oÏÇá5——½<¾¼w0ÌX˜ÅØåÄðí{Tx¥ßyÃŒ™V¼hÿ_‡SáÍbýw0|0Õ‚¯|*)¸ú…n5JÈï"ÐR°Ú°·º¹ñã ƒ_cí×Ät0¼0ÚnŠ~)oì[¥ˆø~m†-‰å9° W¥Åÿ‡Vœkx×Wë׷ÄKág‰=ÖUéS_JêàÐŒe’2eä~Ü$P«”b b¨,i„Í –#çÊEôJ  ˆÌ…Ö ¤6ªW¬é`ßz×âÿ¦ª?ë⥮½kçTW¯ùÀÑô†/æf©v7]ÓZ<¹ÙýtKï^|ñ!†}ñ¿£Ê©šæf‰v~M#¥{˜®ƒé͉ÿ+û³/^ÌÍRíüžFÊþ|L×±ô†/››Ú¹bq‘«¢éÍ‹/[š_ãæïþ-ê•jçy)Xv&Ç‘ÑôæÅ_ž–ñ!þëæË»Yª¹êêt“é:˜ÞÐâÅÜ,ÕÎñ¦ëXzC‹'7{Ÿ®ƒé -žÜì~ºŽ¥7´xr³÷é:˜ÞÐâÉÍî§ëXzC‹'7{Ÿ®ƒé -žÜì~ºŽ¥7´xr³÷é:˜ÞÐâÉÍî§ëXzC‹'7{Ÿ®ƒé -žÜì~ºŽ¥7´xr³÷é:˜ÞÐâÉÍî§ëXzC‹'7{Ÿ®ƒé -žÜì~ºŽ¥7´xr³÷é:˜ÞÐâÉÍî§ëXzC‹'7{Ÿ®ƒéÍ‹}¿*)½¯ÿ”ñÝ¿E½Ríí>YÑôfÅý9/æf©v®¹‡¥‹é:˜ÞÐâÅsóèvŽ7]ÇÒ›_†ñ²¹Y k~ûÁÅtLï^|ÅŸuñüÕÕÉ¡vm-B4½¡Åó‘Þ§ë`zC‹'7»Ÿ®cé½)>ùùª²=Ûÿ•D;—O#ÉÅï2EÓ{S<¹ùQ½äæ1DÓ»_‹tÀFõе3ì[ouSHGåO¯X;ÓÁ¾õîô;^ˆdõž>íX¯T;§NKz­DÓûl="¥W¬é`ßzËd»k)½bíLûÖ»ìü_ŇTëjçŠmÚV,D4½kñÁ¦2r3ìJohñ¸™v¥w-þßÒîuyØç[H¯K÷²[¤Cm£wþgú~ÛëäAÃz¥Úù]ëY}¿-ˆ¦w#>iøŸ¦Ò9¹õq³P;—ÜÀÈÓqd4½kñï‹èçµÇß|î<›MólæDü[Ür­õ}ôMÈïÍWÚ¹vþëÞÎkÁ¯úæGó¿ŸØI)½bíLûÖ[ÔÒAÐ+ÖÎtp^+'ëjÕzÅf:8 ßñd6“Ó›ÿ !X†hzWÚ{ENoÚüß½`¢é]ÊMgOý!¨7e¹,B4½+±[Ô›Nž¹,A4½+™•Û­#©7]}ÑÁé¦VõJôŽ;w&}}ôh”t°Œö~%«”¯Dï£0ª*R"xÑô PŸz-z‡}E©oÐÁšè~GHeòµè}Gi=Z"šÞÁ¡i’¯Fï /\i{:XƒÂR£^ÞA_8Õðt°<ãæ³™½¹ªe\«ÓÁÒ Hz=zÇÜv`l“ÓÁ¢Ò‡#=›)Ò;äëÃÃÛ›Ô¢J•z‡ÜP¢±é`!é"ÈÍfšôޏs¯PKÓÁ"Q«X“ÞÈ 2:xx‚!HÔ­FošºtÚ”*š1Bw°@ÍÒ'+Ƶ€2½éÿÿw &¥R zwðàz¥*ÞD1²³éí&üçæ¤@oÜP«\Úô¦NÍåö*ÿ¶`/õ¨ŒCIo C™Þ”ú”´¹9j¯T‹ø!ß×¥·c4齯V&ØK=*ãPÒÛÃÂP¦·óU·_7«ì§"Á0R-cÄv‹½v¥w]ÙßTõ×]|çxzï_­·÷þ•í9@pßxz—¯MohñáÜ\Ùžö§ë`zC‹çæÊöt0]ÇÒ»¯¬xI?H|Çx~å– qsÇxªÚ3š®;ÆÓ»|mzs•ý•ý ß-žpn®iÏqÓu¿xz—¯MohñáÜ\Ӟʦë'¹9ŒÞ|e%ƒi¤øNñÔ¸ç»O½ã©hÏ¿4ì8²c<½Ëצ7_Ùåé¦Áâ;ÅóuÏ厃ÝÜ)žâöœFO×âé]¾6½¡Å‡ssi{ú™®c¥§Ðâù™Üì[ohñáÜLnö­7´øpn&7ûÖZ|87“›}ë ->œ›É;õ†ÎÍäfßzC‹çfr³o½¡Å‡s3¹Ù·ÞÐâù™Üì[ohñáÜLnö­7´øpn&7ûÖZ|87“›}ë ->œ›É;õ†ÎÍäfßzC‹çfr³o½¡Å‡s3¹Ù·ÞÐâù™Üì[ohñáÜLnö­7_Y›¢}ÝSÀwÿ®zûÆSÞž£§ëNñD»me¾²ë¿Á¹¹O<áÜ\Þžc§ë^ñô._›ÞÐâù¹¢=}L×ÁÒS®²²Ñ4N|·x¹¹¢=N×ýâé]¾6½ûÊ*þ†ˆïOïýëõöÞ¿®=íÿl`0½¡Å‡sse{:˜®cé½YY÷;Tã)ß?ûªŽñT ¦4îw™:ÆÓ»|mzoVFn÷þ•í©hº¾OìÜ\KoñãA/‚]é­®º³^ÁxÐR°_½»úÆ.DÄãI§OôvŽg»ôV ¸o<½ËWìzd|<è-ØÞ²j†7AïxЋ`Wzו©9ÿ7&žŠ…éíO͇Tcwާwùªã‰6•¡Á®ô†^»Ò»®ìß’õuEÒçÛU¯k>²[ƈïOšÿ™¾ß®:y0@oçxÎÛsÓ²cÿ¥ó~}OïòUÇ“ÞE*:nîOšJçÀqz{ÆSޞæë‚=:nî[¾êxÒûêË9×ÏsÅß<{ü¶ [˜tç]ìrmóÍ{›bã¹hÏeËJÎôëÃxz—¯:žÏBàÚÅ\ MD}ïJs‡Ô¹Œ¥Ë7Ë»Øç°Z¦Èdã÷÷㇗=žwñùNÚoFÍr¦ºNQ\cºì,WŠÍAÅ¥úö(´àck;Vøõ“G5ż,rÈæô˜dNo¥Œ¥Ó7©=®”û‚Lé¤BFNÛ4Kòþ!×B–›úÎïðTòÅm ðI(ÖT:W%Mߩܲ)ž·Î}VÉjIß„e}犧®ï£]ž÷œÓ÷µPk%qÞ®Q(4}“J¾º‘\z”jêÚ3ú>4–ëÖ‰âiëÌß ä[Ü%–VÂ…ÐËŸdŠé¨YÊ~ÊúN…?O¯3²œ+—L©ÕJ>ÿ&_» &ÅŠ*Š9÷QAb„Si'Ãún&,¦ïTÜO%3%[®é»˜‹Ì'u}ת7•c¹V8ˆM»#¦è;—Z9árŠË:~¦ïk6ŽŸ”BïÐwþ¿C\òš^öÇo8—]¦”›‘xô뻲y%Øöl´j,åÚÛñP.åS+¥\KQGßéÁ“F擺¾S5š¾ë»<ÆLÉ2MߟTÛúÞ á`*Õu’R©Á\Ìç"AzŠM}W¸fë³3=};\sø8éû’zUß‚þ}ÌeYÌ—X ñ‰8×U^ª§-Ž´«ðª¾ )ΪïD×wÚÊ879WÞ¥¸¾Ï¹$êû\á 8çª:wÔõ9 Ç©åÕôMI1€¾SöƒŠ¾ccо?[öè;{H”û ®ïKÉPõ ŸŒcMí[GiîôÒÚó.ÙO3EA}?šß­i¶b~ÒÚÏEß×ÔËú¾Š¹’åj¹\+£ ïJ]BàSÎ5[›L;}ô¨é3³ŸfŠ&úÎÌÌe cÿkUX"úNç}æDÏÈrSßÅ”ë±T+Ä#[qnηðQÝ’3»)¦ø¨ì7“BáÓkv¨»ÏÆå}= r¢—4Õ’Ïw)ä3YΕd픪ˆI:òýìûGÒG‡7bÛÈj¡²“R>‹V”ÍF>‡×&šÝGK¶'}Ÿ à"ÔŠi—²×î“ÎYΕdoõÖJ„§Ô sš?|TjVçÄ*_ßý±ñ}޾IyÍí£”²¾Ë{ÞmzzW.ÉëÎÚ¯|ú}OªÞëGåÊ©¶ŽÇ¥¶³j̤U’ç;Ŭ4¯;É¥ÜÒw&×|å›i6€º¾…ýÔô/;¸æ.³3V–Ï%™ê#UJ¾¦xv¬ÈÔÙ¡-ì>z­«üQ>Å|c~o5¦ï\6.ŸTóyùjf«KdíýäÞe¿ÅÐw6ËåêbTo!¨€Y~XŒú`03­`b®S€U€¼X¨`Rá“tùkzþ–NŸ=ÿý,¹òÚ üëáOeŠúNÃU×Ûç)³íWöŸï~=þ  Ì÷ªêíß·ï¾ÅùþËS˜Ï Ÿ=;½¦ï›´OúÀ…ïqøñø;}^Ûg›²§Ï%}o}À'1èswE$™®ÂLoíîdš}“¾ÿ}…¾0eïßÓvQß—ïäIç_¡oLùXŸÏ¯Çâõãóœ—g…¾0ⳜÛgÞ,íŒü<¿výlKãñ=hÿ.÷8ÿŠócÀ“ÄÅ;Ã2\½BßÌô Àº@߬˯^9Coè€y€¾Xè€uaèû³=`Þúnn}0Ð7ë}°.Ð7ë}°.Ð7ë}°.Ð7ë}°.Ð7ë}°.Ð7ë}°.Ð7ë}°.Ð7ë}°.Ð7ë}°.Ð7ë‚õXè€u¾Xè€uÁóXè€u!ëÏ`:à߬ qní4˘(€¥IÕ_S‚ÃrVƒoÖ…®Zè€Ù€°.Ð7ë’~»ÓöS{ƒãs¦ƒîËÐ7³ñ<ðÞ§÷ŠMïŸ÷è€ÙØŽÏOòÞË9þÌæ×¸P3‹òs&Þ3p’4À*ä &À … …07u›†‰0/ùBáÌÕœaâÌK´P8óÀ·d˜8sÐ)U(€ð È&@d† …qÂĈ‡ .¡pB!,I˜8QPQ#@Ô„Àe Bá¸a ?˜8˜) ÀSÑÁİÃAoP8&8I &€6®*cîOV€ƒ» º$ùÿ/ý÷È¿ r^BW.ê߉~Ò@GG“ÿU_q‚Àœ Ö½ÏoséX†mŸÓå´Üûù %º„³î}ÖˆÛQÓó[âŠ{Ë%‰àÞÛlºw@˜غ÷™Ýà°±w8Ø0ƒ¸·Œ¦Ú‰Þý…{G€Ó¨»ž[~sŸ)Ì YNä‘7Î…ƒ»0Ÿ¸óùîŽcÒøh2¡uç3ßçÝpp°03‹ûÁ` Óg¦¶îC#Þ +²†¸·PÆcY§4Xĺ·X^÷u9ø:ånʧ /$îLTÁ­T&à†lž½’uŸfÍŸãðn'_©XÀýx {)qgLwdý¥µŠÜ‹WË:õ+LÌ¡ƒ[±¢¼¥]«xÀ‚–^dÁàmäÍæ…ÛB§mÑéóÿë•H©’›èû;ÂN,®ïë™í§Ó^4ÿÆul . }¶Ÿ†ì’L›Ï)OU&àV¼õÝÜn>}ç¯JÛü»9Ͷžü²®¾SéãmüÝš7§û÷L¥îŪú.^w¦áßÓ” ¸‹ê;Uþ¢àß³ ¸Kê»v?XÖ¿¿Ói}þ 1YQß©þÇ«ïçËûü{Ž‚·c=}7ÖFÍøwJß{ýsè "«é»ý´ÐÒø{п× ¸#ké›°®y~þ|xü YJß”Ìåýû·FæÏ·2ò.ެ¤oÒ*jÅó߃ãoÌ¢ƒ€,¤oê™ê‹o7’ Ž¿£¸#Ë蛺jvþ< ù7Äb}3¦¹K翇Çß¡ Ü’Eô͘å.]¿6rý9Äd }s&¹U®??•wq°±„¾9«rÿ΄ƒ˜, ož_êûwÌR·d~}3Ÿfáßpp„éõÍŸß6ðï€ånÉäë+òŸüùöï&Cþ !˜[ß¹¡¯>äߘF˜Zß]sÛ?äõχügÂAfÖwçÔö9à!ÿ~|'-pbâË/;g¶[kçyô~ÿ~zx ÷c^}wOló>0ü ß—ìùcÝóÚdaSŸ?Fðð0¥nƬþÝ?­mí߯½F)7p/ˆSM§Y6wú]•ð¸oûõ.3pw"+ú˜ÑŽY”àV¤ê¯AòÔÌxœ}=Fâ`¦8,ß²:sÀÁÊ,Ï|ƒïq%¬ãâÞ%n½µÅh—ãg¤é·h…£$Á˜Ì¿Ç=ÕÛ¿ááÀ¹ô-‡‡(M°>éW3iû©½‰p|.ᨿ?oÿü¬{þ\=õú‰ölºwa‚;@·© R" )QGàÊÃÂ>ÏãÐýé÷Íöó~ãßEÎ|¿–wxüYÏåéׯŸŸ×]âÊþýVyúlÇç;UooÓw‹ãÿŽYIå)ݳ¼ÓÏ÷ÚôdãßbP$Æt)§Rs×þóçppàF1çò¥°OÄË,Ì{4¯áiž~Þ'–ÄƒìM,˜…+º·o̱Š,Ëå5TËÓòÖSº&£n88°&g],\)'!¢ŽSÊ`MгKQšžŽ{—¼Úz$¥”Á’Ô +ˆ…«ä¢–¨mÜ1 ,HóÄP„¶§1&ny´éH TËÁ!pЃ¤ë°“\åIª_ÔŽš‰C߀tkd]“Ò¿#\‘˸¥÷9tŒÀ ^CHr3ëèɽ†ßê˜88H–…}Ð8iOFÞ#qQr˜öpš¢nªÂcÏù+1(h‰û#ÎÝpúÔÌ¿êo*¼¹Ãp#oõ‘8Z¨X÷I¯çßN2'¨› ðÑ0,NØK6ª(Y÷Uœù‰3šuÓ>è¾V먉ŽÄ¡oPFéälV¯dw |(Ë«íD/1°Ë6˜ µ ó’:u>â¿æ+™ËÄ!pAïâ貌,¼¶|ë@–U‹º°Ïi¯áQ<­jXSàÝŽèò,1Á£ìѽ9¹.áa ¯è»7ê…ÝØ·HU@ààƒòDRû4¶–Àû\Øþb G8x¢¿8X[¾ƒ^  /°Ê¨”ao,Vþ#ITGß¼Å" ðÛcr†—&Ý! —{¼a$QL¹ˆ‚Ū½úÝ"#^Ô÷l#ïK~†Ž&< 8aV÷tÙö[¸G”ÃX=EŒ¨cdÝÏ]±t*+pž‡y_ò5pT ¿¦uΓl¯…—ô´PØ…8´îºwî!†ÖýÜ[©rúæøqPï‰Cá·Á¼ªùrí³ð\\ôX§PÀ|ަ[÷s—]ZíPyVß4oÓ_£%ÀH _”O½ºÔpçÑvâ»x&:JÀÿ/•©šþ;³S=Á¨±y¶ƒu¿vߥï×:.ãú&9bô‘wv$Þåä=‡±yV©_µöN‡Ëè›T<¶ù¾'¹¼¿ê{ Ç@KÙÿ€¾™gÖ2;'9Z´kÖH¯‘|CáËà-ïîñ·Œ¾‰å3a{Ë÷”!ߘÄÅ.g=Ó!é;ÝŽU>Þþœ=Î`@HÑ»Ñ2q¯³&êûçÁzQõýy÷÷Áz…kû‰—♃pa‚<Óë›'ïÂbË×(?þÍ–‡»cŸÜ–ÛA‘Gñf-ô3½¾ü;§ïÏ;øw1åp±‚ ¿uÄzG»yì׿©ùïõojúaý›\ÁtÿÆH|¦×÷¯'Ó^©×¿í•Âúw"FÀóïcAL¯ï§“ä]öï‹ÀÏþM’w`ÿætP¼ô!ðØ0ôýÙÞ&c,ÿ&œ§òø;£ïÏ»—<ç)îø;‘"HÌñ÷–~¸ˆÁŽ·¾›ÛEÕ÷Û¿[óæ¯Ãó~ÿnMK}äáîØYÿnN³}:(þ ð¸L¯ïÍ¿›óæƒþM–‡UùË‘ÝAõì%¬¾ç¿Çýû,pø7s…ez}‹ø÷Uߟwðoân@D¦×wοSºþ­éß¿û1m¶€ÈôúÎø÷{Æþý0óo8xL¦×÷Õ¿_Ò>98ü[Ù¿áà!™^ßWÿÞ.daù÷Iàðï¾]hÄÕ7ñá¡¥ùsž_ô ÿ†ƒ¯Àôú.ÌŸŸ?ëû7<Óë;ïßÜùsø·„ÃÁÃ1½¾³þ9\oø÷QàðïþÝHL¯ïìùoöõk}ÿû^Ðw,¦×·ÌùïâþÍÞD`}“ž?ÿ.W°5ýûdàðo8ø L¯o™ëÏ‹pøwÇA¦×·ÌýcgÿáàK0½¾Åüû¨ïÏøwÏ>A"ë›"pøw<ÿ†ƒÇaz}Ëù÷^àðïѽ‚„]_ñµ7²SòßðÏþM_žÐݱóþÝDÒ¿áàQ˜^ß?äõÏ›þ3pÆòÂÁý›¶<²X‡+ˆ{2½¾äõÏ›þ}Ô÷iüM–‡»cgý›ÞAIí@l}·žv´4è÷o‘ý›VÁ’þ AÜç ¾vGñoÎ+ý£ |ïßœWHÿæ¼Äüàún \äù¡Y}oÿsåa\>ídwP’ûΫ ?ì½[)ÿNµç]Îöïøùc4aw= ›èþݤ¨ïõ½ýÿÛ;p…8õrše³Ì`C\ˆú~Ÿç—»cŸü›‹ìþñd“@ÄPô9SÿÈô(ºeàáˇU–ÌT>듪¿ºäˆ©OÂáxEü_}—F”Z³Í>ãqƒãm´D=s6àÝy×Üý3ðž¦|¨ÅèÀ…³2Œ±™S‡”sMßo™‘¾»;ÆÀô †ƒ/½ô½ê©uÒš{qËGÖ$§Ï@mÇôsZÌp|³,áý»!ð.ÿ¾¼»8ü[4ÞÍü¶L ïúmZúž¨|ê…"€ …³>é·èÓöS{ãYE•Ó\Ï[?Óöó¼O,mw•>ù!Ÿ¿þõïß;«Òöó¼O,mw•>‰:›þ[Áµ|>ÑMÚý­½Ûv­ òÊåíÕ[®ãï³¥W <µWo >þNÔ8N…/Èó¸lw€¶ýöØn}|ßøÖOÉÂùÊø±½{ÿ<Ò뇨ï·ïÆßŸô·+µ_ïÞ?¯›0ãúwÚ­àò”ñßíÝöÛçGûl8îÀv|~’w:Ì ÿwËiAéðÌ’wþ¿‹.¦Š— üuúÜþó&”ôõíØþý`œä¾ùþD¢ŽÑO”GŒéj^Åç×jÿø7o§.ù7½‚Õsã߆‘’‹'DQs6oÿÚ¼/úþ—^(ï’)DǦ.8Qž~`ÃÖgü³ nI 7õýo›u¨8âÿkÆÛ—{ôÿíêåÕNG[•=é|Öt¯ù_cP7矓_}§Ta+e pá´ ¯ö«Q¼ ÁŸ]ÏjW9ÞÎÄSæ]ÖßSÍæ_^òŸë»9^¹¶É¨~j¾û_ xî¢êÞ¯£+oO&¾êcmó‘xÀödÖj/ìTb{NÍÜ ö¯—’_k'bÁtdÒ8ŽJM>è”ìû:ª9‡4ñýqzöL×À3£Õ¶£‡{QGض#ñˆI»©–þà±Óá­Ø^‹xaD±Xº2gIäBÓ·<R+ ¾%‡4ñ_i—'ˇôMtꨣpþ¸Úp$°%éµÐêô–ÖN-¿¦Jõj–¡ôÃ^æ*”ð±ÌTâlŒ{TÊa £5æ×ÅvÒ¿Ì ×k)ÜÕç£i£X‚5#ÅÖÙÚD~ŸcI†:L_N&,ðó¼q "™¤‚#•˜Vˆ”^V¸Dê.ŠÂ¿ùøÉ¿ õæé%"þ‹»É$g}3Ñ]J¥ÂÄW“‰ ü|877n%2SG(0½àÈ=¤X1ט·ÂÏwKH ü°Š µ¦ÜG᮫ϲguŽ2¥ Ñ»šøåôtE­ú~¤ÜŽy2-ù*xQ}3ûÅÐf·çšdîvøçÈœy…šÛ(\ÍkU#ZQà|EŒ–‚n/ìbâÙ'|ÖôÚ«ïøIÌ\Á« ¼ë ¡Ñ³QY•_u‚ß-/ÆIôbZJà½:¹ŦMM¼x©~U±=úî ˲ÍN_Áë|䚢î=š†ç¼ŸÆ£_ÿ¶—wøw˜^ëq.³Q¸é±‚NT«è{¬ùw|Ù~\l²ÇÚuàÿš?/@–ZòîìZý—å˜fK|¸ïã–ì¢ àÖÓo?,üÔ¶Zlf»×Ûv1Õi¦^!®n|ŠËó¼´ê¾I7õýÍcJ~É«ŸA¦“×±rX©‚§×·TŸG^kÅ=^§t[ú~ ¨7i¸<Çã•Ö7Õh»ÜurÎíu´Y &Õ¾É]Ýj¹ Üjל¿ˆû"óÌκcѨŠ+8B@#¹—í»«ûŠSTâGq„ôRKÞ²¼÷2?5¹@÷R‡¹KM4¶8­V¥Y ¥£gWÊqhÒrïÿë·%ð—Æ;v>o‡”ŸXa±r®ÓsfŸ5âk.|©@L§®ïmJ ï_‰Ò à¸î£nÅè"¶]R{ÓKù òh=û!Ÿ‰7lË› ð÷ÔzOFr¯]Œ*Èä,jt\«÷žÛ³>½­—Â`ö8'ksç'ý6ä}RøˆO ;o Q·J|s:¸ìfxõHyKxSäÝøaÃÝ!ÒXøžãyŒã5Ç}ç»g/r›[kˆú® ürr\¦>{¿rÔ]k‰Ýß÷n¡ª ³s—Ë©—ROÞØWåÒä]øõ;[‡}ä%šÙ™BµpïÂóÊ»ûᯄQÒwjë¸øñ状Q‡c;â,Þ-“ãÀ-w¼e²wP¾K2¶Äu¶}…*ï‚ÀKªßR7 >tG­”íy"VvïV?Yâä¼uÏÒõý‡ªù…û)}%ÖØ3æ:yÛhš&#uJò±%.äõ[tygÔ\›V?.ˆ®ú¬Ö=À$q«®8ÉX7=nq5{ŸÞ’×7m.­~Zü•ãñq+…ùFÝ‚QÄm±“’2ótQàòªå­;߉aß/E¯Ym_Öö܃jà¡kL2Îâ—¼sMÉc >1r{)^E?2Eðï?¯›Å^ÿ“.KªÝß#°\]Î<êÎÆÙOàöúic*‰ui"—Øe1…çŠI# rìû£ïïz.&~ˆr¸‚C“ا—‚h¼yöPϺálÐ×#¼H‚mßÏ{Fy—©×´÷¸5FÝÅÌi¿‘[ë³úE¹$´Â÷WÐ_f›8öŽú6tðCÄÑëG&Úe\Ò¿_%#Ò‹zKµÈ¶ú¿W&qìûs€N·œƒêu‹ØÝe•_¼(C7Vá;n±FÆ;Î4p⌾cp*žŽ{¿>Ü8IÏóŸtö¡ÞEó)"v¼Œ´+òfï·(pf °wìí·ƒ¯ñxã4ÖKëøÊσõЏ"·f>úõ}ºíûïƒõª\μ·ß0Õ‹D¼Akz¼5ñäÝ?ÂRbfúÞ-Êô&³Ùýù#ãàìŽÅÝý[&Þˆ ïºhÇÈ¿£LÔjêûñ}I:É[Ê¿ùCpøwg¼á¦':¯ºý!I‡üûãìâwªœ6ôîZäaûꟓS÷[óï·ÀY~Fxÿ–‹7’ÄûîzúõdÚ+ùwoå IQßû^ÿâ߉öJ5ÿf;ø«c!î{ÿ7ŒÄü›$ïaÿŽààÚúÞíé¤Jj³kø7×ÁÙ‹» ø·p¼!$Þ—…Í¿Ûü¤Áñ÷@&…K‰!o9}¿š]›—«üm雜±wÇB<\õ¯¡A”âõ/–Î3ÓoÿnÍ›¿χ¯ó.§·¾›ÛIëûíß­éžw³ûÓ8ÕgßKsBïݱ¸;°ˆ‹ÇëÝpý»9o.ãßî¡™¾Ï 8p›ÝŸ¦À©3;ßúF-^ïcô9üÛÛÁÝô-è߬³àðo±x][nï-ÚÖþíìàKø7ÇÀáßbñú6Ü^7Íú÷EðrþíÛZé;])éߌ9tø·\¼ž‡è¢þ½ Óño׎ÐMߢþÍppø·d¼~¥#éß)©ú·§ƒéûºþ±¬N’Á¿mãõj¹Ý>“ñïç]šþ}G} û7ù,8ü[6^§òénÃÕ¿“òøû?dz‰«ø7ÙÁáßÂñú4]Iÿ~I^Ó¿ý|ÿ¦8ü[8^/}Ëù·öü¹§ƒ¯ãßo{ûY°—~¼.-w6ÿöëWño¢Ã¿Åãu(¢î^×Í¿ûA}}§ŒÅý›6‡ËÇkßrû/³róowÓ·¼Ó ÿVˆ×¼fôo_É¿I#pø·F¼Ö-WÚ¿5¯?—ÈöÐWño’ÿUâµ-¦~Wµ¿Ì×Áôﺃÿuâ5m¹«¸ú·½ƒ/å߇ëÄk¬ïIýû>úÖðï¯ûûY”—Y¼–-w^ÿ¶øZþM0pø·R¼¶úõoÊrtþmíà6ë+–ý›¼ìKß•8{aGw–ñoýxíîÀžëŸëø·ùHÆdýÔÒõkÔU¹™þ]É&caæµü[?^³¢èsÏ/Qòoû‘Œ‹¾äç—pü»=g<Ïcÿ6Š×ªáú7祒¡Àn÷Íú7çÅ×w1ÞžUëb×qªíÂ2^£†;èßœ—†[žKtÓ7·ÙõÝz~è×9•ýÛ.^“–;²²'ç©D ´§4ô|¢~ÿN­ç1 œÜ±l¬zUqûèìÅ4^#}Oîßõ=Vvþ݇ñïoë:¸q¼-wÈ¿¹Ä !b¼W}séзgÀ¤’ÿ¾U«_ëxmô-Õ÷å @­¯uqð}Á©5ðÆã ÆÍŸ<ôŠEýþgÖ’ŒãÕo¸¢{HçÃq#‚¬;+–æúƽ‡ãl¿|<<5+h§‡hÇk oEï¶ëãÍ/D×=J- ¶±ß}7ŽãZëûwï–W½áŽî щF¬x3BeìWÖÀCT°rëñ‹W_ߣ=+ýâÕþÖ æ™"¬oúœn¯¾K%K¿Øcÿ6ŽW¹áŽJFèÞ% oæ-ÿœBW-u½Ä]ãU×÷xÏJEµß…¾‡õ]ð3FÀšþm5nopÛKï¥ífÑ×ê©×Oô{*~ã}ž‚M¯›MŠo¯M¾ª0=žw-¥í§çOæ“ÚÙóª¾ ~Þ“VÙßçÕÙôdsþÛ!^m}÷¬Æßf#pº/^»xiïø»eíõxj/+¡?þ¶º~Í#^ÕnQ ½ÿ|xx-޼½{ÿü¼î_Å¿Óó©ß#ðÏ»÷Ïû´¾w Îz³²ñR®VÓY=X«ã¯´¾-û:»^{ Nú²Om ¼4ƒÎº~aQ¸_¼{ f*=|¤UÖÅ-¼y¥š´¬`U<ã•m,Ö}U¯ºH¯k%Ê­$ãúÞ—%¿•L= ÷7Z_Ñ•ÆÄ«¸¸ÇKº×[пÝ6Æ;^ɦâÑ×™ôðj·Òö&,–¡¤*ð‹wß90é(Ü?ÞH=ÅÈÃw" ‘ç‰÷¹*«…À£lK€x%õíÔ×é÷ð:Wÿ®u,ReÏõ~X}ð.©éFá1â²`ãøCO‚’ãÇûvU }Kdw. ¯ØqÀX?#2÷®Öë®9唯÷ô´šÀ¿ú–y.¦±{çU$ÞO<Nª ¿À‚¶v (‘¤:¤ïp£Ie"T°`ƒsçr³…J=|ÐëxGšÑa?e'±u&YÙE,—ñ ´¶1#‰v^9Õñ¾G“nÀÓo¤Ó4ꄨ`Ɇú+‹ÛÆûãHvL®ï ŠÓ¯ZK[ð¸*üúªÂùWj"Ö®yjåF?Éñž¿BT._àï‡, _˜,üý(}Zå,b>Qnª™6•þΚl…«äl4^¯+-ÔÎh]˜&H¼™­©Âå <¥Ê=à†›¤‚…¿ª¯Óéá#]jMš‘v~¹$¿î.ïTØ'#ŽÂó4ïHËëžÁÕíƒÃÝÚ%Þü†dÝÒ7ÜžU(V€½[¥‚e¿ë~‡ŒIâ,Ecck¸I ü»¸Û¶[y·Œ5 WÏÍH¼2×Iˆ7Æ1$ï}ý~”x‹Ûмiÿ¾)Àî€SÁÂßìëSŒz^¹^êRo]Ú¬²¤À[lWñÌ(£p«•|»–-[î„ωsÞP>kfÌœ5Ÿ=xüu¼»¶!NK¯§?1ís…zx§ÉŽU%\ÿªÀ/*ìn)¤šñ…›æ 3Þ^}Ë6@ œOmŠ·eît}Wlrùd°û6!P‹kе0Eîĵ­Œ!óóïÏ>§ð™ø"þ©Ñº,âíH³¿àÒ× ìµ÷ð&P¼í¬°.NËnœ™¶;®ì©‚[_êøJü¾N¨‡7<&’ ‘>ºn3(ðÂ÷Õ΀»·,·#‡ŽxÕÚ÷\?ktßÁOÔ÷¨0¯.?Ÿ«?)Xùê.P” &~…»=½·Iž}Ý·ÇëŸkeÞÀAV”ï•^ÿ3ý}ä} júSSßô­ï¥Vçßûq>÷ÎŽwü.ÃJ{÷_ür(l}Š÷ù”nâwºõj_5ðï‡i©Çª`òxÉ3z»× äƒWŽd=é²å#) ü•î^ç «×ð3Nƒ–dµá|huŒö¥ÝÜM.ÿ obœsËA߇ ³Ëp$`³’u† ÎÆœÑwŒþn$¬’‰Tý‰w8Ñs€ž¨úÖ®áWFô[’Õ~Äó1ºH@­¹7ø¡lðõ&^fÏø6ô¦ \»DÌÊ=Xs¾ÂØ2ß›00éÝ„ò“;¡ÌNߤºóS»ð”ÉEßÂ5ÌÎP°ôâY$ý}°^êí]2?ŒŒlÏŽWfûòIlnyjÀ/?¤›¾G¼Ô“ôK‰ö.™Ÿûè»(ð!ÿրÿ;òC»Ž±ä—Ô‘•‹å§ ojúä’ª~™ü¤Š³Ê3£oq?#Üéßšé»ÄKÓwöÃß$i¯dåßbù¹‘¾Kg—§…'bŽzý[3}Ÿx ¹Ì÷ÃôÝ[ú·P~î¤ï‚ÀÙåyÑ·ôSL¸N°ô}â%é;ûék÷m^½‹•ËägLß•RŒW.?©âßôòÌè[8àW‡C xÄ¿µÒwŠ·½ÌGÃ/[ÃþÏîü["?}7‹ËXßùI5ÿ¦–矋ÀUü»9íôép‚¥ïoï»ìÝk·wÉüÜLß9³Ë3£o္x¬ô½âm®± ÿ~Ó­ô ÿ^¿[#ðb·ÿîדD¼¢ùIðïUý»Ñ³›ø%ü»£úEó“àß‹ú÷ƒëdÛàß#zW8?IÖ¿ÿŽoíÔ‰_^ú®_àßõêÎOõoù+Øàß½ù©ê»øMÿN”–«˜Ÿ;êû|…ʸË–ü»;?åƒp#¿Œæß™Y_ßç[Ààß‹øw×Ô›¦§ç:$<…Èæç–ú>htÔ¿Åàðïþü¯móñï·¾áßõ*ÏO’óoñtøw~:®]Uôï´é›7d‡ç'Éú·h!À¿ò“¿ÔÎ/½Íëy¼8ü["? þ½¢w,þ ëß»†Iýü[ ? þ½¤çÏùø÷{äÍÿEò“Äü[zþ=’ŸÂßJCPóïO‹d8ü[$?IÌ¿¥ þ=”ŸËŸý“ª€×êK#? þ½¢gôÝhZþ}\™‚ÞÞáß"ùIðï%ýûòw/ÿNðoZõÏàß‚3èðï±ü\ôÝhJþ½k³,‡ å'Iú·`1À¿Eý»å·üå߈>¼›5çÌ Ëæ§¬oJú™âT¨~¥ü¤£“ËÓÊ¿› ú·Vúîñ¦Kû©6ƒ¿äå[¹þ}ßüžh~ ovyšùwó5èßJé»Ç{Ö7Í/é»§õZ‡1w¢À…ó“n¼•¾¹å™×·Ü :»Ã –¾¼éÜ~ªÍà/ùñ),ÿînï²ù¾¹åYÔ·XÀä& ø·^úþñî· Í·þ§iÝÞN:?ÜÓ…ÑíùÕ¯´ýοYåiáßœžšÑ½9,ýüЂ³ò£¯Öö;ÿf•gAßbç‡çg7³%ç—Éîùc‚ùé×w²{þ˜N~Ï¿ßåYÔ·µŸ¥þçi¦ Þ½¾›­þÍK@:^µíü{QÿþnCðo.Úþ-›Ÿ«¾Ùé+W¿Z~6}sQ÷o.ÁÒïNßM¹…«æ§qz|¹x÷‰ý¹J•¦è¬¾UŒN»­àO•tøçépM¹wÓÎójõ£5rÕç§ü<ðêáxEß:þv><,}—ütŒ™G ö ]$?I9ýhñî¤x7ÁÄ{Í6Nß3?¬1S¢cÓà æ'ñ Ú¼(å'•½§&o¹kÐ9GLß??,ÿ¦ÏðµwÁü$âgôokÄ«’ŸÃMÄò¬ê[n ]ùlvúò³+…çʆњT¿N~Äý[lì*ïgwóïÿ8×B,ÝÞ“rúÑâÝ%« ïЛ¥ ?,ÿþ½s%m?ÏûˆÒv×Ñé£ÙtÑüdœL¿eþú©½1;>WÉÏn‰EryÖõ-5ÿ ¸–Ï'ݳ˺éGÈcÕ¬Ô^ÝÃvü-™Ÿ¼Ssb¯B~öþÝ?þfÝŒHXwü­œ~„ü0V½|¼^²yýüMÛÏû»ñ·X~ Ççýѧ/<¿±;|ÓÈOúê›Zž } ùÝë~ôwÀ™||>éë¦!?ÿ~>ªÿï{§ý'vÇ«bù)ŸäôȾ1=>ÏÏw‰Ery¶õ-ðkÀphîlÎzçÏuÓ¦1óo±üÜw~í{‹(†¼…Fàœ€#¦!? ÿ^š;—áâÓÃ÷ßþ½ôëÖíqXà¹õ)½k¯w»¾uÛÞ¸uŒê{ìê? üûÛÏÝ—1çË­* þýâÞe £oàüûÛÏݘ—ŠÎ}M¼àßoî^/ÝÝË4ðïo?wkz^;Ù÷~Þ›Û—AŸ¾—Òx®a¼ûÇ–~¡!vœ _´-×ü{eðHÍ%RÙê~ÀÂ]~fÔÄ/´Â_ g¬1à]·÷} ?óqbP/ˆg¹2ÊÖ ø÷±§ çß †æò~dÔÌ  >ÔÇá}wâxP~âÄT/4À=ù›¼¹Çåǽkø~/ÛåGbƒ2¸°×¸ÀBÑ&Ò«) ®Ÿáà÷wOãÿš£ÊÌmÐVë \^âõZ᥯E£m£ Œ°ñ>»æð Ï›˜ùå_!wAËí"‰k/÷í9B8ƒ"0E@‡³Œ‰]òwZÎÖÛ=ý_a›ÇÊô\ƒë¹¬É±ò¹p¦++yPn”]xâÉëV´ª»¸|àížþ¯É[Í2,¤dJœ*îÙ›w¸î €òY6±ÛÏ CÞÀ97ÇZ—(”a7/~÷î#pè„¡÷¼y¥g¸yû¾yø <3omzï8ô ‚Ò™“º{·ð{G“?kÈpø[û7ä æ¡ïú€;·ñ;ÇîÁgСo°<÷mä÷܈Û:8ô nÀ]›ù]ã7ã¦sèÐ7¸·lé· Ü‘;ŽÀ!opîרï1¸1wspÈÜŠ[5ø¥W CÀ'1hy7Ô nÈMšýMÂà„Ó3v·Àéï æ î‹Uë/­†›ÊL1ÑóÐA±Ž?¯qí…µ !¼*³ô¢õ=ƾüªùÐ\‘ÙøIg¹_ l°UFM!2@xˆ+8BOLKeJ¢¬ùdwPlÏ$XäIEND®B`‚nagios-2.6/html/docs/images/noninterleaved1.png0000664000076500007650000020567107436604462021172 0ustar nagiosnagios‰PNG  IHDR°ô$ tIMEÑ )DiÎÎ pHYs ð ðB¬4˜PLTE19BJRZco ms{„{ „NZcks{w‰— œª¥¯­ µÃ 961^%%e# sm##{"ˆ _1.€10~CBXVaÈKw¹i¢{€¸xž›66•RP RR­+-Á,+³NNÇLM¢ui¿sgÒddÒsr””{Œ¨„””„Ÿ•t.4™”””œ„”œŒ”œ”¤Œ†­¥­­­­»ŒŽµ©­±©µµ­µ½½½½½Êµ¶õ¹¹ÿÆ{„Æ„„ÆŒŒÆ””Æ¥¥½Æ½Æ½½ÆÆ½½ÆÆÆ½Æ½ÆÎÃÀÓ½½ÞÁ½â½½ó½½ÿΆ‰Ö„„Ö„ŒÖŒ„ÖŒŒÎŒ”Ò˜˜Ô¨«ÖÆ¥ÖÎ¥ÒʱÖέÖÎµÆÆÆÆÆÎÎÖÎÎÞÎÖÖÎÎÖÖÎÞÖÖÖÖÎÖÞÎÞÞÖÖÞÆÆÿÆÎÿÎÎÿÎÖçÒÚçÎÖïÎÖ÷ÎÖÿÞ--æ??èYZúWWÞmkÞssçkkïkoÞs{Þ{sÞ{{Þ{„çwsÞ„„ì{{ÿux焄焌ތ„ÞŒŒÞŒ”Þ””猌ç甔ï÷ˆˆï””ûŒŒÞœœç”œçœ”왙÷””÷”œ÷œ”Þ¥œÞ¥¥â«©ç±±ï¥¥ï­­÷œœ÷¥¥÷¥­÷­¥÷­­÷­µ÷µ­ÿ””ÿ”œÿœœÿœ¥ÿ¥œÿ¥¥ÿ¥­ÿ­¥ÿ­­ÿ­µÿµ­æÆŒÞÆœÞÆ¥ÞΠ޵µçµµóµµ÷½µÿµµÞ½½ï½½÷½½÷ƽÿµ½ÿ½½ÿƽÞÞÆÞçÆçÆÆçÎÆççÆï½ÆïÆÆïÎÆ÷½Æ÷ÆÆÿ½ÆÿÆÆÿÎÆÖÞÎÞÞÎÞçÎçÆÎçÎÎïÆÎïÎÎ÷ÆÎ÷ÎÎÿÆÎÿÎÎÿÖÎÖÞÖÞÞÖÞçÖÿÎÖÿÖÖÿÞÖÖÞÞ÷ÞÞÿÖÞÿÞÞÿçÞÿÞçÿççÿïçÖÖïÿçïÿïïÿ÷ïÿï÷ÿ÷÷ÿÿ÷ÿ÷ÿÿÿÿ*£LIDATxÚì½ p$ç}Ø9^¸;‹Y¯#¹Àt‰Z;¢-z%.w-R 6 44º¸À4ƒA\ñåå´‚.4² `¤ˆr•¯¤;]ëT6sëêÊ‘£:_éìðÂD>;9ÞU…Þ½ä|3B÷®6JV#PÃÅý_ߣ{zfz€™Å.1`fº¿þÞ_ÿþßÓ9èIOzÒ“DœãŽ@OzÒ“ž¤•`õ¤'=y`¤X=éIOéVOzÒ“Fz€Õ“žôä‘`õ¤'=y`¤X=éIO!À?ªtÀ‹IÇcrIë~˜] Áö|²Û)yßÈq#Á"1ÀšL¸ÂKË|r<2©íäǹŠN6ržZÀÛ» ¼.Í¢¤žÕG¡YÓžwæ·3é•0ߨ#.óùºtªLÄ“3-ægÔãÉ|bL$ù×4U± ԢȎVÝî™TQ?n$x@D–ƞƕhlLnòÏ>›Ÿœ´ëH °&“=hP­ÄßIò÷¨åÏ1ÁÊ<b£Lrø\ub`µ¾&µ®Iòåc“ô2œp"Òø˜œ&.Ò<…2™X”E“­|«¾óMB &#?™I$Š©£ó~“ãF‚DZ–Thü¼ô_ã øì‡òÙzÀ—6Öºl&m6Fþ’€¿G/våõd"ÅªÝØK#&~òÃÏ&x˜œ&öNyÚ2Ý‘|lž^Ű&›V“'˜¦¿øßäóŸ 45¬†/—&©³Sðl½…Ö€•€Ó“ °ìRjñþz_aÚq#Á" X)¨÷K¿ýïH=}öÃÐòö Q1¬D÷Š»4S•2Éß#{<ò‰×FÆ^úÎw~û¥qʼn€Õ,wTÒ5´é=j§IH„ò +ºV’¡¼>òôÓ<XX;Æ!N+㪑Wœ²=$:zGÂý Lj˜>¬|¢¾¤ª8¼²¿ó±ßá×ö³?ñaͰ `éšÓP‹°}åïïDý=z±««X5n„*/ýöǾóÒ_ÔŒá'R–ò ¨A³£¨k;é="`qš^R€e¥É¬HФýÛ$-yäWßù@üdr 4`í€ÜÊ'W†›7ëÌ0f»;V±íìÜO#ä×û€k7< ¢ jÇäøÎn¤aý”újÓK¿ýÒKv}5%/ưŠîX³®Z‰äÅ÷É–þ¦Øákb"‚i©Ã’ºˆq~ç%ÒîÖ­[‰MÈOæ)¼npõ– éå%GÆÒ¥—Â?›àA¢9@ "Š›¤É”É$a ÝîîîŽK)çó-}^¿¹T &¤@¢?Ž¥žÛõXD€¥ëßd~÷úx º•è×)Lj`QÛ¸~=š‡P‘¹M@CÃ60F½¸PMy|(¯3¾voŒíÜŠV³¼ÜrÛË‹·y¡sÊ_¨þ¶¿G)v“]™[$ù˜€Ž „k ¾Çòù‰<6îX ÀÃüØîî˜Îlç7Å CÊoŽß¸‘§±öÒ˯±±&ˆu R¸«‰–¤)¯Ó,²xƒcœ‡RžØ°ÒH´òðÇÙ§Rðs±šPýë7b7_÷,“y‰YÓÂÎïìNŒ½?Â`¥XcXX3ÇÇLP?{i«éØ_þø³Ïr5¥±'“ÙãXÝ& TB¯¸6‹cc ±)ÿR²¿‡)vøºqƒÄTå90d]c–=‰ãØ_ÃÆ=þÒÏш5îèÈÖøÎN`[À©ZŒˆ„~ŸýI ¢ð‰&€uDý3·À÷Ô8ÆlÀºIùµí)O9póæØ6HéiI—^,Ò®oP&‚Š©Oní¢×š]ätyIø?¦Òæi²ëú1hâàÙ,é<Åóo7k—Ë Êrü&îîB¶Ç°¢)˜¨‹>¼  ðwNwv?þqð_€&€\×éõæP ;À†9A ¼qÚ™¸¾‹äËlŒ òÜî\ÿøup„ɼ51~ŽM\ß™ š»³óñïÞBÕžßÔé| ä¸‘à Xס)R%Ù!• ªÖØÍ›aBÆþWêÉ?û“?AÕô߈2,|‡^' ·ÿ.*4ðŽ% ÿ¸ŠNäoݤÈïAf_¿ó÷°€EU” Ô|Vâ0Ô›ãú«Xø™¸~}‚tWN6îqñ‚ˆœ!>cC«f€u7vÆPu¾¹3&0€”ç\º- ¦N¥Z;4'ÉÇVée8™Ð€…¾ìRYµPLM^R2ÎùLð!!MùºÆ:&! íÆÍ1(¹ÎcÈVw§ oׄXÓ§^÷]bº»&P/&ˆ^¿éšÀ‚y(‹ ôUìëXù<Þߏހ…qõð:–©¤”²•Y.K]®ˆPãDQ~ÐàªX)Eh\qñ3¶ƒý2ãcÿ↮èX“Ø~âÃ?©¦4è”g3>¦¡«$Tº›ð.EÈØÝ™ÀW.VKéíAh,þv°&žPL„‘bÁox¨àð À2¦§VÚ›£«GãD)ºˆ7v'wN ’²Éýû<64jt× °°áÂ5‘¹1aò±Uz°%òÔ“#>Rs&”š'½&L^«ü×iš´Ó4Yà$‚ ¨d¤®3p`]FàqãF<ã&“õY€ÆùŒúœä?¾IÆv˜MH¿ ±;fX”oPüQ÷ãð ÀRå¼ïÆÇo0H©ÔOì¨{ñìA“ãF‚Dô(!½i¯›Š»œ+?&2a«éä¤TSÔ2òjIʤ™Ö8U «()^ôöÃ÷².î«€ª¸{S}ŽT@ÂO½‹´1h‰Ì9¨W„YÅŽ*>Æ…fíù ?ÿ¬JFK³¬ÃBøMÎ>RWö˜Öøø¿ø/7vi„;ž!®_“ÔŽ·J¯t‰çóä+ú  û™…'*²@+/]ƒ ““8kTÒ4Y×鎭kWë:ƒ²¬ëÌë hÈG¼ •äþ°¤@Oñˆ–¼¦¨Žû!He¶‹pl b‚#k$¥Z>!yéìÚŒjbB±,]¶»c \õ+¥hÀB¹N•ߨpê r‰q5­GxaŽÅClÀB Þü;×?Žutl‡z,¨Š²92$ü@oÆòjŽø;>nù{´Ê&\o\+KÀïÆl5„Ì¡Ê[S&hÆ@EÞš±”§~BÁÝ‹û7„a©®¼€=50"pØè0OÀÕu¥N¶J¯,b KÔl…­*åvlWóŠ RMõô‰xš&­y»’ª|³ wF%\K&Æn®s,˜Oªš0NK‹¤&Ä–ÓPmàNË›ô¾À› šd5F=nÜA±sö[2• Áò†R€I¥ÎÓ5uÎïP'<Â3«‡»ÜÉ üBFŠv„ï/ø®æö$…Dë:õkŒÝØ»‰Ý˜»ׯç5ø9ihyê‰ðñb «èv³ÒHè»×we¤ŒÛMÀ³1ªUÊ}S쓱1ì6ÊÓxÆb²Ë° -†Zøu­9¼ôsâ6O=Jy™p=õt:Ì•8R…]Yã·Àw²†mflû}H ¤i¨‚ž=Æüîú®qk^5JH»¥w¯ ï¿yÊÂÅ.kê0G(¦fJŒOù`Ò‹Ò4Y?„©b Y À)õa¸0C£&^ß™PMÁ$¥à'ë×C2ü™AJ£ˆJyê‰g4ƒç8Mkçæ­[2h¼cõÿñ¨>®œ2`è–—Y©\0äúÖu]ݺÙxî×ý.Lj(ÀââθJÞÁÁèql ª–›µ4]·–Úñ.w àð vc=ßáQ,¬^»4zˆã»cãõþN=Æ#SXY%CÄ’˜ùÙ—¦1T+¿[¦7šˆˆ.7í“a*EöDF:Þ'ã€Õ,®»g Ø{oدµ¾Õæ0Iû•€&õ×*Lj$3¬ö3û¸‹[EÛìÌÕ¡ÊÛÛ"%Ù¹—Ñ?Êq#Á"½=ÝïäÝ€uÿxþ¾•ãF‚Dz§æô¤'=y`¤X=éIO!ÀšŸ÷ŠÅ¢GR$™ŸÇ{ó»°`žó5üzÅ9øEÃ˽çÍͱ7ê¾8Çþ@8x_d³92óæçæÄ)>›çˆ;õ ‰-™›‡˜\é¬p„$ÝóÎLНH»ð é³Ò3Oé]Xh”^ü@˜ž•ÿ”6t¡ò]\Yað½ä¯äI¤,æLøøKF~²{cŸï°l•Ù‚Š¥y®¨òî'˜/ R îÁ„‡YTTy¢l«œ‰ÇsÉ.sß6KþP ES"eUŒ–Ìý)ªîzLj`h]×Tö¢Ë -`IƒP £NÈ/öÑUFs¶üž#ÆÝÙ€5ÿSôÌÐ÷MOÁ³™ô€u/Åã0­´¹Í´xœ X]‹¾ºœãÈEã—[×|»¶·Þµ‘>+l¿\+^n—n««ös>1Çð븑à,D…¹x±¥,° ^¸œï6`¹¦jˆïâ£õó2_ÎÛa¹ÚÜ%Üœ‹U‹&ñŠ1¬)‚¤™TÚlzzjjz[–®Ø¦šw¦ž6nñ6'4y·þšò«ÞfÃìvÛ9Ñ€åÖË[E‘¸FºÅ4qs¿éÏA7áq3Ç sÎMãA]Žá×q#Á"XÑìö¼¶kðÁèHÔ`DýpùªèÒ÷Ë=U¡½Lœøe+|F1Zc*<Ò,Ázîckš°êêU};e‚Ö =›jI²$wܤWl·$XnôKE§7hÑx™wR°ÑƵŒÝh¦ºkÅDŒ¶ïë‘! ÊÄ‘ÐÂÔ¤@â—uÖÝÖÓçêœâLj؀5_*Íz%yUõÒjCX³Ÿ™-•ˆdÍ)×–†nPq¶¼X.ÍÎ$£ .bíV׫…Ri¡ÈP§|ÀN 4mXÓGÓS Ÿ¦Eõ›¶è†Ø°’ÚDwA‹YdMª&Y׺[D𞨄íjmIºžÛÜI#Ÿ£X%žn…×0 Q¬ÜNõPˆuÜHð€–äoi©¿4[® .•Ljñ°Ê•¥’‹ +¢ÃÙýVô3W>¨”gùiu¡^+wŽc¬¤`-«¥~Œe]Å`Àr@ŸðÇ™™rЄ ¦º¡Ï²•F%tÔtÚÈ™C µxˆ/ß9®·`ŽÊHýÔz)8¶yãç*ÙO €Xb¾@ß%|ŠWe¼A!_€ò†Ê¹žõfÅ¿Êp¡œÜX®hDrrGÝiè‚ÏŒm¥•JˆuÓáàÔ·§Ž †é@c’굃˜ÅתE8¢ÀëæÉ‘tu›lB% —PÜu†°¨³A=GŒ ×—F­G"gàÀ­,'Bº—ŠËul0tÙ¥\Ô¾# ÆîÄSGì[Ç ×¡pO¤Ón ñ<¬÷öþ¯7"Üç€UZ¨²ÙJÿÒói2{®H€U* ú+•Beñ¡JaxZyøt¹Ô?4T¨T3ô=H¼j‘ þûÁÞÐR©´Dv*x?Ÿ¹è/Ï– °¿!+SþéCXõâ`M3ÍX€¥pËI VqÀ²ªmWEË•7¹Çm“Ë1 >Ä!5sŠêõN†Ž×¸ÙPH <ÕÒ;{XØ-²âXø¨Û»CLÏõ\1sÈ!§‚“ƒ}Ê‚ÃØmÁ­à)Ú3þ q-ÖÊy yž§3µÈLÊä‡S4ÈåX8åÁ’W†¡«­*Â9#íµ_¿üc¿^;nH¸¿…û°Ê…¾Ba°PÈ+XóiF °Ê™Ba `¨`k ½+/f¼ÐÓNÁÅ"Vö„£á ð$€£òP¡pƒX‚+´ÉxV°*ÄÊØ¿A´…Šb"`M;¬þ9üëÐÖÌm0£ÕĀŕÐð¬î 6K×Q «¨Á‚_cr¢<³3§™¢Ç€%~0µè˜Ø*¡gµtGZ³ÎKÎJG¥ËS– •ÑÖ=ó´È6]ÉIÀÜãk×@cÛñt°Ê#åF›› &J®…µEEíz ˜¯£{ Ü6jÈ<‘¬ýç¹´wÜp ÷aÚ¬`cñ3³‹X/§Ïq®ÿÂPöÌÄ“ÁÅ \gÊåÓ…¥Êp¦R9 “=€5W,*¨€-.)À*ÎÂÓÊÒ B]¹€ø -Îz X%6©hÿ2…rB#3 KÿÌN¥Ö”6hM³°¨öò˾£> ²S«„ÒÜHã°q#o}Óƒ±d0Jɰ:Û3§:Ý1þg—…RŠéÎWÒH6©ä„hë XÚ+¼' °ŠqÀk Èä^Ë‹VäWË”¼RaMcL%l°¬"98øõÑÜèoõ(V3a†U* ”Jƒ‹³³ð[j?³fa1ZD–T. åB€FUXB†æ¥"‡‰´ C^êG§…O.‘ðX$JUb¨*——ÀWí}ì93|fhøl,÷ey$›={6›}|èë;ƒ>¡Ÿ}`üÈЙ¾>¸~„žõõõºX?"…fV]¥é¢381TÐÊ-ºži=iÔ–µÄ¤ûÝÍLw·.´Øš’hSr“í5 ÁU3 ÝŽ&Ê«›•š¸‚¥Á óän°â¥ÅÔD_ëWáÈüªèÃú l„­í6Î-!sÜߊõµÅj,XK[*åR{ï T +Q?º.K ‹iæêôÌU5µ]&¶Ïðeİ`¹‡­Œ‡•ØÒ·Áo¤\ƒ-ЊBè^*"€•ÍÝDœ4Äç„)ånƒËdèIÌ#·ÑmÔ¶å>ÁEÛS°¸œ¹=î¿0’»øÎq£Â}, X Š}‹ÆÊO G1Ç,ùÆUìI„iR&%V´„|ùgÆêkkõ˜ 8Î͈ îë)X›ùfÚRí7Gs£ßìQ¬Dé`…Õõêæ÷X­nn®R!ˆ¸íÓ³kÄ´ÁÞÚúú†)s!ÿ{[`iC»Тjb¸W!6oõaÕO Õó®¬íÝÓ©„¥šuO'Ä…ü‡É7yÀOìÐ5Ùq\×JÆrK›*”e&þ­}ǘ\,Ûm•Q!·9 A4Dž/üLû´¬ó/h‚Ð~DÉã/4½Wº»Ê\µ ü++ÛÛØ,À:Ø»”Ë]Ú{︱ᾔÎÖæ©Ì@ucdó¡*r­UdHÕ‡î¯^ ènóÔÙLÿp.äd+Xð€´Q8õÇ7W‘g`C?ÐÖêêµkiëA ·Hž±öò?O;´þ™vM¹ø9ð}j"} 2;Ýî I% ¾ŽC‰‡Û¯åe·Ð MK$+¾˜7÷ÝW€…vÑ™ø&(W‡,KœÄè8MïÁıÕ??p´¹1*H UàDÜQ±¡{ű°ù7ZØ5eL  ò)pLIT·Ð0‚AC‘Iél ðb®¬Ú·Fsç¾Ñ£XIÒ1Àò7O­­?TU²yíÚþnÖl¬T·ª?²ŠÌk ˆT°_øY ªn`wúæ°°G`êo#'ÛZE«[Ubg B|ŸšwxP¿EòŒ#ÛöMG¶H¾’z{jÚ¬lÝ„¬eîâúÏ-"à&À¡sC£fgrä¹ÃÝ¿t ÞøÔ­Ïˆm 5ëòjO°Št|N1‘PøÝ8º¯ŠM­ýÉœRξv´¦&¹Äi×¥Xjü¨V.Åu=!ϳ€™¨\ äE7”û;*ñsœí8yÇi—iÙî¸ÍÌHîbo›™$é\Qµ}½ÿ¡jõáêÖæT×Nå/Ø\?µ‰`µúǰ¶73ëÕU°©V3™êæ&~cŸÖæÃQÕêÚ瀨Áó³§àv ss=sªúY¿=Àš!|â~u#f:Ž¢Ìª"à¥Èd°‚`…â¹(yRŠ1Þä[À%:¤À’^+?TA©—çµp±#Víÿ¸ôØŸVU{ë‰ÜÈ{«^:XDkƒJ€Déþf^ye}“ºÓ×AUܵð{aH*á öxZ[[_¯âwu#ÜÞ`À:»ÄjX8C†µ¶ÙbJƒÕXâ€eíéΘ5ÿÔñž¶K0ÀQC§ä4`õ€X€åÓ-}û> ÿ3SaA̤qW›îà Çê¨J…34ª•E¶T–P/áJ¬I,P/¹R"I °c˜¦oàVzî"dJˆ‘08Ì!ÍF%Å„”¾Í°|QñB]Rå;Tߦó,Ð KaUˈÐ[88Ø{îñ‘ o)ÄúâÈHo›™é`]«f„ ØÓ:ò­õG²ØKµøƒÏ¶ú«[ØgµN=WO™Ì©*ØÌ ’ùz6{TÂl!­_Ξe“­ï­¤jQQÀª%œÒ¸5EZwb)ÀR' yÔ©‹Â…û}B鿱4,š— ½B¾(4¾]st§!‚ß8ÕG¤üî0`©H0µÑ]ÙéÔ CÅ¢|jájlN¡²~ ¤S‹‡íØÃÀÑC jDÂ6…óÊ‚ Åê$¦2á_Ê#¬Îj¶& Ž3%äh´Õe°ˆ 뛣¹5aôøäÈ‹=ŠU'¬k›¨ÑĨ/øYãu+¢-°ñš~ÈW¯dùÉú+Öãµ*Ž/¦k,2·JLofZÍÐY3ò€~SM¥% fŠu·'50ÿi5ù'7ð4I™qä«yF81¿ÁÚ€ ºà¨ñœñö%µ„±¸2 h;2\ÏXçø›yN²ºK,X3œ–µu=3ÔÌ¡õíé_VÄ9¯¹1sN¥Tµ>ÙpˆÂçøIOô©#T \÷¹öƒFr£jGwÜfæÂ[wî;é`=4pjpðÉà©Ì©z&Õô9[:%WâúÛ,’iZcv¥ëj²è”Ù|4Ãò¥õHŸD— G ãÐÑ(Hž+I#¥ìTåCÀÓ-—S–íÛQ¥°¬UÑå7ñpíyš~h/4 t’˜F-šR~›é£¼¾*ˆ†Ê£ƒf¼¯.«[•µž‘5L_E¨Z3`Ý}ûbÎì…ÕÛf&Q:§nlvD¶¶’LqaÏv˜¤ª¾-©"6`éï¨\½š|ݰŽÜŒÛaXu ¡Câ«åÕÛ©úÛXÍÆtï/ Ì"ûc©Á¸ìyÔ€Tíëçt—VO”tzñsýêù¨‰ÅûÕ“fmÒX·ý³ÿT¨~Øx{™£ˆ½®ûýYü§>½Gý %³˜¸³qôÞ5÷4Ïà?)hlEx.áè·¤h›™Þè˜tpñóÑĬÆjl–d'&]¬{-ݳ«!G–=ø‚­'Œæ.ÞfĪý×£¹s¯÷(VTz;Žö¤'÷ìi$7òÅwù†ÎîQ¬¨ô«'=¹äÎåÜ“O¼)ëõsFAì K§KN2¡ƒpæùt›…>ÝfA:QGéxúXi°g˜‹æžx‚gö¨#&ÕÉ:x¿pêˆvïÖŸšÓ •ÐõŠ®:Ù7éÓa°(̢סO}E—O~¶>RFH‹Ñ¿Txÿ~¸–¾~ÌÍqmŸçv„‡Õç.ɺgÚf¦·:",Ϭ·*«9—KÃÔ‚U„^Ä~= )»ssósEÛ³:›|\¸ÛÀòFâav¬¸Á{æ!%McQ'qu# *ú °Ú‰³‰“ù>êË¡™GO}½8Œ¿ðz–†„'©ª³Ÿk¿1š{üë=ŠeK«¸ ŒYq^®¸ g’Š•ž¾áVXM*€> Ùk‡aµžÐ +йë`¹N'=Àjœ÷ °Ú•yOKHƒƒÿ€¯éèsÜq_Iç«hª§ªâ^Ï>5Z¬s†›¹sēȔHÍœ©ºb·EõÁ-’iîÕÕiKr(ÁÙk´]ÀÒ)»RXn}Ènƒ«Ô'?·ÊËÊ:HµÅ‰ôi£Ú^š¸·N@m’™é½;b”´`9x°jß8‡ûò5n3ó•Ų¤S€5_œ-/–K¥Y}ä³:óÙ~4[*ÃúL¹<ëá±ó³æèÞ—Ùî¼€Òº™ÛðùŒ§,¹LŸÐj‹Ó¨ÚÁíÛgô¦í²gÊÚ&YÌSUoWU·ë°UXnô+Á<±ý4Žgô´ïΊל ºñæÞâØúøuòyõ®ñ[[«Ï57]ÉÙ9š€m-O˜vÛÊZ,}òóÁÁÞ 9½ß(Q¬wz tŒt¬Ó½X>“¬”KRkíqKýK¥9°Q(Ï–+K¥º¢Ÿ·u¾ÒR ?ôÔÃÒ'XKSøXS3ö~X¸[Ôµ÷•^ =Ã[û¥èÃò\`ØïÕ§ËB-âËÙƒzÜBá‡zÇ[uY‰ýwÜ*W-8†à¢ЄWuH=ÀOc1à<4ürí:ÑHB:´¦CNÑV¶\G 8›Äëˆ[Ì9 \•k¦ôÈØã®ñØg´ˆùár\ÉkŠ;&s1Tå$å!iöSGL[¢:ïèëÞ63¶t°³Ÿ,C•‘E•ÊåÒ,0«YR ªè-f³•Re°¯°Hæ`£¼¬ ØÙE†–?ã• Ceø,~l‘?);BŠ¢Öm‘,;ŽÖm‘œ°±æ¬ÆT{ó“êŠÚ—FrÞì)…J:X/—Ï* Â-V†³I• ÀP_ö ÓP¥2Œ€U>]x(k™÷!•3`¿\F¤,•pq(€•Í•…¾·îÆÒ kZˆÖŒáTS3‘-’§¨+`I³£jé5ljQ ¹™¹Ef ªáEž’‰ëšž‡¡ëx-Bð´ëŽöÌ©NwO(¡ÄÓ夒8šÔxˆ™PqsF0v&\²ã9¢ž»ÊWû'åķ̰L4”–m;#ð-:ÚÓÅÆ—LfÝ"¿)”Ê2@z§¹Tm䦫µ[(‚OŽüMæUwzË–Î1¬Ò`T·ÙEáVX€A@’+ô¬4P8SBCø_ó˜à÷`A®‡‰M•–À@pµþ%€7ìÿòŠs©kÊl‘Œƒ´#2žD8Õ Ón‘\T€EµÒu»ßí¬"–,×ã.+VV)íŽj<š‡ Ô˜%(•Ðâ.“Ô?)bü °”Ú[T Å1 K¥ÑÊÊã¿«ü³ËsLm\SqRÈ'ýk©>KmÙ°õÔSÏ@½«Ë8i¿Ð-¹}xÕ?&^ÅÛÌôNUé `õW°2}ƒKKKƒÃ}…JåÌ0vb гþÂRÿâbe±ræ ¨Šý³³ýK…þR »´>=‹æ§‘‰Í—ÐÅR¥?3´X^îCsÕ"†–åÊÕE­R%Ep†?SéR „ 8çØí£›ËóÔ(aÑüȯ‰‚ukóÇqŒ›dß¹uh»Åæöž•gÇßau"!:& ’$Ǿ玫˜“ι¨!‹£pcNl‹ÒÉ¥ã$šœ§ü8g<·&åÂ-ªìŽ<[6Ñh[ Ýù{JõãTÕÂgœIz©·Z¤c€5[®TËe FȪ–Q¿«àM…Œ–øÙöÁ‹ ²8ˆ.NŸ!g™³ÙÓýåY*Ó¯ñl,ª“L­Ÿ]5Ã#Ïðµ1M§ÞSqN^>äLôÖˆàrëè^üL}9UìRÌ~õ<Ë|®µ§±Yîñ‡8¢èÙV3>§Ã½jŸz|ä¢>5çàU²áho›K:XD­º#•4€å†E¶k5ÅÀÛÂ=VÕVš©Ùƒƒ— ;°ÃVïøF1H9“[&Ž¡u5,‹¤¼®Þd¥€›ôëÆ¨#€ÃËìoræXE.ëgÇ»âŸZ>_ŒOOv‹‰î&¢j<Òm é~#—Õæ À«ž¹üºü­s¹Ñ¿Û£X$[š3OA“¤”ô ‘eó´dyB%”)€X33êPœ™«W§´Úg/œI£ jÀ2+ãu¾ó‚©¤©Eµ6S)!ž[×£‘&nÝgXzÛ•ÑÑàï&š·LŽ ?) ×m`ÓM†¢&Y]ùƒ2gž¸E üÚ¦7.äF^T‚t”Â_aŠu)7rñöqCÅý!›é>?g—½çÉz*WÝñ&Ñ®ì`æ… ¶çÔ‚h{å~kÀ2ÛËDuÂiËdúÊ•Öëq¢}XjyjÑŒ®!–,aÁê{iÖøëšH+¦…ûa¹éùX{ÂîNEqíæ[Çpêbƒ 7ŒƷžq&ú½Ì0¡ ݺø¹Ùlƒ¥Ü´ÇÑár·—ÙÿÊhîÂßׇ?Ó \Gx÷­'rçzÛÌôvíIOîÙ{adäâïÉZçÚWõ:´º·“J°zÒ“ûEÞÃÃõ£t†Îo ±¢mf¾Ô£X]95GŸm£çŠ<”+ƒäpBùˆ]°ç·yöÈ•:0¢N·§Þ§æ49+(ŒÛ[:I ¡;ÑWg¹5ˆO£8†Öo+;uF¡ ±I–År«>œ0~F»1Lq¼SujF€L##¯ª“ ßÔÛ%Åz»‡X,>œO†”Cõ¶ñXðuÒ©uTåöö¶uÖïv=ó7Ч®¬´{1ÖÔÔŒ¤-±¨“}FªÓêSŸü,±ÖÁt÷dUlñÛ& ßÝ蛟HüÄËæ!t-úXE}½>‘¾A”¶œä2bdžýu!åÔÈi4#MŽêXøõ¾û±°z{˜ Å3gå\BÜ©a47ú«‚Lû/ŽäçÍez½Ú¬ŽV\ìƒÁWVÔ«_5ûååím‚¦m]«})?üÛ^¶Ž]‡æKçã¶>IX1¬©©èt+½ã¨5+Ýž£”4?røy·EZ¼¯¡ßjU‰­¥aÛlÔ~L6v6úòú±ýŽân0Õß7Ž•õÄÔ ?ê0Áu í¾åÖO¶à×ûKÙÇ¡³ëííèÜ:Ï`a7–áR·õd,Úfæ÷z t:¨®là‰ò+««ªZµ à>0€uí0-4 ·ÁfèG ÷M¥&ÀB·ø ̉ô­‹Â(¡W3S RÖ$™¡u5ÕÌHš/uðëÏë~£¶™ât{›aù«Hô­ˆH$?FZø²1ÃJFçh’ë_c \ILƒ AšýF>Dú‰ÖÑ·ífR䙬ƒ?¼82¢¦‰Ö^UËrÞé­&é`m¬ƒl\Ûܼ&…µ®l‡«pUŠñî¾Gß«|Mu jñŠ)8ĦªÃ+hí¦® °,ò4ﲚŽ@Z*†…ŠÑÔ§NTj·[ó½C $O ÞGœVà¥>*'+}_O’âˆ/E‰ÑM¤Á¸¶¢¯Ëƒæ\Q¸ñ5†ÔI¦âëdèü»íA`…ß@§f}ÚŽfHÚÔ7]X>9–Ž*ßt9q]Pý³a䡯²3m Yá¢T- úù’@­Ð¡3tj¿ØÛf¥s€µyêlf ºUíßÚ`^´º±±¹ºñPu5ØØXYùÞÆæÆµÏöW7üps`}secë?®®®À“àÚr³ bSÀÀÀ ¯¿«ýÕ‡>»‚N¯­^[ Z6¬ÀÚkš?OE?Ë Ó¸oò”ã´¦XȰBj¢¾Ó‡bÑuÀ ¾\›ê„[h ŽÊ¼ ¢Pƒ± Ù•‘f€E~ ³¸£#G?ÐñW`ÊÛ‰2æ<8âE$2h'j@¾ ñ6çDÀÅâ‹_€ã£ç`¨õ_–£#açcg.'À§” "1Á—Ê-'0OÉ0àŒÄ;?LX:×Dö¿4ª¶ïcbuñmT{ÛÌt°Ö«Õ‡×Ö2ëÕ äU×¶ªë`RÝZý,™Tá{ jÛ¯f³Õj&³¾¹Q…'hl‚‹Í­êÖµ*_o^ÛXØàúS­";k^è2J¨ jšú¬ÔŽ£W#[$_ŲRm/ƒmÚÁAà zuµÓ†Ù¨í8ÜʃPBBGÞêØ<ýÂ3'jî4€w¬€ÚYÀî‚"– ¡´[=¦fGƒeCø“X)ã”ðèÇŽòË¡ç ˜•f3H"E'~9Ì™ÈØ„ sPÍ pÅù¯òÊ* ´LäP=ÁhÛ9ÚF†mK‘(Ù»<2rñ9šðçžy•ÂÚ×ÏÉ$‡-¬ÌÚ:ñ¬þêÖÖCë™L¯úšú2›j›Û!Özuí‘ìZP 8ÙÀ©L_æTõ³«ÕêÆæ)¸ÞÚü‘Ík›ë§67×3[[èÏú©SÕ–M]Ö´ÙìjºÁÉdÐz†ƒ X¦rvO@ÑaÀ ø.Tйp! 6¼«§]µA1oŒA°BnÍAwKÐÅQl c†‚Â9g©íœ4mq¤È•é”#ÎNÁÅ\‘E¶­p(L'Ï…… °ÉWGÞ Ša $Ñ[ò©s+t|)@Õ5ÃwÂv«H€€µbÖ]ï`‰†¥š«p a X>õýˆZä8ÒèR~o›u° ŒV(h*>Ô #6™â`2Ñ%? TE¹•À·£Ø¯|aøW,ÀB·>™û ¦ê^N–oôËsT‹KžUNGÅ=•]TB uÜǶ" ›å—ªÃXw~MMý…ÑÜ…o‰R¨ÏСmfNúÎÍÕ°º±²É³~ km­¸ÓúÀúzÿzö•W"€5€¶ÖÖÖ`™o0À 7ª![÷}¯¼‚ì¬9¹N¬é¨ØþÉÒwå(Мv­Û“ÀÀ‰¢òšW ÕÅ_+IvJóF’‚0€åh¿ÍÛã¯UBE`!ü8ZyàÅ(øFÙò…am3Œ:¤©)` Uz-¶¦U´À¢MŒÖ†(·¾À¢oüuD¹“\°s/|ã»"\¡fXŽD@÷dj`&•9^YFÀzûò…¯2b½·wÉÌÆBUðÂ5?üÅN±:X×€KU77I%Z…ïÔÙ³ëëð¿ž9»¾† i½Êv€U^G†Üé<&•¾×Њ¸{[DËÀŸ ‚_6›ÙZm^"€5Óx‹de%ÝÉê߸;»“€ezvdOL;4ÃR —1 uŒPß,JƱˆý°³€%1äÞ%GwjI÷”ïs×µ êÒ¨†ßcB œ¨Ô C õð\ ÑDõ}*P=´Ç}X¾ØÕ}kœ|yù¢ÙX÷*î*·Hhre‰Œt´Xkµÿìñ‘ ¼ŸÌÁ{ÿêâ÷µË bVû/ vx²Ïî`]Û¬²D%ôà`HȹàkÝ~ >küT®ÁõúZÔCêæª5¿(iÐXO½2]7cAM¼šJ¿{ŸR Yh6~ý,í¤øé>ˆ,ðí¹C*ür÷yùS®ø2?ICN,‚1…„KÏY2cˆ ‹"~*»Ëus+éG†Ù=ý®Dfž2øú8AÓ7&¡í•Ÿ4k‹ýðÙÏm^£'Uð ,VÃí娭†—2A‹ý^'¶[?(×î\Ä’©VȦF¿Â|kÿUP ¿ôC¸z (Ök'›bu°Èœ:•?’ ¢S¶ ªGr•‘k-Cæ'æZ®~HO"mX8StêÊô4Â’,ÈÁ ýd#w”ëT°eÖÊâœÄõb,뙬•ÈÛ€ƒ@#äajš faFü–Z«7;kiζýܣ˛Ô5-Ò-ßž¾"ëhp1§ÑøÃ×-–J©Ù´â§.Ø™<Ôñ%‚µ¬ú÷’ýáE8>O¡^'Lå²m¥±¤¬Úwq>ƒ ®#$Eðààîw±ßWèÐè“}tçTBœþiÉÖÖÖfSùÍ&:ÞØø«É+tLц¥iÕÌLlQ€«é©´Ž^1«îîÙjBXÒ„ §ƒð}é˜çÎñeN»¬Ý|’‰ ‚€T¼u&ú‘°}ÐxV˜-›†z©¯tX‰DvÛ§R1Ëê­Øb™Ô'“rÉ^c¨ís "¬¡·…1ÅË·›uÍ±ÚÆ¥c ³êõšÂÔyÉeÁB#ªýÞEœÅ:ßË#9ÙfTŸ¡s÷­‹¹‘O4Åê`ùj"ž öÒü¼ÐhqµÃØ6Š€™¸Í“t´Ÿ†Û·n,Q´RJà³GÃÔ´V S –è7R#»Úye%"šQQ­'ºßBØóYƒ!˜E1Ïÿ£F?0‘°–>:æ©j‘qzB búûã0¢1Š2÷Ì÷íÊD k¬\S.ÌGÛÔÑR=º\Ò—˜ÔůE†‘-lEµ7q÷RᎣª‹Vèümìwñ¤o3Ó…ý°¬IÌ­$½0]š gXGIZ{Qº¹[UØõºëy› }p„šQíW/h”ªýꨬ#<¨½J!Õ‰_ÝÛq´'=¹¤ö @)Å«^¹ð±~Q¶K®ýˆ:ýëdJ°zÒ“ûHö_Ô¼êàÎÆâ.­½Ë#OŽâTRÜ"ë$S¬NŸœ ²° Nº1"ç‚ù¼uô š/‹ú,ü¥£ræù|ONæ[°í/èã£ôg^ìãq%^TB>Òt®è-DÃåO<>G½‡t@"\ëûRuÏÏ$Ÿâ}K’ÿìÏåñŠÝHøY?ß(1ž±eÏ[Xˆ¥‡ý6ePŒ»­ÏǺ<ñ’ãbÌ’ý0u7fnÒŒ¿Ée‘"ÿæùZµ¤½WCýó*ÓU{ëÏÁ:éÛÌtì¨z]Kçøp÷èQ æ°,±"¬JSŒ»ˆ_5:%l¡ÑÉÏG,uXÙ¡Îo:„DO lÔøã×iÅ>ª^à¡N™ný4qRåž”B¯m Øu®¼ŽO¬êãkžEêîÑ" ›ò*™ÐPûûr£<·½ö¥Þ$ùÎÅ}t§ ÁÈTú†€UŒVäy}¡ÏEݶ:ûkJm<}dè2g$ßÀ²áÄäK£|:TCq­îSÀjdÛ+À*z­ÜNްn›éX8K.qšÃpI½\ß:±«ƒ ‹ª½'åWWxÒ$æPãk\ÄžÒ“P«få²J8såêU„*þŽ ƒYºÝ°Ôi¾÷ˆaÍÑ1§mHr^7… º:X®7€åÆýôš„a§ ÞVôEg‡ !dÎêrÐø¶%s|wÖ£9Pœ3m 4Aì»BLz`jä2ÍÆª½~a„ÎÐÙ;ÑÛÌt°Ê‹åÊül¹<;_*-,”Jå’®S +Nìç–״°ږº+=`©ó‹ï¥JØÎéÁí–[ì`y X^g+’Æ{X–×=À‚6a5&šŽ%0…'~LŸ¦úø×j¼ÍÌ7N*Åê`•Ïd3ƒ•J¡¿T.”KýK¥ÒÒàÐR©¨ï¨Ú‘,žgm‘Ì‹Ÿg®$m‘Œ;c¡Qš üÀ_‡>®üv]8LÇav°#žn­ÀùÅUIwcîF&†à]´Š{ Õt!¯A“H à q$ÀrS¼HŒ0¡=-8|« ßQ>P%ðä©òÍáG®ö§=‰4§ý_˜z•‹Ö¾…s°÷ •Ab]'u›™NÖ‚¬Ben+…ÂRyvîp+®Ž XWÍžî XúŽwq'ºJÑ%/lGÀJªmWáJàÄÅézü&×€¥^áÜ®xW9vä(|PÖR–‚ª®3âÄÇåìÅu8eùŽ¥ã¨œ–T8ŠñÐ%gˆ§ÊƒýWüÓ*Ï¡0 U˜­ 1G¡RžK¬Kç‚çx\ÞºüJÇ^³4GÀ_ Íi'75ÂFÛÓþ‹çd·†»·/Èr¼Ë‚2ÈÛÌ7tt °€aeûP%DÀ* )ËåÁ¡Å{ XSÑ-’§ÔŽÈ3‡Ü"YššÕFº‹a «òT«qÕ[_ÅÆ1êjö‚ Í=,åº{*¡ãªŒCøu$r˜™œUÿޫӍÚ?» ÷F°lÿ•žxˆOÈdÙ÷ Ô¨¸È?±ÎbKžg®¢8T;]…‘ªo ãà ™3Å“6·L‘€ÜÕ¼‰¦cÑîXµv1÷8ͽû6-Ž®á¤¬Ç¿x2)VÇTB¯<\¨”f C؇Ux$[(ôW*KKý‹³R"݇-¬:ØëÊÕøŽ£S‘-’ù´¯4[$ËkS*¸ÓÙŸD‰–‹¤@3,éÁÑïò¢,ÝÑuS1,¥Avœa1ó Ü4´ÃâN±S8å0$)/,ÌŸa\Û•• Oá¸xp¥ÜºœŸE…泞©¢õëjÃà\ÄXéÔ 2ÐŒÖ+j†¥‹ç0…ØtûS·‡îâ4žŽUûú¹‘QšJŠÙ¼°÷o3Ó9À* .•Üb©0P*  C_•~ü/ßkÀâž©©º=Ýgf·ErQa€cÞÍÝ•& Kz|d Xª·Æ¦î X¶£•‚éòNG‘!×V™¢Hæòcî&ä†ÏÖ]©"–ë)`Rþ«~,ñܳI“M½Ttæ =UÒL¿ˆ‚yÌ»ÄߢòÔ#*gVÛœÆT±ݹôØ%µPðîw/çd_ÏW¸]òë5\ }B·™é`¹¥þ @Ól¥v¶iqªTéïÒ5¯'/ÜÈÒ€5cNÍ™®%$f5•r‹d®¸¤ºº}tUô(¡þÑcS¸«šZT±ÔBn³ž6Vt-õ±³e`"^jcFXGR#é0½ƒŽôIEˆ–£“(5ßÊеûö\‡F(*JIsU/šcilÝ{®Ô`u¹ËªN œt¥Ñ»=Àº…ÛÑݽGs#~E ˆwÇú!˜¿sqdäò¿‘ƒ(Fqÿ‡¸ÍÌë'¯«cîó ª§©¶÷ °:*²®û×ÝúÜëV—`JTKÚûÚ蓹 _ÄÒ»cÕÞ¸{üUÜsô^¡sçò‰Üf¦·ãhOzr_IíW.är£¼.çà®Þ«ö•s¹Ñ_Å‹ÿ8Øå?z÷œ9ÛÌô«'=¹¿¤ö @,YIxPÓ»cÑl,:¸Õè·GØ_ú÷ÇÙ{-=ÀêIOî3©}ë"r¬ïóÚëîí‹<ë.MÆz{ÿ[£¹Ñ¯Ÿ4ŠÕ¬žôä~“Ú›R£ê€Â7¨p;÷7.äF¾´¯ÏÐ9‘ÛÌô«'=¹ï„käòwõÎî4ëÝÿJF¿Já·öOâ63=ÀêIOî?©½ ˜¤KvÇz·î{‡¹Vîâí=ÜfFN¶?)Ò¬žôä>”š½LGíŽEûË`Gû»x†Î/ìã1`'l›™`õ¤'÷£ÔÞ!Äúg„G²;ÖÝÚ·.äÎý 9ìë‰7÷þÄm3Ó¬žôä¾”ÚmZX¨ù¹ðFíî»óÜÈ…oÕð \îÒmÚfæD-ÐéVOzrÊ{{¯Ž>™»ˆ“Eîþ!OÇ¢  ®Ð9÷Ë{/ž´s {€Õ“žÜ¯²÷ê¹\îíÒPû=Ù™îÉ ·ßyþ„m3Ó¬žôä¾\ “í‘yw¬*ƒ£_Úç3t^¸óË@±Þ:A…=ÀêIOî_ÙÇ……þí‰Å»cÕö¿4г±îâvÉ£¯!Ñ:Iç@÷«'=¹å‡´ú…= Qï§yq¯¶‡ÝY@µÞ¬zþío?‘;w‚¶™!À @ü á/ ¹J)a€^„¡¸ñµñ1Hâö2öî£íîDʹCé±Ô½´A6†f Æú5!‡ "ÒÈÜNÅÁAhüêtb0ú¡¤Å7ÆM‚ ›Þ‡ ì·Šw˜t¶´ /’,†*O[‡Ð"×’ÅÚ¼wÇÚ§#(€jᮣ¹Wÿðdm3À²¬¬P5†ß•¯Ò WÑåímr±½­Ìý´tJ°fpC÷+3¸MßÌÕ«SzC¿ †ðšŒ§R–x¾¬ÓÕÍ„m/cv†Ë:œhX~,èF1iCz€!l7áè…€hÈñ_^^N-?öÀ¾÷ùœMãàgóŒ‰eG£|®¿h?”¹Ö@°ó 8.,äݱö÷u4wî+µÚmÿ›OäF¾tB(ÖêfØÑÖZv kýáMêyJ×ÿ„½^TE7O­U«ëkoV³ÙêæÃëÕêCÕõ‡6 L¹gìðoŸtñU€uÅ:‡~Úqè gþÖ×_I}T½TU¨êZNàÐ(êÊr×úç(;©þ‡ °B†L¾1¡™y¿;;þàP¯´ !¤´8 Ž;{,ñTâ§‘µ¢ˆ=¦BŠÙ}xDã²½´s=·ÂÏÙWN©öDƒ»P;¼søKÓU*EŽ“Ϥô%86)vÍòG²ÞgN¨ž8]£ïw ·Ó‡Û°±.1b½ÇÓ±îТœ7j¸B'÷å¿–;1ç@3`m± É¬on`µQ?`›¬µµSXëÕÌÚzdk#ï`…QÀbåð‰xÕÔ´@”°=爛`ºrbµ^î:`ñ _ڪаûÆa #ÉÀDíE•#nD9„д¼N#,­@â#1$ È‘^áÇÂ`ØÌ¡7‚U†9&Ÿ‰ YXá,@CŸA‘AEÙpØK4&`¡?ŸÝòómŸ3‹ðHbÄ\Ö …Šq~3›v‚ÔëBrKç¼/€Åñ!4¤WZ'ëàîWùŒÕšìŽE½Yï¼ûöÅ'só©³Í V¸±>XÝzxm-SÝܪöW7Bõz3S‰¬-€;=¬­³¯dÖúº¶¶3™êg}m1 [úwx±‹Õ?‡UC‡þ,Ne œÖJ!+O\o¹Â²RØ:g'ØR1;å½.Aò{=ä†Àâ8јœ0GZ%¾‘vh1,±t¬d°D%tL*Ì¥NFè1±¬ad0âÂg˜Óš´Glö-áŸÀÞ+Àb›~¨PÜÎ\âHBFÎ0y?Žfm¡âP¤ä2•%·ÌÈ”‡ü %q+Ëi³LÚPs¹»÷±º_Ûÿâ¹Üè×öÞ¢n¬}Ü.ùó_@ŠuÜXrO„ks}pT:¬êúຬTŒH«„[ÙWÀåæú)ôiýôÙ5T/ÑËmc³Ë€e©„‘'XÚ µNHS, „~˜Ê'u€ `I€%nYZY(æ¤U 5ÃêXz5°ªòKÑŽ@'@¡/J–¶ªþ âGœÚ@Aå|°”ÿ!–'¡,vZ€¥s§~¨x&EÒÕ+€‹ß¬qJüØ61F£¢Ô’V›ºÌ[–>ú‡5šŽõ½ÿþ‰Ü¹¯ïãö O~ù‰“²šUB™µ³ëkÙWÖÖ78«SUaâýÔ‡*áFH> ®­ŸÊ¬W·Ö¯Vøu¬T\kÚR fQ§|Ú>¬ Guht;ºK)¢I€åÓ5}Óü´ëK¿”jÂ~ãôX-²û‘:}QŸÉïcc©U¬/Ša)ÜPhKQóiq„1± æØ4Ju%E›,ÖÕÉ¥Àk¾•›ÆÅÜñCÕM%8(RMʶVΕšC¬”㣑\k)?ø/qaá×÷jw.äžxcï…ÇsßÜÇ3tžŠu2¶™Q€Ü*óÊZ–$³õ½tê ]EW·¢67«ÈÒ2ëëëg×­eY#Àââ»ç€U?J8¥qkŠ,´žâÀ€åûªñhÆßÅd˜1<xRƒQÜ Ik‘^!_úa|""a(½WÜcÓx©‚£ýî,`™ž)ÕS$ØjPíÚ½ƒ+¼QÃob|ôµª©õ2Gì’Ê…`!޳²¢¬1u,¿Ýݯ´i_w¼©ÑT~9XÂ! Y:Òq%ôÛÎÉ4€uðC9±°öÎÃzãçq¿}Ü.ù Ÿ;!KÖ`Ìš’êæµ@ˆjŠl'æÚ¨â‡x$?¤`†ax/æ¼3`!ɼѫöâžë>#×)§ºã´Z‚n=Ã¹ë Žô•(#Ó×È>t“ðÕ°›X×#›Ld¬é°O‘=ï5ŒÏÙTvðky¥qž.›µIüE ?ª}~Ô‰þà æ›ÁH+ÕßH}J8¤^œò[?>¡YÊ¿í«¹ïÄÔüPå¾/a2òy¤\K!µ_¢……wÞÅéXÏ¿ý©ë߀RøP¬Ñß8KF ûOÊœÉ<ܯ«5ËZYÀêØöÃ\ôo€ÿ^-Ò‘‰£Wõ—&¾Që§hùNšI¤¾ªâþ¶Y×åDpÝç,ã!y5ôj,3 ’Â0áÕÒlùJ Sº}{=!_¯ ¬¬¨'õuc¹n¢¬sµ&Üðw 8n¤…fzD¨¯ù…Ã3%¶5`ᯰÕÀêuÍB]¹7*:ÖŸÇo§¡Õò¨¹–Fj¯_DŽugÿV]~û—Gs£¿´gè|îs'c›™8º±iɆYœ“N-Ä*zm#â‡å›*ÉîMPUÏ–’«W“a¨‘y"Ã"¿ẏ›Q7Ç;yá¾ä¿¦à)¼vS‹2Ö¶rÖ·0e¥ÓebGß6M²Û,lõÌ® ø¾Œ?G}[^ŽL̇F5Û6hAz´¼ã1?J.Ê 'eƒ•e:ïìãt¬¿öÎ ¹Ü…´÷ÂÈS¹Ï?•=ÛÌÈÒy¡¬Är1¥&.Û˨e âRV1$N7„;!’·—9ŠØ­/–£†uPlÀ²ýO´=tøJ%ì‚¢¨i qÓ£Æ9–Aºü·ÖÍXwqKÖ_r¨QØ‹»Mºn7YiË Ök£#O¼úÖó ~;³žú܉ØfFï‡Õp UQ^4p¦öèÈÒ ÀºçÒý0uÝ(™ãȲ®K×ëpê&[{ëÒÈHîòÛ{/ŽŒŒ|ùÁn¬;¿yë©§Fßÿç@÷víIO,Á qφ;??’{âµ_Îåνvç…ÜS€X#o¿ß·wïVOzò€‰,…~Wç<ñmÜ«á-Ü.ù©§r#¯½ß)V§«X,zž|èz~¾XäëO ™tXTx .„Õ•pn®èzÞÜœNŸþtC0œƒW…'ùº° »XŒÞ/à¯ØÁœŸŸ÷è7)ÃÜ¢çR%ÿtZ:‘¦bñ׿ü Öçr#—ß|ž(Öo7¦tU:¦ËÃÙáÁJ¥Ð_b–å!šýcåY©º/‹¥þ%xZ.”gË•¥q/°ùr{šûôR©S[Ö¬«ö~XWf’?_¹Â[û¥,ׯíO—…Z<Ä—“ëÚ·N¦pk7ʾ”«($…à¢.8quP,‰a$‰yçÆ·l1rböµE ÂØÐsâ9âÀúíDϵ|v9ë]àê”`Þu¨nqˆ˜yT<žNó!êH[î,t*tî  >ù…§r¹Ÿÿ6)…ïó5ЬÅì' …B!S!žŸ2|—+ø)•> ·€RC…rlf+åÊ`_a±ÄöÊåE`gÀ¦ÊåÒ150þŒW. •á³øi±UjÝËâ%n‘lm„uˆ-’©ŽJíÇÆAŠ®†ÉÚ‹çRCôÝÎÜ$ätW"éêVã6 Aݹ„a,Çõ¼:O“U1'fRñ˜?Žu¡Yš`Šg»¤ s4à¹Æ­SŒ¢¤ä˜ÀhçŠyS9®u+^q:±ŒÀI‘8÷°±."Xa.Ìyí D±ÞßÛÌt °4`õ T€=Á§04Ð_*ÀÕ@eq±¿o¸L€å`*…¾la©2v CCÃÙl¦ljh¨PB¦V¨,>Tž/`e*`«m-•¼VÝö €•´VJ°2 ‹ª¾ÀD÷)–,z•{EXªMq»vô‹¾ˆMÌUm’I€Û">‡æMÊ€.'y‹ä«©¶HVdÆpšn÷º3`yª5‰JèZË‚3nÙZÝÁFë:¤ÏDÇ`ëCð´ë.0¬¢Ä_"HÄ•´öå ‘’î®cFå¹Òþ]±À®&Wùï*ÿºñ-2,å9…æ¨^) Œ2‰€PtÂúž.ÎGÇc2+öŽÊ1[GtT™{(ûpíOýÄzЍUî Ÿ§^¬4ÛÌÔÔîÖ¢÷ñç­ÜGånó)…fÇ(ٿΖ %ø. ”J@œÎ Ð ³BµXþ*™Â'³‹ðÔ:°™úÀ„l ] cwƒô= P~- ,V ƒäÏÀ²³Öå ±¨+ O80X¿EòU>‘°>,¥ªPÑ=bX°ŠvVœaMsWR–S´ÈCGD©„*þ*f†å`ÔØ.ESC‡ÄÛ‘¨Ó3vicPœm‰ÿÌŒb€å)À’[kÚâŸfVº‡«¨û,9ñÀQ´Þ< ¤é–ª ‡ÌÍC6¼ÚÛ— ±ˆb=ñeìwÏûÍÖëéoÖj?~êààqù@süùÀ»ñ0>PKXµ˜ïµ}þ=#6KrÚÁi ý•Yø®ôÏÂÕbåt¡Ò?<´X†ëÅþòâP6;\.õW>6—–úÑÖ™3•%t&ŸžÅήO“ë3…ò\q¡´808°TéÏdËKC}b)¦5ÌÌ(j•pêŒ2˜¹’ö Õ¢õµº0º(j”°h~ä×DÁºµÇêJ‚݉Ó‰Žš@t íM‡”J’Sw7pŠuq·†çXcs\K“Q'šô ;Çx„Oå bÑV+N­I¶UØòÑG  X|báS,¹ç¿€Já“­Ï®=ú‘½ÚþÓwjû{î×PößE޳ÿC´°Í7è‡8ó »h¯v~o\“›tS{lÂÕ>ÛªáÕAMûK¶öÅÇÚ¾ã÷Þùw‰ñí?m›u°<\,—á{ñ“9ÃØU¨à}~+úí,--~ ®—@-ó3…J„Ÿ³Kø^œm܇ÅÎ^ƒ£êY®^µç]µœ‚eK‡qo¦r˜fÎPã0]ë?q¦V²›b7§Ã6š8š>÷Üæ[LÙ0’¦IEyž¶&©ìy]ñ¡E5Hi¯A<¤ºéÑRh,œ‘…JáßnE±j½ö1€„Úížÿè;=öÚöo?÷ô3ÿ¼vç¹~ô6ÖÿðÌù_§ç·k?þoko=ýûµÛÞyîü3ÿgíÑoäüï‚íGáñry~ïŸþTíwÏ?úÑßG[¿ÿÑóúóµóë™Ú>J>à³ ·O?óÖûŽý!˜œýQäSàÅy2{Ì>ô[LJD§k¶Ü?4|fhèÌéá¡¡áá¡á¾ì#}Ù¾á3™ \÷ õeៀ Ÿ>£mõeÐløt¾3Êüt_Y<óÈŸxäô™>ry6{º¿<Û¢–{zO÷éè +š"zõêLÊf¦RÍú·Bk ‹!­Ý¹Ü:ºÿGÓâUÚÙ¯Ñù¡­³éÜyã¹ÚÁ{ûüÓû¯ÿ(>ÿ³ÏÕ~ú§÷¿ô¡OíõSèô¹Ÿ©½G¿òG¿ n^ÛûìòÑ;?µ¿þŽÿé´õÌ›?xûC{¾±_»ô[ä#ÀÑ‹{ÿôCûÏýtíï=³wþO¡ïϽ~çõK{?õÓû_yl¸Õþ£#2[û_y´»€Eª»RiX†uufZ¨)uüD„uÍÐÊœé¶+ÍÔìNvôÇ'õ«fç6k£nÚ¨Ñdhª:&žL£× +«¦óݤ_·ž:òå\ô>¶Áµ V-ͼ÷úÀçꌒ2ÜxçÆ ÒòÜ:9Jëà ±žú<ÂÖÈ×ZQ¬ó{ðÜÞc{ šÝy •¯ó{?¶W{¯¶ÿØãž?¿€Oèù»ßÿQà;{ù‡ÙûžÕZûÙ{ô€Ü÷/ mt *Üc_ü[ûûçC/¾M³*îüûÈ£àA­öc‘µ¿ó¡½ý Õ=ðýѽýà£Qÿ¾ïbx`ö(›íßé*`y³%œÚ¾ˆ³RóÇðœæ¡¶Ü¢ —ä\%@š¹25¥u?[GÔ+tÚ]š«óÝ‘èÒW]×·\×Þ Å¶ß<—8„n­D1¬ÑÑ-ÝM4ob3¶àÄm5ÇÒ£çã´>+Ç,/þrîzW‡éY³¶7~ S‘eäÍ¢‡þ¢Ò饿c퉧ºà<›4\xgÄÁ…aFn£TœP?y‰¥½Ì0¡ ݺø¹ جk±Ä(ís[å}Bnu°ö¾¦ës¼ÍÌ»Í< çâc?ÕëÏ^Úƒ›§÷.ýìþÿþLí¹Ÿy÷Ïÿ8è“Øý ,ë£?ýG?ûÜÁÝŸýПÙÿʇþ!Ès?[{È™ÀÍÏÔþüמC—ïžßûÔ¿ª=óOö¿þ!´vþíÿSç÷>¸*$ø&wñÙµòŒòýOÕ~í£ûÏýéw> ùk{—Y³®2¬žô¤'Ç(ïþÊ…\„b½ÝbZ¢or§û¾ûã;Ý?zþ™ÿ ž~æßД‡Ú¸ÓýààöÓwj·?ÀÓ»°×üÿ©á<„ìÜüÛ»hòÿ‚î?­ýóž?ÿëhëÏÿÐþ4ÍV@Ñǃßæw%4G©o/›ÓÞØ ®ÄC)·—ñ„^}ˆÜ6`šæ°JXÓ¦‹¶Ä¢Nö™©îdW§Õ_Iq^=¤ºLÇhêÓˆ»{ö3Ÿè[É«ð|ó‰‚ob—*jêäC?~¾rç¢oN`ö¡öõYP¸Ûv<ü0v­cilùõ–ÿŠ„X™6JŸ˜ûªb›LŽûn@5!Š‘D¾b°ha¡…XïÏmf: X¦¼å o‹+ÀÍJ¸®,ˉºT |9Çjpˆ‡‰+` øÜÝ(Lµ:ˆUÖÔTdº•ÙqT&bñ~¤iÎfðèúñô±DDÏA÷¹ù P%Ï£ÆØ ——7W›¶Ÿ*_}ò3³(îÆÉŽƒÖYIH2Ëò2»]^ö£\'„êœG+b_Z¾ ÏW€Èec¹ntë\;²D+wá÷ã誄››A¤èb V¿·²×V‘,¯®†VC ˜TÃYYf[] ‚k×Ôaê*\ƒbW%ôjfŠA*>Å=ݤ,ÿuð°¢ùOØ*µM_ƒU À²Bè`ùuà`^_Ñ+^Ô=i€ÎõåÁ€wä'br®úÉ· [¶*ôÿÏÞûÅ8’¤‡a 45ìb·‹U…ê•nÝÍéíÖËv×b4+=»Ê]•%ân¯–]KK²sO)1Í,U“’ÀA¾ûFš³ß :Û H†Ï'H¶çÎÞóÚƒ{Y ‹ÓaøÁ¸õ€/wððx¬š¥fØÃ®¾øþÄŸL&Édu²jk•_w%3##ã_füò‹Èˆø|+Ýã*Ù9ž–4€%‰õ³_ÔÈúñ´°Ú-)mn¾Kµ©¯îœÜ;ît>nÀöDÒ¨Ûý˜ô&lE‚ŸF |£ûI§s|Üés“’™ý„·=JœÝ¨µBZ »%øÙe+ì‹ÄÕx§é(1/24O>ä¦NþL3kFúXÃÒ×øé‹Ë n^îµÊÒ¦êuÔ‰Lº•9xü­{Ѝ!Cñu“GôÚç…@Bë]\о6ůJÍ4¤)}¦†ËÛ Héç`Âya5’ÕUtGÎUj)ˆ5Mç…–™y}8ú²}ü44ùìË¶ÏøIÊJn…¦O_ºÌ+éëÓ¥ë¹B¯-ÉÕ~ë$ÛöqÐhÁíîJ¯]:/·>õå~«-ÝþÇR%ëH_¾Ô¹¤>Õ€+ývï¥v»·¾Þ:Ásm nû6¯‡KÂïVhò3/Ѱ#@»J6ùY>‹B¦@ÈàåŸ/Ҭܓk¼/ÓK‡Ù"eeªâÁ¡®3¤±ú"0WM—ŽÞ-‚ÂN7ù:%”:î‡#ÁÂ=W˜ný©E"¯«3E=*ö€ÃêÃy¥dÙ©F?|­Ê5dOpë”fÅçé.’F¦õ2ôL×aÁP, A¤(qYûF{Â"Ö÷ƒ=Úkaç*µôˆ¥t¬ŸþB*6Æ I6”¨‚É˃p÷ç> ï~áæÛÃW²MSnFÅÓ›§²¡7x8Üüà³W7¤È£Oîþ)…ƒs e3ñ BûDMd–Þ áøŒÂߌ(¦O¾ò…›E ]úþL6 ï`Ì_¹y³xkøÑƒÏþ¿Ïd¿ôs_ýÂ)„tw@[ oøCr7ÙH¯IØÍ?iJ]¨ÝËIŠatýúõïwêDR¾ùŠDV3·|]n%––ÂÛëò7¤†ÕëI¨ÉÖcWjeù|—îi‚^,Ó$ ýÄ,‘üè‘°üL×° }¦”,¡û–&ãÀ2‡¾V`+` +ºzMŒ!¬4 ®'4vPý˜¦ 0:Âb­¯4*@ óˆJÞF;ªýÀF˜<øU~ÑŽ& Z‚|= “~Äô’©Úœ #Vf}~}p¼@õ@5ê.¯IˆÄúy&Ö¿ú¡½ ² ¬!ö?½÷΃7‡7?< °g‰£³Í÷ ?{õ£”â³Ñæw °ÎΆX0óyþà¼Öðí~C¿ƒ×bÖðìLb \Ÿe Øöð÷Þ{uŠÀ’[Œwøð÷¾î&é6 Û~8%u(©4]o¶$ƒZRÃj6±IˆÀZ’úWkµ%ÝÇ€Õ’þ%°dòjPÍš­©a5›Nš|ਠ¬­Ýñ%’¹»{µ’4 á‘7­´ éÃòMÍT]# X^}æW}\F3™¨ª¨’Y͛ԒO͵ÀàPhº²ºbiX¡ÆkXŒ`lêœãzwóÙ› -ÐÀòlo¶Û"Ú¡›„¦Ä ,v2 WÀMpõ> Xà ‚s•fšÀz>üŸ~Љõs6°6ßü14 Oe“R<øîéïÈ&áú‡Ø$”gï~çtscpó£ÏFÿ`ãÍÑç›û‡ßyÀúÝ»¿8žùg,€„¹ñg¸¿1ÜüÛ§ÿòáÆáoÀ´ç·?x°1øÙ߀Ћ ¬Á€õ³¿ñÉ>Þ¼û6«øÁGÿíOnl~ô¶lÂv¸ùwÿòÁÜ%°LŸ~jÀ:éJ`u:½Ö ©5%®`+u¤%‰؇s’e¯ Ȥ»dVµ0¹mBç–ÜoµÀß§]©^ÁÕKׯKhåó¹î 'MÀ+ ¬Ýme5G}Œ.‘ŒD³7(`ÑCJ¯Þ«Xæ+¡ð7);Â"_&ÝïõÒOƒï[_¼ÒL¾J!}qƒnuüŠF -•BüÇ=EJ±ºÁ¨¾Õ©\ƒúfÇŸê<òŸoµÆ¦ú°¸Û]õÑkoô“áàÁe¬4:8O_)…UŠªG?(wý•ÐòL‰ñ~€õ|ø÷˜XÿÅ–«êt‡îîÛC`ðþƒ;Åß*]îs§ûÓöê½o‡¯½ ƒN‹ƒçèü¡<}´ñŸžÓÚï’9ò,gm¾:€ýÛàïwº«ðO7¼_R跟·¾ÑÃ[ó_ëhpçC€ÑèÍâ½ß¾9ØøÃâæGƒß+nžBýƒ‡oÞ»÷ÛkàDZÀ:‘¨Buª‰òD¶ eQ ;ŒíYG-sV^Ó²N)êdè™·A³36(Tu°o%ƒ¥›„¹ï™N U±ÔÀÑÀDEã•”ƒ·¤R32á8,vêÀòô÷;“T=NÁdæ¥Ôt‰[nzÈ“GãÇô95Dͳ⌠‘|ø~xP¨t÷4òC£EÇîshð½gSÖ—6¬!J¬/¾õ„šŠ™U<:;ñ 4 àìÙ3žÂ|6²gK/Дü>6ÞþZtL‚™­Æ6s7Ï`R3  ˆ­ÛµÃçÐÃ…+qqzÎxü…ejÀê¾ôrni)·´ºº$¤Z°’ãŸüHni ¯‘WÂ5Êy¯’ÛÕÂJç8 1ñI€µƒPÚÁé„úCìÇJdA'™Ð²1-Õù>£/Ï ïsÔ¤žNˆš^“° ã@YºÝ.l:Ÿv, Äɧã× ÀàRœ‹ØŸÙíÎÖ–^üX’jÉdÆ»K\ín%µA_ ë9/‡2XÓ}Cïô³­‰+“ü"S€¼ýEM~®ó´»ºJ³=#&2SÐ:¬GîðxØG}Òtiã¢\ûÍýðùð´Á0v<›ýžš38±¼y§^?6°ž¨ë‹_ýñš “æò2ÚÓ÷Àšqá›&HÈOž6A ¾9ç{ ßj­T#p۬Ѱµ«›† ¨ßÓæ Eâ+­.^BZÔ„‰w3Ò©u¸™“ŒÏ‘z+ðúXØãé×X“¨‰`, 8{j¥|E'#Έnò Á ¨ç+0šz•zÕþüÔ±~úÍ´¾Ô9Õ‹X+‘è··°Ççmqs _P8k´É9Š3± Á |q¥v¡÷ãB$ýº=ú[_Äúé‡Ss6šv·„Þ,´§lÚ³w&Ì·™˜¸9ìDÛ’­8šI&?¦2ü¹/|ñ§¿úá‹_ÆZóèõ³³[ÃÐŒÁÛjZóÓ×ûÙ­"Á¹…K†Þ²CŠ ~ônñ¿Ž˜ì:?{}nm-V&™ü¸Ê𵛯NcÂhôù,8? 6†Oï 5ç3^$yˆó–‡lÚ\ßòÈróˆÎ«%‘?§¥Ñ? o~wôüskæçxDvÏpŽ|¤ÙÍgd+úéðé4å+-`}ÃØoy¼OÖoàøà€ÝÉ2.˜q?¶L†<æóûô &DãïÁ[6nû.Yqõïø˜+qÐ$4éˆþ)‰º½À1š›»„vø¶LJKÒø¨àñ2lJùÁ{›ÎryVÚ#á–ã­)O{B¼Éâ6¦ÒæK³}ݼåµRCF ÁûÓU˜[Ãâ/Ý+~oÓ’o•5g¶ý¼!õ¨?*ÞyøþÍ›·­`†8Êý¾_|Wžÿž<ÿï(¤w‹Åûÿ€uûÍûÈæ‡05zÆ¡?J·!»ƒ©è‡¯~€%Ï?ýHMšþÚŠ–¡<ü·,2U¤7ebº)¦r”ÙЗyŒà˜+ íEžOéF6Á$éÜèÃgí;\YRV9ÆÖؤŠ—¾ù¹8˜ˆŠ k’Ocl¶åçIœåçy̸GýÆÁgZZ'Å7ë~Åý¦%³Ê¯üb†TÏ-·7ßþü{0¬?o¼ó™²æü”g ‚%ç{áÅe†8Êý¯¿{—Îÿo°’ÂÙíÁÍ¿5üãû8¬ô†d¿y4’:Yw.~o8„?²ëüí:ŠØ'Mßÿþàƒ{ƒ»Ê+-`9ú6ëJdn̾u›Ê‘êï"’ÌK*îQ‰–GYi&ñÀ‚…ãCN°>2kÜ6¢—7rþ\Çûåä†ä]ý†˜U¿Biuëò£ /©œ X1éõgÉ÷¿0`Í(¿EiX³„'AËFÙPMK>ý [jFÃñ`Éy,´ }ÎÿéBú‡w¿öáhDó‡`¿yctV(KΣ‘vG[Ïd×VÓŽ~ˆSoNßþÚ½ e8E-L Xp ¢t(®‚±ú‰Ò·"ÂÉýò|¹ºëeÖŽRüªíÉP¥€µpËôÑp’ëܲÀö X/PhiÃâ(¸òÐ¥},8T}wen ¾ªÌ Ž;YÑÑ1Àe._TN§¢2°L eÝl±é —¨Ìê˜G÷¿ÑáØ…®Ü‡gE]ëêó‘[&Æ.K‰«Êš3 ËZgÁ‘™öC[™'QÏbä–\‚ÜBw:ŽQëÏhÍùC¶Ô ÃF`­ùÝ¡Q,/Èž +ÿ f«p•+¾‚謣ʜ=»Z{*«nL;k…H}—•¹²IúÜ7=“’Þ8, ¬_¨­H¸®mVkù|~­º¿À’íº=W6þ¤&u­t¸çVsj˹ÂQi9 µ'’ ¡å¤^%u«õ< ­& †¡¨Ê0«bÑšîÛ¸Zƒ2B»D2þì&Y"™L‚ëÅT¤$V“ê§C)P4Ǫ´\6ªÆEÊÜIåEÀRÙY€†Uæô nN.‘Æ¥Èáº*_ G9Bõ¹ÐmÇšŽPÚ%ßÒ É]í×±4/¼jQ*<º‹22º³&÷ú×Ñ`DÆÊ¬«v¨|—éçj­Í)gÀZ ¤¬}hÒ­È\¡R‘ØY“¿‡RY*I`UŽdÓ¯öÒž‹}U•ÕRe¶%©ˆ•ÖåVËÙ{IêU¬Bé¨PBUë°ú a•æ± LNÐb ŠO´Š»½DòV¢>,Õ£6Ô9Ç9Ÿ] Xa ‹4"z—³Æ¡ÒÃú‹«ü« 51×`d1MBÕàd`¸Ôz8]¤o©f–C—ÀyÇu¨™‹° °ð'uèZ“£ÏF4),‘ç2ù"Àr@‡'¨–5°ÔÇzp‹Ëö¡o-,'Öâ$-`=.WWs…Z¥Z[©TV¤®´R«TŽ®-C“ЭVW÷ö~š„{+µoâö°–ËÉ®­+Òåpe›„ëàXxåÆ*h\…jõè•å\ulÐi<ºL§û®±š­C4«ª¿¢fµ¥ ©ª& îÓ²ŽÕWBl"(¨cu,f7½cëžþVÅ-,Õ1‡TÍÊ jºSÈ w(‡ã£†®î¦QÏŸþðWBøÙ'…Ðj~¢Âã¨>,«+ qè,*ÉÑz«Õ)§ÌÝWê#‚j¤9ªMX-6Ç.ŸÃn}]ÔÜsV6=‚å²õrÐZ.{¶Rå˜æ*¿Ë–ú8zÝvn§9z6ºøžš>ýùí°%éIaÍô•°ö¥"}èö8ÁwCØ9B·j¶ÜâiÞJ÷#Ø©BEŽôCû²„: XØÜš° hÌH†èXxûx|PÑ„˜ÓÖ mÒ)ÛŸ¸¬O^¾_Žkº¼0°È…“éX>ÔÈtóåpŸ=ð~(ûÑØ}ΉO9Ž)Ç\§6'‚wÇ4§èµûe“ΤŸ‹Ô€5¢/ƒÏðû¹=g¶òŒ+°Èr3Jxíê(‘i 6ü<ÂÑì2}S îÐÇÀááÓ‘ZEY-[sfžqXàA¯j;A'-`íUWÖó7ÖskëëkúïÚü²üÑ;¹¬_ÃíúÚú2¸Ò\`GnÐñý,/¯åäþú èfe¬‰£ç5°ií옽™-À˜&áAùbå€kü¤ï :Aû8HmŸ‡ªíë!kS’ìrí€xññ@Þžü¬Ó›vØ?˜£hÙï"nÆÔNÉý™ci e&'çþ~|°b»Í=¼³ù!í“+îÿ+˜êŒfœŸ‚õæ"[n~ÿañÞ?ù&.yH.`×lãŒþ ¸ñàýÑéfñÁûƒ;¿ !“ÕæÞýÎM0 ñ9 ¨WÖ¢ÿüá½ßA$þ{q¸ñwÀµ K¦BûHÏŸÂù±é •¢EIUž,|³âšî’U[°¶_X0üõâä€WkH¬}Øßßw Xü; Xj¶âk®HOÆå† eïÌQ¹¬©2Xád] `m¼1øW7‡›¿| v–Ɇ3Ú„ý¯œÞµµæQ‘-7?xoðÁ½áÛo€h¶ýöà VñçO¿{O†6ø§w~iðò¿ü›Íáæƒß¼IFÀøï <÷ÆéoÂ(÷³ûâ-P_{ç3 KjbÅ¿%CNáù±ijÃp˜èt©D~ã¼ÄŸ«ìUÌsÀËÓý€—³e:XÃÒÍÁ ÀèÞ4`a9=gÆL¿0°`µ Õ\V•õ™@<(«ýýçÏéwÉŸ05g?Û~äwªìóâCÉÒK¥@(—×A¢øpÕPyšØ§à(4v^Ù‡[rqÀ"[ÍÅáS¶³¼ñt4ül@öœožÞîÞkÍd½ù+húôí×lHmkøð?Œî~¬6¿ fR‡²1÷ßÜýõ?Å9´N[ÆÐN%°ž=c`©XG§wdkï…H¨ïbX8ñÛwý}ÀÔÙéÛ_{°±0`¹´’Â^«ÁÕ4Ñw“&6ë;¾Ü†Z¯!nÝ{)µHZ®&¬sèQÓu‘´e.1°ä>¬Ê ,w°°v¸,sw¢nISp`¹¦ì½˜¢ó˜âÄ«8\ `Ñâ1OÁÎòèlX|zë66ÛpM½âhD¶ %.”æáæ?úþ‡ƒáæ{ÔÙ{§™çŸ¿÷΃o°XŸbkÑ2|X§¶¬gläþtº§þ£ïÿ0¿¦@ß=ÕÀ½÷Û¾ ©|øeŒ V&™drEd`º#gŸÈ&!®£MÂÏUˆ”Áð5m­¹8øY´ }÷ý~ncðôÍ¿7ÑÙ×ÞþàÁ«Ã³ç£ûÿæôïß…à{ˆB°ý/d“ð—>øªÖ?ýèg¿pŠÀÂE_ãß…•F¯bˆ,‹û°î¿÷ÿfÿàù X™dò—]`°Áç·¡×|óCmÃYÙs.~™mA“uhÚÿÖ½{¿mºâéóçÆ–¢ï¿_ü\’åï¼úÏ`-Ñï[V ?>|ðýáïïþCX‹B‡X¿ú\ZæÛ÷î½QD(Þ~6¢?ÇTýà~ñÕwAûö«p>šöô¬æ~ÄÂ1Êh·ð¯uÊ\ÄYÇ·­£lJENZëa¥Õ$ ¥ø$Ðfg‚EDP1-0 |fö.ÔžNб]¸Øî³>¤Or<Y¹>£aÒ+ÎQ6ær¤nõŒ§âpðq¦ Á lÞç²ÙøÉ¿x@¡ØQ?{ffW”ß³ñ‘ )šù ›9m€åSÄ  Ä»Ûh¨s 8òß@ ¯j ³ «¯ÍÐùz_Û¤ka«ä>kÇênŒ®:°tœiÚGžf¨N[~n¼X@³bXL~¢†«/Vs•Ù‹&t¾ØâD=é—¬K‘׿\|øÁù/OQÃê÷±4è6ª[)ÙÓÇÇBÞ˜F\åÖ+l{RùnXXªG->›°#Ÿ1¤ºKÀ² ©!Sõ‰,Õ[Àê_$°|ªL:FÌ1ÙŽäÚ Û,¶K³^Ÿ`­Xë|–?§'Þ·€åÅZN¥¾*åjbÊ©0f«­W{u|NƯ«CQ6À½n¥ÖÇêV|^½NxŒåéPøQËÙcÖ Dåâ/ °žOšPRVàõƒ“K3ð=|(û¤D5¨báÝù›íN§íã]õûáûŒxü ,ðr|¬fÏR9 ® ÀBmáЃ&­]ͪ$Èb`ÁÃÙ÷QÃÇEË'¤XvÕ#ÀÒÆØëamf}°ÆkÚ‹'žµ–Ìñ,^yöUý¾m¬9 ¬1ãÐ ;è~©`ê&¢|8XF! âuz}öù —Œ[”¶ã—ƒI©×·=Ÿ}ð¿ŒÀzISÃú¸Ó9Wƒ@co@h¶{ÍV¯­Ÿ¨Û‡ç *(€ˆ®@g;îtN¸¹Hu͸c\^Y–†e ÷h=BŠEOÎd–̦ñè_œ©zê!¡\yó 6œOù`À‘gõ†+g| žé/L1õZÊðЋpGõP$P<Ö·}V`žÍ=•ŠÄóŸK(?ªPØ“m¯|$ªäªò4ý¤òjO¿<Ðã @uG­Ý—Íù7ýÒ$jâ9Æ^3õcÅY‚N ._gz4šRšV£Ý]é½åKÍÇÿøøøXþ6ÚíÆÇíNûXêTíöqC ·¿³´œ{¹']@NŽƒÆ‰üõ?–¾ý“¶ô/Å÷Ûí¿`(íÞJ„cy¾ßo´;oI~A\m£¡éºB}Xöɰ–^ûjgkW-4³»½­'?ÏÔ°„|…ħàwÑB8‘é¥CBRBÈ ªêáqÞ…r÷øH‚¤gÁa§š|™Ta—Fxú@’@i3zRŸò†4±4¬P‘{úÈ”{Œp™y¯ ÌG("SjX$œQ†-Dõ6BÌaJŽX#àOøÂRHÒ«%34 F ŒA@•$Áo{ÁÕ‘^ìTE¡²òîbj >Q¯ÃzRNêxS°®ç«/žæØú",Xsô=Ô&ý-Xè<"W„Ú6sÐ %¡ô*ð+ðWéA•$€´õ±G%F– À8…(&B‰ÄsTо§Ï ø=_—è9nú-‰Œ ÃRÄtôt¸qʶ?×öš¥;ZrF{ÌÒø€å‹ad¶âŒÖ¢Á Î|}N i–óP›z楔Gjid¢“ŒTúT–ŸieäÛÊ×S|’´SNXf¾™ëIͧÛùR¯µ´Ôkw––:¥ëK½nïåÕ‚„S.×kË['×ìu ­ÖÊK’[…Þ[R‡’WÁÙno)—k­æVáD·Û[y©sÜi-I45Þê½\è¶2¼Õ^·ûrî:+rÓ£ÀÚÚ k›LRŒ-‘<[ÃŒ õ$›Óe•zv¡Â3–ðé§êƒïuˆÜcØÐbrØüÃJÄu’Þ÷brVËÔæ…‹ÔÖQ úS†]¥=¢,)+‚ð€0Ä í ï‡Gp|­Î¡¶ƒžU©Ñ?ß¾ƒÆ ¢»Ñ‹ßS]*ü‚ò¨œÈ¸Ì|~&À_2êðGX–Uæï7þ ‡(nÞ¼y”'˜ÕüÁ^30âÀ³ô¼±ùañæ¾póöíDßú£ÑG¿üæíˆµè ²$ñ½âûÿÚwFkÏ£ŸùÏ£î oNÞ¾ÿã,N¿»!c"¿·Þ¼?(Ž~û£÷ðνß} W~Ù\‘>°ºù'M©÷Èÿ+Þò“'Ë]©Iu:­æ+­–¤Õj³…'eC®›Ïç¤Kk©Û]j¶ íÎËÍÖJ+'¯–ÿZÒ[«Õ”¸*´šKÝc¿Ó`I=KbOB°Õ¼Þ‚ý\³Ó·†?„…Í?½ֶ؉¬8Y"y°øªUá/°ç½ ¨L\õte HÃòM%"媰Glõ™e“Ò©bð´çÔÀÛç&¡j$™ÿÑ]Ò^¬ Aè% KÝÎix«.QmAûl`KŽu( Ù7¡ðÓ£Ú|D$Å1‚«g¼£˜[W™``á+úIèGX–õe´éŒæ·6Ÿàú £‡_þÖ&ØkÆ‘è`ƒyøÚÿ~úÞæ@jXE˜ówóí!؆~cø_¡µè °ýà¾Ð”3†ºù¯ÙÚóèë_¾ñóŸÁØ×ïßǘ7Ñ(Øàæ;Ã?’áÙ–¡ïÐuÃûúw¿öáÓáW¾°Q,~¶1ÅOxª2Îü{&C{NÖ¢?‘¾6p=«oßûš õ[{~þüôá`óßÓ”gÙè{õ؃F®7!Ép_}Uú•À„©A”²Ó_üÚWo>ýäápóOdAzÀ:éô^nÞÓZåž,²µèÛäÂÖ¢Ÿc¨C´ï<S©gßÚxS‚j¸ùõ‘l_n’=hmqZ65É/Y’æý⇟üÜÆ\ù\þ—ŸY °z’KM[ÌÑÉ,èáGP–èGyáýXiM9 MBO¦©CóÐSã°`•QbõˆÆŽîªXÐ ¿3štz“GŠa‹kløvºÒÇCD§@œ0;“9všµ°LèqXvú­!àj`”>i>vÆäqêþÌ,„qy¡kôxâc½®>¡xþŽéÅh¥‘¼ðTx>Ž;?÷/¨Ó][_>û‹ï޾W,~«(Áó3_=§N÷Èôóç`Ôù{0CúþmÁÛ‰~ôð޻سýÁè?)kÏÏŸ¾<T§;ÛƒÖ§‡hùY[†¦ýÑ›Å{¿u¯Ô¤ÓÖI÷¥——rkKK««KK¹¥Hµ)K9}†ö´ßœrn—r¹p`¹Õ5øYÍ-ýd»ç5°päk€…3w!™ ˜ìI9‰ææ˜y&ÐŪé… ä‚51*/¯ÁÒ㬀µ(1Ã+$.-öø1}ìûK’›G/˜Êìp’<þúh€E㺴~²ot¼˜‰@ç}Ÿ]Ô°Ä 8ƒÁ0 ahYv¦A4ôlDC†ØÔéq gиû݇¨’YÖ¢¹áF– GO…œÀQj7vfŒÆe¥ÆœP;ØÓ~ë× &²Z¥jÿÚjQ§lÿ¡ûÞbÎz4œÃõ”’èªy˜ð~_.°Î!£a‚áí ’T×ò—²Ò …ú(|#Ñu¯"ëi…ÜY¼ â}ÜÌ\Â{q§ñå·#çxDTF¦¤B ôa03‘ú ³ˆ…·SJ§u2à‘ìч'ˆüÍ–PÖß/Å$ËXÑ£`üL“™ó—Z& $[q4“L2¹2’+“L2I(£?ºõ¦}üz¤ihNï- á˜+“L2I(Ãâ»0ÕváÃ"Ù…éEFÅÁH¯óÞ/ÏÏdÉ€•I&™$“ÑÆÍâm@?Ú,Þ&Ò)‹â›÷aj5ÿxþ™3`e’I&—'£ÁÍáS²ýÚÛƒwïnž²±°wa éŽÿÆé;›¤ƒ¡™Õ”%V&™d’LFƒ;£Yl¾;€U°6Ðâ3ئQžw>Áã¢VúX°2É$“d‚“§¢ è»Ø[UD`ýhFãÚÏϲ&a&™dr‰ ʼúþG_Û¼öÎàïÃZ›oœ¢ýh8=Ú ãMò]ĵHÓMA¬L2É$¡|~KYl†N÷ _+ûÑ ›tügttKjXg_N7°2É$“y„G1À–m·,猞?Ohþ朒+“L2¹2’+“L2¹2’+“L2¹2’+“L2¹2‚ÀÚßwÜ2ÊãÇå²+÷ÊðËŽ3ÄqÝçÏËxä–÷÷áÊý} À—N§,.‹#ÿ¹’Ô——Á´sFT‘¸ZÒΈ,NUf‘¿Iîcåð5á£&…÷bâ”áip^TfçiöŸì?IÙ˜»¾>.}ÉÃŒ>ÉŸ~~/›WDX¦X 3°•šõ€–ñ…‹•›uáÁ‚êt\BLIêÀº˜äÛòâq*`M‹aQ7ÆMü{Öõq K5©À=âe“àŠHXaI¬2¨XÏŸ`·sÝ…KÝöØ¥Úa…÷GsÃJ˹À,8ik’6 ™¹t`¥‘¿9Î§Õ X—%,£)äP“nŽÂŽÜ¼ýrôòôoñ„”lÛË ƒìàQhqdFØüÖÅk¼Æ;îXÌ΄½DI\¤Þ¨€NH\²’—fâŒM¹žˆ jþ°ùYNï¸l\!`Q‘=®T¾¹W©V+{¦Y˜ìæ°öª‡ÕJe¯R9Ø«V÷dXÖcå§|QÀÙ…ÊhU»z«mR °vfúŠTm‡Ûž •1œ8PrV¥³RO®øãH ÊÆ ËŸ3+•‘“8ÆÙ‰œs,oΘw'Y–íubO;ô,;ãWL¼j–\6 ®ˆP“ЬrT¨Õ «kGG¡%!¶ ˆêµüúj­VZ©T×KÕÊÊQ¥r´&Ú|/.¬­]2 Ê†Tw…¤’2¤ºe @£¥Õí–Ÿå(dÐöß‚k¼L/=öuSyèRäØk(Ëe»¾:pÒÑWE ƒaÈ*,UZ÷ LéK.;ûÍåD#·J˜Ô¡p‘ÃÝ ë……0òã ;|¾]òW%C˜8"Z‡Œ)Ëá 8:'à ¼ t¤C,<¼=®Îóyž‘Ë&Á–Ô‡ª•o–òG…R©”«îÏ© °ó¿P*ŽJkÕZ>_;\+Õe`k‡{2¨oœóÙŸ[¨IhLÒƒNEвMÕ«ÝíÙ¦ŸüôCå ‘b!qReÃúâ:X]¡ë™£àe‹'’A7%™‡×9)b˜€%œ˜z«“£ž/‹5ÆËXÂ#áu½°´4f “IŸtÏ´>$TaJr‰)Üðm¦R1o*õwáª<ãBÜê‘ka‚À*ƒ.´Z;ÊçåFB¦ŠMÂdÐBa`æó¥Úº<8¬•JGÕ=ûa^p£ÐÕ¦ê5°ŸŒ£å¬ ^©òi„7µ+.@Å2ÀRš•–ªSuHU]á¨:‰ŽÓ´& ,—²ã¦¬²ÃšaY)+TãiWiB¬¬ÀsAnB”˜)ʃ«=•nМHûú*BŽËÇgÙD¨t%~í`@¶^$4(™ SŸë ~e¹ÂZÿr0,KAêâù‘Ë&ÁVi¹TZ-•$hj+²AWNÜ´•¿.›”¬ÒZé† ððpu­p¸g}5¼ `YMBзDXøï‘j&&ѰèiŽ{!B XT9©$ `ðÎJ‘É媋×9„²™–«•¬4ï&‘šJˆ.ÁˆPé…ÊOÊ•Ë'\GùtWxaˆpÍõ°t (mT!¥LÁ ¾ñ¥©ËN…[æ(-¥‘$8 ×UÉ`¹®òíU–¬s¾'ä²IpE„€U-­×j¬Ê!hXêÙK\Ø®S]—ïÁÕr¯´œ/•Vjµ££•Cаœ êÉÒÖ+Z»–Nµ«[Ø•X+-ôÀOå@JU|',S ±f;FK‚ÊM#1ch-†³ µ«2k"Bµ£HKµ:€Ü²@=Ö±ÔHåÈ¥ ò£ÀäðUÈ»2å‡â¥õªêþáh=¡Ž1\×UwTŒ÷t••ö„B©C­×Ñå]6À›䜫}Ù$¸"¢4¬B¥=NG/ÉfÜjE5êçV¹²Z’×UäÕÒ:(kð¿úÍ}ÚEkKµ%¯¶àgµ³¥”¬Ýmn5ÎÖ°¸©âboì¢s1®aé&a¬†E_•ª ü'–`!Õ{Pææ¬‡­aÖ£4m[ÃÒy0èJ¢ õK9¦”n䲯6,W‹û´Ó6¡'ÔÃUÖ}–úåà¸Ì!®kÊ̆š¾ä\7=“Bî•ÚÊÞÞÊÑQaåhuuµV¡“°¤eã‡5¬Ô¤.µ‡!Õ%©ªµ••ZåWïÛaÅMt±ÏY¡ò1왣™•e{ôP»« Xø·5»AHSsöå¸/tý(/VÅr]õ•°\¶Õ SË"‡¶>Àý>bJèT;´ßòtÿçH?}v¶ÓúÊŠQ˜,p–„}ìº1L>÷ÃŽeÓ]ÜØgeÝÉ¥ÒÄ-9úÖª¾¸º®«ËÖ”"暴¢°ˆóœ}%\´(`IÄÈöÛQ ¤VÝsç˜SƒÀ:Ø«Ê0*ÕÃ#IýÉ£Êãl\•Xá£ééqÔ$¡ml>Šð#¯¶Ìà«-½™ ,Fæ‹_L& ¬)ã«ì\›ÿ±#µbBW#ÝC¡¤™þ GAÍN<ÊQ©?ûX=ûñz»³1â†àâ¾²jZ|h •=®kÂ`X'…ÞÙË&ÁÖ7*…õµµõk¹W®ÝÈç—×VB_öf k¯º²¶ž[[»öŠÜääßú+ò/wm}mô5÷ñøøøñ8°f!Ÿ g»O¼Ý&bEdÐÄãÝw-×dM pòäŸ="'òq#Ý#òD©K0ú54Æ|v ãã­B'á‹¢k{M0~zšæzè»|Ù$¸"¢†5”l©UeŽÊ²…ý+ÕZi‚`ó1kIÖu¬h¥4S‚Ì\ùƒƒdsÞ†%Ñ´k¨-3Æ}w{V+ÉÐì4¦f:`©j猿è-OI“†ƒ5¹JM\F¯ÃýFx¸ú”qàNܯQåÓ@ãú¾¾.2 Á± n÷®Þˆx~rLÇé±vøIô\#°æ–[©ZR©<žóåþüùcšÔ£à_Ü8c7§l÷O•CC—ýr\ûjfõÄùØÜÈ`íînï².õèÑ–nöÙ“õ DÀÚ/GUþÅ1 †‰¨éè4ÇÓáØ]g¬2Ä&#IÚ¯aé¥Z&$GÃ߉uŸ™? ÐëLðA¼Jάæx€ûÆ‘§ìœãùØ¿l\!`é"v¨¯hÞ¹„÷­{ÿ uÃÕ< ,7~ÿ±éf§st%ºqs16 ®Õ$Œ´ w,—ííÙóqÂ}XVšÆÂˆ¥%c0¨Ÿ^ùÍýS3’çÈ{î$×Çæêt‡åÉÊŽ]}'L¼ ¥:“–Z& $=`µ[RÚ'ÎÇ€ Wù{Üéœ é¸Ûý8¤ŸcÞGyч®Ñð|ôÝ9>ëá~êöæ¬ÛNÚ“!În´Ëj'„´DöÉa*<ì·¬öû³[¨ç™ Š2ð°qMMÿ©Úà«Téãqõ!.pwT« ®ñý$Œ›+ù X Zç ãÆÓ “ šŠ§Ÿ¦~ßçß¾ç3Õ¹8;¿ökŸv{q=¹,53y]¡= §ÚÙô›Î_ ¢v°ÏJ-0ú(´D²ÔÁÄV¢åe NÊu[>ÓÂ÷SnDEsq U0bŠÝ¸’`õÖ{ÝDØ]LЛX>Ö3Ÿ®óS$Óë­þgoC_æ¡|°þ$" æJÿ§×žx°Py6Ÿî°@øÖqX‚t&t¶t$U‚H5Áä•¿*+ wØÑx†dÛ%zŽRË$¤¬\%õ¬žÔžºÝ—$“Vz°WøI‰¦Âr®Ó‘jX­^+Ÿoöz¹\¯Û+,å–¯/I̵ …^»³”[íu;_êwZKN+×íB8­¥\«=³ª+`í˜Å®v¦-‘<{„ƒ ,óp.NdC‡€å“nŪév¬ iØÐbr”wUÙ}2ƒ °ªÍþb€ÅtJÛ‚ó‘õCŸ•d á|Q¢ð*A¹öÕET”=Ħ\)‹ä[G€h DÀ³ø†8Âè‚è“rÀ 0í“¶aÒä¾oBƒW™Î÷ˆdÀJ&é« K$÷zM‰ BKêY«­B³Õí.5›…^çK½^ëI¾+¡Ö ‚îõ'¹æõf¾ÙÊÇÖ’—ôÕi¿Üj¾ÜûJçØg`õVd8½ëOž\ïZýæ¯ÑP¿¨œÀ¢¶ÕœÐÉ»Û!‡DK$›w*Wo¡»‹¬ÁêïEëõ>˪&ºA õQ6•&¥ªnƒ+œÑ³ˆe~\|ªIª²–ÏL¿Õ$TJޝ*>§—µžÀ>Ò@@dùÉ·Uô"”ëÀ\EÄÕÀ|߬4øÔÊ‹¤L5U¶}LDiW A­R‘_Œ” 葺Èà“O$}YžU~°’KšÀzÒ”ú@FB*$ÊvÔ”@êJ^]— AÙl”À’çóÍWZ×¥¯åe‰*ºbéSÜâþuù°äu¹„#µ²|¾Œßð¾Õ¥e¬OèYÓ]:¶F£‘+eIo4 Û!§µÀj6W¤îÔ*´Z+­ü“'!`­J`I_ÍfKËl¥»V ›‘-è“~VZËOž€v6]­ŽÖN¸hZ…I—Hæ¾+¡ á‹ù?ZÏ#¾Á‰Rø5¯*ª ¥øžn$ùúRî$ÂKè°çï65ýºI¨ÔC,ÀÐW¯ÐÍ,l„y¬aõ £[j ,ʯ¥­ù¾¯wBÊšÖ°|u­ÇXôL¸"ðM÷¸ÄaÇ3¡¬SaÓÔî,Pמ£Ô2I ©ëDêR½Nš„©–lð-]¿ÞjÉÿ­ÜõV4¤VüH­ê•hXRwZ’§±I(·MðÂWK]TËd89€_>ŸëOBÀÚ¼D²ò’l‰d_}dÕrwv:BÀ2=;´'þ*e;"„0ªgʾ(ê±\˜Â~}ë‹WŠÀâRï’P N-îžò¹{㣴ãÒóBǾ'" XôèË|¬ìƒ‡ áñø$œH# –³d¾5¦‘~Ÿ'„ÂT~ëcc+ñ‡?ÒõøÛ<%øz0@Ó3.”7j‹Âð(Ì>^ÕЃ*h5ƒ~=2@+~W Å‘Wñeç4¹¼²©9óIzÀz©[ZÊÉ(9©-Ù²ºªNñ^Ž÷µ¬™ŸÈÕ¼ÿòK0à4öÐ(tºï”vvKüáU†«ïËì‚ XiIzMBþiI·ÛíL•O§Œ½¸Ýþµø©9æQ0–V«vw#ë‹J\íl%]ptÛ̺»°Ù„ Xü@›J!ã÷¸cž:Çë”w ,3•|zM²€­Fé$?·×¨“^#¡aOvW¥IóÝ¡Äöm85è“JhVªJ-Ü“ñlÒ${Ë?=AÀzƒ¦ÖÓö(°<[có"ºV(_Þä×é”2ËVkH(©KO\àá8>/0­h³Ãø6 3p›é˜ÉZ·Ÿ]Y´RÀm³FÃÖŽn& ·oø‰\hç••‰pi„EÕžðz ¾ogõÄ`&Åø^´ü_4ù¾I„5õÙ×)§˜°©ú.€g¼`ÒÇ‚À¤3”^/œr_Cŋ͕çÙN¬±JM]aþ´OVªÔ+!Ú,õ8%cé›UbÙò2‰eëaÍ^Ži>A2¿8:ªa½°pÖ’/p”‚,rµ*U;®hòçÍèÕ‘Ë&Á‘lÅÑL2ÉäÊH¬L2ÉäÊHZÀ"˹®±"èZÂÖTÐußXHE«]ûÆ![Lz¼nÊFáíÿ@›ÒÙ?˜+qÐ$d+>h±'·Ê_zÇ22Žu ƾԟ:¦s\NÑ?m¾&.|ºìò¸åEäG†vãblzÏú³ü¹‘üPØæ”£×Ž—ãX™¸ñi1nña˜gwÒß>ZšŠ?7»¼ØæÎe“àŠHZÀBpè§”ŒríO37o,‰XM9zEto¢ i±ƒI–Ÿ_Xdêé…‘'–°ÕÀI•?ºŸTlSõ €ç²2=%ùIÒt M¶Å[ó­=vU2ûàI$ «ñôN¾æ…J-“’°F桟¬rX¡óã7}?|í ŠÈÀÚRËï¼0ºŒä‹–S.“Êé\űbøÖ$ßnÙ«ìκæ|r9ÀÊ4¬d’¢†…½Ë÷oìæq•؇ßä[ìªv`|šU­jîn?z¨¢mTfÉVt`)k¾¤aí£™Ó9$¾¬§"h,†ô€å¸XN4LwJvÆ}…_t68¦!Ä\màn`óÈ>Ç#·û Êö¼rÙ$¸"’°ª‡ÕJeÏ-«þK*‰©½juïñÞžÜ/‡{Bîþþcéã1ù{v& 5ÛÌÔœ J,e¿øÂZ„eìL,óË)/X.ËýqÙ?p3`]¾¤¬êµüúj­º‡·ÖEÚèjWY9ª”¥Ru¯Z+À~Yõ_Eª\R9Z©À?.öÏ,q­%’iòóîvÜɸâè6œMÔ‡%ðÏáß… Å) ÀbC+r:´ Ùuájw'|rr Ò‹°KC\¢a\ "6=aÎx ‹yW8îø…Oº"pø–ÑyùÌÅgXè•pÓP;:C°#é‰;.^¢JtB>§Ëe“àŠHZÀ*—ó¿P*÷WªRÓªðVê\ò_M¢ |äkÕÚêÒ!8ï—C©•¹{à÷ BÚ^Å­–Öªò}Á9ë[âÌʲm/#ƒˆ´þèÖØÉÉ–—qàéÔ°H®ò9žÈyž]ˆÇÅÚå ‡`× ^ºR*àó¨T¡ÊØîbf La‰ó‹ËŒwݱ@X¡òÀ?"rÞá\;¬E ~Ð]½Ê˜)¡§ ÌqÀŠ)¡)0­‹¢\¶ßT `eºœpô£C̳c‘m¹l\I XŽVeem­T«p»Z¨ÖV×o0°JµÒ¿ g µÚÑLr~¥$µ©ÜÚQ¥º.÷k‡/I%¬´V©”ràk¥VZ[CÌu§ômÙ•E¶ö¢À¢£Ý-†–Y+A—<ë"®Â…0 X˜ N¨¨YÙÀR¯p×åCõú‡*FYy› ,cV}OE °H3,szªñrW*ƒŸ+t¦œ°Ui§\¥ñ _GçMhÜ"¬…&èfq€+D«Ï; |º—®Jq,sy0:é~[Qš·–Qw©,•£˜¯4¿—M‚+"ijXùe‰§Êa©”/•VK¥eÜjG¸À*­—n”þ*¹ 9©M­•äVž•.+5¬•RéÂÊUIµ5a‰äÝs.‘Œ¯QáZu$½Ê/FÿÁÿ ,¬5»$­ÌZK¡Ê ,>ÂUW/®I(• À¯ÊPÚÆ¥pX³QE 0oÂu8˶g±Cš ø¡°¼ð¾ql–{Ù*\}WËÚ_GŠ Æ³Ö]Õµ¦í ipY™+›¤'.¯ XsHZÀ:p«ë¥šlýÖ®åX5Ù ,-ç¯I0á~õeécY(Oî¥Òz­v£¤%ÏÊS«Õ=Ý$<\{E+ŸÏU÷µN3£aÀÚÝR øQï{üɬa%*4‚ýéHIl`ÉZê€ Á– Õ+o¤ºú‹]Z®û¶¬€¥*²3g›y8&ÖÚAÀî!Óúr™G G9Üy$·ªë”ËÆƒÞ×G CùQh+…¾ÖQáá!–¬Š›ËIƒ‹7QÖeMÊ,§]˜æ;åj¨EµsÜôLHzÀªŽ*Nyï°@ºU­öŠD’Ô‘Žd;±¶Z’ͺJ¡”+­£$”TžV+Ò¥TÀ-í¯Ë_éOªeµÒê¡ÔÕVŽ$Þ@;K^Y˜B[ckº?zt¾%’©^QSeÿBºÝCÀr©1Æë5iTãÀ‚€ëL–öK¿°X}XVƒS(eË1WƆ9Œp¸' ¯T:]¡aÍéF­a¹¶§€å"ø.+a0–cô«²—)—¨Ëi&Gx¥”é{‡ËÀ:Ÿ~Ù$¸"’ÚWB§²RÛ+°®ÝX=’Z_.IÍêtbVWkD{+GG+‡‡+G‡µ\® ÷+è²W.-¹_;¤ÎùÇyE¡T[Y_;¬å–פv–pp£étß5MÂ4üe%Dík+áÉôàbŒzq_@–éÙQŸ¨¨cZªþ–2Uw 9ÓzÚ¨¡k5SL}ø+!©6ÖVÝ©ÅùÐÜ¡®$¡Ë™³¨šúC©Ù*GÇôía¶42T#ÍQ½hÂj± xr9*Á¾½•î²YY•BçõŇðL,lnMèQŸsìû|ƒ8Ó‘$q:e»ïßú䕦‹Ì•išdNI”cypB9‰ì)gâ©IWLö‚êqΙxÑÔ5³ ²©9!©«º²–Ë­­­­ßÈç—s¹Ü²üY[»‘_^_[_ÎßX_ƒs×®]“[tYÎ]“në¹nqÜ—Éã 8/7×ÀëµÝ座 =ä©¥±G޽RÀ:¯˜&¡9J9ž÷pqs/_Pß)9Eôkø²IpE$-`}µ¢I-°ݲ'å¼0°ÜŒÊ|#Ýç(§ ÖÂòðã$°æ“Ô4¬oÂÏ*Œ­j©ÐÒ¢¼Åz¯ìí=ÞO6BiXs˜ÅI¬ý„±§$sÎ%œ3p®‹‹Á½ ¥ôêËe“àŠHjî8Ç=À¹€Ñ{ẓgæOswA©âIÓó+=uá"5¾ZÃ"¢`%h!rÕ€µèy å²IpE$[q4“L2¹2’+“L2¹2’žÕ¶Ø¥l–hóE¾r&Z¿!Sž|6°=©0š@a«9).8ÊVs.ÒK°X³3˜•¿Vs®ˆdf¾æ“Ô€EÖŒ…ÉFÃ6zÚ0'Á˜a´_Ù;ÐÍl°UâìŒ_gÝ-„›É+Ž>Ò›™ÀJj/5Q†ýfåø¼¢˜²˜°)ðŕΗÔë` 6VRIXu¶Ó‹–Áµ ]|tµ\/|«`Ûïks“p­Gh`J$X»Ä¢]Ô·Ø\*¯?úl??Jú%²Ö¯_ÍgÎ…eHž¥?Ù6ª§M(‡-«SìÎÊ”UÛO:¹´LÕëð9ýÆ(µ—À¾{(]êo¢x&ÃÊŸöïE÷¢@U–rqU“Öd¥RcqwžÌ™RË$¤¬F»Ý>F{¸““ã¡U]°3çà£åíN§íÓ=F³Þl°Ø?nwÚ“îž­qÑ£•”X,äÓ£­]Ý8 £iW;$AÖ¾z½¯kÄüÏâ9ž] ,U =«Šyc;ª ¬zç͈!RiÉ{ŠÀòìÀ­VF“ ¯ÂIô´yí1ÁS1i›„‡z=¼Ü«k±ÀÒi² 3°n¹g݉ø4èkæc±]j™$ô€Õîµzã¾¼[ÇN£7µ¬FƒÎÉ{)u­v«Ùê½ÅÀ­ç¸+=µC÷›žíyZv“pk;„¥ÛM·g2KfͤÀ÷AÍ4…¯€etL,ß·¬ËûäÍ3‡I^òƒØ])éd‹š„´k\±¦[ÐõuåöýðíÆnÌÀê½´òËHö휫+mDÞ×1™îO§2.»ž*J}¥xÊE—“I›v¤*½ç¬d’^§{g)WèµONŽÛ/õ¤>åK9‘z•äU·°ºÒ;–.Roê,]Ï­´ývÛ—z×ÇAðq»ÝmªÝ+,­tOÚí·|¥¯I_ ‚ô¾´X;¡õ°¶ì%’·vÕB3»ÛÛ '?ËQÈ'QÈàåì§R³'å À>,ä"°BÈCŸöÑr]ÔÕS Wy³Þò¾Ž/£°ÓÉ—–N? aGx|ÀFÿ°¼`‚<N“0¤€˜ºrGƒÚˆC_ør`©ùê)Ô¥o)|*zA¿T¸r뙲ÆadËM•™¯=«ÒÇÐA2`-@ÒV³µÒëõº=îñqö;Ç Hî}éäãI½·ü¶Ô¦Ú=Ш` ñŸ¾Üêu¿$/mµÚA¿Ý’:Ù œû¸ÓëvNV&?²DòÖ¶½À¨½DòÖnÒåe¤†O#<½òO@5Yp³j<Ô®'Pµ ®]u±f ¥1° ² 7®±"6l|ïû…!Ç)˜¥RB:ÒFÈƒŠ«N¼¬9ú ƒù­¼0°R Òê¾=¥x2Ö‰^Üw-ª¤ÔR‚Éåû–¶å˜|`zðD(äAŽ(’KTx„Fºîļ…™+™¤¬\³×[iµV^’[I¨Î—z­¥%‰¤F§¹ÔXÿ•ŽÔ¨:¹–T¶¤>Öëår½N¶’X~§Ðص^^’ŠZCž_’‡/¯t»Ê[çÖnXjÅQXlf[êZ[3qÅ}X,¥`‰…jXP5NH³‚Z Z‡t¢÷:T8þh-9j ªITM1Á±²…\ Ókê`‘Z¢´E‚8àÒB;¬ÁÂäƒPÇšLÀ¹ö…vÅtC)Ðy­ïP¾ß±ß.ÂWT6º9Ê÷GëE‚é§ _PXÞê?+Xê@…GPƒ;E~æÇ¬d’^Vg©Õí®¶Z…nWêZ¹ÖOvzן<¹Þ•ÀÖR§qük†lÚùýn>_ü?Íf®EÛv]jZ/¯ÊË›K½ÞË­v§Õ\–aõ:_jåŸßl‚’ÕÂP`DVB`á¢ÈÛÛc+Žn?["9A›P‹ê×î›YˆØúÕ ßªü\Ñíª[gÕ*`¯ŠñeäÛ–jç¤,f‚Rö,`¡NE…(|“/öii<„•kR&ÉÑÆáóa°ê°8B¥v2Í T–à¦6ÑËI)³¾R©Ðv|a™Ú1Ö"%= K‚¨YM: ,©=­¶V\’MØ.5§•öq§sâõ¡Iø1öxÉÿR$¹Z½¶ÄZ¡‰ÀºÞjPïÊ7[rç'[ËOž4;ø õû“+÷è&áøÉ!%Kðbï3ÅS÷4Ö¡:¶Í÷»ô;à}Ó`3JGXþ`ê*®ˆñåäs¿8WÄ@׳´ºÝ©I¨úÂz’f—î²IÆä²ÀÖ°B¹ö5€ø°otcÕ° T”ñÍ–§K0,ul KÃMõa!`%õ-1V2I X'=©Iͨ}S’DËr¿™ÏC/•Ô’rp®»ÒëBŸU³×ù´'ƒ­ë×—äöè­’î­ùëlòÜÊ+àœÜH—î±ouÖN–çYÀ²–H¶¾nɿr2×mõ6_°|%¥¾áQÃŽzi0 žrÆ¥zqÄ´‚B`i¿¾êJXvúéƒÀ·?§a”o¥Âçuvq6æZõ5™­˜` cåÌG‰¥"°Ppc¡o¢^`5 •þE!ûæ{§VõW[ßö¬½ X‹“´€uÒé5›O¤²$ÿ……]Z´Û¢ƒV‹”§–:x’oÆŽâšzÃi„Ÿ‡õè‘lb§úî–Ú€ÀÂÉ[ä¾½¤×¾†»¬3VK§Á •;©e’@RVw¥°´¶/9½·ºj¹æì3°¿º¶*U±œ}m_^éÎßvdÑ#)€›"“ì=Ú%¢%š›ƒ³Ž"Õ~уÝ’¢¢ÑŒj|h«eH °˜a ±ƒ‰A}QãÉ|{ú¥gO ÔØ$L|çÄ€)·Îù>…"KÅæ˜5òj¦ÝxFs‰ÝO^òùë£í*45Ô4ðúÆÉ³O…~Î÷Y¬d’Z“ð¸ÝIEºÝG˜Øcæ'ƋǷ9´Ã“ mEj—ö´¶•xjމbñsPMTU1R“è‡*zŸvã’äéñ“k‡â#ýY’X±:0˜¥ß¸Y‚ÞxºTæ# 3qÔû¤üØ(§ ¬™G¾. ÒÏ·ÁI=z «š§©UEO¿¬¹:ˆYͫ׽ÙsC¹È€•TÒÝà ô /üçÊ›µaköÖ1LŒÖwUÏzÿÓp4§™Knî1¨vv­S[»‰ÇayãUoQÿt÷x°¤®=‘&¢ê&‰N¼¥‰"qå…U ¿}úöi匒¯’ºý‘)@6SÃs ½ˆ«ÖgÂzgL¢Ö¹¼ COÌÂG\L¦ŒtÑŒÁ73¼NåY Æ1]8üZKP^”¤Ë&Á‘ô†5ØKüDwb„ëTà«Écz6–ñwÍ ™´Dò¹íPØY›¸ WÊ2qA).­HRtá©C¨P¶Ë¤‚ ýf9/,§ÇÇfÌ:aÿÚSkŸ ÂÁèó&…:ßÁÄpbžÅ¸…Ü‘±—&”Ë&Á‘lÅÑL2ÉäÊH¬L2ÉäÊHjVsÊe0œƒFïöéoÿ±ë‚±´‡s@vê\:v¤_GÙÉ!#¨ûûem›ÆuÙ4jÙAËmd&u_YØ•Á9Êøùä«`5Ç)›8 í‹5³Öeqºª ŒÓ¶éì¸ÆÒ0œ }G»iwg²i@0l£®³ÃKÃN¡mù9”&×J»¾w³ãŽž^ë RÇéØþÕ½ƒs¬ëm‹Òcñ¹æyµãá} ž ¾i®–™¥¥B¹l\I XáLBƱŒ‰,؃?õh¸Öm“ÀÒŽ‰ª R.¦²0hvôÆêyçNw^ƒ4ÑÒï,§œNUN*d„‹M½;¶uÛ€ºcY(äîLŒ¡ì„K VÛÕ¦êí¤œ‹ôNrw'rä„Çò ‚ÌÌ–5œ±0LÀN\8ç~“eÀJ&iKßtu”MÁr--|î›kïb«Îøƒàª‡Ëöàâäg\ktg|½QÖ°‹k  õ»Ø‰ONšB5ÞÁüi…n<³¡ÂkÓ’h,U1-íŠïÅãŽ%ajš&;ü'¢•cví׎c\wû<>[N86u½£¢ 8ÏÓ‘+™¤Ø$,—¿¡ Ÿmû£R‡Ò{pOå)§l»D/9 Fe¹üøq¸:q31¢a¡…Pkd¸»Àèewgg'Á\Âñ'p±¦7ÆIHCIVœÇZ†gûœ_ì&aø¿H$ q:Ms¦ùwb=9ØOQgêérÙ$¸"’°Ü½½JÅ ?\!`éݽêaµ²÷M×4 ]å=,lFW*a'L§ÇÒÕ ùV6ØV»6¢¶ì#­nmïl%Ö 4fÎ'!`76&ÀË™ð;9†Åäk2°&Iκîôós¸;ç #þF$~GÌ’Ë&Á‘´€åH ÕV*å¥èI‹>ªÕõüz¡VÝÃÛKÝ\Ñ»w`v+G+ÈÁ°ŸÊÊQŵãâ§&?ÛK$ÇL~µi" KDþÚëΖL/EC¡Ãûêl¤¢ˆ8÷IµÃÑ~EÒ‹’%Ÿ€å˜ôGR8."Rš‘cʵõ u³Eè¢1'ë–éW£°N+Êì*“îª`Ê©¬`G—íð킘ÿñp.›WDÒÓ°öj«¥ÕC©eíI©T«•Ç{ÕªÔ䃶”9ÌÿB©$‰ÅîÚW幸•ÒZµLúÛÞÞãÇì·–+IWŽ–†e–‘ÙÞž´DròåeøQå§_”Ó«Ü“Ÿ]ˆÇu…£k9ÓJ×·ñÚïX‰4U8&t*&é_Ug1ÙóyÄeÆ«ôÇq‹Ï+’ u»”«£%“bŒK·ŠÙ”“‡ïè­ƒwæ<¥yÙ$¸"’°*¥õÒJ­V(Õ¢VZ[;ªT×׫••µµ’t¥-éU¬£Ra¥vþ*Gê,\·&ÿVkµUùWZ]©î°ªàRýÞúr©êŒ)fü•p°v«÷%P¯¶yX±€ÆÅ«l‹ßö\‰ðUWЭ*GÕY8ª2ºéîŒ8 ,·… Scô>®×2N„+ž‡ü@]‡«¹0ˆaMF•+,W,Rj´cÙÑW¸XNÒ,—ËX^„)…×ÖJ…A¡Ké#â¹H.ḂÕQÊ›*3×e?.3î|Èe“àŠHzÀª®—$†J¥e‰­£å’ÄÌa^«TʳsiUî"°ò7GëµÚ:ø«®•$ìàìQN†qCþá‘t•€«"°@+IbYáUËnü°†-x¦v¬&¡ØŽY"Ù4g÷a ý¦NªÚȤg—EQÂ8,xdÆþã7L®º:dÖ”=jXŽ–)Úà>,jQ ®ìÄS…H#—ë9æKåW`Ò¨]EŒp”ë¿#•ǰp‡_¦@\n²•í‹MCÒ´¸±ÌI ƒP¦®Q©ø¥¡áf+Î\7=“’°$†ò¹ðdµZ“ûD¯”ŽŽrù<дœÏ°ö«¹R­²wXZ;<\SÀ‚³× µ£UÛ2^! µv¸ç"°¾Q!ޝêŒõ—i § ê[·VD»a%k7ÉÉW#þI³Ãgâ³V9,KÃRÕ•´êÚޤV2gz  ‚,LÃr8ý¬ì!¥8®ÖR•7Öí~8GéµR!ÝŠ]vt4°˜pÌpF¨kÈÊú.‚ýç¤ë_ˆ+8Lˆ¯Á¶T¼üÝS¸X®#Êç|¥]6 ®ˆ¤¬Ç¿rÖ+2¥BåP"§T­JG¬[!°äÿ#а*«¥ŠÜ–V+P¤*ào.-ÕŽÐW)'U±ÃœCµjõð]8¼Â¡„W¸Ó]W–m{mdúÙ‰]"y›mÎîÃr7UÕ—´Øo†ˆ'°Ê6°¸¿…5²ÙMB¨¬|ýbú°´âã¸ÂÖe΃#”f¤JÚQ]⬖1¤\ ^®–ú.A´VššÒ¤\£a•µ†¥»¥b€Å½†ØÄVÀrHË¢&ºÃ°RM^û~è~» X “´€µW}éð°zX[9<\©U*¥õåµêÞÊQ­[^•Z]_–ÚQNjXA{+5ÀVm¥²W{r»R;¬­ç Gk×VKëë«5 ' ¨ÚÊÞ¾l V×Ö 5r)\[Ƴ««µJ|eÙ6kº}%ÜaCª»h—P:Í^`†š„ªó*®k7}1_ Õç';z ¦9¬a¿n•uͲú|Â#ÍÇbp#*MZb5 u‚ÊÖÇèð9 eõ¹­lR…œr(™‚û¨lGGM.êSýyìæoeU`"¢Õ‹¯ô/ݦ‚Öj%›4;¡=;t?tH°&©ë°vX­Ö$LŽä_ Ô¥ÃÚÑ4öŽŽ– ¥X#GЖŽ+nGà}É-œU‚G5 ü‘SÕOmo¼:Zs wwÆ­Ó›ƒ¨•ÀT=ì˜Ñ;ŽßœºÐ¸€èÜ5'r.âØßég\Ws ¡*êqXe;E‘™‘Y jΟ•™èÇü:Æ“Æ‚š² šRÍ8k cú°ô€;œ7èÒ}ÖñÙå7¯Ð̼8W™^6 ®ˆ¤¬©­­¯¯år9ù»œ_^_[åÚr>·ùåµ5é(Ï­­½²¾¶¶º–[_»¶þJî•5yɵu¼Dú“7àÒååkkëè{¯^—.è)nÈæâ~Ù=»íÄ™G;I;U0L4:Q'Q“ЮD0€Ô8ÊqÆUÍÍ))š2—°\¶œfê]x$Ôð¹ Iuô¥†GgJN@Ö´8삨j‰ÈùÈÞ”bŽˆp¾Ò¼l\I¯IhkH!G3¥”©]½Gë½'UDúP ë…db“Юjé2XÏ%L#¹F¥;s2ÙÛ“ÿìi‰c|’¼l\Imò3ú¼H©<Ž¿ísÀèGXW6†Ë(²+/Ùäçd’êäçËçÇXN¬¿Œ’+™d+Žf’I&WF2`e’I&WF2`e’I&WF2`e’I&WF2`e’I&WF2`e’I&WF2`e’I&WF2`e’I&WF2`e’I&WF2`e’I&WF2`e’I&WF2`e’I&WF2`e’I&WF2`e’I&WFX¾¾[On|–@ïÍ·¯ æ»>=QËËL4:ÓrêØò2¦,.*G¡â´îȸÖ¦.˜yI(†…äHN+Y±Ù @¼w½¯RiRL .P1NÌžTÀ“¾±h³ 8x•âØ z}"ð"ñE5^Çi:eTE¡–·ÏÕOnêäÏ4³f¤5,}Ÿ>°¸Ì< &N÷³)mª^GȤ›Ó@i©{Ѝ>9k°QØžç…@Bë]\о6ůJÍ4¤)}¦†ËÛÃôÍðùPwS™ }uÝ‘s•Z& „;ÝÛí¶DÎJ§Ýîå–:øœ%,h~DýO—®ç ½nï¥vçåV»½Òëtz++=4ý PÝ!Cª[–!ÕmeùyG¥ÕdV äƒ(dðòÏiVîI™•B¦—²EÊÊ TŃC_õ ,˜«¦ƒKÇ ƒð…nòuJ(u\Á…ÇÈ@°pϦ[Á‡×Õ™¢{Àaõá¼R²ìT£¾Vå²'¸uJ³âótI#Ózz¦ë°`(ž)ky 1 <gŸ=sn}U˜ÂùK-“BÀ:î´Z½v·™oõZ¹¦U…„Z}ê,5{½B³õr§—Ï÷ÚâK½Þ—NôC5_Gþ¹+˶m’Ô)e§~ÇØ€–»ÚK žPàü@5¹€Nw¨dë,ÖáauRUTøTé=•ÎxÞ'ÀÑï”ЯG“ªªoUÞN>ÁSâY_XÿÿöÎm;q]ÝóÚkö.Š„TC’ØO“ŒJœÅE²8ä ¼/L§0xRÀWór_ÎÖw’dcÀ$v2ÜCÿ°eY'[?’e‹¿ñk7ã-ˆ±Èöy)´øæåÖtг’°Tj pœQ¹Ø[wxÔ”ì HŠRrKOÌK( t£Ë’¢%XôA~")wBEàB~(ÏŽoÖ%êt_m{­ÞVƒ¦\-—íí‚ ¼°v¬tÝÖÀú¶Ô¸Óá$Ûö2énµ6+©7;êÙ¯U¬Ÿ–F,C1t¸ž•ŸUZ#‡2› /—sªlb¶˜b´!Ù Šù“{|Ìd`aET\·+QCŒ):q`ËKQjɆŒ»˜O å‚rM6”wŠCTÀqñ-ƨÈ.&ì³ b¤ˆ©PS± ÙŽ¦8C*eJfäD`*R˜‘bؽ£Ô¼Jˆ,¬õ¶µÝô’egy¹\þî$З…*gá)ºÑ¸ÓÐÓÀÚ\þn/¯–ÉõfÓj·±GlŽ÷ ëïÇ`=r“ðžš„L 1u÷v•ãð ÍÄãÀ⫩ìôú°2ÕÄ‹š¦XìgFÖCœÆÂVbÙ¡¾)±°Rã9®X±S¯)6½¶¶Û5çkþ,%ä02ÈzTCƺ¤fG OŠS¢RB–ãÍ8çÂâ>,i0ÅíÅ!¶ÖS,ÆVÌÍJ ƒü¨=°jKcF7é4eÚív§ÓÓÀ"¸œ¬ßËí Cjë.—Io³s»ðãÏ–ièÙ•µ°ÀáçOåø9naAûLŒ,eú–êÌDXv5޳ÀJ]`¥la¥ÂŠøp `ÕÐ$´¶ž2ØAó#eš ` t”ÃÚX,*@ óˆJÞE;Êrê"L¯ü¾Ð¦ šq|#“)v¦+º I‰”6'ÃˆÙ”Ž†âa–J_8Ôù&a]b`%Œ™d«!MBðY0ПžJ“pE!µ–Ië{²Ýj›MóJ˜W{guZ¬»G ¬l«PzµÊ4 á”·­´OéÊmÍ”ëº+J³À¢ÛüÒÇe-“ƒ† Ä@•ŒòTmò©¹–Z*CW6W K¬$iç2@bj¤)›ÓtßÎân>×b“ÐR¬Èõa»-g­Ñ¹ÉMBÇ’2Àb' ‹–VÍõ$e +MßUšXå$Àjo·¬kÃÀ*#ÖÛFk½ÜAÿU=ZI§³`iðU<ÖçÈaG(=B÷”iÂMAnþ=Zn!¶Nn`Q]zk6±ì]˜z­bîË2¶ƒip‰ÅAn©é÷z—ˆ!&« ¦»„1ßÝÄ»ƒxZ’B¼Ç=EbX)Ó`”{u’kð@÷ì€Øl!q¯žµØ¤‹»Ý¥ÞxK¡Ÿ §(.c±è`;Ý¥TN)J ßþP6®XºÅÄ3%&òÀªSÔé¾N–"XÚ®ÿâÆ`ÉÁÿý¶Þê=“diCbmÿ¤‘)Ÿ€+wÖÃÞ Pé`¿+=Ë4 Ó”nw™A@µšX2p4µQÑx%qqK’²‚‘%Ça™°+VdîßÙ¤šq Î ³x/¥2ÔØmѲÅe¤:ÑeˆZäÄY"ùˆãì P¸ígŸ-ºwœ£\&ú¢²öÃê+ZýgËÑ·?Ö‹óõÇ·v«Õne¥×»p›pþ‰Àz@(=àã„ü@Žþ}$€á°w^.…-z–0µUáÏ‹•ÏD¦°¢â Õ?7¢¼Lò\`9½Úä[œ (låv†‚2li¼3cJ i{™rpÜgfì‚y¬17B=5}e‡åb,ÊDSðŒã‡JÍ«„xàèjíhÔÀƒ9eh5Ÿïvpо­2a8¡ýey®ÿiB¶°4JH&;Þ]ã ˆUâ±V:ûÌçr(©S2‡”xªÑypå_d wW×ÃÏôËŒŸ4OAæò’æWó§Ü~ØÇìÐãÒÖE\wÍ»ìöìcƒYìD.û#“ï>ú97(\2Îfï=U<°Ê‰Íq¯[¦ó£l? Mm(9ë9ŽÓ¬ŸßýpÀv[\ÆD‹&!ÑJ÷ö w¦iX‚Zp?í ZT¡X¬ºbe¬¨ÞH§±áN>düŽÔ;ÏöÂÞOï¾ÅZÆLœ§{¹¸ö8ÆWþaÄÑeŸ<\ø%íÛ|ÑÃ>_M‚†ˆ-¬Ê B:Žê€ŸRû ´èYÂгö©ïöªàˆ+¥šcp¯¯Ô¾â]kõê«IÐù7Žzyy5FX^^^QUÀ‡a8 CþÕßaŽÃþqyšO(>†ÏÙλÿÁàY¯?ç!„Š+™pì'ôo MBIÓþG”wûÀºŽ+Й†nø®¥¥l|TÔxÀL¡K¹W‘<…éO¥=®=2:÷xËÅ-gÚñ4[7‰ßÝïÜò ôQÿj4DU+PZè`Šbæ0ç$°>gœ_^P×ÐúÙ?ùœå€+KåÀrSYtòçÓóñu‚äiÑù°ù?Aèë´ÿs×C<¿½¬ò~‹às,­‡â;u¼Š~«Ò©òÂ!ñ*¡ª€em \« ®à¡!«ëð!5»¦^ÄýÅ`0s¸'×P,“b`Á‹‹^†\âýÈ ¬Aqüù4„Åé;o}0<÷´·i9êÓMkPXÈV.¼²z° Ò_èÏR¸ï¿6`(?oa•U¥ÀB{èÀù‚Ø¡š_h¯Ÿ­„:1²NžFÁõ`€TüÖör¨`Õž»§4€s·æ8jŒa@Àú@¡U ‹÷ÄñiÈé«IÐU¬§ñd<½¸‡áùé)DX!°žqëÓxü¤ÝG#i‹}??“¯Áé>àÃ^}“𓉙¨7Ê ´ ÷… ÜËë°ªÖø¶s{=ö»#]ú¿ä0<ÿÇø‰_ÂpÔ}Õ[ÇýñÓxÚ{ebY ÌÔØÑkwŸsNDçÉôð³óžQçÉòðs™øé`~þý„sâQŠP©à†B¨WCZƦ ¬JßݛĊ÷ââÇàT °[È; «©¨ ,èÐ4[Uaz²%ª³ºç!0ýo´º·c¨—¡©+û†f{]÷RJYsLYóºÂuòC«ø¡oƒ TÏbîx•PuÀštþÙï÷úýÛé¬'ýGO£éì®'½:Ñ”ºéküL:éxzý£?±¿ñD[g!îñB–šÞ!÷oÆú3A» ¶=Ÿ<êaþÉ÷î»eÜW$ß—~Er'¥•BrÕkuAWPq Š)E‚ý*¹Ñ@õÐ T¦z"ÄTx*¦°²¨X’~.Tå¼_Ðnñò ,t æO¯'Ù8lÆ¡2}PP *–êeRDDâ²Ö”$ß ÊÃf`Ññà2£|Bh Ó€Kª¨—êäA÷*¡ª€5¦ ¬Ë‹ÞtÚëÃçæº;½ÑK×½édÒýq1ÖÀ#°úÓþe§ÿ [¦¯7ðÒÀï}mMµ5д¥ÖîO'h¼!°nõþ:œþÍÍëi[ õX ¬Ç»åËÂJºå¥ÇË]g[„aEÀõ6'¨Á®äXŠ*/‹^#G0Àú„•–ƒ“À ±z™JZ•,°†˜~²Ñ[ÜÝW$ß•êÒƵ¡Þy:žyî:ÀÊZXdѵœ-IÛ/¡ø§Z$†Ðb¤ž&¡48X®­NÙ[œÍ0 ]`{lÉàW¨¤¯Œ)) ±˜³5gI °gl…Š>ÜÊsÀ=‚êÐKnvÀnÔ·ÅÇC®AXV}ª XÁ¿ºÓ' ™i÷é©û:™j{«{{3w§“I¯7žÜt:·ã'òÓ}íw'ðõ½Ý{}Å=ô÷¿¦½ÞT/kƒì¢?‡Ï£IïúšÃy½ø‘i£Ëvº?ÚYs uˆÓªš»„hYÝ™‰T¥ hú´œu¹KˆÍBu¬îÅV·îÜÃ3÷ª¸…5"ȬR• ÔL§PíPÎÆG ]ÓM_`4¾?ýÙ»„ð3 ƒÐi~¢ÁH–Ó•„¸‚LÅb ŒƒùGÙ ¹ûJn"H#-^4å´Ø®‡¼ »õím@Åb¦Gp(Ÿ1âší‡CsÒDpVùy`•Sew ŸÆÓéd<ž¼j@é¥)Oýþ—õïÔ¬i?ºÈ¾ÀÂÂ=è»/îýéx<ávÞSëfâá.•…Aóxwà…¢#òcáÝõýAEb®X'î1C÷—sËë@£yXÇõa`‘ '3p|ÈÈt{çpÀx9“‰½!ÃÙ§&È­”H`÷ƒ-Èá=°Íé£Ýeo{`U£ª€õ4îÞÜÞhÝÞâçö²s©ÿoqYWz½ó×nn.nÛÖ-_´Ûð-î?~P`zûÅÅÎåÍMûò_t͘®C'„ÖOC ‡»t²XÐ$|~®^¸ÆºÃ`[Ò>^äÛþº> ʉk=•PýÍ}øág“Þ´ÃòËEË~ë8G;%‹ £´ÈX³9y÷ýã¯&ACT°Ð†ªWÓ£ÀÂ++¾Ó]³êÎÖýõbÇÁ~†^øm %€5 ‡ÄC®@a)`ÉÓŠð”fX9öf å.¿œQ¹kÖQV6YXõª*`=ÿ €Ži„'.Šì-e6Z_Y?#w^==Þ%Щ¯é` Ë44óKÇ€…q|æã9'žôË+äwc Í/ù“úûoó¸Tå:ðhÎ Û ÷{Tòà|¹ôR)8ïû°Ò—ŠOÞ:2pnñdß—òÎ&Òý\ àx•PeÀz>~8r§Dö°>ÃÚÀqå˃œ>GBÏëvÔq`}&­À˜+ ,½¬Ë¨Xáà°°v„Ÿ,{tòneSð`…¦Ü¥‚òÏ-d1Å ™ô…ÀÚÛûy`••㨗—WcäåååÕU,œÇ$Šej.žÚdon“Ô8ÙmiêøK3k{JO9:ïêªIXœ“ú”šigÒ:¢M©˜jÌ@­ŸÌ^SçÓùj4D•‹&~›ãÏÛÙãÌÌpf®CðìÎõòN6ÍçÙéVãLú;9ObLÀzpºÛs£«Þ¬4µ9ú Ù™Ÿëšx6ÎÏEYOò¿BçMÖû… eÉYíUNZXÙ“Fs&v £ì“pNÍgÑ.‡ ˆ*è|NS§Ïg:ˆØV«ÒÀ=°Ü‰T­hªúR3Õ;ÀÚ}&°xîY#– Í=¼Wjé¡Yg³“¨ °Þ7óçéc ©Ž gN¥¯(»WvÚÞƒ)§Â˜Ûo3{u4›AÉìï7Ãk(¸Ï,¡ ÔvẨ/šÍ³ /(;©ô6Í‹VYU¬ùj½^YË`·CFñi¸X@}_¼Åi4_,è iÎÉ5·o®ýŋſSd^*ŸÒÀBÝáЋ& ­Gê2Èb`aüq5¼  ¬˜âÌ«ž–™Œ}–u0Ó¬ŸÖ~MûxâXÙÙ’M=^Eî^»;YsX{“CÏÝ w3þ¥‚™Ùx$D8ë°Œ"÷Š3›áù¶ã•î²?£´X.9§wÍîužªk®­U”Ÿá±µX¯;ø~ÛÍ`7àa¡NÆÙ¦ãb½Yh_ÑÑŸK…„óñ¸ãXXޏGë'R,¿ñ$³tÖ8¡:þøó¦ª§þÊU”Š¡óöðÃ>°9}‡ÙÊYY²±ª’Ô +ÇÃ(ǨªbEj`ÍÒŽp„Ž3ˆÙÕB k—I$QœÆ\ ¸Fù‘BaOî|õàÃ"Q’+å)¥‚ŒÈ\<È%µÝd&(.Cëö®ƒîUBÕkݺj÷¶«8^­VÅÿ^­W‹t¾ú3ÞéïMw»Ú¥ë^²Šqy±Ò¶ØÛ l²•¶ºZó¯V‹¿âøí-þsÛ]­¶¬ $½åm1?Xî+’á}XæÝWwò¢™Çû{óðóI Ké“Q¥;ýߺE8Ñé¥U…B¯RBÈ ¬Jõˆ8ïJܱ¦++ƒö¬8ìJ“¯“ªÜ’"Ð(Û–Ò$Ë”Âã:“k]¬&Ž…•)òÈòˆ®3ñ¾ijÀEdK ‹„3ªÃˆ±…(W#Ħ$¤ÇXâ+)kʬ*rDŽÂB›]8ô÷”šW U ¬d»ý¶]­¶Év½€ï |¯âþn'«4Ýv:ÛÕ¶ÝNÖÚ[-ÖÛ$Y&ÛÿyÓKÛõÿýö{{Óö×*ù¶Z%=ýÑaè?m‘ívóyù>,û™»û¿"OG¬ðQPŸbcuÝ=wÓ9Ô(…1`ÅP$ÅW{ÅÕ‘.ìTE¡²(òîêh 1Q÷Ãz]QNføS’²­ËO».æ UoÄN¡m„0ISÇÆT&È%ËÀfš¡¤ÄΡ¿ ÅRØZHÇ&~“]‚?àz ˜yT”rh|<"³ÁŦDßqнJ¨º>¬M{¹Ýjk}}ÕÚn6ßZ½d£é´]¯·ßÚ—É•l—Žö§Ý7Ûo­öU»¥í­í7 :m¡éýÖÿX/ÖËÖz´7›v»»MZÚ\߬»Ç °îiJнW$Ÿ¶°ãBÎdc5Õ<îB…g,áÙOÕ'F³%FÛaCo•Ãæ$,å:I×{u¸+À²µ¹`‘yÂ6 TÊPjªtD”Ed¢ƒ[™(h¯DƬ‹½ƒé†R@LÇÆœCk=K©Ñ_ìî‹Ac†ÑÝÚEŠ©)¾@ETNøÏó˜.^ddõüƒîUB«ÓikîÄëdyµL¾m¶­$i/—í$éi@°6—¿Ûz[g‰îËeK»/—ßVëoËeO »ë·t °¶ÝD#ïê÷ï«MÉNa,lþ™÷aÝ«‡ÜGs¯H>,:íMõVq=ïó NÀd⪇ñbE% +¶•ˆŒ¨Â±5f–J§ÄÏ•wÇMBi$95=·HÖ‹³¢½dAb©»9Í~Ë.Òt·¦° àØ†Âc Ÿ=JÎ#%&+·P•¹t0å _“Ã'`ᇀuú›;$^%T%°~/·«¿t›OÛP £öÕÕ-'ëH75¬®ôßòŠÜ×)÷»­Ót•è=t+2i·7Ú*ët6%-×ÂÊü·ö^‘\ÂÌÂNwE6Ø4Õ"*+ ,®f.°¸ŠEŽu¤²m@©M±é®9P;¤’q˲²<íø&gÌLPjXh(Js׿‹}ŠÅCUkä!uЖu„¢; , Óº;É2®©–⦶J-°Ø˜e{TYßÊÀÒ$d Ë«U¬µn®âpJÛP½%ØYšAI²íi› ,,¤ËèÜ—í<°´ÖöoËe7¹üý{¹fKá¶\`Ýíë>ûŠä~i™&!¶ ‰QíÝî`™ëzœ©ñ.ÎT,}AâÍì·¯îÎ9À’ªJ<î¤0΋ª;[X®Å­4jR™¶–²„ÊšlbÚ8f¦ëÎû+Sh±A“c¯:´ƒßYj #pR¦bó™~c€YG9<ï:è^%T°Þ k½Þ.üÐV’\á÷÷¶nâ2l£b{ ¶ÓµYaÚšê\B¿–vï$ÚßF›W°w« ÐÒ-ÍÍ‚oæVäë§óŠä{§ù÷hιKHWkê5©°vg§»™ŒH¬O ¬ÜØõýj(£»i}·;ÐÅ[°¿«®8B΋Açm‰³ÃîO`ú¤c”ev6Iß}œ`Ѹ.:ÒîeQf¯cÉyÏùáUNÕ5 a¨Ñµ>[ÅûÀàRhȺó‚®væ?üüøàRls¹ÖÖ¹Àú„¡î‘c¢®jÇ\£ÃžMí «ú Y`Ír"GÅkGžÉ;™ù="…áYÚ Åáð3FÆ‚Ê?l“±í¢ôpIŸ[ªþm eU°ÒX}÷Åì›øq”;Ge{DéE<¼Ðf(ûÂpÝ?ã/‚F…4 ïrÍ=Õ£û0ôÝc‰!+Šì#_]©Ôx;ÖËZÞ88X i¿¨(¬jòÀ‘»CEéùQȵq¡uãf&svˆ»A°–ÊqÈž'²?œj‘“§4óëšAtd#'V·Ül’".Q›|›’MK$G*b·ÒÇÛë U7ÒÝ>SEP‘Ç«Ø|UQzÐ5ó~­*x–õ®WË0°rɬÿ…Kç~DìlRLY§ö7-C=9Êî¦<“NgcšÚ RœûM³{ŸP&ëi—b™*ͯ¥ûӂ̼¿Ô¼JÈ¿qÔËË«1òÀòòòjŒ*›ùy8|ùEs„A(SЄ%¿ìÜtas»ü‚É©`b“ÐÌC2”™€XÉΗ>ÛéKŽ|†îDªUéᅢl<8|žHË»?ºüt&Âg)Xß/*(7nœî=À~0gÎ ãÐl/E˜ØFâ«4/Cœ¹(”ynÜOVSn'Ï>NNœA&Ãlz$ôÎHtdB=S_M‚†¨2`½ŒÆ“ñèY+ ŸžžäѤ×GãÑ( ‘MOàï),½ö2ÂÉ蟫l_Gl:õ°Ix§›~.¢¬-e_’\úÑœâ&AÊ5 ó•༂¿Çb¨#_‡uH¥9{b{I÷=Ùí!=wàXVމufÚê«IÐU¬ ßv¾¿Ž èŸþcüœ’“áe<íÝÜжáPû»íŽ2' +½ÞÜô¦ã'÷ ¾”:Ôt¢`Ih߇UÙÃÏ:J‡í~êÄWP×é%«SÁ¬ò¸pä"%‹x£nbè×}XwB>6:Ù¯ÊìôáäŸ!ù…d¶Pò剤O—nð’[wû íé§„‚@´(“£ü€W'|:\!î@ᇒQøìõj鄸uÒC.ž€WCXUx™…_ñ#Ç W9ÏŠóOà«IÐUfa…“N¿ß›€•4žN'ÚVzÍô<üõ4íõûýîH[ZúO:ÿì÷µ'msi/°«4ÈnÀ“ì¬ðyÄë B9ÕÓ:VöýLJ^‘\öõ2x:X©au•ûPN N¨ú¼ÿÅÀRT¹’ •Ôþ¡Ö@)ý ­»*–t:+§"W‘~â-Tê È)ÝavÖm/‘ ,&Ͱ0Ï`éÃ…Û8ë’O¨ãJPMå‚^>EáÂ: ÝCSfDò£Àw@%z¶¾š QUÀ†ã‹þt¢ÉÔëNoú7zùiŸìªQ¿5ÕmÂg°¼†!kú4¾½|^_O'ø»jÀšŒÙÎuotÓ^o:í_uö\¢kø8°²oï+ûŠä€Îd ÂDÝÀ¢›Žq@'?T®Dbz¢lämÂîk€CFà £^¨"š+’kÈöÈP’­ S¥å"Dó„$í” ñ†ÊqÅA›Ó:J¾%ð¥bÖÁ[ÀÙeëK9Ö*9ŠþVŒ^•ɃckçƒóODñW“ !ªÎÂÒÒd|Ýï·_§ßûýË~wª¿ú×cm;õoÆ`]i«ê ,¬Noüö˜öÜ›¾Â÷€Õoßô&¸“&֤ߋ­ÿÚ}Õ¿7:”s€•kª°Î{E2¶=Ô€ª‘kÚÔ&,ŠRš:Š8æ#owH…‡DÊ2 _^ØÂúe€Ua“Ðôa) |@©ÁNï0°H2&+¥ƒÿ^†ô…tþuö\?öß„KáåVÕPbC’0’LñQú2 EY@R z@¦¤“䘲Ã<ÅÎt¯ªXÓiWÃe2¹`]O¦NG£fÀúo «ðé¿Ã_Ãñmòêïþe§Ý{í_u.zmA=é†$Xhß§ÓkÒm6ÕÃPÄ~?щ+v²+ê[wçÉy|Ç+’±^S«z2>X!UQüfK@*í0Wã¤âPo² èP Õ‘ÑUlaõYX¿À.Á®ž,¥¢• 1¼qɉ hPé (î~"w”;†*pHt£6#˜F¦"†OEfJA¹mNkLɪË/·smÇáy—´ åùj4DÕ k€>¨®nÀõF#m4Ýô¯Gm,õÇÁ`ôªM¦éOÔ‡5êa3Q£©Ý￾ö5¹t1Žþ `ÝRò¦Ödü°°úc© Ï'+‹¥ùùYØ*,;Í—®|,ìVåës­÷ XA)` ]` ¹_*‹äH Ò$Tn¬D!rQ ,JY0t€…Õ+{ȦtaÓJ: `A‡›`eáe€…½bJhmøÃ–v/qYXW1°Ã•]àB ˆJ˜ƒ,Ål“0ðÀªOUëEë¢7§Ý§§®FOwú4z½¹„ÆÜóhÒ»îNžžþ š„ÿêNÁžÒ~¦ßÛ=ý}¡-¬§¶°º×Ø$Ô«ãi¯} \½ÞxüúC)[YRíÝ%”‰TîÕÝc黄О ‡Ù†L­²w åî Ü³b&ÙU¶³ ÒïcRœŠÁv1U%Û$n$òá{l48@Yæ*é|²ëè!È{0ß²¦”Bh ‡b7JOUpyq™¥µ©ŒEçôâ‹ýeŠ8Óç¬Cnzö^áðL Ë9$^%T°F°”&“Wç3§±Ö”¶éFßx'avWÁ¨±0 r²É÷G8ɶ ¤<4å>cd5’'³ãÓÌ0A4ãÄÂÚf™Õ\ ΃Rìfc:K_M‚†¨*`ÆÝÛÎÕíÅÍ-~nnÚí››ïWK½¨./èp¿¾ùþœôòí%l†ï6ºè…‹‹Ë8ÂÏ‹››ËËÛöíÎmwütb”»©,–5$ÝeK±ÊkàžèŸ0€ÔyIq 5Ü<’¢#ÏZWižB ¼h¼æáDe¨ôžRòÀðõcqäŸ,²GÝ¥üå)pùÙ øÜÒ°<°Ê©*`=¡U›rJU–è<æ–Ë<ôœµ°>WÆy°IXdoT#û,aÉ=ðäfpV ‡½ñð_pÄáÏäx`§Êš„8L…ãEGfÕ¸RѶœÛhô/z‚çÔá/ÿz™²¯ ý|`Uk¿„phe­1TxîŸò¶Œ/ÑW“ !ªnXJ¤Hû¯ ¡{² ‡O=Ü’}zðü|XÎH÷“Ã×ϲ°>½Ž„uÆ)Àª18*Mÿ¯ôÕ$hˆüG½¼¼#,//¯Æ¨²Ysx†.žåôœ$Ž;×ÉJÌ=Rasš„ÍŠrÖ*¥óûþê›üç+ЬÑòÓ|•WuÓ|ÙY3wsžðÔUÐN‚ºÃiŠç2÷ Ϻ;ŸËm¼o;“Íívâïät”ˆ¹/øóÝÓ{Y`¥Ÿ-3é©ü¾OP¾:Wµ„I¾WIñœå^%T°HÙ“u>Ó CôìŽTÀ‚‰ÖeÚ,?èQlf~>gäÂI ë¦{Îd]ã$’\õ̌ݢ™9(ö°±ýŠ_³™ä–²åLî‘rì\ÂbŽÄÄÈQráá¹2sÊOÄdhf·ÑG©”ô:áEÚœöˆD'7m%KÍ«„ªÖ|µù_ÛEü×"žÿµx[,þŠç«•þ¬W °©þ|Ãu83Öí«vo»ZiO X[fÚ÷¿W«y¼X‘þšÃ¶¦n»+´´þ„½!¼·4^mºˆ¼hÿ°ßçÞ‡u—yE2.ÝáÏv:ýxVm¥ÏJ¥#S).g+Rµ`¥:½8ýèU\ÆZ¢S¡W¡ªD¸VX±;×_"À¡ÚaüF ªõèÛ”  ™úÓ‰åW™5dx7sl.cpæ…9'X+ÙÆû@H*&Å%EÛg;c¶s0‰SŒå%;•µ¢ áBœÒ7 ÏøáÄèÏ<°jPuÀZ%í¤·^lÖ‹Åz«µ^¬´µÚ&¸Äß+°›Ö­åvÓMÀÓv³%ÿ›·?õV½¤}êÏ öwØëÛ ,-p™§Þ›©¬µµå6%ðdÇ>,AQòn™ÇÇì+’˾^OÙ˜pÿª†fTþܱ’F”®à‘¢ê$uUªaDUŽj mÇ* [Ôé(ÙéÌ*v(l1ÉJ¯ÜÃY)²ÒG;±sRNÊ&g„Û¹dÌ%#FR`žØ%Â5…¥&Öå3BgÞOþá‹Å—%Å—AžâDR±!³ ÄhЈ› ^%çãYÝ«„ªÖzÙY¶5ˆ¶›õm“VkûçºÕZ¯Û—-M¥^«§¿Ûííêß©¶°4°zIÒýc»íõ4¦¶Ý.mÝl[ívrÝnÁ½Öýcý¶NZët§í7í²šKxí«d½K uwàÉwÙW$ÿ,ûŠdÝØ%`5buÎyø®*O8Û‡¯çXáCkÃ&¦W$SuSXÑÐ=BG•î[ 6†Ô©ˆiMÀBØ}Cû$f€Kø¤«CDYG +€6ú¥•¯ÙAìyE¾Sa†Š•pXÄ…™q¨cc :‡– 8¥K•“2y  X»™ú„ŸVªnÖ¦ó{¹l'úÿ?×ÛÎïßW›u+Y¯“åU’ô4‰–I¶ëæÝ¦ÓùÞÓvԷͦµ\öV+€mm/ÁvÒÒÛ{Éòzó#°´ý¦¦‰¥Ã»Ä­`aíwÖb“ðN®ÇÂW$?˜W$ÿ,ýŠähF§½¹Îªê‚Vú4Ç&!G¤ØŽ ë}¤Øl‘ê†5KqÙŠ­3ƒ²âÚ‘±jjrøß.r¢gb1:ЀÅÄ(±«ìžì×ùÆ’qS”ÅŒñb"æ¢4”¥’8“”ô;!Å‘…bÍ*j»²¥Í¼"())Kº Åñ{®iXåT°Þ¶N»}µ\^-[k¤N€¥Áò£³\j‹ xtuuIÀú½LV"mkißëk©eûòò»ö£öý:Iô­dÙúŸH«½]ë¦"ºèp:^²Ž÷»°l“ðÑ}ñh¶xæ+’±" |°ÈªŠSÓ‹––Ô ,®ó©4(+2{W aµí¨¸Tê‹J1f`aB”¸qO†£ŒwÊ;ÙOi^ØyÄÈHê倥”AÁT).íŒè‰f†W)3‰€eºà ¹øj ýãË«>U¬7ÝLœhÔ, DËõZÃG/üX&ß’äj©·ÐÝAh®â5ûk“¿äz ØÂ=ôÚ·d©ÿ[ë]´N®´¹ð_oí,aáj¹Žò÷Âià(6 Þ+ûŠä»’}X±¹î§Ü„¨c0À>N\ ‹Œ&±§¨ŠZ}X?SÛ€±™Š5 cÇÂ2Vce7¸Ihì˜s¡R“^´P¢ÔXX†d©XX1÷f!P šã4u­¢Ì^Ø—çkµÒl-°¤˜\äKϽéT³ôQ!©X¸H]nŠ`ü¼ÿXåT°þÜv“íf›|¦l·Ë?ÚhUu:?~h]i»Hoi·¶m-iú{©}$Ú]û¦­W­üuØ/X]è¯sÙéhhµuذñlít’õ®X‡_‘üóÞåVÙW$Ë]B·ÒÔ,Û³ƒâÞ+%wÚ¸ÁåTBs—÷‰'’Í+Câ¨X©“~éÀ&ÎÊM5J³XL‘dIødש‰Ç}Mî·M»„gÚ·ÜLæ ‘³WÄðª¸:À²ö—6I’ù¢ÄÒNÓ¼g%€öÀªIÕk«-¤%)¡Yýý[·â ‡ËnKÙxXÉq؇•;ïŒÃªê3Ø$4C*®tôÜÝÇÇላ¶ðP‡CݾÎH¯S¡ŸøøØÀQ;†ì£]ñÎqì«|ä6 ®œ&aa™ºãÇŠbtÓóþ~yæÓ?véÁ’‹ÛÂñ±²£÷ñ^ƒ26Û̹¹·»ûºŸì|<%rêUZUËÁ”sÐs¿{ÛÓãÛO(¿[­ïÃJß™Ès% ¶zcøºÀ?«?ª ¼¤»²¼|5 "ÿÆQ//¯ÆÈËËË«1òÀòòòjŒ<°¼¼¼#,//¯ÆÈËËË«1òÀòòòjŒ<°¼¼¼#,//¯ÆÈËËË«1òÀòòòjŒ<°¼¼¼#,//¯ÆÈËËË«1òÀòòòjŒ<°¼¼¼#,//¯ÆÈËËË«1òÀòòòjŒ<°¼¼¼#,//¯ÆÈËËË«1òÀòòòjŒ<°¼¼¼#,//¯ÆÈËËË«1òÀòòòjŒ<°¼¼¼#,//¯ÆÈËËË«1òÀòòòjŒ<°¼¼¼#,//¯ÆÈËËË«1òÀòòòjŒ<°¼¼¼#,//¯ÆÈËËË«1òÀòòòjŒ<°¼¼¼#,//¯ÆÈËËË«1òÀòòòjŒ<°¼¼¼#,//¯ÆÈËËË«1òÀòòòjŒ<°¼¼¼#,//¯ÆÈËËË«1òÀòòòjŒ<°¼¼¼#,//¯ÆÈËËË«1òÀòòòjŒþ;úœ–ãIEND®B`‚nagios-2.6/html/docs/images/noninterleaved2.png0000664000076500007650000021171307436604464021167 0ustar nagiosnagios‰PNG  IHDR°ô$ tIMEÑ (*†É6Y pHYs ð ðB¬4˜PLTE!)19BJR))[$$c%%k!k!!k)!ss!s! AZk hNZUQ,7ssss { ˆ¤Ÿ¥ ¥­­­¿~ ::¡//Â01‘QQŒ€i¿TT½whŒ”Œ†Ÿ„”œ{‘™†””ŒŒ””Œœ””””¤‡~œ”„”œŒ”œ”ÉŒÖ‰Š­¥­Ã¢«)ÿ1÷1ÿ1ÿBï9÷9ÿ<øNÊ5På,Gï#Rç9b¾Ms¾`^ÞAmÓZ{­s{Æk{Æs„½{Œµ„­­­­­µµ­­Î­­Ö­­µ­µ½½½Æ½½ÖÆ¥½Æ½Ñ×®½½ÊÆ½ÆÆ½ÎÖ½½½½Öƽֽ½Þ½½ç­­ÿ­µÿµ­ÿ¹½ó½½÷µµÿ¹¹ÿ½½ÿÆÆ½½ÆÆÆÆÆ½ÆÎÆÆÎÎÖÎÖÖÎÎîÅÖÞνÆÖÎÖÖÎÞÖÎÚÞÖÖÖÍÑñÎÒÿß))ä9;ãYYöTTÞikÞsoçkk÷kiáuuçs{Þ{Þ„„ç{sç{{ç„„÷wwÞˆˆÞŒŒçˆˆÞ””猌ç甔÷„„ÿ„„÷Œÿ‰Žàœ ìœ™ç¥¥ï¥¥÷””÷”œ÷œœ÷¥¥Þ­¥Þª¯Þµ­Þµµç¯¯ë±±ïµµ÷¥­ÿ””ÿ”œÿœ”ÿœœÿœ¥ÿ¥œÿ¥¥ÿ¥­÷­¥÷±­ÿ­¥ÿ­­ÿµ­÷­µ÷µµÿ­µåÆŽÞÆ¥÷½µÿµµÞ½½ó½½÷ƽÿ½µÿµ½ÿ½½ÿÆ½ïÆÆ÷½Æ÷ÆÆÿ½ÆÿÆÆÞΜÞÎ¥ïÎÆçÆÎëÊÎ÷ÎÎÿÆÎÿÎÆïÖÎÞÞÆÞÞÎÞçÆççÆÞçÎÖÿÆÞÿÎÖÞÖÖÞÞÞÞÖÞçÖ÷ÎÖ÷ÞÞÿÎÎÿÎÖÿÖÎÿÖÖÿÚÚÿÞÞÿçÞÿÞçÿççÿçïÿïçÿïïÿï÷ÿ÷ïÿ÷÷ÿ÷ÿÞÿÖçÿÖçÿÞïÿÞïÿçïÿï÷ÿï÷ÿ÷ÿÿ÷ÿÿÿ†æ^IDATxÚì½]pÙu&˜–ZóÜ­" ¢Š àž '¨b£4 /Üþã4%‘-{Þ.]¥* i#±@¢ôÓ’µŠ {Ö+f¥±šÕºc"v#!"𨑣ÖôD¸å;ˆ6¬$A/Ý;´ -N«»±÷üÝ{3+« ’¨C¢ª2óæý9÷ž/¿sòÞLo«/}éK_ñº}éK_ú²SéV_úÒ—GFú€Õ—¾ôå‘‘>`õ¥/}yd¤X}éK_aÀšÜ“ìõü „ª0•efPÿG-÷‡ ã#9h,x$„«È:›˜€Ïóç''‹Å‰‰óE} X ½zW‘Ó´8ÛvÜrÊ„P2ÈU§„úÇD±(yL˜\''¸<)l{)rLéE,Å—¬–ŒeLLpÉR=ÐG÷Òùh1‘ªèê@œ°eMºš³R€Â'“õ7eð‰ÔžØ‰ÉŒù§£GèAc R»‰´<¨äó“&3G]Ejjr.Æ…¿áL«ˆö1@{° ç¸M7ánO¸çá(‘ÒyYýï|„<rÐXðHˆ0,6@«½Â 6Yptü%˜*¼z®à ;¬vP@Ò“Ê{Øœ(Ïý?ǹ2`R`&U `ÐN¡]OQÝc(;¥au¨ä ãÔ:ÝRhÏ”Hiãí¡OÒþ*òó“…Ôêbû‹í.H%νª+Q˜, ¬Mš"eÚµ©/ïwò,ÝM¨`¯”1z¤C¢ù6&Tp ?‹6uqŠúX Ózš(Òˆ@=·Ùp¾SN[Σ^¦d¹z™D%L¯É8(Èñ¢U^Û8e/C§Qéªô„z/Z}ÙVb.¡ÆhT Xz·TSÅâ…_{nœÆä¹Wõ 3J퀖6U€V°#?ff:Ïç~MsîW_=4bŠ `b§xeKrž´uÀ’¡æ_Ôh€­Ç’õÝ>(™ÒÄ‹O+Ø5);±)˜ï)»   LšÓ5ÍécÅTÀ×œŠ¼9U0Ù2÷4›"‚8…ebM@ç'Ý ä>5é°—©"ÂÃ~& Ô' .HõXOxÐêÉÑzqªT¢«‚ˤ1…E8@î<Õ‡Œ³è wLÌ‘˜.c£ /=…Iƒ†‡ôkwâÖùIëùÙ‹¬$t,>÷£þlBŸsŸúô9HÄãÎ/Ls¡‹u?‰*ÅÛ!jGë…ç~øÃ=7Ž—â©sŸþÔ98Ó×Qþ &y–ðœwJs0O·§PÀJ¨ä>W¤á%¦ب=S“dÌÐ –7M%êU ¿JÁB¦ÈÄ5KšGÍk `ÍMIAE°¦&C…RQÿbIçg*f·ú{›CˆeL‚K¶d4R@÷rŠ`Ý^P&%Ã)îÁ‰óç'XOãPù¤ž0_]ÓRi¼T¤A2eXëR¡DWA8G€sOÚ Ã£X"§“SæÀ¬õ¢A&Œ@h`œ"oW*û¸ð,Öf_¶XSxý¢¸\ÁÑ@qäpX¿úáÇ„ÜĹO^=7%z·P<­mãç”Äs(+ÓEÅ ?úøŸû« Åœsîê'Ï!·s9Ùö2a¼Ò¢ÄĦÚFra’y—Æ+€*ùר‹â’]ÀÒv„ÛâQ™ÆY™â¢JÐjø}Iá5EˆõÀþâdÉjN×4gܯb °@Eã¦1*2 šr™a]nïÀ(ƒÁ.7ú)#ÕOÔª˜ÛV`rEjxÑ€5ÎzGu$ô4‰±„âúúúÆz \;Ô‹>Ï8—¥ÛQ©(ÈÌó.×7˜¬NÀÆ­[¤kÌÚ5ï{Tí­Û¥âäÄDŒ¦?F\«X;Ã*Þ¾¥ f}ýŒ"»;E ñ oÒƒöÂ?þܯÀ"³›r/´…Ò \±ø(‚ëêÆÀY)íEÇaüמûø/hcC8CsÀÑ]äÐÏ΃ª[[çµ[´~K×A_Ö ¥’=Ħ1%µîS°%C]°dNMžécÒ1lÌ„Ix”ÚH76´ÆÈô& ÂÃ(“Û·‹Â»DsÅóÀQ´æ(ÍD¢þú,åú8Èxšâ¨ݠХ¡+z‡Ê€KeÈ%˜Ø(!,1†`š€æT‘µN—JX*èéG 'ȹÈzš(8ެÆ+“"Q\"o‘oÝæ;¬E„¯â·L×–´‰1aOB¦î<»—zdêÞ¸µ ˜=i/‡çÏï0fðhÈAcÁ#!°6`Üé4AÔ›¸¾þ»]šB—C_eôp=Ñ$ bTdàãã1¢ÁùdE²ò·6J´_xȵ!<÷£qmã˜^þ§ø~Ö®K—³q«P(±%2Æ[†¨fäçŽcÉ`ˆÍ¥d“Y íˆÒ"ós¡ò·4~L ºtY·Æßz mb¢ÄäIê8@CÝi­¹qÒ\iœ4%Úë¯aý-åF‘ì¶ÈMеOHkóèAô;5… ˜Paü¹¿oïÖVz÷­qhÌmèÖqäÄ„ÀEá¦àÒ•°ïoÓ=ýöDÊ@OEìø¢q5µÖåtÌnÊhi§Ð¢È´Vâ“Hƒ±z`Ú‘TÚУ˜Q2i&û€uØÄ¬q,`¨z‡Æ¡šë¯_(j“¸páן}õ™„¹…€ECJÆšóöU/Q°Cz[~ýÂ…ç´sá׋…W_%ÀÒßî ƒm$׉MÑ¡ÞØØëøŠ&›A{¤’Ç©äsXòø«ç‵>.ÞÙ8ŸZ</Ni2‡¹êÝ%ÒXaÒZ¨mœ´!š»ðgÏ]inŠHÇ„SdMw K‰Õ%ˆÎ€¾Ž'M9lþS¶wœ2°52=„æõõgßÚÀ4¬“s [GÄ ‘˜^LOçHOÜïæîDqýÆ:÷ØÁɧʜ,´.;Ù±‡ÎvVæLÊ€·ó¾ `3ŒÖ»iNÏÆ¢‹îŠ®kÁNy2H«Kœ=¥·º4a¦Ÿ¡µy¹œ5I÷ÈŠFyò [|”M¿‚Rd2%à©Ì#•pm1«‘Ê Å/f ¬ó´ÉD¦ŠR.Îì1lÏ+šI…IÓæÖ~âüdѬçÇÖÐ]Êœ–õàOÒ¥¸<Ð58NKkà‚…ë.‹´˜PSx„£RI·ÉÌåiùSð@ Q¡ÓrÐï#?Ëñj  ±—‘叿‰X¶¢Q/O>'eñú‰ZàµÜ¬ó*ò óΰóv!µÓMˆWvâw!,¾Ã2éTŠó›²O'ˆÏšŸ˜ˆ=+y•Y½VdôH-lÊýe×õò2™ó¶/ÄçèhÁŠ9iÊ>!X˜hX–·PJ@‹T¦ðU,Ø:ƒõO8Ï”ˆ=C"|Ve…I›‹Ts ÖãùÂÕÝYe×'MòÒ£'÷tù÷Dúƒ,Ì£}¸]±œ¤‚áöŽûy"V¼Ë}ñK°v'mOu‡µyR ïİ‘¥Ï<é.?¡…u².Ϭƒ6Â+ô¼Ä¢€ñ5¬€] ÉŒ¨$`ÝGÊØVÈA“?÷®à¤i{HãDr2,<-ÁÎEŸjH_±Ë¦…=Wë MX;;ZèT€5Î3/Oåsó.LÄ«(L-e—¼¹=ø÷y»Ëùá•©b°v"íHNèvRÈàI¹{v+OTaø§öôZ¦ _Ov!˜{kÑŽ4%±%z4ÎîòÝIýö. <¥ÊAcÁ#!Á3ÝãÏÜËB>Ðö8Ï=Ø·2vÑ ]q–þ3ݳ”ƒÆ‚GB›·æ¼ÿÞ»¿øÅ;ïêøîü‚ßf#rÐméK_ú’. `½ÿ‹?þ»ŒäŸúˆÕ—¾<œÂ€Õ(7´”ñÓ÷á¯Ìßô×hÌÌøú8ý¦´ú7mû[[¾¢sä|ÊIÄ÷1“77#GuêÅE›rw¹¿÷àꕬäê;ÔžEhµÔIôàû´êÝ0û hƒ«3i³«£Ã²þnHz¿V¡¤_\„4NZØWæüf8 µÛè¿)=ëÞÖM5tî¨h裲{µm kH{”阆íoúµhöé¤× Ö\ïǶ@~ êcý{ÚQ&]:ýÌu‘ü|Æî§ús9ü½¸hõYÆ~¡}ºH«˜Q_¶¬†U_¹ìTÿ‰Ø=p~ìœI?jŒ mf¦±Ka}÷ÇW._ÊH>ñ`Ë©ÃæˆÐS‡£ ¢É²1f áqM”|T¡XÑ9­m±ï§4Å%4|+!3ñ,”{†lÀȯ8€)Xe§üýÔ¥o)Ó´ãRœï'›ëoSÞ£'}ÀÚ‰Àj^áès™ÔÞ ²°Cßfî€ì °HÔ»wåÒÅçI.^”_©G)…MçžqñòÏ;VÌ@“üÃQ 3VH­O‰“«ä¤M_YÖãhÈ$¶õÁ£ÈfÛnr¢·:V#e¿{þb9þ û)–ïÎËï°œ ÚãXê ±à‘ X2Ôn‚ïËùÄ®5\|óc¿”sš)åZ¼ßø-’ÍÀVÙ%}åXõo°~ºÂV@À*7Ø©JYæK¥Rîa•vn›Q…î$ƒî"€¥œ¿,$UìkÛ†¨´í;v\eÕi¯é.ì¸oWÛÝ‹evÅ  ‰–_©ÌøÓÓ•ÊâNµÝÀ*ës§Ë;Kn§)ºBªÅJUKeÑ»–Ö¿ªÌY-ê:Áw™/2`=ÿztÏ?éåçõï=–®rÇ‘×m´+w—þ×f’ª--¨Pm[†jË=-Ë1À’R%òí Êm=ëÀºŠ§k;S¹Mn+Eµe£d_{Æ&ûv TÝF%?mJ/Gõ¢ßE‰4<b :¹²p´2]Ë-TD›Ûr-P6ž_Y˜«Nƒâ‰]¿HòYÔ¥SWrZt ñÕ"Ѳ²ô¹!þ AKç{Tj£  ê«…€ué•'´¼òÒKyEÿþÈË{,] Ïót¾ð‰ÄMø¦ªéM%;õ'é=®f§ l݈7=ÚénÄ|åIL¡( Ol’Š4ÆË•ðíY…ËôLSö.˜¯çTÉTÐCãÅŠ»-õ½úxm0‡-¢S»¢s(OÙxØ)Fçäçj+†-žõDßœ%DF”§? c?æ†zP95vó5•±uml¯l¬ÅƒÆ‚GB°f4ï©L×êÇj•ÙcõªÑåN”­Ï÷§«¹zN#–&?šjéÿø7­³ÖœªVö+Ä«ªõ|½^ÏU§«5J÷[”ZÕ‚ì‹¶f¦«€:ß*r?}öât¥ùÍÕUcµ Àzîñ=ß—/?ñÊ¥½aÏ'3W2¤ØòÐÚ<úí·j¨3 ¼€œ|LýaéÑíKÊX‘$tŒŠD§ò=ýÏW^~B·q B ³¡ZX RR[©¸S–ç%¸ê^ql‚5£¯á 7k•ñ©-ŽšFÛ¬úýð¸S°'«àCÑm¨!Si+¿M¹uÝ™*ËX÷7ÿëæACÂÃ-XÀ{f†‡fÌÖ+`•Qµ>º:{´>TŸ{²67?077 ÿêGjµ£ù¡jea(ÿtµ2¼Ê7€UÊ/Ì äæjµ¹œN­ÎÏÍiîUÏ ™Ã´ÕÁÁªÔoA³?Ìo>b¸«ƒÖåËXWžxñåÞàJ Ýõ8»¦Ñ`ÑŒ@%#Ð KåËð|φ™!Ñ Åý˜@'óq§òÓ0]Ã2 ôtÑv6]†ä1ÅèN›Xìõ>#ŠEùr›‘{&*¦í¦ ^}¦/ &1V§ÕÔR¨• Šé—)Ÿ{ÊèŒØ/–ƒeú¬<Ïeºè(›%w¬-›º*΃!‹ª¦buåËšÂ6˘ØFÕÎ͘­­Öëg?öýÖAcÂC-X#óõúðB­¶°;ÀB†5=70_¯ç4li<ÊÕë õcs³ õÏ ×4ä|._«> 0Õ€’†|j:.07¿«ÏãYÇæŽj(8[À´:E­á`éO½GS+“Ÿkî~ƒëÒ%¬_ýЕKtï…eiÀ*ëqvM¹EÇTr—aí²0ŸÀ†&&xæÚÓ3(ÃWÉ,/y•Žo’ñ)Cd ÍëÆ"†ÅÛFï2,›ä+Se%õõ˜6‚!+,þ¯œšö  §ÍhŒ+ÀkÝm…zSJtãêL¡£îNzDšb PY79æ£{æ Õ°uõ|¹5|žíLº"(BdÌh[ÄŠÖæÙœ¹wИðP –_­çfg5(«MO×rÆ%ô·‹Ž`UæiÞ3«ÏÕˆ“ÏÓ€•«Õ ثֆO `UêÇfµ÷çWÕ¹ÌÜluv^ýh­–;®O>V_"V7 ‹ ò›…ßCÖ%„©œ3.`½ø¡_ºò‘Ë—^评a•Œp¸óUZÁe.¾?3,,¸ž1&ª_¯…{xæ|+ÃbPdèXʱp§"]A€Åؾj+½gÁé® X ¸H`è w*7dF€í¹ "œ³ÁtIÐÝ$Ã"ñ©? 3(Æäq–s„+9#à@/\zêB¤BfH®¬ç¼D]Í¢Á¼Ð3ûbue÷UQº*û2¬¼Þ§X]D«2?P©á©}Ư ÌKH{€¥1Fì"ÃZЀUÑÐòy, NXº$8 J¨Õð³úäBþ_×ëµ2³úÑ9€§ ÕCŸ=[­Tˆ[a=«Î. Xä~øê+—?rù…ç{eX¶„°7á‹[áË…ßñc쩃ŀEÁ`©°‰PYN$€µ†åPOŒ+nƒé€Ë-cÀ‚Cì†9èªÁ;]‹õ­úÄa&ta•$è0"©.“[º‚P§»¢ýÊæ'<«!ŒÈ‹iͪNIg(bm »Óу¡JªÞSm'cX»ŠbÁ]Â{gÇÆÎö)V—pzîÈôô‘……£OV§+Gæ¦ÍBšÛÆô‘¹ZµV{rváh­Z™˜[8¢&?W-+( Nú¬>£6 Áªª?«UˆsÍ=vlaàé\­ A°éß„zhÀÊ ™]€=”ßô\î¸ÎÉéjr _¾ w /¿Œw /ÿ³öÃ*Û»„4˜ºob!NÄFÉP޲ûŸbÁ.6XÍMG[”dѾé%Kò¶eXŽfé:ºà*¹%†â²O•ÆZœ“]8ívÙ‘ñТºg©”“¥2Ÿ J¶Sâmèš1)@ÚØ>òbw;5«õúÈèÉÿÔ§XÅÖB­6§yÑž?Ó«†Ã÷P>üرcýh^ËÞÎéÜóy<øteHoä!ùìÊ[ú¨> }4—;vw ú(dAi‡ŽR qÒ¢»„Ï¿ð²†)M¬^Ð/÷L°°ö[Ü»å*}â趦£bëþºHêŒô ¤S¾î¨ÙÑLÿ¶Ã)$0eÒû®ð×Ü9ÜþÌÝä«¶»‡±“Ì|™éÞúþÉ~«›Øi uGæçv X‹xiPñó…õ,Ù` •«õ¡ `ímIN°äZÙ6 ºÓ´Û™^ŸŠnö¨X>ÃJäÒ6ÜÛÆ>¯H”×&1`ÉeQ0ßL.§œeÈÐb¶Ö¨Ô&™µV‰ƒ'§wª’êpfüxâSµõ”JdŸKŸ6.ìžX÷vŸD/w—i¦{?ŠÕ]°hÁŒHezÚßñBdt g>kOŽeÕ&)G;œÑ%Ÿ ÖÐ^É °2¬¤©ŽíÇ?™´[w¢x2£³x7•ÈZB¿½•¾-3%];ê(X;Hî\ø¹BvËï•uõª­éôK¥,–IKÙyg»Î’´KNWê–v]j´­2œ×€ôK|T$ˆ¨™Î´ºi¯CªŒu´­Ý1@«?«ƒdXVÌðá+dr,/¯ðPl‡Ùá ?̘#ðr«½Ã1X"{˜á@€öö[0xÉnÙ dALœ(?\`BÓ“Ðâ¼›n^Ñ®l-ä+ ›s•Ur¾mù-3ŒMj¡a\e{&h"¦Þ‚ö<Òƒ’L.óM¯ä_+ˈaAktä}Š•*™1¬Õ›««Äáo®†ìêŽ@Ʊº Lj\ÝÄ •5e"7WñÌ(‰JX+œ&Znëj<¶MÕ{cX pëçZiì&<ÿ³ûä$bX3'›§PÊNô(HÀAº}YÀÊÖ±Ö¦cj1 0 ÉÒÞ¢Èeœ6Ø2mŸœs’n“¯=|@H%âR¬ÓwNÉ °V×šÍæ* ’Õµµ›€S+Á²î>¦¯Œ+ô»¹¶º²b¾`9×*ì¿)¼+Ö—f†i}½¢ÏS–æ¼°'À"è´N¨cá­À?ŽÝDB/%‚Ãm ,›rƒ% —ó ÌØ© Mî”kdÎ R r{†å–¾wq"o¡èÅVÃÅ^b8n©ægàj70&V$V;p´/¼=tôœ„LÞ¶Gþ2ôÝÉ×%Ц.òùÁVèÖýë§FGþ]Ÿb¥If€Õ|*7Ð\ W4"=¹¦)ÔªF¯ÕÕ`G«ÍÜQ½oUƒüÐ HnêQûõÈ t"}þÍÕ•ÿquUÿ„L0—m¬Ë–Yü|?÷úˆdfXžçéÚÁ'bÚÔ»i„ëMúÔöƒ‡tÆ·Ýɨâ¡ûçylŽš²Mïå3¸HO€ŠŒƒ&`]¶¬ä*mÊÀÊL­á !Æg,H\^À 6Œ%À¶RãI9h ŒD¯‘':†ÓlÏÀhT§ŒÑ;>I_øéž‚½‡°èá~αqF ö»y ÀÚÚ<;2væíƒÆ†‡R²¬\³© x0¥›kkzòªhõ)½çIàUú·N§ahM 2-ý xYSCž¿¶z9ƒ\n"‹JvO½|ù#/îåi z´¢½xl„C™‰= Àä!ÂaU(%C Ú°‡æzlpÎÑ€M™Lß#ãÄҖЪŠŠÐ*¼B¹·FŇœ_ÒÄ€ÅÎmÊ@(_ÅÀ‰ð8Ë1mÕb|•ê@FìËÖ~Kˆ6¤×€ô‘jƒ(­|QFð±D”Iÿ"G3ú“:€ú»„.ÃFÜ;Ú¤ñ‚`é–):éÖý7NŽõ£X©’`­5skø—lÕk­yDojpÒ}¿–Ó¸£!èÉÕ(XÀº¹Ú<ª ¯â'ÖS°š«k¹ã¸÷©ãƒk:Õ‘&å²¢½IݳKíN!ü0ñÄQy€_€EÖÈ`Bc?d³ £¡”ŒHŒQ!Ÿãq²Çã”aè ¬HÈBÈü•(BäÔÀs؆ͷ+m`ñ"Sxf€%`bxPDDÉ3LŽªë!Îxì3z¬ ×p]ìõÐfpeDô¸½x>÷€À?ê0Qˆ5æ}²ââùâßRä ãb˜ÌއnXKIÀBŠÕb¥Iö€Õ„Ï£ÍÁ&p.5ËX+«èÚ­¬5玮BÊf~aáøÚÚqø\^A¿q°‰ç¬…ÍæB~mM3³£œ xùËé]ûÃøG?ý¡Oh¼ºØãÄ,Á4/à+0ð¨IœH¸Bd¨„kpt‚µ˰ػB–"ɱÀ…Lú4%ÑYžð®Î€º…gʰ°„Íìsq刃ú<Ñ‘1ÒD6ØçQÄNüBÌß@”vÀžÉ®GÔ 5·Xí0/•šƒµùFýüBV¸©ë!|§[ÛQëÞ@O£XßêS¬vɰš5 X¹æñfóx>¼y«)÷×àÖZþĉ<ê> {ôçj3b¸ ç5›ƒùüÓÍU û+r ]BxDò—áá ½!VÃò˜%A¤Ã‹ŒS»| g2FÅÖšX ^÷ùGg—Ÿ\ÂЬÐR@N`Êåy½Â`±”`…¦ž‘aUêø˜çˆXÂdB°Q0"w.p€E4 ùšÚË%{O œÓ½¼¶0ëCÆ%$W2b°eˆ%rŵôÜ Û¾#ÞÖxõŸýçä ö£X$;ÀÊ7µW·j ‰ÝDà8xkM M¨æÜIŒ¯ùz À§Ç—P'’xAì(b“rœã6¸C4Á/70Ù¶ÝÙ †E6ëpKft«ËCm7­Áz¤– ªzš¸>°%0Qh‰G¹ _–b÷H—Rî˜v’Ø<ú.3âw+fb[«ñ¨G- ™àê¢o|âlÚý_G¯Ad¦¦F^°¼Ä+Vy"ûò$,e*m`öÇ'ßîüU™“òÙ°ÐmE+Œ¶À<5ÊjØüb?Š•"Ù-ÍYÛG…=zütv Ñ%¼Hb™Õ^î¦X޳#p¿ Ù˱×îŒOüe?ÉBÚŠ]Šñ̶µ×iÚ1kþº$êAB»êei‰fU  HsR»SžÎìR“SlU“ÛV»ŒÑüêXT¿E²l: è³ ‚ —[î¬Åô†´yV;…ßbÕz£¿¢0E²{¼ \•"vXx9D$ó²ÑoLÏ8KMl·µ=! ë_`]‚.}þî¯\¾”‘\y°ÅW[÷ZÜ>†;=!ŒËPÚ“‹&Ì)XmÜ }GMkÔþT…LÄ,Ì.(+—>FaÔ‘U8­K¿@íàÓžcÚ[»ÑÁµ¤PÈ4Öý7OrìªÅJ“lŸ‡Õƒ˜ØAï9@ï=¸z%+¹úÎÚÃUÚ]b»–pd/´›|£Ý·~;Õ"AKjýM±¾j¢X_îS¬¸<.O}ÿÿ]fòîA·¦/‡WÞ>36zê¯ïë_­×FFOÝ9èúió™Eûî[ç#æ{q‘¾gÌ[_(GûW¦”dìÂ;s|_·'VV{ý¨>ޏ{Úúíùù>Öß¡œþFéd¹m ÑiZJ^kdÊë^§í¶e¾êØÉ7Þ¯iúJ×_ZÞñ¶lŸ>ÑnúrÛÜIâØY;Ñ×öú”—çølK÷ÎÊ#’[_;ý7÷#*ɰDéiï1J¶¤Áë®jÄá‰ÇÏüåÕc¶³ è² ºâVcßÄѽÊy‘jû`î`òw^8–mÒïhómø;~ßa'àÚi{:å÷AH'ÐÜ‹þbm¦Qï—Ř®ŸåG$ß95ÖbÅ%3Àr¯»ë|‹L`-6€UŽ–ɃÞx7c§5ô8ù*>­AgZÞO›¼Ík7 ° Ëܰù¤åouM¹û.€•,c›mÞÛ;`%Ž=Ô€•øNþîE±þ¡Q¯„aaìŠ&4 ÅÂ¥:}aÉ”ašÄkÆx„¾ 6‹*Ùíx¦ãZ–ÓugÏd÷æç‹X3»4 = Ö,_!Sj^¤ºù~à!reî{›Ä˜îß© m§(VŸb9’`Ñ«î+ˆI À*/V`¿þ¬|ÆŸ®Váó XŽchN(7f*•EzÑÙß°®áú]»4çYš³†åºžû,1—pŸ@k?ËäÛ¬½ˆ3²5µ¾1Âbýu?Še%« {e–Ð,TˆWþ5·K* Gõ~b®:]­VaçßR¸Y9ºP?ìÊÅ2X±uÓ¯Ÿ¶ø™øRO€¥sô<>ÉePšGeâÑF'÷û <ŸŽ+HãIÝñ‚î )ƒ á2ÄeâS0îåK_ÊëjÄXÊ£¼¹˜ Œ]Bn‹â+U s=ù± $6zÃøžÎ\‘6M NYEÔ7ؤ;­[?¦v95!]rz>©UIÿÀNÅYsŸJ_ÉðŒ¹†Þv­Ù^Œ‹lÍéLm¸8u§?+.YVu>_¯×sUÿ·4‡ú­éJµVÖ,Is®ÅÊ\}HƒTµž×ˆ57<\›þ¬æb‹ÓÕZ­V­T¦§5õÒzßg¦W]«æêUý7«÷ÐAÛáîÇ/óÄ•Ë/jàÚâñê¡Ax:QÆP<<‚i |mF Pá~0*28Fç7Ø0ñ ËPÆÎ±8ÈZ΃ 5 pE |[Ån˜@·q©îZðcOÛ–ÏPãÖÊ€ORTÊå…ü€uÆÊ×c½)Ø&ýãÅ Û?tôHçÀĬ†'%bÿÈÆÇlÿH¿Á5E)º¸`_+ .n,*ÀÂ| nÚŽîßû°|°õ}S¸¤°õÚÈX.–#VYÃÖtõh~¨ZYÂÏ\n¾RYÈŸÈ×¾Nq¼>·pb¸û*Õ¡ááüÐÀ\­6—ËÍÍÍçr³³óÀŰê9Ø?¼ útJÓÒ¤Ú÷ÏtÇøõİ.^dÀÒ$Ñ+{l00^§íõA §ñl _Ù€~úHâ¬H–£C‚ ‚D|}çÂô¼>s‹œ“uF,ªˆê$=˜䫸žÊ! kñ Z6d“X 5ÐWB*q:Ô`P°&Ø¡$JùqÀRˆK F:ké1ϰ*.Aå©ð|l¤eĘÚW“cæf˜ `ñ´†Ög?†³ÜqIá÷ô¯ûÝbÅ$CÀ:04=Wÿœ†¤\ý7òµê@˜†½–þ—«ëýOÃþZþsŸ;Q¯,Ôôf]›ÐU%€u¼^ǵÏ4®]Cÿ±ƒkèÀ’gºø >Ò½‡Ðšµu÷ÐX”[2nó,¿ah†OWϰ(¹JûH|Ãü†øvÃbÀRcæ&öKtY¸Jâ¦v7¾›Ç˜×ÈÊÌ|ã*j·BJÈÐÞðqC‡jûžm£âýÌHI;ž½((_!‹ò ‰3n9õªØ·Øð ã6±”–TË–Ì%3ò,™ “머’—Gã#;ÀR[[ÿxöä=]æM˜Údë§Åz³Åɰ«õ!tá*óyÍ¡€ jH:1Œ€q+ä`Ã…ž–ýÎòs³À¤fás>5`9 KCÖñüÓµiîÓ47f±°àÉøŠ‹ŸÛÐu›K5Я@BD`‚”†íÝüù F Z>•7€¥)RµJVe~Hó¥§ë•Zþ7xÿ@EÎÔjø[Ÿ5´PQ ½oV¯ÖÕë °Ê M¢s ?|õ|Í—CI®Õm›‹ãSlt`%¢L.`)ºê»ŸKŒÃ“Ÿp{L K Ê–rCZö¹suº‚–rÁ.;À"|ö §è?é 5¼† eh—Š–a­È˜LNÛ¹â#‘[Àò `©—E:V€ôHhI—|ñðèƨ|禆ég¬F °3*b¨•1`mm¬¯kxzÿîé±ÑÓo¶èFá©¿>hœxh$«i Ó³G¦AñÕ\~x¨Z>‘¯A$+W­Ìåôg£1=w´V;º°pä7iÿôý»¢?5\iÈš;2 , &3LÏ äj³ªÍ j†•BSO°^6/R}^¤º—×|58$3ãÑ…Þ„’$”çÞa²‡ø¶ÇIsS.À`97'ÖLÓx¯‰Zy¤è¨ä¢$‚âQ<Ì×µƒ~È%dg-=ò’6w»Û6×Ú¦¥¾2‘,!NÆð%H¥¬oj_bF.žÆµéa¬Ì™ã{šN hš/÷im~ :|/CôàyñtF9íYS8¡:åhr·ú‹obÍ€!Ý9=6vê:àÔw4tÁ’Âûsš×öe+KÀš«U+Õê,žfgÕ?7WI¹2¥VòUõ{¬FÇ¥9{J[®’¬™2ö‡OwÁ”³ ƒî"R!ÃY›¦¶,?V™®úÜ9`)™Î@Ó$nÅE9¥©†SG·®†Ý¨NmL oô§â›ÂkͺBNâuk}£ËAS¦R]V ì °@°ZßáGŽÒÓ’ïë]¿72vò¾SH’`U†ðaÆCy-CCÇóÃùczcøø<õ8‡ôÇÐàà%Òûé÷Pîléï!J—Ë ‡<0‘>v| âÏÌt@é~šéþò¥K/kœzÿz,0žødÕnsíãÇeNYúùv Îøâäê38Ê´?"Ëû7q4Qßr¹½•ËÛj¯Çj¦Ñ)WÏ”*å—Ñ}.ÇöeÑ|3{poB:¼F3Ýr–BxâèØÙÿ¶…œéS,‘Ìk¡ž”ùùúžóX¨4ìõ²]ðÕ»ôLw'Õë¢B¼Kè7z¬FwÀr“•i-¤,õèVºf²W,ºåš,üîZÏ]–ïï`mÝ93:zêÍ-ŽgÁk(à]:§®4R<$’Õ´Zš#ÛHÙUév°ýT;—!Í Ñÿ7€•Kè” Ï“€Ù^w0'g@oc"Z…eÇ¢ÒÜŽ^Ÿá«òŽ)ïJT;`¥‰<#my<ÿÚÅv!j{³œ±‡wØŽHàêA~C ø#½èÏ€~‡1Ô§£\ŸôžÀñšÞSNœ¦ž¢üz:<Ë,t G^Ûä%…_ïG±¬d÷ªz”•huÕù²Þ‚á½®ÞÔXâ>úäQd:}}Ã! i0]¸Œù…ÛÖ ™MM¾s8†QÛˇ]ÓI„%Þ¿¤¼¨8ΰÞ°’)IY´ƒ5Æß€ÜìšWÚsì]äÍϵÌy±¼Õ¶c‰ê ì'J¢yÛœu61Ø7€ÄÚè¶d‰·áÇÊò2¡âMÒÎ(©„@Þ\¸€Õéußn¤ocµÚ•Ì9€…áv|sÎ]˜•uG#×ÿÖb¡dX«kM-k««kk«‘yñ|[+bztì&~ÒoMrY‚kd@ÃŒNB¡3DÒÄrD€Õ¶4§GÇPÆÅBqÊ+à ñÜ „:‘ 8'à×ÒGÉx]›éS–#l"0œah-%p£Ý ‚à0t"†½˜Uz¾¡Ô–[ÙŽ„X*¬®?A‰Ün¯¬ãÛ¡«[Þpþ\ƒÀ8Ò6†eôÝJž¶Šüq£Q“Ûq']°:2óµ./ /t«õ;…°T¸ÖûÿÐb¡dXÍ\î©æêêQ@­Uèf¯æ“«È½¢ð¦ÞÔ[†šG5éô«l¸:ÙÚÚÍPã0´ÏÖÛ«Gt~Gšk7×Vá‡4ÀçÑ]üü?|ä2.~îÕ-$Àò<>hS‹GÃ6ÃÐ|âx‡C‚tpˆ ÅÃ8žbòWܶAŠ”bNçë10E\ŒH9•pͦ°@°6a¢ìÞ…Ë£¦zbŶØå…B³Áéöã@¬;dÈG BÓÖµPK0ÿ.( %}X]ÓéAD½ÀWR´íÅH:&@}Sï…Ü·ÔNáx©{`2êåB°„¡ß$`‘/N!ÎÊúA«?‹%;ÀÊi†5°º–G¦u“—À)Í’Vqc`-ŠÖšƒ¹æjóĉf¨Ó¬…«œ  SëOÍ«nÑÚSüžâ\šÍ› JlüL^¦Çà;Žaåh !A‡Çã×9І#«BÆv„" Ȩ<´hsdæ8}hú |<¸‚Fµð˜)H ,g0ÅCI‘cÜéÀ"öR ¼LXýyn3`%îË;6x÷¾01Z®£a<žÇ:`(“NÁTŒcˆY÷X-<¬q*ðHU¤aB¤€t‹§J^TÕ â~B8 ©)CâpNã¸wz¬ÈÆ`ÝÖ>P½Áo)Ä(Ö½ƒÆ‹—¬kÍÖ°þñ¤æVͧr¹æ 5OY[]ËåõþÜZ´¼Ǫ̈iÀÒ §¡k-7œ?žШÖ|Jj¦ŸG4€­åôN8+‡ÍÕ•N€†‰'ŽÒüžïù%D<õ8ü#2OF*ü¦q±ÁÊ  ""Wh? É [C>²´li–€¢¬a!GéQsÆí‘*2ì ,X‚ÀLKpë0Jx ^Èõg…˜º{p Í€AAè*²-F'Ï‚54d†Œ-”Þ M¡ô“À¹8Dž P&ª2ñ­ÐíifˆÁܹ„…rŒêK90gÝ ^X÷ïýGvû¨Þæ%…ßl‘søú¡ôhv€u<§‘fum°Ù|jmíhsPÿCŽô$©ãXËšaåõÏÁ…ãkkÇàÐH'Äóž‚ßkúܵ(dÀÂ|0Ñjç>Ö‡>ý!xDòÅÞî^$Àâé øh…+`G j`¨ñ"2.q T‚È>“×R;Ãb„4 À³)S¬”  T‚™—Gù¤AÖ ËRÄm‚ªõsw.!é#ô ƒ -^ ±/‡µ©ø?Lü÷XøÓsꃩà {ˆ¡À‘ǘnJ‘[3ö)EI¯xžÃëH«ìBãµ)²W {å†3¬(Æšw&˦“°þòìǾÅnÕ×6á©î£c§ï¢s8Ö§Xº‚? 3ƒò[hj…€@ÊA ZúHþĉüš9£Éÿá÷ñ&p±!ä3xü8ìK5!°È%üÐ/]yâÅ—žï‘a1`…rU÷B! B›ÀÞÙj"ãL„°¬Ǩ"¼(ê@ÃÞ‹{pX¡,‡aÅEäöyæêš’d¿u,ëd†”cf€Å&1`ïÍ#FÄÍ]6¨D‘¦À¡œ‘ù”@!) ¼yJ·åˆ æI飊ñ£È(=°Nµç\wvBÎGÊ”âq4,´XhºTVÈÑ4 XK=Ö Vëk9õçŒXðÌÑSÿ¹ÏÃÂ%…­×GèÎá¡–Œ+—pmu52ð`£q‡ h6ó°ô^¬ÁæBÓ¬üŸ[[…³WW°ž"~…ÙÝ4¡Û„À¢×|}_óõR1÷‹¯p +F¸—Ðü6i´ö2N¾G@bΖ!'u´1,kŽÖ¯±<c)±JDÄÒ„'MXÔËÀ!¤|-xb$Zñœï(ŠlÝÅ+3TËî']ñO·–¡åL¤'+ ß¹¨I(ʸåìÄ{±¾¤Œ÷¥s¯ 0±°€%}I{s@†u÷ôÈØÙ¿'›‚…9àÞÞRøæ}M±F0šu¨%ËÜícšè4ˆœ ~çá/[:’/>2l‰•Þlš³!/}\ï9Ž1¯Aͳ:V0`%^¤ÚëôQ{—Ð8 öqºþz¥ %T‰S"~’Aª€]€¸ˆ8;0m6ài rM÷LNbÐD¹'.a(dÍ×)Š:€IFH¬@œXÏ/‹9Þ(uð–“@ª‘…Œ 4á(Ìy6Úef]KñO‰G,ë>Gx…Ãô¶/åd@m #¹Ñiy èzܹE»—û®–±`µþü” ­“S¨©Õ÷`máæVëû'i¡Îa–ì+& 'š{Ng§»„0µ't^UO¯©ÇWÕ÷üš/çŽ×¶CÎLÅ ì¼ÆØ SgšÀÄC™‚éÞÈÚá'àrLÖm«ÚJÁ¸„FL#pŽìÅÀÄ%Œ7ØKÔ—o_òTL¹-Ú9™2«8¢[4wØÎ—w–ÉìÀu’x±)RV;^›²‚¶,þRsvz×Üædé>C¾ƒ>E`H­oŸùŸ¡QµÐ)¼Þ¢§%¿õ>E±÷Òü̦5Í92˜Ïæz–NgM ºÃYŽd-a¯q«ÀZÓñ"¶´íŽ%è|IJK†r[¿KòÈLZ º$1²d+_Ù`‘éîTÁK6ßðÈegR§ƒ¸l+¢)±„WÎ,ó¨m]_`!ay9eú MSuïšš³4¡ëÚi˜c»þí'~]HŽ‘Ëžƒ–´ ï!üÑ(zZýû­ëxǰÕbeX+8ý3SiËq5L jÒm°.W°Gär–æ¸0ÃØõ;eØïXhZ¤Yí×5—©ÙŒAÇô¢£XîÙ-&ä ©ÝštØŸÚ°Ä*m+Jë3c´“·iá½%kÝ2K[Ó˜YA{[²Ñä²Ë°`UÎÈØ™;D£ði ßhÑ4Òo´Z÷ÎŒö(Vv‹Ÿž !¥ ¶ $Ö¯!,U¡Åž®Ó#1á…’Ôüƒ =^æÊåKÉ'l%Ʋc@º!µÅ˜ ·'£ä¿À~·q^b¸ŠY`¤é!Å{‰i¶ýfa×ü9'„=ý3gBÅiBjïÒ@`49í—zÒÌŽ^™£¡Èæ˜Ü"§>¦?¢0¶•ºzÜböÆ»¹½ßBÓÛ´'œ²ÛêÙ›>#Yüܺ~Ú„±î¿yztôôõV ÞþuúN«õ'#‡=Š•áó°bÓÝ­¨í@”’Ö.œ³¤CœÕ·yïÁÕ+YÉÕw¶Ͱ•Š×œÿœvEa²ýÉóÒek+Š¥oWe›Î¢vew*…;(Ú6á.…×v¨ÓîȺŸ¥+ õ´ L?Ïùµí‰}GígtÈ)[-J^lK­×O᪜-z;!L¾jý[X©£)Ö¡Ÿ‹õ¸^æR¯Îáå[hxe ‡º@|ÜïPpß9äã!ÜV˦•< ðŸçÃ-C*›r)S5¼r#L€”§ïX q =,^Ú´GÀ¢|¡˜Ÿ‡-UÒŽõ’´ß'UH< AšÛƒÉ8}JsÊÒžÕ'õŽùâ>HäÅ‹ÊôãýÖÆ±*ÀÚjý§ÆFþ .ƒÞü>àëìÛ­ë‡9刕ÏïÊ@½>_Ÿ¯ì¹+·íi`‰gº_yâÅK=3,=诰1*‚ Üc| w2`!H±xòɶÅF&{$7Ç´ )Q&Á@Ø€Ô€hÛ¡çîï¬#,·Ø.iw!>çk‹ˆ– û„anyR j¥çY°ã6°Ê<)®i´Ó)y 5åkEò,ê˜$‰á\!eÃ*X¸ úM…'bi§p–þÁáŽbeXCà"`ÕëùšþµpôX®J\iÿ†B °ä™î¾‚t߃KˆîB{Qä *û„Xžì†e]:® ƒ1Æ8ʼnLÔ…–ʤÐd•þö Èqa ÐÀ³ĉ® æXîVm€Å&o`Ä#7j„õ÷.xÖ=c@V‚ãʳûjIçJp)„o‹XØK–ù6Ðé“»° ñãyçY=ƒEöÛ~£òƒ”ryQ‚îszûìÈÈ™¿­€Sx·uçÌèè™»ÅúÆ!¥XÙÖÐlµZYÀ:6»pâĬþU«i¦E.ÏfSõ*‹IÀzñC¿$/¡èõ­9à}•µç¦Ç>XŽÇŽWÃKÀ¢‰£Æøb2r%÷ù‡— D–a5â…–E«† XŸÚ:×RÅ,·j{˰X1JH–Ü)4‡1Œ'j Ãò8TG0}LTÌ™‡Ú3ì‹àváS66Kõ8ª–`Xr£Ãqô*½ƒŠÂ—yÎß Öý»·s¬Zož9û°NáW7[ÿNCÕ—7i.ÖACÇÁHfA÷ù\¸NW•Y X•…ÚìÀB¥!¸q˜î`!C‰¹„¾úÊ_ó…€®»„X2ö1HA£óMü‰LÕqúÌ~ Œ»>‰L`L¬FÊ&±=¾ `Ź_ŠàÄQ7·}, æîΘ÷¦Œ;«„aÙôE”Ûh=â.úˆZàóDRërÖr«‚ç¹1¨K·`Q9•V¬T²kÑä ‹ëÎ~ìì]Ã`ôIZI~ã§xïðÍÿçðF±²¬é¹#Ó0v*GŽL|ÍTjµŠæ?årlFû~ˆï¾Hõ%¸KØû‹T/Ú»„Šü-Å›æ.¡\»MüÃwO®ï ã'¡©(¿3K/qEGÀò¹ ãßÄ­ßn*‰¤I0Hua†¥ä„ŒÔŽ@è5Û' °x$4ñÛ¬èóÚÃÔ‘vµÕÕ8›Ž›¬4iuçÅ4`‚Š”ë°,,\7pÿãÓœÊA¬ß9ÉË i-áÝŸý)Ìɺ·ùÅCÅʰæj0«¶°PŸ«Õæçj•êl½>[©üæt¹¼Ã;~½‹Ÿúªú=ÏØON·Œ­˜1{9V’;CÑ]R’fX±,SJIÉag&–˜à™™aÚyX©Xcf³5“Km:ÍjuæÝ&RîäìmŸuŸ>NuH%Ö ë.¬Ã9k¡È.ƒÆ¼usó‹cc#¯oÞ(Vf.aîi|ŒñG‡‡r¹!xÆñGóù¡Ü‘ê"FÝ÷k/Ɖ£/¼|éÒK§^ ¿žüAr gLîdz3õ:fIi“3·]½‚A÷”¬cSÙ·™öÙÅÖX2·FB§êf~æ¶sIÓ D¥@žj$rOæÚiÙ¦ŠeÐI{ݧ¢î»ÈSåÅ-xŒ; Ökæq ÷ïÊ2è÷ï¢S¸yåw÷Þ¡‹•ÝÄѺ•ùyûs®ºhf_íCh‹’¡J="Vç9JŽi›•«ò¶_ÄÓã¬ØS2l„Í7ÅìÓæ·÷>Õ¾w’ަ̇m’;µk«uçÌØØI‹X°tp䵄_ßÇYX~ÿú&ì>”Q¬¬ –äTqyI¥B•éÏøTe /î‡Ì¸/¡Ø« Kh³ï"Óö±„6Àz¸ó=„RnðÒœÖ_œs9Vë›#c#`œÂ¿‰LëÎ=ˆbÝ9hô8Élñ3 <« õO³£œ¹Áû XJ3¬ºú‰Ë¯\ÎD®Àó°äé\û?VñI  Â}»ò÷ëaÑ<­¡õ†F,‡cmšeÐwNŽº¾ùÇè4Åúò!¤XËG·Þ{çÁÏþäç?Ç?ïYÞyï Ó—C,­7ÎÄ8Ö]yNë»'!"ÿ6<-ù0ëýô›‡ï¹X `õ¥/‰$8–}>ËïßoþxKá½;‡“bõ«/}yÈ„9Ö?Êæù̽ñ«7ïA0ëÛ÷¾¢]ÅÃÅêV_úò° q¬oý”7a4¾+§õÝxÍ×›ø–Býy)V°úÒ—‡N€cúö&oÞƒeÐwZü,¿?¼÷;šb}å¼ÔþÎa‹bõ«/}yøf]òSÝñ Ðc8ð~æMœÚpýÍÃÅêV_úòJë›± Ç2oƒnýÞ)ü¬,|û0F±ú€Õ—¾<ŒÒú.r¬ŸÑÖϾ®Áé›ìžüC˜Úpò{×O:ŠÕ¬¾ôå¡”Ÿ~ó”vü¾Í‘w\=øF‹Â;øù÷_;ts±ú€Õ—¾<œkÌıhôû[­¯ÃLw펎ýÁ!Œbõ«/}yHâXc§øÅô0Õaäµ{ïoáL÷ï½ o)¼~ø¢X}ÀêK_Vù)p¬Óo0b}sdìäï´è­_gþúÆFG¾¨2ŠÕ¬¾ôå¡•Ö·µçw†ë_;9rê­­Ÿ}Uï|íÎÆFù_ù ‡)ŠõØ.~ÎFÞyÿ Ó—¾À3e„cÝ×ÎàÈé;­Ö?€Sø}|>ÖgàmÐ]ËP°Â¸DüEá¶¢“ðù™³MFû/ïþÓÕ+iO—éå‰3WÞ1ú° èØ’hì¬TáNÔÏ!Šw:ßtðÎJر´ ·ë´»:àêáœ;\ Ðïˆÿ`c5^3[lªÂÂAáX¼ ºENá˜õþû¿;¢)ÖA£È(XQDŽ XE++ÑN$¤óWV‰>s ² ñìpyG9ìQ–£à‡O½Hÿ{}>2=ÀÚ³¬E·ÁèÅ*Èî z‹Úvàf$³Hd¥U¨?—–‚Ô£ô¤âƒùÛÂz,-e©wÈ7Ñà@j¸ûR4’šaº;pZ—’H–šƒ9g †f€ãTÔ ì ñLLt,B,æX­?:5:òµÍ÷‘w}§6hŠ5v˜(–F—ìÑ•¥ªÝ Èò2^3–áìpe‡x·7òV¢ð°øÉô»'ÔÀÂö ÌpëhhÅ@Ä…’ jC– -iìˆÝƒ\Eà$Ã(y]¢8ì‚ í„%YÙ¥¨3¬§`m™n Ýiówªƒ˜æL[;e²­}0"µìİ∵ù5|tëîip 5»ûÊïãÞOÜ=XQ¸ºº²ºº¶º*€µ¼àBkÃÓVAñ𹺠8²ºzsß;ܬäK(öÀ°¨ÝŒAa¢Ì¸Q¦±'± s,è|PT…Ãd&ó "a½É:@HGÛAôs)Kuòmkg‚¦«/};M•ÉT¡€SŒíF.Ôwc“m™¦—òÈö€Åˆõ—J¸ ú/Z­×™]iØ:3v˜¢X°p´…kušÍæÚêrîLáÒ`Ü®®5ñ<ø†Ïµ0uN«ûÞá踑Kȯùz~¯ùb—‡Q(h+!ÃØOà‚ó<ƒ¿- É L ‹24eÛ´!×#(ä­n +¤Ô6:¹GC#æ"xˆbBð ÃXÅ(bäèǶ ÏtXRz=MŸ„‘5v'&Ôé<Û9!ùƒ‘‰b0ËâFt²Ñ÷ñXgðu…ü6è:…¿ûÇc£c_:\Q,XÀ4Ä 4›¹æên]B}f.÷TóæÍ'›Í£kkÍ#«7õ®§ÖV3°î² ,0t_¤úòG.ËT_Þ`yž§í>qXã¦ÌOojƒÁ£”ÒÒ¸‡CüIFè¡’ðüöcŽžÓ,)ܹËx¦|Q„Qž{V× 9ÛÐs3ê]°BnÔÓÃv¡ÖL5Q/n]¼x}õ‰ Hמ=f’™H uKˆ}cË3áQ• L“M¿Qþr›èa°³•"bÑ V[ÿ—A·ðY~߇© ¿¨nJÐ’þÈj3ÚQg`å༵էšÍÁäà·öäÚþs,ˆí‡±WÕÃ÷G.÷ư.^$ÀÛñB4421Eõ|”>C>äî¤K?Úï ùSà‹„Ë‹SÈà8_Yƒ‚K0)¾cOþ¦SUg;ˆÛ^ `…¤)h­SO0Uô`‹g•@# kE<ÌV(<Ê!²þ¢.C>Öƒ2¢ºPÏPÞ|ËÒ‹èN7U° ÐêX÷߯¬Þ… Wð6è‘on¶^×ë ß;5:ú…ß=LQ,XH¬šÃ'Ž75?Xã;„;¬5¬§V×ô×ðq Zkú—Îép ]Àºt ëÃW¯h’•=`áitè¬GûAzü_l˜Ùäl[€1kˆ„á¦!VrY„1>Î좃~–V˜ "rÕöªu‡aq=͹ÑÃ,ÊCϳç{Éî†rá@¥Rž+Ëîq‹û„u%ýá…̨Àm’úÖ/d—ð~ê,ÐûôJhäXšnA ~ó,8…_ûíÃŲ€´¨ÙD¼:Ú\Ýñ >XÇsàJ`囹…<VóhþøÚ Ýõ¡O\ê1èn ›ð%~û8öá  ´ŽˆgˆFw,ïž’ûFm`†J®ÈO Š+ÊQLºÄ; ²F8£]_+X€ëܦÈózïÙgbX&×ÍÂCFÈØš(ž¸mÐ=ƒìÌI=sëÊÆÅ ÏôL›#òø¾Ûø”@ ½˜XŽé™zãÝí¥ìÇçöÛø‹ëþ›3•+µÄ¢eÐ?ƒÕ„§þðÌèèç{ìðD±°4CBˆž”Û-/"À ;çqb¸¹¾esß‹¯N®Køâ‡~éÊ/^âY0,´©a$ðȵ Ùøíõ:24‚‚63CâÑm™þVŒK(Æu,F+¬H¬O|ÕTÀ"`YZA°åp[f€EšâšÓ^F¯€>#ãâzRyÏðDØ B!e”éÂöÅz% ‹ŒÆŒ¥(3Šz1ÀrûÍ–u°€….áû;ýÍ4’åp,|ôÙ{›°lüÁÑ/¢¹XIÀÒ°3¼€µ‹»„»„««á ÖZsx¸‰œMï\ЧÝ `i—Pׯ\ÚË´†‘‚Á *“áÄ]ÂHœçø øÍ,Œ¯þÝœb-; ËD€L4(°¦jÿ“»îÙ’"7*–ÐÏÃ2H`ko±ÃÆi"d¡Gw7 ÊLÔJîZ8Pá‰ÃÆ K¼HClË•l´Ê¡X c¢ZN™ùë6þëËWåòòÁ{…+|{/+[ÿç?;õÚÝ4’%ë}|ŠÃØÈ×7ï¡Sø…ÑgžùÒèèÉCÅr ©Q>?|âÄpnçw÷––L kM g³ –F¿A ]æ®öò~/ BÀzî¾réÒGôß+yyO€šØŽúÈÞ% MLŽKh‚Å|}÷$¸-‘`ÃŒ³YÀ0w #Ã2Y0<9›°d¿d›®#žàéRG{½ë>ɰ"1~ÒUÀŒ+egçÕÄŽ„3’>M¼w‰.¢'eˆCi¸%åÉÚ÷ØÙ%rÏ+˜Åû-´°É”ì+X›¯Ÿ9ýz]"Ž…¯+Ä·Aÿ—ÍëÚ)<ó»ÏŒŽ~áó‡æF¡LkÀiTŽÀݽ••åh:$Àê$k«²¼¦l™)ñq¾Õû6_yqiÎ%”矇¿—^ꮜ¥9vòº*a‚#Ê©ö]‰éÔæÎBšëÊ£•ó ûx¸Ú€Â)zŸÌ°7±S¥5Ío³³¸¾p Ͳð¹´.Ý­þm¾-n@½™IM¸oÙèO.VËKKnʈ (®'Ž>µÏE·<º! bÛ½Ë2LwÖO{}Óqƒ(’)c¨šLÆcÏú¤ »æQ'Ç4Éúû¾¤É+¡ß†çþÅæ7F´?ø¥±ÑgôßÈŸ Š%€µz4çÈSG4`­`í@°âç[8²føËÑ>¯%tbV{XI¨ëƨ——Åc[A# °R–’t\!hÄæ'gaW VÀÊCNiáʲIÏu/p{Às¦5,a×ô»¬È´gy)bP§™æK+ ¸.3Â}ŒÔ+RõÄ¢ÀÀ™ÅòPÛ+Ø<ûöšúäzÏòÊ’Ù×Þ)ÎØµ‡>H€êX[÷ò]M²NžNóðZsëþVëM¸3ø6Ìvûí_}æÌçGÇÎÞÛ…Ý?²bžÖ°ºæÈêêê.†mç;9ÝL¬ ÈZhÝ¢.z¶`ÕÛh,w@£•¹úÚWøÆmÂ$¸>3QÞ5ûxjçJ Ï$@[Y•674½€ïŠâzOðAZbúa`I0¶½ óáÖjIZÍu\!XŠË ê‚•Ë‹//‚ý—b )î­Áq­Ï ¾¨ ¾4g%Š3*÷Aý–\¹³¼|–íÊ ¥;gOjïËo·C¾`;Úú>¼ úÞ§GGÏ|iô™±/=3НZ}ìÅ–³h#¡²Ãû3­ÄˆŒ…±ñšÜÎFx¹É»?¾rùRFò XAh- 8ëNRëv©iä2&çU¡¨]˜YçA²¬Ð|k)H+; ™¿¹SNß=ꞃùî%)Ù~Ó(Ww+f-w¬%Ò#ŽÓm‰l—:wŸ¤ÑQã’û3>·Õ¡Ä2íÒœû÷¾{"Yo¤!Öö aôÉ?¾÷u¸SøùÑÑg ÅjV|iÖŽ$í±H{ÈnW½ýÞƒ«W²’«ïlí½^»hüßÅó°z­}jP¯ùîó˜xDÅÁ¥7ÏjÄÒ$«m‚ƒåXÿŸNræ:<àý™/=óÌôî×Åz\ž8úÞÿñße&ïtkúrÈåþ½¯ŸÒ êìõ6"Žõå{[°špäìÝœÒNážyæ™Ï?s((V°RäÝš¾ziýÞ.üú½$dÇúŸ[4ô+oydtô ÏŒŽ~þ™Ñ“òøS¬ŒË÷ýņß/—Í·ß(/.Âoý­÷/.òoó·×íFC)ý±KØpDêÞH”kÿÊeú³ûÌyü7ß3éçcýQ…ªCþɲ$« [פ~ OȽS~½èDùÉ|“úJÕ…{\tÚU·)çuIç–?3ӥͬ«d?ÉÞìÆç6ÛÒöEÆ›ÔûÿíwNiõíˆjøvë~ëëÚoüxlÃ30{ôó£cgŠ•`¹CV:ÌËÌÙËŒjDft¿ò@«CÍ]ˆJ€møÛAÛ渵eŒ­ÁÆÖY$ÓØ°ïT_ÀC–ŒEçëï8ßÝÛz÷<Ù›Çísi;¢/¥ _.¯.Иèz¨¤QµÞ8;¢IÖïÝkÛ¯„þn«Ë áecÚŸð0D±2,åØŠ X´¹Ÿ==ÓPüLwšÇ°—º_Äi #`aQ Xj d?‹j½Ó|3¬ÆL{^`)¿ÍªZoU“¬“gï$`¨õm½ûÔ77[¸ úúWÇFÇM+3†S¾q e ìï`Ðþ Vzø•»F¬Ë?ßrö„,ôØmÉ1¿Ü9/µ¸Å¹Óñ½£zQÒÆ>1,Ì7ÞÛ–âǾw2*˜£—¹Å‰vûâSq ¢á\D4`uÐ’Ï'˜ËƒSZæzÚ®}¶V)v¥IÖɱ‘3ßM,»i}û$p¬ÍÖŸŸûâup c†¹XYÖt¥ª¥²8S©,`á@kø33¾‰O4õ1=:*•éiºZÞ®/!=ÓM’¸¶¥9—èi =P­‹XþN+1ØÓ«“1 N-²éï´viXûİz¬›Ù9`•°ÊËFNM0á«s- ÀÚjýÃkÉJ,àX£šcmþÑ©±“¿ûÇ¿,€õøG±²¬Ê,ÄY¨TŽ.T„ÚõµnFMWŸ$XB·§2´ÒÐ)æªÓÕúP•;Ëçñ¢¯ˆÊ2eÈ ókëÛ6™IYü|éù—è`yžçã'• ?<è>mâ§ï2)y'À)õõðt墹„T¤É‰3’4¦*®éô ŽlcXÊ£¼½mÓïT0_ÏÖÓi‘[„ï·×|{ñÜô—mU®2Hcž©•¿QË>éþ<'Êʹc_ð™žU‹ÛŸ¾ç+/Mc¦fðk7츓øé¦µù:Ì"=óý8É޵ùÚɱ_þã¯@Ìë™Ç>Š•`Uçóõz=W­Õç€BãªÍÍá/`JÕê¬>®Õz>7W®Ñ‘éj­V«â)p"ìûŒþ©Ñ«š«WõßlŽÂ±ÅŽãb&öx™'®\~QמËóqàÈT·pb¸FGªCÃÃùcsµÚÜÀÀœ>/70;‹\ŒKç30ǪÓ\r gºãüžï)†%€ˆ³(†á³9xŽ©{e:ŠÖ¡‡=€ zÃè¿/i,5H0,EL€ØÌÀŸÊP5®Šç9YÀå_Ša×XŽ7–O`­ˆ­P} ‚Ý¡b>ƒµGü’Aœ›¢D=ƒ9 ñjŠÜë‡)ƒ5‡™QÂ\4<î#ß¡ºT®"â†ÔLºÍf­ `©Õ‰™o˜v&B€õÓ{í³ÛSIr¬Óol¾yflì hœÂ‘ï>Þ+3†UÏø©å?Wš›=ª  p.€œZ­ÛX:¥þ÷Ñz¾V}š îsŸ;¡Ì×êð?ŸùzõšÖqÌGï­}ÆWén¡¿˜x¦û‡®à#Ý{»YH€Õ ˆñøª­`¨*ÃM'ør ¡<‰Šx1? QÇoØ«<â-;ƒ•]¤_d ¾\ÿ‰(Æ?8àá%MxGw`qL~{r7€…oë&˜Î0ŠœÓÀ× @¹(¶ù"ƒ§D·¾ç'ðJÚJ`Â.¨ÇE*ë4 8yFߘ–ãƒXJBpk”¤éäÀ‹—èSaÔÑ& ëÿúÿkûªgXª32’x²>qT#Ö÷Nýö—˜a=3zæíƒÆ”}•ìkH»nŸ®‡àS1¬JŽò9žz Ö9LïÇŸéþKôŠ‹=Ío¸È€UÖ£Ù+SÐÇzž\yåÏwÁïhyTøI¶ÃdÍqûÀB~@F`‹Y†K*°|t?A*2š.«¼µµhm~o KÂßRkaO`¡‚<á̼ÈܱqŠâE^±fñ9øÓ¸°’?·UØ§Ï ñÚ7ôŒ”× ]D •OhÈ%Qß@Z„œë)Ãû¨ •t¾éÆGÕÆ{S)}-‚!ý#¼(õ[mmýä;H²~à’¬Í/ŸÔˆõƒ{_ûåß=#ˆ5òÇšbe5Ó½2?P­W€&U4Ô«Ï×ëƒàæê Gæ˜:AÐ}~Hó¥§õo`c’Èð¼ZMÎÎA¨]ï›Õ{æçëCú_}AV§»8q—ðÃW_¹ü‘_èq>–O„f†Ë÷]ÀJD™„4!cðÅy0\€§Aq.¹œw,f#qÀRNaƲñ,,º–²¬'KÀò]ÀR¾áW„³%XŠ]=+Ï'©`‘çå'–bBó†Ë°øR¡ä˜Û±R>ቒYÀl†…3á|.C `A½°ì ß— ÊãW¬O…€õ_OkÚ4rúo·’s¯p=ô鯹ô _ }æ·¿82væ·Ç„b¾{Р²Ÿ’`Í™†ž›>2_?2]­Óò™ÊÂP>WÕgèTÓGæ4\iÈÒùhH›­Ìè¼ær5Èg®6;4¨V9 °p †û"Õ—à.áåöBÏH~€¡s³¼÷Ö‘øø¡œCÊÜÏrnñy”5±&'7ìæ.¡S”2Y/HrQb%âmsçÏÜ%TÎ Ì D‚îXÿŸ½· Žä8Ï3îbÃÄõ€ä°1h`†3¤ û†õcvØ!;ì°ã~`fb ]«[ÐèFI¨è3ººWéSHgÉ\ÊG‡½k‘g…e¯$¯nµ¦—;^oÄñ|öÈ+OÄ?î×mMÄi¬!8MÖLáÖáµ—ïG~Tuu£Tc8d¿3¨®ÊÊ|ó£2Ÿz2+3_EbsŠL^§|)æXƒ]u¤BX7Cîu=¾o š‚UôÌ~ªä¿s¬¯ñGe}`ìØªU«M~ >`a­¦.atýâùsÏH.õ…ÑýX‹ÂWˆdĺOˆuíÆ³Ï<ýÙÏ2Åzúܯ¿Ÿ)Vv€µ^)áwÁš„¬ª$E5K—?5‡ªm¬WðËa…|É;UÉ¡Ö7$yª`(¸‚_è^‚O¸zð^u}%ujƒ,6UÿÊTý‘«ÿ’"g@g§gû º,®å®[}¿ºø:¸@—0ñQß"éQÅŠ$é¥_ëwº‚8©^™Ñ&Z£MŽvJæ`etäå:McXQø¦„,`Y/ÞJ°, f°éÌͰ¼B¬?8ÿ ìŠõAÅÊì+áÄí‰<=uút>?S˜ž.fð|úôÔÔTA^žšFòxúôiyœž)¦óò†+ù+C². õ ÛL¾Ôû™ÓL÷Ÿü©ŸúÉŸøñÿ þ;œà–3üùù¶$×f,z‘r橎ë<êtFÌ/½—–Ùç¼áˆžÖ…×aËѧÏ1a£0êü*,kÓ…XÿâÜÓùüG>£XÙM­jÙ¨¦ŸÛÎ=ÜûJ-°°ròÒœ#íåÎxÅG °ÒÖf,ÇX™²·˜,/›yXQø'/0˺ÆÀ‡HÖ…_5›Îb]ÿœZó~ÅÊ °Vq¢h\J]'êº?-u.•Òôõ^¤“¶–ðÐð¥×Ÿ¸{CŒÒÒÒœ4½Gì¡"Þ{N]®ÖöÄÑÝèÖ‹’L=ýÌù‹oÆ +ê|ñ|ŒdÇúìµgÏ=­ëܯ½)Vfûa­®ª•wiëæô"U<-ºëZ-oîÓ¹Cuë½6gõïÿ¿ŸûÇ?óÓ?st‘:~öŇ¡l\2”Ö zUN3˜ê}ˆ0©å<À˜á{I67­Aw#Ñ%Ë’Ëq–uï˜.„½ØLçœûìwžµ(Öûxëý²ãèÞ?üÝßþg[þ6~yù»ûGOÎHFrD‘,닞"–eï;í|G²Ôš„~lÖkÄzb½ëÐx5¬‘¼G$ºýëÏâðûÅoØ"ɺð!}.ŒnÁFŸý¼š‰õ‘<óþÅʰü aó¥¿]”Ä]eŸ©Ë[`Üú)ËÏÐ%ÌH~–¬æ ÛÞO¬<†eׯgRC×Ä~©/›ïñàÐ×{MT 'clÝíü*²¬sϾnAVtûÉâMgv‰c©™Xïë¹XVæ—áumޭѰΕ‹¶Æ»Ûض½‘ù:0Å¥T¶[œb× lvúzÇQõ©ï‚¦êA­¾!Û¦c3_CÒ?íœê,UfbÈ´ÑHwk dÇü¸j8¿šÓ›±¬gÎ=cYáwd=û Zª³û7`úŸþSM±Þ¿£X™1,]å<|ˆ>[dYÎlå—+ŽïÚl;ÛæúºÍö€}üÝÚߘ«ï£¾ØW˜õçC¥ß÷`ÏMpÆÍËomy±汫}¥,o5’îè·ae0ßSFì·”µP/°´zVÜäÇÓ%Þ¿¥k`ñâ:·¶‚# èÕ/™£o …ãñäx‹ Po)û¨l»·,« 3{êù«²‰§zkËöOJ¾$¯cñiûÐødc1ègyħéµì¬¸U{5®hç·.ËúºYd(IXÕáõÐı `}äÜ?{ŸR¬¬Ëo¢ EtzüðÔ· yšM X¿wé\Ñô:×2_eGCæÒè#~šú½Q™ªÿñŸÈdâ¨,”UÙx“ð‚t˜ pKq¶ÝÙ†sêòXÔôÁ¼%dãMj˳LP'm½'˨› yAF€åKÕžoKÛ­W`Ë|‹½›ôpo¶Im*¾O¸ì:½¶ÑyEÖãY÷”?6_Ïi §à{ñRÒ¥Áã–‚(u‹Âa¼Â¼~Å}ÐRܰ`2ÃëÀ²žy *Çð·Ñ>4‘¬èo°Wh(Ö…¿ÞÝ¿Ù>„’`5[m)­¦õá9 äÜlµšx”.MyÄÄ D ÔÀÚÐhP·RúiŸª¨ 5(ô@®/ÍùIµ4ç°3±¸Khš8U{q ¶*¡kÃ<öíÑÈ »ú–Ûº»jú>C½ˆñ8Oµ'ÔHAušTôý,¸#Ž¥9‹–Æ€Eñ“QzÊ».6ƒž ¦TA’°Oœ=γÅh§JÐ.ݱò­síîÅy•oÊV—°o8 ¯ÊM÷âû“beXí“ùüÉv3P#ù.b]¾ÄŸö) >Íöd«¹-ýá Y—$‚IT’€µ¾ÐïM`aÍÇÛÍæ©vë¦Ô$ïmo©Ûh¤Cl+ÀâÅÏûØ?úµøù€%„ðè#å¨Zk4^*Gð ny_¢l¾@puä.èè)j¤ Å„>…@Eì#¬Áxô9ŠæôÌh “¦†€E9" Rc…ðyˆÀ"$±¸½î4LJÚ=AECe‚}J0%TRÙ’;Å 9õáq /ŠO°ÁÅ  •›@Pô)î8¬ƒûÁ>×b¿“,ëâùgp+‡Û³§Î×a$ë⛈Xo^0Ÿ %b¿õ ±e(’`å%Ã:ÙD¦e%Ÿ’Ç™V´ÚSùv³}æL\$‡j£HîÕ´B´dol·Ztî54µïýÐÿK|ÇÑŸÁíe9øŽ€…P@€à{Ø|‚(xYûö]ásÛÜÞ°J# ð‘?jb>)å<®M_p3ð}ÓÞÐ+5ßç»Ä( …Bx)øèᛞ›Ïm8 Ç@#ùÑ‹Æ,_¢XL¬g´¿ƒN ©ì1|¦‹ Ó€L+P€åQB)ñˆëšÊ©4#ÂPî9‹XÊ‚1Ç”Íh4ÂBðˆHg@ê…úÞ§Ã~nBá“Aw£P ‰'õX} X>b,J.{ïÎ °è3Öîåâs¯ÝêD=Z?nåð må@>:¿†VuÞŒ’ëé 7ú#HôÈÏKHDÅðÞ$}<±¢dø},z¤k›ÂGâáI‰>«i ­ö v %#ªZÍ“iZ­™š<®4…Dk¶=ÓžªÍ û AR»-ïžÄ#žOIÆÕ`ÀšŠ…žš}?H#8Äë¿úïp‹äÃ~+$ÀbÄÜ÷ 7±Ç]n\ç…YD¬Ô(‹zWûŠŠùª«§aÃ,a4NáÑ›_xö˜ 0ü(çôiJ;ò“€#9:^Ù ‹qÉרL‰äå÷ÀöFî”"¼£¸(u‰Äª®1V@ÏAHï þÆÕyâ`Zƒ¡0|UóãÀ ò*œ` …-|„õ&kÙŒ¹o«É@X!î…üì ¯ßJ `YYç_ü«»ˆÑŸã¦3_~;Ä:Å só½½±0ŠÂ0 Ç;aFú¸·›ë„á®äYxGýÝÇT {òH÷” ‡g?pGjÙ%*Sà#̅ѽXœá˜<¹/ïÛC,t¿ÙlÏœ™m7óR­Â™3³LSȰ$\µ dÒ½@€¥`K+ÀB—)ø›™·A »„°E²2B‘I—P¨“€š—º°ý0;òu/¡†ñDq V½«“ë3`™l1,5"Øí\ù{¢gh;KHÙ&yÐÐ ¤hlÉrgÖ-_¡”,dA±3åÅŒKñ[*{~ †ÜT(\¨ ˆ@uVÕsSeÁLË,R½¥É²ÉBE˜X OÁçÀsO]¸ø+²“J´Â0kôésž£E†Qç«òú©‹ß“€ðæ³Ï :Š%1ê7ž‹¢\çV1W¼•;{6|$Ú)ŽÍ_Ç‹0S~÷ÑïÌŸøft[Þ¿Éÿ6v=úÁ‡ ÊoæÆ‹Ý‘þn…c¯ÎGÅD·ç­ðoEÿü@Dß/ææ>ʽ<7p >ø»Þÿù߯Ø~‘K.úï?JÑËXǾýhؽæ$;À’DHöÝ€=Ͷ$`·šªÕ+És!-O€5Õ®µ-Àš †çȦ°&ˆ_åq$‹¾+6zc)À"3_ÿ5™ù:äf ?öÓ°T• ô@¿Á}ºâ{ °„‚#(€ ¹²ƒÀå)˜Ì#‥øTü®XÆÇÞ-H–b=µ6 Xq0õ-â§+ôˆX^`q¯Y *yº¶¦ê'‹Ê£.=T¥ø¯·e!}üE£ Lv–.9JqÃl„?$ñL÷·Þøâ­§Ÿ9wîÙÏ}ýÏS†´h+é¶r€»Ñu°}þ«w¢èOŸ5ëÜúQ¬Ýp<,þe˜ë\¼^*væ:\X¼t÷[óañõ׋@zÆ¿~óDˆ÷ÃËò8ÿbxé£pãÄ‹7ÈßÅNî›atéRxùE Ã_¥Ÿ?š‡ˆæßìܘëŒ_ £‹ÿfç*.^о5ßyìRø¯æÈ÷;ÒåÛóñÎG£èâïK_ëŽaÁW¿ö¬dU8TÇBgVžË;ÐÇ›BêÔ.Ìb%/g D©d§”À}ð‹c^SSy °Rg+{MeCªûØ?úé!ÕÃméN Ë·¾ú=ƒ&L‚‡~-Îä ë”/jîcš1,F¬=%ŸÔqcÃñ<ßhÄöï1Ÿà¤pòút Ej|ùQEa©*þf©sÃ׆a)¦KqUŸÒ}õÁÀŒƒñø˜ý<¸wèñ@˜·Î 9³yšþ¼Š_kõkÁzPJµ§¿Î]g2 Ë–þJun|÷…gÏÑ:áÅߺv~ß»õ"²¬§h+‡hçE\ªóçQøL¯ðé ÕoIö¸þ²(»‚soGá ‰òÿ ìΟ­î›Ûû·Šùk:Å¿„¾:ÿÜÎ;àï¬dE{{oÃâ÷LøGÇÏÎ…àgçKÏÍËX:»ÑÜÙñ\ýI€‹dÒB.ã/¾¼G¾0Öá–ɪ$^ÕjgÚ–^aš0[¾\m7¶¶ž8Š–ê?öã?þ“#sõ‡³AÁGaŠþ¶5·*­ÁªÉÚOíÑßî­¹H€§ü‘SÏïŒMDõèíJ -)Q’=>6Õ>&E/E°@íG·âÓ]ÕhÏ!÷Ô0Q`Çc§^Q'ë~rSY×>tvc@ì§äÓ#e꣇5¯>ï £@ÝUŸ-yJ«.ë9›9©[zþœgô˜x²3­Aöí:7^º(‰ŒV;ÿìÞ¼ÒŠ¢[ÿìŽe]üÃN$I×›8‹ôëðµóÚâ×¹úP¬Ý0EÏý†DŒ; À‚¡+„ ‰(» Xï†Å7%\!óÚ‹îýÑå ¿Ù¬¨(9Q<|~^‘÷v‹_¿þÃñÎø»°z£½û °":;!}¿óÖ+—"òÎí„G‡XÍɼ%S…ÙÙÂTþ€")Uj˜É&®ëÛÞN›8 Sª·õÒœ‹Í½:”‘/5Ëo¤Äe-ñtë‰C”jX±©ð[ ž° …9f¦ûV£k¾’jù:A¬Æ±Û,ÏNåa—æØ‹Œ°X45?\šÉ䉹ÿ8ÔL/èÆ«¸wbölxUjÑÌÊõõÜzÕÕVŸÖ‹ÅË•&Ý«¥bÖ[€ñŠçÚ 3 $æaEáík_D 1ë© _¹‘øvÝþ5³È0ŠÞúÂùgžyêâw¿f«ï(V8¶·×™—]— Ë÷è[Ô¥û=Ù¥»ýn|ŒIÀ£.cxïòÜ—ÂËs/atþÛá¯Ï½+ýýN´ìí½2þ²*©Â“¬7î<—ë[*^¾÷O@ñ=ò7†,}s̹ðÒÿ/Gÿ¤(·æ‡É°üf+&Ø·ËHš¿Ø·Ùk yùó°hOw?…SÅÖbx‰Z¯›ÒV ¦«ÖBî­­¤>Ýt<®¬¬Î,ñæÁóì†ø]@åuûïŰ,¶rØe9] K7póÁ$'¹¤ÉºÐŒ-E[¶4ä™ñ)ùië4©¤“³O½ÀO”Kc˳ӲÕÐȨ•ž^,&/®ÏœÑªI~¾ô ·Í–]h7 oýÖ‹D´žo‡ß½aï2ßÊ!º‹$ëÙ¯í|ýÃOò¡&ìþü#á-TÏéAóÛÅÜ<ŽÃ´¾/{vc·£1ZSýs¹oøøüí§"tÆdLxéý_àî½zbþå1üŠNèBÊ0ä\nÈüèG1úH‡ùcÛÖà31Weo*&í¦z¹J §AÛ5ؾ¤í|û¶¥6ðcÿ°òHÀúO?û3?•‘üã¿Ý ¬eɆÄ]<ˆÕótùúì™0v…÷cXã™™és{æ§gubì¢èÑ5U+Ûü û†áµ„žÂKüþ³Bi½öÚ¡@÷¯¼$•Q.¦ÿOL"iö"ŤÁ_  ‹Ô€¦Õw´Ÿƒ)Ïp(½ÞÀóM ñµŸ^‚ÜYuùhÿ¬l¤ÃJtçúo^|öœúvøÅ¿#{Lêëo˜õ ²¬ðÖ Ò×S/ÜøšB¬gÎ÷™‹¥&ð´…è[lZNÜÄû÷”L»7T“ ˆôíªIò~Ä“îéhÒÃ.kÚÛ»*;fÔÎÓö8̰+U‚ØÌæ¤kúµÆ¹ƒÉ?üíÏýlVòs¼VJF,ÇÀüYù üî ²»èŒ/X¦œ‚dÄ±Ó ñ$º„P¢ìHÂ_{¥6ž;ÎÀïûˆƒ¸g£þå“Ô`§Á*û)ôª–*`ô+²ŒÊÐ.ÍtÙîî\ÿâEžðpîÙ‹_½¾sWQÔùLvÇE†á»ß@’õ¡ë…»Ù4ð÷Œ¼_v½ÿ_þö?ý?Éþû›‘Œ$.’µÜz]};¦…ÓáñVÔù}bY~õvxësÒÇùÏEOm¸þ Sž±¼_koïþáï3’xÐYÉHºe7Š:õÊE3¤õ…÷Cúvˆ, ·røç·v¾ŸUF Ÿ¹5Þ÷–dX««uÇY&³6««NÝEc{õe°jfo—,–¸t ã(S¥Ë›t]ß4näwYÙÕACH«=¬Ž åç½½ÅìMØ @0 IVé–¥B°ü eÃúm3®]–^ô='éî¤Z«–®Ú.!…;ªñ¶c”ÐKNâ:ž”¸×IúuTþЃ)§K§6×cÝwl L*¬ã*[Î|§Ž“ÔM׎Öã¨?²Ü¤Ä<Ÿ¬-Wºƒ4´Ýhçͯ^<¯‡´^º¾ƒƒ=kŸ;Ã/߸þ¹?­7šyú©7‡¾Í̱n¼•™™¯x#HÖLs±¼œlh˱LÕ“ µªƒ1^Ùž“™ Š%ëJ —–ðwIžÂÏ €¥r²µùÌ*+Æb•”m‡Ýéåä÷žÞå³a`q2ÌhB½ÝJ€1-8NŸjh;2à;*ñ6X¦†vâùÄêžq>¬=\›wûßñÂy5¤õ¹¯_ïÜ‹x‘áÓçÎÿÒ›_{ÖlÛpXŠU £Ù×alaòî‡lŸñ{Iy$–€¨HÓ%+–ƒ6 Ÿ—ÿ¬*dÎ7uÕp–Ñ_L–•Czk®Z€E”­ßc6€µ qêÊ “A-ª„+\ûÖñµ9GUVUjVÃp¬˜ INÒ=-Ý./|m¡ÙI {!†•iI îÃ3fX=K-Q\½è¨Ó3HŒ_ ¥. ʰ4†Dë/ñ·CÒúç×níüá `/úé|þüÈÓië­bnþûÑ-X„|oü—çO|+|}.Wü?¢·p.Öm¼;vwo÷±³°è&,îD·aÍr®x‹®væ KÂ\˜»qn,œûڅܷµ¨úy˜Ük¤_ s×OoÑ‘âUî/Ïg X›¥r¹´²â®:+++8ä¤yÓ² ÷J+›Ëò™KòTž'ŸÖ §/1à‘ñn¬¶Ïå4³»„W–5{ˆ2\jAã×Ò"ƒY/À†Õ]#‡X§¿o,Î.õÞí=™¡¬@&­ ŽCzë T N7×tbî1Çn·ý^+‡ÌÔ!Ú]¾õ_°¾þæ›×ªž~æÃŸÕf ŸºfJñKoχ¿|ç¥bxö+›ëÌýÒÎ5éòzÃÝ»¹p7ëìÎ\xéRø¥Ãâ¿ëüÁÅ^½òé Ç;ã—;¿?'ÙP8·ç¯Ã2f©UüòËÅpîõν‹_~çò£Ò.¯Î…áÜWvÞȱëåËá«—°æ¯u®Ÿ½óèåΗ.vð(ã}ûŠáüµ·Áýw³¬R-ŸŸX/¯Ôë+åÇWðlìԗͽºƒç§Ê+ɧµR^ŸÈçk%űÒjßfërÀÍ!À‚Ūü#ñ¯äÉUå°€zwÙ°ŠzüoHB‚K&•‹@wy©ãV—±&Æâîi1P†ÈŸà`Y¤\êÕɈå'¥ÄœD9&®)¢ë~—;ž;:zŸ —ÿâÞLJ’åí´Ü]x²B=ƒH·«‚dW3œ2,Y0þþvøÌ‡ŸýüW>ÿ‘§%ɲ ×kŠ€ÎtɰFPžýÆÜ ߋ¹³s9É|èn¸·›Û9»#;z°¨ù,O—WùNñ†,XºŒëswÌ2æñÄ’ÃåÔRÄæ:gQû8jº„³t oK¥v._¼pv4ÍuèˆúBvW ›`Ugªë++嵚ĦI˜@$çª×ËùjuãT¥ç¥j¡Z]¯Fµ‰ÌL"ÑJe¢Z­N”VÊòÞ¦ä[•ò ³6dd\7»«î˜¯„ ¢z´lè2§Wúv ¨‘PQñg؈€å`C fàPÄuÁMÂaà´ÛÝ2y°Ý{%Kù"0v úúqáô¿N¦Kß·õ ]–G™?(;K!—[ú³³àFد$r—ª°ð»«ë/z–î³~’CÖÎõ¯^|öÃÄ´>l(ÄQ¬o¨Ö~߬wÆ%Žå:k_ž5<{k§*ÀB™{'ã¢æ¹·:^}w>4€µ»Êåi8Ã’è”_/U Ÿ’×_¯~j¶R’ ¦•–ÞcH°’]B‘,í÷ö,øç¨6>dÄR Ëa”„¯…ÂQ£È‚@ÆàZÈ$\›%ˆ^=èºQ`C²²ÃR eµzW¡½ ‘Âd‡ÿsƒ0Y »”¡ËËaÀÑzuΕzXBåRà7g@…w8çÁ¨ã_c`ªc¡«î¥L á© ÃÑY€UïJôî-ÞJëi µž>÷ËŠbÝæAwî†É„׋å¾ œçyÐýÞ¿š›{%^œƒÉ ;':{»0f~K^E·ÇaLýG"t„§:ìçÞó1 þCˆå‡ZÿNqþz޵Ód†¨ø!Ž™\£Î£·ðÛà«'æ¾:×MÅã껂ûø;zâDV€UfÀBªHN%áh¦0Å€U-o–U—pz­´Y®>QY›=3 G¬µÊZ5_*? VÚ7°ªÕÂìiв¼ßÃF\žž ±u»x%N²lšÕ°~ƒ j®Î0ÄfXÌàWµ[õÍÊ0 †@Á ©¬•a!. {‘A€å 60KbRãÔ NaÁº.q($g&ÏÂu•+¿¤_×õ]W–£K‡uy|Í\ 0.?O—ù¤W¹ ûyséÒpùOp7¬&mÛ˜YêÌèdzû÷£Ø^Ç»ìyÒûýb¨CߣQ1ÉÜvMè(²·ÕÉŒamä×*²‹'A&_*MHb´!OkXÒm­ü¸,8¯åK®SÚ˜(«–Ëت°>S~¼Œ€€W’÷©BEj©MJŽU­­ X‹‹±Ÿ´^áB¼[؇aa§…x‰ªàÃ’€e“M¸ (h< D¶¥#ª¬l £ù:Áivm†E]&=¼æÚŒµNÀ¼'s÷P1!^V—P€P÷0XŽfXŒ;qÜ‘ŽJKÒå¨. ûÓ̶^7Ï™‰_ŒÍ:ìH€å¼–nù;o~·Òb¢uîòý£kÝÛ;ñ-8~4Ó©óч~×ÒGSPïõ™ˆš`­¬Oä'*%·tª¶qjåÓk“•Ri-?5±öñºóéõ|~²\ªÀ×ÕõS%Ç•ÇOHè*Hh«M$Ã’Ne©`}E2®éõ•r¾0;]–:'%ï:-ÖÇi­ÆfŸ‡MD ¦ˆ¦|%\XB‡«‹f:±0`9ª“‘]ïþºþJ¨Æ_ôWBnáÂê3²ƒêÿåÏ|%L|;¢Ø]BT«Fày «N£RT€|Õ綺ú®]²„Ç5_åˆèèA2Tçа˜&›uS*&ŠOº1WóqC3rf0T°®?U:¦¸a|%̰öp¦çí7^¼pþ"Ö¹â½,•?Hɰh̼²^ÛX«TÖ×°ªøAPºmÈ{àç5<®W”+„+K‘¾7j•õÙ_¨Bç°Š÷66Öá|c}e À¢yVKÔ1Œa’u±dû‹ž‹3ÔÉïzÇd³9¹£' Åç—wŸ$%9Á3ëyXŽ™iÎÓ4ÜØµY£S¿TkúTÔº>U&Ýw”ß}fÀ¦ÎÓbvgtÔq¹¢•šÞÅ’˜ðî ƒmg X ²wø½ßüœ$Zç.Üzߨ­Ï¬K˜Ÿ)`?ãé©'§åqN …Ât^ŸLÓ¹>¢ëS¶§'å÷V. ë“§OË`RñDiA÷E˜ º°‡¤…NÑÙAÖÖ³pн«yXqö‚'–®þG³\Jhé`Rkœ}‚¤gÇIS¦Æd¹û–¡–Û—ùl9¯“P5tɰpDKöŸ›ÿSk‘Ml—å¨{<*m)3ؼS™íÿúÝ?œd7q´zÙ8ˆßj­TïýJë,ŪôÖØïŒ½üò‰7±?kи4¬?³ŽÝ±³gwrRë’¬}“¬?K·¹{·ii´+XŽÆy[c¯xùå±oFl#ú2Ø›–Gé‚J£1µò9;ÀÉHFò0H(1éRøz:mvð|NÛzÞËuí̽þÞ|Œaåà<ºW¼^¾ØÉýîíùk¯ÏAÈËÅ{óÔ¹~¬?[ö¢ß&­ûÐB´T=Ö eè—p<Ýÿ†‰u7÷Ýóüí!ÛˆþRøÍ9<¢­èpüšÙpbX#ÉH¬eË»° P-3&F•ëŒw¾vá¹[÷ÂqkSš!šµ9Aëü`áòùû޼ ß¾ô.MŽÐÞ3ë`­ëÏÒ BC¬÷ùþxG…ˆr;¤õ6ÙˆVö¦¥ûS`ú<33óEæMè¨,ëö2~šÕ”ß¶So]hq$³áÕE22cÇwp3>¶˜ÒóVÿ¸21ÔGû°R}@ zÔ‰.]iR6ݲOë±VÄÛñáÖ{0\¥l=ï`uþðòü«1Àzîúî^ô=°:{áÎÜ»Åß¹~÷R {Ï÷cZÃ{ÿY¶‹ï¿K6Ÿ9VÒzáë×owÆC8G«ÓgÑ ôx˜ù™ %£ÛÛð‹çÛÆLdºe=np]&uÝØ6ï¶·c¾ðíA¾¬ýöÝ_h{4~¾ÕhèÔnQlév.ÚjŠ4ÝgFÀòõÚ‡’n_Ù%Ì@ Œm)g'h¬×O3ëztÍê©`å:cdõYBÇ[Ëú2¸ŒI”™£óÒ|˜Û1aþ¦¸s÷ÒsЩû•‹b k¼øÖå‹á‰[;/œ·í@[Z}'ÍÿYÞËíè.a,ÖßáXI뜶 é¸V§Á ´m:+ÀB³“<ÐÞñÖ¶±h»(èÆæÀÓôè…00)=XEèæ¶å®uZfÄÁl,ÚþøÈˆµ€PkK£Ö”GMŸ¢iØ&hé,VZVT`ù‰r>ª(»„êú0å#kFƒžö y2¥Ó/D7’ÆlVûö/¤–þüü‰†<èþ#àKÂÞøÿ2VÜ%Ë/¡–=­ƒµÊxvÿBY.žˆn«ýHÓb—GÂW´èGø ¤°ûHö[$Ã3n6·©IÚC WÛøð|ëH³Õl6‰3Ñ“RgªšÀU£¡ªøUÜ­ÁLN·î-®w%Dš¸•ŠaVŒ«tVš ìVøg”ê ÀòýàVXqZ•мeizÇX´ß:máN6—µõe5é§;Ï0;eÊ:3ÌBajÏ>ˆ”¶Èü’Ocý9v¿;VZo}÷.¯tÖ.Qx×JG†€%Ÿu«ÕÄ dl|ÝU6½ÁD¸Bµg, ³Ÿô&ÄLHVݸ>-Ͱ<åšÂPÛ¦7–¶~¾®ÔÙՄ㬬$RSN3YV=¸dXÍöd«y³‰Ï÷¦d[’‘Ü”—-poʰÚùüD» Œl[²'ÉÇ øô9ÌM w½ÆÍÇÛMäoͦ<Þ”šó&›ÜenÖ½EòBl‹d<[ÀŸé´´/`ùþþó¸xG¨‘=š>§_L*–Œš\Â9¶îzpÛ;{‚~)3Ú½í@@€£§Z–} d=,5Ò¤KÞ œVÎ[ ñÖ>eÅÝ—9%pÖçæ™ð}ÈüQù40ô.6`©Þ=§/ ¤s ’;jŠ`BQ³>˜X_‰Ga¥/’Ίa MÍÚ^$`MÍ̳3`ù1^“`ñX“ѯºaoÃT1ã& | 5øDÀ¢D`F²Œ#ºs×VP¹?Í£Wxlž<7®ì”˜ €|îj¢+F«¸U>¬€•Û9û•Î9غåÒ¥ð‹.…¿ò"Ø[þ.¨¿ÜùƒyeÙy/²mCK@‹.¿6 Ç;d'šÝÁ¶ßÜ££í@ï’µé¹_Þù·ÊÚ3† Çwž Áª´t1~ë>è¾ð"è? ¶§eþÍ\œbeǰҥôèL­v¦ÔˆˆÕ SØûO±H®H¦†G3Ûfø_@’ôÙ1V´G€õ¥¹Ëá—ç^;Þï< ´kóp…{:ÜŸ'ÛÐÿÓß.†°$9zuüWPÈN4YuF?‘¶ßœèúâé»2®]¶ö̦Ç;ÏÝëÎß¹ c¼q»~Ñå¹/‡—ç^’i»sö6Bè°Ë߯gTY|ßêJ˜•jO÷ 8ÖÂÕ!µï~¹ZÓ÷¨tŽÒÉê¥÷¡¬ý+éƒH“šY{œ€õH˜»«&ÜÊíDð‡¶œsáº_×–÷®ǵmh´ÞÜ9±aµiéŽ~"m¿™C³hò7v6`¶,LK]/_"ëÎ2Æù7±K¸·““W'nß—úÉötrjCv€õ$0§/~>ö¬ 7Ê÷þ~XC—àè*†-ÇX½…§*ØGhöùþýîÉ »ôƒ!ìi t~7²uRÛž4[•ÆÝäõ¼Û&uÚT¯ÑŽ£#ÉHÖHF2’‡FF€5’‘Œä¡‘`d$#é’Ýh—>ÖYŽbã9]F€5’‘Œ¤Kl»Í$?‚ƒà÷m›ÐQÔw‰tô­±W-D‹Y“NÊý|k$#ù€ ÙYÞÛSö™£P…Þ‹,ËÌÊ*4싆÷”gÚKyì>û‚Í)¤Þ 9ê̽R,»Y“Ž´õhÐxß²! žÁ×]˜Vz?²|ÅeX#ÉRÈβ„ ö™£â8Øu~u>*þ º=>"]Ææ¿î8Ÿê‘0wy>÷Æ£gçîAfô‹K¥E ÐÍ¿F!£;¼ì9?›‹n`,oIUßË¡ýç±â!$h¼]<ñò¯”%¢×ÆQ?§¥;Õ#ÀÉH>2ÿ:7æB˜þ"L<;ÌÁ†3,‡¾übÍp}›ÜqÆúXcþ6,™Ñ~ß £ó,@Ï݃ÏéQg<ŠÐšsxñrøM˜Û.u¾ Ö£¿‰»c/‡—rñkatñu°ðL–Ÿ-ý÷ºS=¬‘Œä);`gÖ‚}æZ>‹Ëß.vŠ×iMa„˓ώ`ñ‚i0µŠ~ï¹T8Ÿ ï\zîÂÜÝ·‹ïotæ?û(ÚŠÎq,¸îP^ÒªÁ9ZT½·{bÜæ:»ÑXxÉòó¸–.ÖHFòA”Ýâׯß~Ö½?º|á7Ñús÷F€ÕÍ¡,eÑögxg—lC³ßh—­F¿‚è¹C¾£ìHï…¹ûÆÒ°ævÂ-ÞC ÏE²üÜA›Ð`d$#ÑrâÆÛÏÁ »hŸ™ì0£EèÝWÆ_¾ê.¡±Ï,ámw¬3¾C–¢CË~3Z€ ä=cGZú¸­9_¼ýïóÚ†.ᥠøÒíbµÑÂ3Y~&ýœ–.ÖHFò”Wçæ_ûÊ{ö™É3-5îŒu¢H ºÛV¡Ñs1güJ_0ž~;úÑs/aÈ=&=¼ŠÖœaó_Dlÿù–ZÐüVqþÇ: õ6Zx&¿¶þnÖHFò”(ºÇë‹É>3N8 õÌ‘==AÙgÞe«Ï¡òˤÑ×nˆs$hªÖ=mÑ™cái ‘ï‡ákÅl<Ó}í3ì±öyX#ÉHŒ|ôÄcÅ¿T3F4Æ€å¬ÖQ\·^_]u]øÝ\†ëýüìí¹.„²ý£2w G“åeüËx{Ç¡²vê]סr‡"„øt¼ôG)HwSg±2ïJ1ºHíYå'»¥×ú«Û¿Ýáã)·ü§þuçßä½û¼¯þñ$ÃÇý¥å¿ßýÕ)?¥˜H†uï a°¨Ý¸›p\]­/릱Yß_ Þ®Ú•µÔY×ÐA6cÀ~ª»Šp˜å£%cA½=â¶(†ƒ¦ÇíS^îpʲþÁ¬ÃVâ± °¸Þ>Àrb€¥vu_Ø×ºsÀ~{3éÇrVÀÉ>†XÇ  G€¥%#kάååÞg?qêqzº67éløoÚelä«h„¢ÂްXNÝ`Õ‡,°¨Œ ¤¦O=ˆvæ3ߥAI°VK¥••R©\"b5(àÈÖ¶Y*K)mÂoIª(mº ©´2üíÐÃ~h»„œ~<À+cÖN%Õ¶™ùËÿx>IsÑ]B|¥ÚÄúúD>_+ag®óª¤72$ߪ•J“ÕªÔ±1YúLy=Ÿ_/¯O"Cªd4-^^ËÏlHLS(Cªx.®ìX"ñ‡2¤K&•‚Àn‡¼´ã¦K;ìÁ¸÷ö' 0 €^'MŸÓƒcçEe©žâ€îÆï «&Üî°à&ttbºtî‘(Aõñƒ/e‚3–ôLÏÆqÙFò°ÖîØÜY²~¿øßÌ¿k£ÉNsñ¯‡X«ÈŒ*Õ†Dœj¾ŒÕcÀr°ÜòFÕóÕêLÎVÖágíXËÓâ¢e§^C—9°„nBUYgXˆ…€… #@ÀÂFhš~¼=ªæIsD=”°hðЊ³I6!'Ž{·i¨®î(©Ç®ñ’qþz*´G—Æ*Á–ˆE$Ý”PHgQ8úÙ™ÄÔ-$TîìÛ~E¨‚Jz†£È2`…s;h-z.œ¿ö6Ø{†s¤[÷rá°ú„ °€!M¬Wggóë5€…Uv ÝrÕV¡g¥|uc£Z-e÷Dû?ìÅÅ+½Kᖬ‥j­èÑ3L¿ãrÃqù…ÏB½æ>êf⪄Þ\Ñc Ì,ÑÙ(X$ÈàL­‹àù #ã•àDò)°ÂcA7‰qi"Ãt WòèÒºè1pVåà0ô”Sá0 ¹º,…(—Ü1‚Ó-byˆ½®ðÜu°äÉ™aÉ.!Ùfï½gm§9>Ã*IÀÙ˜¨þÂlu}mrº*‹뀅]BdXÕÓÕ™Š<[Ÿ<-¹ÚqÖB¬KÀ$4`]]Œ9¿ýº„¢®0«Þ£c‘eú¬°q*†…çV—¤NÍÄ0‰PÂÑ/~Ñ«³Ç€å¨ÌdÙ%$€•é „(P1:š¨ò=:2`N‚o9ÂäÝU`âòyJÇ1OÇÁ ¤ŸB9ަEÉðø‘CS9†?5¯Jð‹ÂU/N?äp°\çƒ X»0†Eë _»ÆöžÙ°üð«\^[v´±V®@—pyyðqE¬üZ¹ü‰¬Ókµ3gÖäY¥²ñÄñÖq'þY\’½?gXšdñ¡×—C5†%„£IÍÐÓ_ç¶€­Ât ë O8‚c$ƒqî¸ÄÇ»ºÐð&Ä¥‘‡…ú^áÈQ-_¨1"{øMX m<8qÀ2úIv)_u °„zj¬™tÙ€U×]o \IwXÔÙ6}ĺbXˆ°ô¼2¬—Dã·°ÆC°÷üÞÙÀÊ~?wͰ6&J¥ Ù•«=^Y“çõƒ| ‘õ¶Daê%¸*­IÀ*Õ&Ö*µcì" -˜.a^¡éö,G1 †:è®» qÀrtó‰–Ã\ƒÝ­Fšú€ÌL?d; ˜1,`zR˜`'M‘D2ÇN1È‚­ùR™æ@OXã©]ÊÄ™“tŽ{ÖîÉÙäŽ×ïÄVe°_'M¥}×pP½†³w‰è¤¦}oÍÃzP¢»„ù©|~úôÔÔéB¡0“?Uþ4,xqëûNl€Áy?1G™ž:-ϦáJª:=qŠfb¹ªjí/4zŸRWËð! ×r‰Ì&ŽŒ™‰£ÃŸ©OËÍUÓ8'ŽÂœ½ø"¬eµ6ëØ¥»UMZàkÕ3ô»œ¶°lÙrh–âàévV4<€µZªU-ÙXC˜Yu÷( °báI µ š:êl©jzuX®§~µT3Ý‘0õY€3Øâ,õB=Àr `=¤3ÝWéåfÉò±,{O“Þ€õ|ßQzG€õ^X8q´ÌRÒ¹г··¼©£s¶²ÒݵB®º­íF ¦¡kÝ]Mú¶*b¯ô$?€20gƒÖñïÖP‡ÕQ˦´íf§Î½2Ó`)½ËæÏäàAVR\&èR¦uÿìúÕ]ß]}Ÿ¶2V:—G]ÂDm/ÓãA ¶8'¶xÚµ÷iØ\Ö ”»¦íáÑÝ¢ª± Sçcži!5_ö¬«õ °Žu™Ü€ux¾çÀ´Ô!$šô*V²üÞ,ÕKpz-,ß°; +¸§ÛHö•ÑŽ£#ÉHÖHF2’‡F2,_Jø>ýò‰t¬ÓÀöß-ò$uõø8†uåÈAv_„üÁ~©ÌP ý¾Š(ëx¥"z@™'z8z‘’AÊê8žãÑäAcÁC!Y–lÞÛÛÐÈ ú…³€š=üøÁ6T+òµ½0I?ÒŽFHBƶqŒëŽ >ìÓJúWB™ÜmL…†! 68*B”­-pÙÚâ2È"K{–éö²g"ñZpÙðyøÿèùÎ,˱\kÉ ° &[ÛÛô¼€Ï48Ñã¡ç³ÝõШxx{+°ë®ïºŠô¨š°–ìŸ$Ñž¤K‹û‰¬ôª•­hÀò(,K5/Ï:lmÙ©ñ$jìß °le¥<X½om©T§ŠgŸzi÷¼¤ éSZá7CWb¬çéÑ5UBOØÔÐ# 1gztqô:A©Â—ãƒÆ‚‡B2cXM”mùËhã-j6Q?ÀoÞ”OØo6|«ªom«öH€¡ÎoQn²G¬Y½Þ¥X†¾)Ï‚æãRßãíÖMé"ïõ©ði¿ø~Xfñó•…%µiÃÒ"ïÙа‚@H­ò/2™b؈E"“J-F ›¼¤sj"òÒ‹÷ÀÀ?ºÛŽ=´ûù“y±9Õ>§3ÁjT ˜bF¾bˆåi_ÚÁ·áÈ×éÏÃ{ª<<õ„ÁP'|ƒ‚ €´f]‚ꎠüÐsH”¯í™Ž¾IáaeX“ì+/ÖD³U@¦u“— [mÉ”šx1Ñ ‚V{*ßn¶Ïœiû-ädìOù–Gàb^Ð<ÉZÀG#µAr—j±ÏÉ‹f³™…¥A¶HÆj Õу /|q €…Ð$¸aoS# –ØÕ]õfdžƒÐ šè§Ýç¸qg#BŸÒêóh#¦7 ’ä@hC²ãé! ÁPȬA噟¯$Pæyäǧ’ñ™ûÐÛEГbe…½z‹q°dHÄ8*VaJ™Á‹pPÅ(¸ÙÑÏ ú¹4G²¯dX- X³òäqÉ­&Ú'óyÉ©$£:Õj¶òéžoV» &K‚œ„®V~¶0#É™ rr¢-pŽ\¬•—Ž*‰cÖÕÅøfXK XWÄâÒ [$+ÀòU>ÀR"¼í€c&bÄmN@“B ˆˆ,ÁéÝO;ƒŒËGG4›9$‰ñý •¾à ˜!Gà ȃÇH—`4âPg‹ãü0ÄCZ„”œuÉ2ø £ôB\8T’ ›}*«F¡»„İä™ÇÝÕ˜U;áa›€ÙF¯±6ÓáTÜêðˆÕX~àëR²QÊW,‰ú"ð5h(ŸjÐ.Ì€|Î/q+ßÂ)ŠÁZ7s @–I2ŒñfËt6Ó—L¸•´P4”`^ Ì‘ƒ¬,_d£‰£IF€@—°Ùl~l$0MÁeA1¬y…€5Õ®µ-ÀšÀÿºÉ€u’øª»é}¿ö¬ÄÉWx@¾Ç »ìNÊüà»Y˜š™]ÅLÌ»JaX,2ü¾÷u£õüx³2¬"¡_6HÖ®Çy‚Œˆ–I§âY†B©¾gÉ|Ͱøó¥0˜qu–qôÛ= Â:b?‹N }‹Ü5%H#ƒº|Œ»ÓÅmº™Ö‹ÑL÷Á$Ë1,øÚÇ4 Ðiª0Ëçøƒ#øi›á;³†X¾MµuhÐ%ïƒ_óš’<«`yu ‘a]µº„‹Wu÷ïªÂ­…}¾à ¶™‘˜šïY_Ö3”†D,¹Šàñâsü‹)€áfº2]BÍhH¤ÏWh4ÔŒtò(EY42š.ÁqÞÄÌ uhÚªœˆØµö Çšô1îˌ ŽÍÙTÑ7KúÂŠäˆ (&Ž®>nèäO˜¦||U¨ì'éYÔŠ¬ê7¬$;ÀŠIíL{ ©¥»öÝJmð[ÛòiÃ~Ìš–hÖÎ]â X8taÀ‰î‹zg¢]gW 0ÃZMí´'*yAª{rªfß$bÎLõ͇‹A´¤ècáyX="÷Ì\OÏžV›…‚Üíø}š:–R&|#M£×å„#Y[±”a¹lõL”>‡y]e›ÅRPLÓ¤G€5ˆd6­a2oÉT¡0•?´ô =ÙLàÛj kIoÐ@µdÍaÕ¾Eëd€›˜¶wÔŠÙ[¶·ôLwOOJ´‹¤ƒ—p÷Rýl1`±?ËÏÑ ¡“3è½ oöÒ®bŽfŽ?!ÍRÂq¿[™Æ«†Ž91iÞ£ü+Z[ÂãõÄÛxZ®)ËÕ X£.á`’`mãôÏáJӺפñ×´KhÉ’=HÅœKÁ×B?ĺB€åÁ2¡FüÍÍÚÙ¤¨ô§LOõë%Îh8qíÙåÁfX˜­ÚJd/±î÷È¥}Ñ/Á^,Kžšño‚˜gèY¤U¯ÿ‰ÅçÅŽ^‡øÎ päÿAcÁC!ÙíÖàé…jµˆ½zš¡­¦ðÅfU©ÎÆ_#öNõÍ*_ßþ']ù]€”\‚Ã@µd/†^Xê¿Oòw ½ÀZö¢“ègýº‚š«èYÙ±…(é&N)zê÷­.¡…‡K¯©ô¦Â‹Yog-yIë¥Ås`áˆgû·–(ÖÊ;¼:œ°Š¸e–àpâTÕ âð¤&´RP—|{+žëõåµFXüAcÁC!î‡eæÇ$0Nê$°ï*ñâØpñ—?ˆ`—pÿÑ©Á„÷÷êÎR0PZ#{{¶î´ƒäY0x’ºö­Ê(#Z¯•–ÀO©ý²“ôßu‡æÐ]å’–‰Á3ƺƒýÂv=— yš• ju‚Û6–e Ø¿`ÿõzo`À"Ðà°H¯JgüyðWÁ¤ƒ«èÃ\s °à‹¨P_]„ !‘Ñ<¦IÈ Rh–ÓãÙ rÄ2qÍk¡Î¯úB̯*.cÎ'¨ ³¬Q—p ɰ>^ž,L—KµÓpÜÈç7JŸ¨Íœ)Tð1S]ß83[6V+•§gg Óë•ÊÚÄÄúºô ÇIÉ«JXUt™^¶ÿCï XÖfX’a ²E²lÍа%@P­`«„Î5—^øðƒüš§–-ðwQ  DAtn~B)ÊB°K¨tþA ÏvuÔ €¸>ªôº žÐ»°\L@q4!´2þÜÇAÏ ‚쌳«c(20Gyª„5Ò «Ð,m”IÎgF2¬A$CÀÂ.áÊzõf+n>Y¨”§Âäù§ •:BÚLõô/H÷éjõ‰r¥ðÉOž©V'6jÒ[o¢:³QÖ€7&Ö>Þw¨'Cè.áÕý¶H^d‹dntÂÑU=»ŠÙz,€àA’.V9ò‹#Çë$ZN]7>i§ÀN6¼@é­k²[=³ƒHaû!h`¼‚1#Á8Gð¤Â£.‡ÀAÝuêñèè’K8*nå­nérTG~—9ZLj£À‘Ã:Â<}Ç.î:³Á`³dXÓÐ…Û,m$‡*?Q­NIH:3‹€U.×,ø÷$¹—ÊOJZ_&µÇi8ªe‹aIÈ*¦&*Ša¹ýöb|ÇÑ%«Û"yq-’:¨a+RÃ:»ú™L¿»Ê ‹þãº!Üöt+Uí¶N¾ Ûè,iÃ`X¤á’À!—ºP®Ð¤†Ç¬…Q\’‚óµh¦‹V~] =ê‚BV(/ÖeæÓÅ]n* *Aèdâµ£® ™Å5”aϱ»„®3¬ã–ÌÝ7&pœ¹U« ©\0´1-ùÒéêD©2#ÝKà>AÇJÏe¨ij—nkÒeCê¨JäÛ€µß|!wð-’1óÅK¬ª×í±8ýi€e3,Lظ°ÛƒÄ©s49è,Üü2%ŒºK¨‡«®@ÆÕ)B7ÃX)§ÂQ÷e›=¸x±NGи¸;IÀNJ€å˜»<Ìï¸qÀrpŽ¾à¯¬Ó±Œó£«Î|Œ8Hé¡TŽë˜%+ÀZY?U’q¹œ/Ìž.—7fÏ*¥Ú3ùòÊz¾/;ÒÇd¥2¹Q;µRªMK—•SÕÚ©O—N­K¸šX«H÷òF~­äÖO¬çó•µüt¾VY›†…•z³ÿÃ^¤¡ô…Ô¯„lHõ Ú%ìû•pÁt ]Gĺ Cý•°n¿Ø]-}—9;è!Ñ·›GÀ"â#9Mư†•Ô@u].94 T7tÕdL09úº.\åÁu´7hëÕ9<ԥǪ¨Tܘ75¶žl©9ÓÔ¥c „Q*¹¤õÃLª…~?h,x($;ÀZ¯ÀD¬5xZ[{¢ú©Ùõʺ$Ik•up)—+5 Mëx—J­V…óõÊú‚ß©5˜ÍU©¡yÀ{ë+8γ?`¡,-Ñ>3 I¢/€<«çWB˜°[š£C8¨ça¥ÄdO¢ø:QŽºÒ“{3¬žóÆ &Õzæxr%§,9¯ÝQ3øã>]ÎÏ'?¼бóÐsš¨Ò¸‘ç4j¯èIQšâDë\3*Áú°&™u óOâ6ÆO€µ‰'¦ …ÙÂtþÉBaæt^^NË[ÓÓùü“ÓSòH.ÓOâ¹üÃ+üF%pùÓRÅÄþ3²`áQ‚¤ÄÑäB}»„É:]&fá´†D+‰ÅÙ nœXºz%ÆšœÌ3€zSW ¥9˜lõ’ž.Lqœ4oñ‰[†Z:vÉvÏM&cèÓÜë£.á`’ÝÄÑ*ʆ>Äd£Ûɾ›Ä û óPÝž[ÖBHÑù~@Õ°’Íe8•Õ¦&ýšˆ3 ›-fFº3X€EaZzzLOA£Þ‰éœ´½U$½ B2SÀö8Ъ>¬Á$+ÀZÅ¥9(%sª\Êi¢üÅýw‡.—hûœ4™ X¸5‡Õ¥ëÕÕKºôò+ó³| º–Ee¦úa-¡yPKsÞW2š8zÉlñ3—=¯WN‹Ú ·FrW»ÌmvÕÝeWß¡ÛÖªÂîâÀÊjä½½Íã¬ØZÂ!½ÌaZêô©T>@2Ú­á 2Úqt$#ÉC##ÀÉHFòÐHÆVsbFH‚n·L‚n—¸Û¾:2Ü"ùêb—‘™áËТdRYª?ò ±à¡Œ‹­×ÚfÆeámm£Î:òÚ½%Ÿ eæ×ÝкR,•[FݰØìj‘xeÆjQp,¦NGVÔ%ÛÛ–!ÕÌ„Uæz?xB%‰­çAcÁC!Y1,ÏjÚÆÄ»Ä îí7l3éê ¨se­ÚÓíF7l}fÏ×–Ÿ¹Ð[–ÙêáL¹F„n›,™Tj'Zƒ—˜hÝ>\bô¦‘°éŽÔóOÀ¾=ÈË$åXJd eñ¬›ÈÉàØM¬Ôö˜R’IЖ‚(š@Úk‹äA¶—ÁfÕÑóñGÖÎ-«EvÅÔkì\ÉVMÚˆ§a ¨­x c8%wÏ·!¡E¨Ðü(?ÄO–^>“`ÐP0K¨à%¾ûDI D1¦øzÔ³û–ŒyVy„ûMø”~ŒkVXÁ%!4Ӓг%Y<9SŒžá‚ ±TĪdÉŸ8•f@ža‰=c*éè+=G~þ#ÀT²¬V;ß’ÍV~¦=Ù–èÔ>%/%8m7üV^bR ˜Wþ¤[³=ùxo7ñØ`ÀjËðt(Lµ¤¯SmÒâX i[$_Ñ»¸+ÀZd‹dX\-¡Qn©†7DÀR"ú_ñl®_횈Øv´»Å:z–Gà°°ˆÕ º  nו ¯È •'åEée@$?Ÿ€ß€©M`=”¼mó=„Œ@øô¯M©1¸ ®’zd_ð@·DÉúèL¬B)BŠd½kÀ èF€u\’1`µ$8Áq²=ÕΕv„€}?Ùkiµ ùÉ›à³=S«Í´ZòXhÉÊ}Å),IÔ€UI×ÖD[‚ŸÒ‚ÒëËŸj5G ­œ%üS[$/-˜n¢·R]BuÍ]BjPX™}¡ÇÚ†"6‚½Àׂ8 7EO'‰Ù6nABwÎŒ¨i ª‹Ëmúˆ]Bó•Ð×]Wó_ƒŒ: EcUØ%$>6U«µ Žš’”aÈB޵Ybk¬Åj&=šu — `]I7œÓ ëÊžÖ€•Ÿº6<ú¢†3ü¤£U†(4RouõR×­ÔÓM†þÕxãgXŠñdÓÎx KÓ+ß,E™ø³à¡Â,öIpà›”i`±Ø¥áY:“ ÅC©'P'Oø ÷44;ö"èÖÓ, ß~ ^vÉ¿ã(Ë ° 7F€5dX… Œ¤3PM!9š’AÙS”÷ž”—“xNä§PÀã,{z²P—³’ZÁÐåI©¥iïzغK¨¯º ©öýJ,bX ó*å–HÑ °¬AÝbMû"gÓÒìAÒR§Ëñš¬¿ýÖ÷Uh¥>b†X ]ºêk'ƒ‰Sæd›o¢¨5ð—D_}±°BøÕ‘¡ß袔Óã´JP½<»‹«¿Â&<ë2̦K8¬Á%;ÀÊHÎHÞ%…ŽZZÛ½F$W÷¼ ˵„ X±™Ì~âÛx¦Bé§ W:¶~ ƒìÅMj”ßsiÃaRÃöÑÇäP¯^×ૹ^Ý O~bP“bsËtøF`f¥§p;~n/S!í$ð7Gk ‹|o[>ìtÄžAZyÙ>McX‘̦5Læ3‘©BaªÛu²Ù°fXW®ÄF¤”Ðù ³ÞõL÷`m °‚ô™î½ðj›áÆnVjbdê×' °¬)–YˆS)íÆÞ5"~ÿމÏ(¼=…4=…Û‰«öM)…‰Æ&V]"ŽWFOoÀ‚£ùš/í£•ž)` .™-Íi¶†(Í}Z–g3¬4ÀZ8À*«‹6!Á†`ADöâSúý¹íoq%ÕdZœíÀÊt1‰Ç€eÊ¥‡Q;Íû”€ßí7Îl(1þÌúS3éeËríŽ!þ»¥}5ôÁ^ŽLnݰF 5Û¥9£A÷Á$3ÀŠ=N^Ø^%M&Þàq·I=:™ÙÐi⡬,¶¥Awšy£ãâ® NtäÅÏb A*©³äÄÓ•^Fi]Âl¤Ç È®dé'›šB? wÍôX•]=U—Š.Yzjó{ú »éñeXš#ÙW²[ü¬!(!Aâ7yžôž~/èsÏ÷õZÂl6IîµÍSŸø*±(c³¿3מ¡nÖks -½Ó`î šÎcÎσƂ‡BF;ŽŽd$#yhdX#ÉHɰ\w-嘿ÕUe‡­‚¸«|½¹i¬…À9ù]ÖvjÀÒ/êàëåemí^õkt`ÜOk°ó²)hògâÏæòW¯¯*»6«ø3¯Ì¹)`ø þºïuë—¥»··JåDe–”ƒ¥×º‡Vs’é²-'%­¹‰|™Xzå'&fmF=“xÝÓz¨ÖAµ[ÆÚçÀsÔeâö§®©Ô¨Žštš´ýù[ux$ûJF€µZWÌx+{_Tu7Yi—Šê‹6Ý畃mÆ+nh *ͪ0­eÕ¬%ùßþ(HÛ&«¹ òÞ~)ƒÍ-gƒÊšzêm—0Ýú§Óã~jRݤ9®ìLÕ+U©º÷1VÚÓ2ü%‘pwö÷ÒG“æ7âšæ%ãj1¬A$S»„N]Y„¿çÕí²R¨ÐÈAî´iì›Ëh‹\6A Œ/ÉçU5rØI‹,˜Šµ° Q ‘Jíׇ“Э·ñÔ$` !eSYãñX $%n'Öä÷O§m¡9ˬ0`%à '¬êC줯%øü9)jÏ]jâ@غ]ñœ.]ÙȰ‘¬º„²ÀŸ'0²Œ`ò¼‚!ýTUoÁ@¦bìö|,ÀóÏ[¾úÙµº„qú´Äß ¦$h-©“ý+¥¦O°œzZ“ÜàP e˜–ŸÓRÑTÚ×Ågt¶÷ý8–;Iñ"ºSOÕ™æ/tYVŒ` "™aÕW?QZYY©#æ,/+–”x&0€¶èK›‰×ÝrŠ­eì®–JŸq­±ð.ÝV“[¡•ž×®Ài)ŽcVqÀr†U*ýP‰H\¤tMœ¾é´+ÓüH½q}=µ§ñUõè{uoÓ]bgNRMÿ¾_Ï2Lay1KU;ê>ɰ6Ýz©6±V^1£Su>±€ÏK5XlS+Ù0Ãìqtsh¨üOÖJ›ue’¾Ž(XªM–’{1¾ÖÕøâ竉ÅÏWö,‘øª ÃrdR (>yÉ玹´ü“û>¼ ‹Ã‹E‡B£O7rG¤/ÛŸcÊÕ¤Þ$Ì*8‘ñ8 º"öCµËAŠ•1¡ÓÀŒKU&ÝQàñ1Ä€èöì¹[Ï´fŒkÉ °6W*ùj~½¼ò™•’dZðW.}be娔åUY7KÀ«$ØT Õj5_^)WJŸ/¡oy|êßÒ¦t“XÊWËòi¢ËægäÏæfi½:]N>ìÅÅ´G»¶H^h‹d¬§ÔÀ¶ñìêe¯ÊŠ1¹ÜRœº¹£›˜N†C­Ûq1iŽiœéÀ"X¯È “úzM‹¿I¿‰tiØü1Ç€š) €JæÏõ`&ÆÑ”΄Q"êÖk ÇI¹» $G€uÌ’Õ ûJym²:]]¼²¾‘__Ÿ˜X_ߘ8U©L¦Ë¥Ú4‘W-+À*Ojà¯RYŸ!6òù ./a/j½ ~ËSO–ëËe, ýéòä hš9S¨ÔqÓ²MXD­¯¦o†ÅW¬ºÆ¬ã,—È¢BÈl>D—!puƒBìX¤.ÞÜ& Xôe‰1 °ÀR ¦ÂÑ9®p]vÀ¸®ö£–œ%ÐÌSh¯ŽA~²…#òMX„&@=‡2îhꤡÓ1¢ÞLB1[û¨V¦Ç–pG€uÌ’`­OlT«…ÚÚäÆLu#_­ÊËéõµZõ“³ 9Ÿ,TÊÓSȰ¦|*³ŸªJùÚDµ:¹!Qìôú¤„2yR«¿•BUÂR9¿¡òÈÊÖ¾z`-um‘¬ëªÞ"™:‡BìXT×űt °tËRotûR!‚;ÔhL³½:{XŽÖ•}—ðÀì dŠ˜6"­òÄÛ€-š»àµ+\òÃPÆ€ÅààÚ¥Áç/77ªqbÈ,âÿµ»éuš1´Ú<aáÖ2¦Ë/˜ìêÀHö•¬«´1uºpfvM‚‰DœBaj¢VÍW*Ò ¦zZÂÏ™Y¬Ókн+(­­­•ת³gfŸ¨Tò2ðÌ“µÚ q0àVå' `•PœO—c£ôØ%\0{#Ãàz—œ®-’÷ÃbÒÒ²¬¬Ø0Ý`9‰VVW0 úJÐX5ê;=aUw UÈ,V/‹pd˜®èá*Sž˜v—o:êÚåÜ ‘X‚;éqJÄÏ–¶®Ÿc[°œØµq÷µ/r°V}XÇ-™VõIÉŽN8œH–´QÍ—ÊOT?UЀõ©*vî6ò8`^’Äj¢RÁcùñÜ­TäEMò­u h%é£ «ºVZ)£‹½®ñô¬}Ì´ß5îFßϸW¤·Ö:ôÉa½¬Áå™÷êåâ¯'ç½k2ù´Á‘7ØÙª£e}zjd÷tïêyqÇQzÖú¾cÐÍéÎŽ ·Gzð*°ã¨„æuîõcÔ9rçhW)ÇC‚aw÷´ªw,NlÇNÿ%¥X|­ýqiÑè"â!áÉ´ŠÀê£`UÂÁWè^u=úz onn¾}»\µ®?Ç·ãn蟯¿Òw¯¯ßn´Ëçoà>Ò{oÆ$}à×Ñèó}bãÑhtóÖ?ßë«ù£³ïˆVêÍ>iëŠNÓÓ_K¶Cü"r¾N¤24'Ëü‚Ò1¶¥³÷Ñ¡9á/:Žšnå­ ­G¿Î¯É‰­äÄvÛXnù–N Ø Â±ššX} Xkm‘}ô¢ÿ­^ƒÉ]§—öõ½ø¼ ÿ—Õrþè”\ÛÓ}"@š¢ø;ïSraãjÚXíVË™˜•ñ)á©Ý]Ú •ÓVXzÞ¡9|âfr%­[Y‰s|Òá«lÒ8ORÛv=Õ¢’´ ðKüÚщ=Ý?@¡†æüÄ.ŸoѬÓñX³Ù£#XÀn \%Ô¢ÑÎôцÉ!6õ8ÕshÎy³¨—Y›§kž­Ó:1óÇfN¸«àpýÊQïÑ1Œ…¤AÝäTz'-†Y¤j‹#1ë³s|b8E`õQ¸±„¶ý¥6†ðÁæM/k›Á7ìK¾Ÿ•¤Í‘…”…LøIÆyöÁ–£û»÷|.Ù|:á|uÀffm­þõÔ)žžÙÂrîêbÝ}Xrbçõ³†:±Ô3ª®c¬þvÅ/ŽFEE]Œ"°¢¢¢.FXQQQ£¬¨¨¨‹QVTTÔÅ(+**êbu1ŠÀŠŠŠºE`EEE]Œ"°¢¢¢.FXQQQ£¬¨¨¨‹QVTTÔÅ(+**êbÄÀ*´*TñzUtü‡ªöy™÷ ®çiñöøŸ/ìêL¡Ÿ+ÜÿT}4 .BXUµAUop(âo9þ}Ê«" °à‹ïúzªÝn³ý­ñ× ½zqè¡CÅXŸ;uþSÕO°@Û-$-a«W6wómN‰/aé¥.ú»7aðUw[€å}y2q>/ªÓ‰ã¥C}\F7_<°pN¿³Å_§=6ðt…MM>o^°G ã“[OGG`‰?'Ì÷^„›¬;q“ø÷{€å6>9nlmÜ(¶¹It±ñö|™kÒ?'QÜ+ÅGr.ñ‚PñŒ¹NaҖΚ·ÄVbð ÕK,N³b¯×Šý~G‰ØXú˜Ã~¯Þò€µ­^ßÁÝ­ »Q.ÑçÛ šì·{~ÒµÓy² ̹û|×ÀÂb”os´¹Ü½Û Ýû8 B…rËLÞV‚Xžò׃Oª‰FîDZ2×a#%Ðôá™»é›Ë…Ô.¦ð/”ÿn½ÍMå€Ür,Ïéá™ë”4i‰^ÉðÌý€ ŽO¾éná=PÂ(« °¶ ©âpØk^•å~ÈÚõzBî J¸?”Z‡¢Ð5¹ œ ÂÁ,±å§ðv»=K5k[µU §„ºw¶¶a¹£‰EvÍùkºTiËéŽ pRZ5uS¶ ¹yȰïv\Ièµ¹`±Æ3KÜ1ÎŒxÓ h½¦œ;Mˆ9‰¼¹ÞÜàÏ^kSC$—­¼`pÚ[fL!G9’öÊÑ=§k¨$Ñó‚2Bd,*“$CfŒ¬>2UÂ_`íË+M›r08ìv»¾ MÀ*‡ƒÁ§rÿëK©Ã8”_öÿ»? ‡‡½›eÏ ¬{E“¦âŒ—wuo&R½ŸLeÒúé]Ÿ‰Tu”•ޏÒÙç&!EG• ƒÂ‚£7+Œ(‡M.t„®ýæ(ôÕzQQp:l<,T¬ ާd®ªÂ–‘’ª.ÇVâaH¦TSÚ“ìÂèý9ÞSMT|Jej¾z?KÙÚ›ƒ:¹ž‚t·i[Î —‡Ö­àNNúÂÆ0HjF” -$½ë?ƒrp \Ô/…k îŸÊr¤W?4ÂÊÃ`iUV±°ì<ôÆ’ùo&®×5ÆSÕc–„ì˜CùP&ׇU˰è+.0¬‚ ¡},&ül§¥"üàQäÜ" öWt]®âÍ ,(x*c¡Td¢:oŸé6ÒX¤¬½BÐREeìÁ Ø7"8²§¹Ð‘¤èNÉR‹)«<Ø 0‘ý93NÒ”sV€™WèÂÉ”R’ü*\NˆÀê#,m! ËòövPŽ4rÊ}Aï'í,]áƒ|{ `úÏB€5mi•¬©,°«X÷ênz¼ò€%Ïíß,.ÒüÀg‹žëüü‡"¥äé^T ,äÇ·£(u£¨Ø…ÂFUwÁ(] ÇAѵOŒ:#¦"#†\ªš”ŠiTPøœ8’"gJ,%4QD–yêHìÐ “Xñï4A¯R| ;J_ñ­(íÃ$`ƈÀê# ,0‹4l€WëÛÚ²ŠªêS…c`Ý 4ñö¬¯å`=Ft]oìé<•A5ºO°.¨YEUB(åšWâðƒ«‰“¶¦-X…<³UXÓ¿#³`)kaAU -WÉ%[=R\\±,·=ñ¹û_AäýÅÌKj¦N¶ÊhˆRNEŸ¯®Ï\àU!Ç;GVvÝuÁÿ¹ëŽ­] ¬ªpª*²)+/ÜœÝM ‚ÁU¦)hNŸÊ^9íµÉ-±™¢NJ€¥-$D̮оßX=Z€î¿ ¼ï·å~Íð¿XÔ­Al'ûGÕ€ehqX…â¬î4jœG…TÚl±²–iÁ1PºWó¨$+±š‹…Å¡¶°ªBL<å`‡âXCsŵ9×§X<•l‹¡ƒîd ?|<„ÏQ)BIEÀÊí±Ò¨jÀª*Û†E)]9îX‰åƒ1Ö¶±P¶^H„f‚fÁEˆUY`•®VÕé !$®î÷û Âtղ܃Á6ðª„çê‰)G»€å0KV;gYêXü@=k³;÷rv‘âµa1°T X¦ÈP9û¦õ¦ ‹C¨ñ—«„bû;ÉZŠJÚÓíǧ¢˜†rÊBµ,¾ ¯KÊXXαEe^›¸À¢tTå¤ ˜X¹m°±®ì9 'ƒK:—D`õ‘ca^tÅ€58 °ú¼)$`ðʃ•Jͽöt0/¯Î,h‹¥*áÎ÷lª„æ-áUÁAšãè»5(i!"ûFå}:i¾I,~ UH«µø` ry'X9Eš[³¸H¦q¹qyKÈÅ/”½ÈݸMÍÚM ׈â—•yÅV™6,iøRbQR Ø¥õe“檂«kÌ]øÍ»<ªðåØtç†E±‘––3ð•›·„‚"~KÈf õÌQ¬<«—,°|õ»—oó–ãݶÜÓýL¼Úìô“‘ûaÝßù½CMw+èN:ñ{“ÞkuU óí¶¥SåyFÎäÒÓÝô]ªÜ«8½.ó¢ÕG]~ÇQéNù¶Ž£î1¬F·P³•›þ¦Oô/•ANo)E{ì–š×–žmWkb]l—Vö/-^õ¡|ßa"]OÕ܆mïÀëS°KX}dݯކ_^Ña[5Ž÷CÚpÕòŒ­XÔÓ}z'šj8M¥›ûäŽFÜÔ:ºw ,, ,iuÃÁùy{ëÛžî0‚Ñé( Â8ƒ`rÇݬ¶ž¼ªœ±S!oš³Ù´…뜬ÛZ,ý˜G ãôç¯{Úxh±g¦c74¦fãö–/¨'UÁû[ƒG¹×Ó #†eàçWV™Ž£ûƒ«ý¾o¥ 6·ýrB: ±r¾Ù8g:eÁʽ´©Oɸšp#ûäX7÷)5ºç[gïœÆ ÁÆ’øó–µìšçÚn¤ßRe‹§ƒÒÎ$2„ÆáÚ[Ü´°ì(•÷ͦÝq«ÖRêMÄ‹zÌò; PðØ@g¤ ô’߸ƒ—4<Ù[tæÔ<þÕ!¾ZÁ¿‡åDº²kgŒåQkœ°ª¯U(UÝ¡×]ˆ ׉ ¡Ì=SU4®«kµuOËñ•,ºƒ9ªêh.­¤»~=تvxØüðÑ,¸Å/ŽFEE]Œ"°¢¢¢.F€•eišeYB?XxÈÒ$MÿÔë)l'è!KÒì Vñ—$´þþÁc*µûO usLCO^à*¡¯#s&öÜmç!ÿ.–ÃOœs% ¿²/©»Cò7ÃÖ®ú¹Ç%éûDg©‡K¿¤¶íGÅ%Kê~¹>ô`Ó!i„™dnlçÜì&Ç&pÿ(Ñ6®&I=lÚæ½:¬ÄMëÚõ ß4p~È>š¡°À’Ûg2¦¬p¼¢•:7[Ã*MÂÂès4e Î éÏ–ìA‡Õ€åwWF÷É”z8œhtg`É$’veÄH·$ÎI“.§ÄºwDÂL,IÀë€0Üf çN¬¶ôcàÔXÜ“÷ðžÈñ©—'ɧ›îÞub|X}X?é ï#OX‚ûäèè…C¬‡È–}€51œºŸ™,µTÄ•€ë°~_™K$³Ò_‰S[‘”ÔÝÛâ­ÓY_PÂÖC® %'TKÜÚâšÝ®çïOÚü¬ßº9ö#ªÒ°²°¤C(ÙPŽ5A€Mîüîï]G'÷ž…ÅËsU9t ,ÿÄ Ÿí»O<ðÑÂr¯&È šýÝ=ž±…Õ™jµäê2G'Ûº¤óC8O^ˆV…ÖÏÙ\k–e³™áO’>>þåÜÛŸ¸ïi6{|Ìçó§b5ôðó§Æø‡ßÃ)`™*áýÔŒ#ßwfs«ÇМfŽ<°Žÿѳ$=\Òîò^¿ PiK¨ß¡îv½^ ’4mÍĸ×8Õâ©ÇÊ/ê£Yp ¬Ùâ¬g³«õÌd¡ôqþÇ£½#³õ•Þ7{>ÏŸæ«ëùC®R°¿ÀÿЄ—uò"F÷„€å}"ùƒŸlXUêÿÎ$*,U²XºëMsnÙôŠ{ðÝÛÎ@Dþ"æ:\ ïzZR,©¥cm›.@5ö7Üq=1g ,¤2þùÞlLêéôîÊn+N7hƒÏÏ™x —3’haõQ(`ÍWãÕj5˜ÏG«¥¶ ghq-–ËG°½fOÚ®š?ëý)ø,çËÛÛ…¶ž´ýô8_,s0»`œ¡»ö9XÍõïyN.³ÇVh%ö-¡ýŒÌÝ]×'’ïN|^F «„ äH(0øçÜÄ`%X¨$tâTq‘H¸(¹åî<¸î]Ñ`‰?ÀX%¬…wÌæPÉñíz¼Ì~7|e’Ãñ¨¯ÒÎ Ó­ýÞ9¸Qî#‰ÇœÃÕ?¨r5¼ô‰ŽaÐOŠÀê£`k1þ>^/ÿX,_+mr­3°½ÀRÒ¬§ùËx¼Z¾|¿]ü ÷̯ooÇ×Ãåóây8X.ÁR[._Ð#`ép†Ë¥Þ7l½Ñ§å½OyÖTç[BEùßæés €• °Àв=Ë¡AŸHNåEª2PUª°ÄK@`aX_wE×bø˜È€ ¸Yª,ãUÜ žÐ;€‚­…i¢´%‡–M†V¨=‚ÈF>k’qâ½Ëh™œ?Qü`€Fvä_F)CÐ_ ¥•Êüäò€Å×0DT@`]~ã¿W_—ÏWš_7+²¹9‹Å ˆ†Ö ì¬Æ‹ù5"îöï¿¿¯^ë—¡ÞDoCíaÀz£ÇŽv}þ«õñm€5©W [?‘,ÕÄÉ)`Á¿DÊø™‰%V”„·…*ˆ±@å(sȤ2×JP]•=¨ºI!LÚÔ†%rJ}&´w©ìåð.ð :KÁñ]2é@ÀJ8&\så¼–’«TØS‹”¦.&&aNK)›YwJ¨DÒ¹q‹âc•F`ýn…«Ž êö ôy±@Ì Æ¬õóóhLÀJX€¬¯`Ýêý_5¤–Ï€µgX^Ãr Àš‹…¥GÃÅcpê¸ÙÈ%¬é)j[w+÷­ŸHîîÖ V‹5jl_sȵ°Ø€¿Rnå%•µ8R.OY*\;†Õ³ZXÈ´^4#X ²­$6j’Ôr 6ËȆÊlÕKÀÄœë¥ðe=5{3V"À2Çfܾf·•LÆ÷3cû/cBɶâxÅÐãäOàŽ8ÀJ"°~·Bu½ °±}¦Í¤áLcfvѪ„ÃÕú˳v¾=Ðè~­w~Óë‹ñ¯^æ30žfxÜbaŽ^Ï ¬gíò¢!¶ú¼Z½h`uµ½gý?‘<é3ÍW*`»D2ø¹Ô,׈0 *!žTZ]Ä8英ķaQxç̵°¨Êdš×2×bM L`¼`ï`®Š%$ðrª„~ÂÕðcaio‰€™H\RŠW"U@ög,Û4MÍÃÀkt—Î l °’ha}ˆëi¶üò7vöåeýåq†vÒ7]Íû2{\^]-—ÃÑx°^ùŸ4ÕÛ‹ÅÕ|­¯Çƒùã ´¿¿,5®†Ï í>_}~žéÇ×_Ëá`¸x\Ö‹çÑhøü˜¹ÙdHAÑ–·„<‘ꜗP;Mz+‘JF¸"ÞÿÔ¼%”öó–K¸rêŒì`†Ž¿ù³o k/ÅÞ)·JˆÁJ <·a¥Ô*E há+¯ÛRy¯¡TÖð8oå¨zlÉ0¸„šÅŒ±™ÚT±×(ödæ¹Ú—Ô^弎u¢Ç›ŠLGô¥ÈÒKÎñ–0«—Âk¹˜á{Á—õrñ ÀÒ6ÑúEch¹ÖZÁÖü,Öà¶¢åJÛPzçZ¯ÃQzkIGsXÚÂÁ}/ËÇŽ¾XÞМé”*†“œ©³<,–Ûõù|2ý°øL®5çt²cER§3cs¥®zÏÐý°ÛÓœ»idÞ¶cbàoʘ>¹;®GDÐ~3¾ïDØÖ~ZlÝÙ0R®èĦ-P!àŽ'Ŷ¯3XÛX}¬Ñ}ø?‰üùzôíëàz<¾Ö¿ñèÛõ`pýíÛ×ozãæÛè¼\_>»Á=Úñzpýu4"W}”þûY;ÃÀ Î-xÒ^‡³Öí~¾¿ŸL|$M ¬–ÌQ)ø„92 :?Ðçh\?õLämgYû;Bé)ÞŸGoÖÓ9€Et.ú}žï¬W¹3ë#˽–Q»|`eé?Xq,aÅ/ŽFEE]Œ"°¢¢¢.F€Å3«9ó‹¸Ûvþµ¶yFªÆô4âß½©î·æ°JøCfÍ©Úâx&5æµé{îZº¿:ôsÅú•²9äŸ.Nï3Äõ£Yp ,˜Pu·ó&¼Û9ØÙÁ<À»Ý¶prÒ¢¤­31%‡µ32>jç¨xÞg¬Sß=-ú¼ Dm³ÙnýéÓíÀ2©¶È¦Ì¶eòNšJôdèg‰wÑ2¡å[±=ëìÚaj&pš¬ÕG¡,¬’€¤²¥çÂek§Ô$Ø`*ÿa¸m |D5ÊXôùãwk À‚[`j©@åTôé4[3°™Ødi‡ÛWÌ<,À*Lª‡ËÆê-é³Ýê‡YAWÓïš\ ¼ûˆ&I½9« ÷/ÜgÌ¿[›ævQtQ9l~ˆÀê£`UÂ=ˆï?Ýb–̆¹‡IëqipæÝxðµE`A@°Àò2_;°ªà©")7uPœ Xž­Ò–½úw‹lÚðÀªB‹¦ÿX`U½u27¾MyV…ªî¥Öa÷Ñ¿Ûýá ï1, Xþ‚lFûŠ -3ÈJÆòBŸ{:†Žßl;² 9‹,Ûo´Ýz:¥û;©V¹˜%eóÞêu¢0Å‚‚ƒ×¹ÍMa‘‰ÛÝBV`õ)÷Z óÎ"Ä–+@5NcfãXX¹¸6! ûøÑ+Ä›n覲3ÕË„ó>Hœ+(êûx Ûñ]Êù®åôȤƇBpˆ1¶aÐÄô…„ÆÕ×…¡ð£4ç{!­±mñ|"°ú(°Êá`ð©Ü£©µ«ö¿ûÝŒ.m/Ê+ ²}yuØûòÓ¾B÷B3I“IÛQÚß/8ìWAVØþK¹×¿Ãþ€Áý/X:ùQ`UEóÉïɸ6Á?í4= ¬BÁ¯â×Ö¶R4ÃÉV¥£ŠÀÒç„¢›°ŽÅ0‡½¦í¯ÀòΔ*¤èv=ßU x¬XyeÃÈæ˜j9ÅÉKïP Ž+_[ex›«‚.¥ðöë+%8›u{Ox?\ü(}¶jR.°¤vÏñ«(꜂èN×£L¸úØ‚=ó!6†ïWV…ªî˶°>íÑÒâ坨\°~s¨ªC9”ûòû÷²8ÊCñ«Dí·ùÞ9â ³ÄáSy8 i/ìÛrÖkµpX»ŠÚ°Ú¿8úãGË'’OT V `…LIéŽ+'³â™,,ðSlã ¼ð9`@¤’{Aï_Uq:tE…û½1`U UÈ›3çM¯k­äær¹‰€×QP80MÂTñÍÅš¤¸«BÂG–`JHåj#ã:¸Jl(uÁ±OXn׆‰†ÖÄX­©¡×tzXÅæ<ú©k¡§§[wŠçÃÉ ]k†f6E[#í°·ÅK=þ‰êÆ!IûÜ }†'æoíDÇùÁ;´Í¶öl¹‡4lƈÀê£pSÕÃÄôÐBõó±VÿÀ}zW u:\¤.›™~>>žŸN±e åik•¬©­ûéŠmM}Ž™b`=œŸU(–-i»•’v”fÄÃÑx:À z=:¡üð:Co«ø ºª·ÆOc¯G·Ä ¦ÂCími˜GY»Óë'ÕG¡€5{ Ëùcšþ{þÇ¿)d>¡!5[ã¾ë›ò'¬¿hÐÚîdÊÇùr8¬gôè2 øNΨ·iÕnöÿ‰äþàçÍÁÏÇÛ°R¥Ï¯à/ÿÎ*¨&‰Ž*½aPxýz“ÏMޏéVŒÁ?¹¯ P£;ùÖaÃJÖ]Å~…„1{~¸ùªÕðrý%6]¹© È¥nP&ÝM"XG³®ÓACÛoö«:Ì(mi[G=‘”Á† E·AÉed¸©Ið~$|µ¼$gÈ}ˆÀê£PÀ𝯫—árö8^kni{‰¤m©d>X­^¾Ìaý­Ö‹9ìÓUö„Wšýµ®V«¡>^ïû™=ÎóÇ'²Úf`‘Aî8 ¬»ö/ŽºŸHžöúD2Ã,a`¨³ Û°$({>yb  ’ìT×{2ŒZb gWè@0£Ç<°Dïn›V5ûF¹;<ŽTÒr ò/5ÉT ÒÎ1QÕâðaÄÒCI¹3±‚¼i…if ˜¼¯§©ŠÀúÍ ¬ëçg œùõíj°üc±ÔôZ‡hsi`=kîÌÿxd`-æëá—å XTÿZÃ2ÍXK}üøz­±u5þ:kìÅ„‚ø]…¬ ¬À§-ŸH>+šHU2+°@2h€Þi¡ƒ( ¬-ˆƒRÆâTø€'à!%KAQÁC+AuÄ¥‹¡j÷÷‰€¥ã™ gP[h̲”Nבˆ-F†¤ÂdeE…ßztÐéȰ=iŽ …¾M*ᴰǦxÉúðY–%Ê€J«K‰Å¥Ø]±ášÒ}Wda1P]`1$樓 ¬§ùj0‡ßbü÷êÛúù ¸¤ «á‚€5'›)`]_Í4Þ–kð1Ÿ…% ë38~0|^ý}»ËìÚ„BÀjÜf²ºšUBû‰dpùa>‘|7=þ‰d ¬ ó:æ[úXR²Ì=¡u.0D„$ìp¡‘˜ ÊÚÁ¢’T€Â.0áŠgÂ¥ž­eIn&ò|]\àA`ÒÜ\»³ÎËT.=Ó¦’³a4Þ|ïܰ8:¦Ö I>¶‘¾´“Ã×7ŠÌ.zÀÓG³à"Xók  ÅbÀGXºªÇUÂk°¶´ŸçÛï·p¸ÌÒÇÅóây5˜áñóÙËø; Bù†¡¤¦5sÖm¿s¿ ëyr‡É‰O$§lµ¤òŒ=sð§S%”2nM"·)¢Eu»ÔÖÆ”Ø7GÀ"þB5½¤Ò6FÕ4Ä%1…1"‘²ÍU|9dehRS‘âê®2V¤Y7ÀAÏ®(ÿ2¤X6r~+1´Ë2–Žû7ñ6tµÉÍfmõ» X³—Áób¸žÍtÍn0› À0ú¼Z½jôÖóüÖìe8KR ,mKý×j5_Üü·^j`Íÿ˜?¿ Xz9 K‡µ¾Ò6ÖjýüoìáBê$°œoº ³~xŸHî,¬à+á`%.°’ÔšDÔ‚-›,ì¤ërÍ)ËmE!ã¶.¿¾S™Ó†•aùͤÅO¬e›«ìŽ”ªb‰R0È6Ëø3V‚F¤´©§‰<š'X6‰¤NbõÀâ·©ß§Ú6ޱ •D`ýv…š3[ÃÅìéñËËúËããòj1Ÿ?¾¢mô¸ †óÙâÇ4y\~A—/ÿš­¯ÇÚ–Â¥ÎCó¡®>j‹KW çƒñí×ù_Ëá•¶»®¿Ö,,Ìs~õÐë‡Ìš3ð¼©ò‰dÍ­ÉôNM§}ßÚž¦ç&6ºÿ)ïñ¤¥E9íNÒä”y¶ü”Ó:ÔY2ñ—¤i0{1óÞRdN9Ó‚M;± J˜ª¤ñ©¶8Yfœk¾Û@I" âðܼ[•¦-¶—\W{;m Š“s"ÜL$i“ÔMîÔ3ƒ¥fÔIÖóËJÛQóÅòe½\,–K–¶°ôßÙb©kvÏäf—âºÂãÄ÷òö¿VK]9¤}ë5­/·Çú¹7Û4B™‘7ý¬¦'¿šE=Ý»»=‡ëOÞ”¶w*:ÚO(91K˜dNàabuôócÔ9r§#& ²³œw‹ÇGÙ¤r¤é•ËÊíâà÷½÷®'i9ù©Q@ïIͨ“ Ök8¯ƒÁõ×oúÏ7\oàïàëÍøæÛàׯñ+ȰþíŽéå·ùÖ›_Ç·ãëϰ>þ¬ýêp`}8Ki 4ßZ›7í+aÓd>¥£šb£Y½I{L¤JÁ'µ"¸§ ŸY›…°Ù§2i8×j‹¡¶KXÁ‹u5ÝÊ[A[~ý"û ÿkÛJNl·m°åvoíÌ^ë*ÔlÄ:hjF`õQ0`­W®^V'õb}ô½`e ,SÆÆ"`MU¤)kâ ÅÁ÷Çl/ßÂÊڲ㙘•Ùá‹G†üµ*ž¿ÖØyÀ +ƒÙ¤YòX#u++qŽO:|5ƒMçIjÛ®§ZT’¶áà äë{ÛXX}rhŽÈYmhÖÜ>æ½h=ù·¶QôphÎÔÖ')Õd*,sŒ­£Àzh‚v¶q:µ¯5t1«³:r"bXu3FC¸«hKx¢Îæ8'šE”ÔÒ»Ñ/?i1̺ U[‰YkªSÓ|¨';»ÕG¡Ú°¼ÿ ¶×9Ë~ÒBú4ÃÏ,‘ÛO8z‚=ÐCƒ›ùáÁUßõTûZÃ=ÿÞ&V²hŸÈ«™7*¯«^Õ©S<=çàçÖ˜¼&Ö݇¹}ÓÚ‡õë?f u %ì ˜3r °Â¡ŸÀê£øÅѨ¨¨‹QVTTÔÅ(ج927IQð´^…; Ž7c ̧“{3šTƇLÆä‡S›ÿ¤hΟÓú‰d·bøšJâ‡ÍšS»4Ys¥–NFv\• ½ªÎ#áµ›ÛéýèvÕá¿:TU¿úª~€ïÂÙ çÔé>oUÔŽ‘¡Ný•úh\„ÎKèΩWlá~nͼ§0§LM ;¶ÆŸLc¸óæ$Ü9nA¶Þ´ñycC´ªO転SšÜÙ Š¾‘Å߯2Ì:,Óß5;]mjÇÜ[ÙmÚf,$—Mªù1ICÍ~èÄÚp§òîíÇWKc]ˆ«àGõG³à"Xå•6œö…¶ Š¶¶ª=KßÕ=ð¥Ø£]´/‡ƒÁ§r~v`im`Yñq²¿ö’¾‘¿¾”û |’ u(¯ö»Zѹ£QÏSç{Xvðód*_½¿ë3øYÇYéP•Îèúo¥ÎM.*ú:ªTP2½©“EQ5Q¯¨Z4Ð¥àeWÈXt¼¯Ðë —kІucCEµ¬Nl×T›»2r×-W¾?Ù¯Šz³WNwoSP;ær×å‚0ña“^¹ÉMKçÝ¢¼üÑ,¸…«†å,'NYîÉ’ÒÒ.²<üÊwðV÷¿ÀMÿa°÷PâqFŠ®AËý¶Â£Æ‡ÝnS¦a¾ù‰ä©¢˸_w÷¼ÜßwMô…×9³/d[,áùvsÛa³a¤@¹@¦P1€U<9=õÌyþc -¸œ¢kkñÙpèr–·7 b+"`)þqS@nlSó“€[ðµØw•2küÑ››wqr]~N¡ÔqÞøå|“ Ef$¢g·©8rtÍ+û‡ˆÄ÷— h«*¾ãlƒr xê§z®èT ³÷?Ê$„haõQ(`ikPÞ–åí‹l«ý§r=â3iäo|"yê}"ùîÎûf2#ë°¸ðÿB'߯½]ˆ”J€E…KP‰‡24–vŽ´øå…ŠK´W9óBGë‹Â"ˆ¼9®5`ÙJ’ý¯\`™Îá¼ÊõSp0¾Š+U™‡„*üõJAØjK×ÙË]¢‰uÏMŽ·7JÌ3ÂP!*S©æxs¼’*¡\¯1ºXï!#U#°ú(°C£Û›RãåkYŽÆ7€- ¬ñ÷[p+G‡ÃøûwmUÚ'TøŠÃ@ÀÖXyû]ûÔÖ•þ ¸•° 8 ðn¾ß‚»Òcç‹xSûâè]Ë'’ïú Öªá$6•*\ `éâ“;…fk&bßTEwè•„Ž–Û{Š–AX’XÊVÓØ•µ,Ôħµx؈b" „T^)ï(´ Æ9¦ ]3ãÊ[pu’ï ?¬ªœ+}TX…SeVæ®ä’ÜÖ¬Àú…Tô´a4b •bU!°´u•k ô¹ßÿªda}ÂÿW`aáAšXÚÐ2ÀÒ€¯Ù]»h_¬ñ¬ô):u`MýJ UUÏi¾0“² Oi¢Æy$UÂÊ.X…³)ÀB§Ê‹¢+t²Á$4§ÍéíqæþùÖ0,`Y KZ¡ ˆÛ¯°RXIÕVL0¶¸<J¯„pLÊ`uͳ° XE!ØãcðJë¥ Þãœ-µJ°Ä‰nìkJ]ÚX|—¢N*°?$ÐWÀË͈°EvSIËÛ14S¡Eu8áÀ¢Ò¾Áæ5ëFcü [% ýÝ~¿…ÐÐ…ÃÓN%öÄÚ5€õãGÛ[BË­I¿·„b½(Æ‚ÿR*¸ÈV±í3T¨”AVªä¥¡K±©b]¯Ùí[BnvWE0`™—•ÜEZÒš$ïᤠ‹¹ËÍ]¦F‹×M– ‰kaŠšÀÙB’æ1nç–ª-Y?L{óÎ_íUTsŠ·ÍûQWᤠCÜ9¯yJpr‘±æ¼%¤hËX} Xe»Ðnú¾^/ß®uscM=¹òj ÆôŽ€eàØ)ëïxCÿ¨%þÞöÓºoZ8‘FwT޽ÃT¿:V؆%¯XÀ7ò.Í#„ñà‚æD§pÓÖDoãÈÂk' <¯õÓ¤3f5?Ú1“ú£Ñ¥Û»S¼^þ^X²¹•WkåUuW‰e.=ßÉ5·I-o.ãrô›´¯"°z)°öŸooÇ£AP ¿öpŸÛ€55˜²_µøÂц÷ÝÀš`a0o7°6¦{€)EaŠQ¯±.Nèîèòê}–•®›.›–nEQYW*âk8g¿<&Zð‡MµœÁŸ¤˜× !¯œç÷7§(S(rlŠåÌû÷Z¨õtŠÀê£pÝGT–‡À¢N¨&³zCsjöÒ±æõÎ*aá”3vÍÍ{<ܰ…ßq«Çª@óîéïw}Èv_Š·ÁGçÑ~~ã纸Àb߯yܸçØpœÎö¸â‹þh\„‚}^Ƥ{3›Õ[V|S‚ezPoýãüƒÛÊ]N7û5Dê¬z”χ,KUÏRhž³+…Iõ¶ýÜ8>ânß óÏÝj°ŒŒñë>—y举ֳvˆÀê£ÀßÃjª6`ËŒÃjuƒVx`ý^½é”'Òä¡`¸ÿ™úh\„âG£¢¢.FXQQQ£¬¨¨¨‹QVTTÔÅ(+**êbu1ŠÀŠŠŠºE`EEE]Œ"°¢¢¢.FXQQQ£¬¨¨¨‹QVTTÔÅ(+**êbu1ŠÀŠŠŠºE`EEE]Œ"°¢¢¢.FXQQQ£¬¨¨¨‹QVTTÔÅ(+**êbu1ŠÀŠŠŠºE`EEE]Œ"°¢¢¢.FXQQQ£¬¨¨¨‹QVTTÔÅ(+**êbu1ŠÀŠŠŠºE`EEE]Œ"°¢¢¢.FXQQQ£¬¨¨¨‹QVTTÔÅ(+**êbu1ŠÀŠŠŠºE`EEE]Œ"°¢¢¢.FXQQQ£¬¨¨¨‹QVTTÔÅ(+**êbu1ŠÀŠŠŠºE`EEE]Œ"°¢¢¢.FXQQQ£¬¨¨¨‹QVTTÔÅ(+**êbu1ŠÀŠŠŠºE`EEE]Œ"°¢¢¢.Fÿ»?Dé™@ƒIEND®B`‚nagios-2.6/html/docs/images/physical-network.png0000664000076500007650000001112107436604445021361 0ustar nagiosnagios‰PNG  IHDRb…m_]²tIMEÑ  ¡€s' pHYs ð ðB¬4˜0PLTE¥¥„ÆÆÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ5Ȩ8´IDATxÚí ’¤(…éÎ ÌÞ`bN@„÷¿Û–à/‚@ZïÍÆv•¦æW "‚š YR½€2bÒbÒbÒbÒbÒbÒbÒbÒbÒbÒbÒ$™˜úˆ¼{ôºYí§H~›Ptï³ žuoJ|O Fë)êLbÃfXÇŠ|߉)HÆ÷OàÕ¤?d4)ÒöϼQ›½ ±Ï&S•5ž ”9pMäc§lZËó–15ª_ɾëOp ­Ôúdž~.Cjº3ê³Ç”²¬"CL+ãòÝR°PæòõáµýYKý·lØ LaÜp40¥M˜aKñÝ3ÕŸV´‚#ó?SÔ6bÊî6uáb0-¥h¹Ê-ǯ°@ŒÑ÷™˜VAbsQº%¦÷ bì¾kÓ²Ð.±­%h“‡Øá:¶±¾«•s9›6b´0ZþS¶Ãul²Ms 1ßmÛPïÕޤݶâd!™6½Å5-kÛD­ ɵz]7õ>½ÐY÷v Ä÷”¢½¨îǦõ~lÚˆéÅà@l>Þ¡¬ÁòmDê×cijdSØv ±.* ÖÛõ4 qÚbÒbÒbÒô bçÆ†ž¶gþz2OXV#Ó•Hæ–Ël Ó@´÷c½Ï!Y/#fhm#æ¯ú`¤—3¶÷ÎóÍ÷‡Ùg#ѸÃ:.ú:b¦ti³ƒ@¬—L"Ù>Þif0ÿgž$ê@2£þü1v¶>´(A¬—Lñ™¯YdJ‘!f¾¨ùdö™’7£³}‹±Õ™¦œ8Èñ4"S+ê½Þ#ZˆéØD¶lÑ´”1ûýìS ç?RôbÊ>üš|Ä>ûè€õ@l­%Q+¶ÕR+NK­x-cˆ%qµ]Çö‹ÚµVÔ–ÞîÈö½Bô bæ™±iRhZ‰Ù§Í†˜mG’1µ<´\ÛŒjmeŠ‘ W!#“&“&“&“&“&“&“&“&“&“&“&“&“&“&“&“&“&“&“¦çÄìÌ]eÚ¼[õ£T@,a{ŠÍ»U?J Æ+“&“¦±ˆù®˜äøroónù# \b·6»@ŒWï ö]µbJ”¦[›]eÄ.3’{ˆ]m¾Ø}”®sjë$“&“&“&“&“&“&“&“&“&“&“&“&“&“&“&“&“&“&“¦Ñˆa,U(µKbu¢bãh4bþíy6ïVZ”¦Œ(áM ^õ¦„/9º÷åËÆÝû" ¢Ä1îÞ—ˆ51P¦ g¸–K¸ÿÌ›82Ò{Ðëyû>æÛphaå]rqu¤ÍrŒ)8¸RySÊMã²åžÚuUïØ>g" “¢TÃË=ÄCŽcAéû8\©¥BbýšnÃ¥Ó7¼CU£TBÌ{µ¤|©Èw}c[Ù“ÊQz)±ëiÖ³¥{ëš®€X‚tl“'wN‡F"fÖS^ÖË;|¸Úl~›úòe œ¿Gq^ʲ¢±qÏã‰y²¸ør°ØTWìÖ³vG­Ȯƒ»®Ùé’Ú¶mj¸ªÔ|áP£¨µb&*1±8ð¹d«¸»(Ñ­Íf[à˼Žò\ÝžŠ<Ål–BÆL,”¼žzž(M·‘\õ–G8øù±°ù4RË#%Hy6ÌÎĈ5p¯N”^H,\ZtÄ {dÃí Eê>þÛzËÏç龑ô>bËJ«‡ …z±çÙ)d ÖÚÁR£S×Êü •îlÃ÷ê© ncª{ ê¨ÖÎAÕ"¦C¾86æ~žQ%…©ˆ£tÚïjML3×> vïË<üP™1Iab'V`žÒŸ%»u¾b(Ò{G¾OEÄæÎ/Ó¯Éüz|×1׆%(Çïvôm”¦5Jž ›­ÆBs—1K#^+žm85"±-·µâ´1­î‰í6œ*¬×XªÅ”(mÄ&E-ˆM[§ÙTSiÒ,®m˜(X«ZñžØbÃÛºš¥kp[ZAó²ðônÃ{]ücàø5¹Qºk+NŒmÅc~Ul*§süz±ò,ô-‚Xk'Kb­,Õ«ˆU¸ q^È0jà"kìK‰vÜm…„LJLNV±y1û‚Qs©—Ò³| ±ú/Ʋ ±M Žëˆq¦Ü+Íï ÆõŒ¤¶@lˆõò…1ó!R±E|à + Ĥ¥ bV\ýJ ÆDLPƒ†“XhÆ¿Ø;á5ü} ¾®Ûê³ûç×W«ž4ˆñ¥jbb}"Ð!½÷ëý²vzωýõ´;~¿ŒXíÄ™‰] Ø_+S{bÖŠ¼ƒG*§ÎMìR)‚XƒäJˆýºE Ä$÷zbæý{&›@l?®±à’%!±†ô¢Ó<…®¾…Xf]û–Ä ]1#[kG,«¢!Ÿo‰ÎÄŠ\-‰ÒI ˆy6‚X¦Í;‰ÝøCËún¶ {t`Ä>JÌÙIÇZ›y*h~É"™X‘«%Q:é+‰é™˜6=k bY¾¸ŽõŠ»ÍgÌ‹ÌDkó”ADûŒj󔺱\WK¢tÒ`ÄþÛõÇÙöÇgÌK-sA}>¨ãL4d'AÑvç2ÅY’Ï…®–Dé¤q‰‘³-­Ä莕«þÄ~Ž¿ÒÌÄŸÖŠ¶õ1ÐÑ챟ãE«j24±‡aˆ[¦—\æ™\ÛŠËq;±ô268±K ËCL[[ë†ÞÛÏågœ£së^¯Z¹®>Ž•«:c©r½•1_“ÙlþãO¼-±"WÇÊÕ Äè†cÅ€Ä|mÅ©+±¿×†gƒ¶bf+qõq¬\…GqÿóˆƒØI?¾šfbç¼ó\}+WuÞ”Èõ"HÌ+9HËÃÉ;ÏÕDZr•A,ò¦D®:Ç8–¸¨qÏl\XL‚ˆ:½ê+ìv5^ñY¬\EÓÍË>Ëj×Qc‚ëÄ!ŽBg´8r¼±çqˆË/äÉ^T#ÆÛXänŠÖ&vî þ[Ó {žAˆØã†ˆ1g œ˜¨÷ ëÄ¡;1ÿ’èÒ´&oî ‰y—~òbša_]ÿF!vyyÇCìjÓ–EÊQ«*}˜ƒqÓW‹„>yUN˜Ç™(Â¥YŸ"ˆyœ {ÞÙpŒ"ˆ¹¢àvÜÙ®ÛÄ|Þ„6‡G]¶{2bÉ'µŒG§ô#Xb>…f×Ñ‘}­b^U$v¹Ã¸J'Øpjbq¨HŒ¢_ôtoéaˆ%Ä*¤Zļ×RÊ·áÕÄÊâbíbé±]DÛúŠÇŽžîlx51òEª}#ˆ ±éÖ†WƒS.¬œ_n½Zqn¹;Ô(j³®xÚPc³Õ`>¸|$ñ˜+“&“&“¦ôµdµw’fîU ÄIS)1ÔŠ­bÒ4sûøu˜ØÅÄZ Ĥ Ĥ Ĥ Ĥ Ĥ Ĥ Ĥ Ĥ Ĥ Ĥ Ĥ Ĥ Ĥ Ĥ Ĥ Ĥ Ĥ Ĥ Ĥ #s¤ Ĥ Ĥɮ æÛîÙ’hYS æ oJH“7Þ¡Z1Ѳ¦@Ìʘ4á=h¡:µS-›8Ö;2ÃJ;ï-sVœ}.óêr7VÁ²–k½c3¦(úõ™e%ØUÞÖ•YVô®wxˆIˆI™©…§y*áõCàµ[ÎÓSIJž@ì*òÅÜOL¥ZÖˆ]¥ÔÜ›¡×uxì‡H­x²Ô Ö^ŸºÎ\ŽVXSpÍ«‹¥£U vZPM˜4˜4˜4˜4˜4˜Gî”cÈý¼Ä<:‚ˆBp çᥠÖA &Mz¬HÛU‰S )ÐYQ æÑÜY¸®À/c®!ˆõ‘žöÅQïkÅ£¡fïº1ŸVûŠ©©† ÖGˆÛZÑ5±>Ú+»DbǧA¬ƒM@ àøl×Ä «@Lš@Lš@Lš@Lš@Lš@Lš@Lš@Lš@LšþëG÷§iIEND®B`‚nagios-2.6/html/docs/images/plugintheory.png0000664000076500007650000001047007436604447020617 0ustar nagiosnagios‰PNG  IHDRàçhšªPLTE@€ÿ @ € ÿ@@@@€@ÿ``@`€`ÿ€€@€€€ÿ  @ € ÿÀÀ@À€Àÿÿÿ@ÿ€ÿÿ @ € ÿ @ € ÿ @ @@ @€ @ÿ ` `@ `€ `ÿ € €@ €€ €ÿ    @  €  ÿ À À@ À€ Àÿ ÿ ÿ@ ÿ€ ÿÿ@@@@€@ÿ@ @ @@ €@ ÿ@@@@@@@€@@ÿ@`@`@@`€@`ÿ@€@€@@€€@€ÿ@ @ @@ €@ ÿ@À@À@@À€@Àÿ@ÿ@ÿ@@ÿ€@ÿÿ``@`€`ÿ` ` @` €` ÿ`@`@@`@€`@ÿ````@``€``ÿ`€`€@`€€`€ÿ` ` @` €` ÿ`À`À@`À€`Àÿ`ÿ`ÿ@`ÿ€`ÿÿ€€@€€€ÿ€ € @€ €€ ÿ€@€@@€@€€@ÿ€`€`@€`€€`ÿ€€€€@€€€€€ÿ€ € @€ €€ ÿ€À€À@€À€€Àÿ€ÿ€ÿ@€ÿ€€ÿÿ  @ € ÿ    @  €  ÿ @ @@ @€ @ÿ ` `@ `€ `ÿ € €@ €€ €ÿ    @  €  ÿ À À@ À€ Àÿ ÿ ÿ@ ÿ€ ÿÿÀÀ@À€ÀÿÀ À @À €À ÿÀ@À@@À@€À@ÿÀ`À`@À`€À`ÿÀ€À€@À€€À€ÿÀ À @À €À ÿÀÀÀÀ@ÀÀ€ÀÀÿÀÿÀÿ@Àÿ€Àÿÿÿÿ@ÿ€ÿÿÿ ÿ @ÿ €ÿ ÿÿ@ÿ@@ÿ@€ÿ@ÿÿ`ÿ`@ÿ`€ÿ`ÿÿ€ÿ€@ÿ€€ÿ€ÿÿ ÿ @ÿ €ÿ ÿÿÀÿÀ@ÿÀ€ÿÀÿÿÿÿÿ@ÿÿ€ÿÿÿ£0bKGDÿ¥òÅ pHYsÃÃÇo¨d ÑIDATxÚí ‚›: EµÿMÎ[@÷Àk'dc@6þsäÎ$MÈ„˜›ƒeY–Ãæ5YôM'ðå‡FÛÚ„Ç0­NƒàƒàœÁ!8Á!8 ‚Cp ‚Ó 8Ç 8§ApŽApNƒàƒàœÁ1Ái‚c‚Ó 8Ç 8§ApŽAp‡à‡à4Á1ÁßÝ~ ªýÒõ¯­¿!8Ÿâ}«þû-û“ßg 8—Ùò{«¥®(™ÿl%3!8‡Ú+¼[:÷ 8ïÛ×–Ä# Á!xÿÜ–ä#"y¼rN+½'_à|æøóóE 8­ßøóvy Á§$ø˜ë×|þ²tr>€à=Sð¿²V¢¯Dò†ùžÆT xÏŸ¦¸À;u½3þ]Á³Æ¾KX>Á¥5ÁÓ½tY 8¿õb¥Á¿ª>>"­y™œÁ»øÔ'ø ¯0—’ýÁ»&ø% õ3ûýz·Dš-/*'àÜèÍ~È;ÓkÜ Ç› ¯ /¼G‚GÎWEú:Ú¿óOSXݼK‚'Ä!”_^ƒàñ² ¿BzìL^:’CÙ^^àiY¡WI5`@ðQá} ²”xztYš2r§!x)ÏûáŒóÞG2WŠË>‚)—Ë—Ü%¼=½óü™®sQDŸ§ φSàÍs¡_‘‹òin¤Ôs‹?ɲU‡XÜê²>¿>¾ÿ÷íÔc¼#‚ç —uŸM¨†a÷:'ªÖ‰>"¢å¼ø›Êñ¥rvøš}(Ú QŽ´GðákDÅßHûç‹Â¼ïBðð}OðO¤ÜÛHêEQÔˆT¿9¼KïÛDpùý‘æ>¸Hõ£ Á¯Æ[Yv‚¯ÿÜù}½­4'³‘À!¸ÿ=þÓÞ$;ÁWeG¹Ö{­9™õÁw!ð(ðÞ"ÿŒdB𬱠wÜŠ|‚¯ÎÊêƒ×&øÒ±ÁÇ%xðš³E]±’7›‚¿€à‹Î&•­ìî‚Cðá*[‰­ž•Ÿ"¨— r³ g|ð7¼QmB1bÒÏ&Ÿ"v“‹Ák\"()º¶²¸ Xö#òÁ!x=‚GWg‚o‹”œ'~‡à­ .±Q•œµ%‘{Y„|X‚K\4¡‚KJâƒ÷Jp%ï9¾(JͪäƒCðJùà®î¤Š¼{d…àf‚×(ü³[š÷Ý ¶•­&!xÚ„é¹ê"X)| ‚Wª.+‘+8\Î=­ä£@ð .•|ð$€‹4eâ¬(^àÚ%0Õý+E‰öÀ¯ö½tý{êƒ÷Mp£Ë+UWYÛ–•°Õ4â%kô DpÛÜüqðmon9nòÔתT`ÁðÁoV#®ÞòtÇ¢Ü_ ìip^7ŠrIð!«Œdºïê_#¤ÄXÊÄTä‚BðÅãøÖŽd>/é“·Jcòž¼–à"ë¯Ã£Aß9Wü£w=ž‰ÖªÏÎÎÄqVþ«Y“nÃ_…Ô8¸Ää¢tWk+žÏߣÆëe‹#øWà_<ÿýõù·?ðõþôñÙàÍ ÁíÙ„£7‘Ÿ -‘Qú3’àI+q+ÿÙ¯ôÿÇ{6x“/›pŠSjÛ×/RãMêuf”¾iÖÑèvO<ŸþŸl'…œùàsPürxÿö"÷‚§|ó9þ„®]Ùv_à!¿‚‚èR™Üü£Ë£—¡}Ñ‘•‚+—þâï$¸ŽòÛ¥V·jâ¬ÿãû&>x@àøàÑ(¿­ß&Ù'y¾šà›+"·Q”? ë¢(¯%øžå~½Q«²-y)ÁïBØÁgÔ &‡à=|O>‰¸ùiÁÛ\k[çN†2O2Ç!8ï—àÞ:•êŒr–µbE8Á·YY×Û’¶O¸‚x„Á§'¸lea¾UÖµµòŒÝæ&¸H^Cð9 ¾çÓxù6Ëa5¢gsaóÜ0‡àçyîÙê:!• HìÆ‡à_»fÅÄô(Š—Ñíd~&¦=‹¢Ÿà›¯ZQ.Å+ô_·÷ÊàuQ&&¸+Á‹ùtsüIÞS]¼Ç€Kܳ¼˜Àß@ðÀ: žÝ.SûðfÍ£¼>07Œdš—YkEðñ¢äç;,y}àR»?KŘ‹²ÆYj¼•]æCܘ2ÓœÌÏ·¡Á'ÙôÖ?àÆ?>׬úÑÖJëdöïi§Ó<Á @ÞEðŠJ |út”l‘–ò=õ:‚“‹’m$óNæÒÒûV_¡×ÕE5¥ÏlÂs•K¼æÑ8‡àrQ‚*—V#˜‘ÑÁMìõEnrÒo½y¹ý"=õÅ!87{ÏZ&‚‹\ÈxßIMÉÁs'¶åƒ-ñ‹ígË{VËTøUPÜ­Ý›ïÏö ÷œÁ!xÞ|ðÓ±[qÙé©Ó¿«YB[/¡|o5ï!¸ÆþûÛ{‚'䢄\fÕ]ŠkÈñLàªô~ ôåPµTTSˆ¢8Z–ÿ‚gÊ÷2Y¶ÿðë¸ >Á—ÀÖŽäOn¸xÁWî|ˆ¾ÞBð´\”å;=Œ‹ã‘/Ú™v|ð}ëÀìð^ü×ApÏEÙQ®õÁS³ ·+Hs6KHø þPàüt›mÊt³ÇoôÁ!x©9™ûì«Ú‡à¾ÀWgeõÁ!xF‚×θLŒƒwaeãà$„à6‚W.TtU'çœà¡Ü‚Ü?"QÛçÉ”Ør~Ÿ¯Ò g^®[yÇIœ‘Ì!jFGQN§>KœÂ»$øÞoFprQrúà‹el1 ãçÀï—àv‰CðÎ ®=a¹E¶ ÷ÕÉ&bpy$-^‹à Ÿ€àötqDþ˜b¥5~ÐÜß.®j›Cð WYå˜r²lc G/–YÐiÙ„u .|L‚µ!ðcBÖ–£rL«Ê¯Ip‹Äû!¸ ^Í*ÁϼßÛ)‹ï¢8*§ÅâƒApÅ/zl³ uQf_­ÇHð‹.èf ³'‚o}Mp-ºš5Á¯?¿ÔœTŸ˜Þ*Š"ñ>¸‚jy‚›†*+õÐÝ› ^{m‚ÄÕ êøàòn|MjZYÖäǼ.C$ö,µÔˆ¢ˆ7ü5Wsw2ùò¥Ï7=ü$¶z¹‚×FÔ:qð}ïfôÆÅàs˜>s„HpfÛÓû½:qpoa ¹P.†!K'—A îú×áˆIÈo¯5’)7û9 ÁÏ–kì€à–³g×Eºï`Ñv$sŽèŠ>äÀk¥xý2“ÙA.Êð^¹)ƒ¯ý=ËÃ5z¥O¹(C£<×Zšúj¥ÈâμýJǃõŸy+¾² \~^Ið ³ ã÷g,pŠqK€ÏGðž×/“Aö.7ÁóÆTâr¦#ø§—ÞÎv‰¾mRÈúùÇ—Ø­!x« W÷³¯k‰” øï'î‹KlD‚¿ç櫈¢y&uÁ;‰[Hbש‹b xÒPb>ï2ú“5’T*¾ülÿPœ|Þm\êu˦•­bÎ,1i韂â/òFµ‚Úçag]“‡.?§5!ø—â?t×\ÿ'Ÿ‚cî`Z­ÅãÜyüY 8­ÁÓçáBpl‚—ý,œÖœà%? Ç 8 ‚Cp ‚Cp‡à‡à4Á1ÁiƒàœÁ!8Á!8 ‚Cp ‚Cp‡à§ApŽApNƒàƒàœÁ!8Á¡mj‚cXdÁÃ>  öz Ã8†!p Cà†À1 cÇ8†!p Cà†À1 cÇ8]€!ð?˜y¡Ü}ËõÞÅk"Üufü*Åáëó %pAàFËÓC•é` p^Fà‚Àë \u¸{O®¾¿j›ÿ}ö}¡Àƒ]øïfïC¿ÿÕÛ¿y0^!p…ÿžœ \Üž_· üØ…‡G|ÁÊ’÷`¼Aàâáã{oÝȸ8ý¾¨¯€·-vÓÉú÷±{—Àé4ÇÁx‰À]1ë>¼êS÷èàƒÇ^d;>ø€Mà‰ã•_|_î¦O]W3ÜíO£À§#ÓÁx¯À•³ôÁ¢/H±ón÷.s’žã`¼ÖE ¹rç}ztg°‹n?*Ðꢜ\®¦Œ™¾B‘åôZÅïS.2S¹bòÁo/2sŒ7<&””0áB˜Ð,ðC.WZ;Õ±aÂåõaBOÖú즂‡1=ú»ò %xAt¥ç<-lîo]€!p Cà†À1 cÇ0Ž!p ›ØþeSu'í½¬¿IEND®B`‚nagios-2.6/html/docs/images/redudancy.png0000664000076500007650000001261707436604446020050 0ustar nagiosnagios‰PNG  IHDR²év“B®tIMEÑ  †þ pHYsttk$³ÖPLTEBJZcï÷÷ÿÿ÷÷÷ÿÿÿÿ÷÷÷ÿÿÿ!))Þ))ç))ç11Þ)1Þ11Þ91ç)1ç11ç91çB9Þ19Þ99ç19ç9JJJJRJk91k99ss1)s11s91s99s9BsB9s­ss­{sµksµssµ{{{19{9B{B9{­s{­{{µs{µ{„­s””œ”œœœœ¥½½½½½ÆÆÆÆÆ!Æ)Æ!Î!ÞÞÞÿÖÞÿÞÞÿççççççççççÿÞçÿçïïïïïïï÷÷÷÷÷÷ÿÿÿïïÿï÷ÿ÷ïÿ÷ÿÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ«ðªé"IDATxÚí]ýÛ¶¦ÏSîÎ[Ë@‚ÈhÏ?Ô·`I³K—b ¶[wËg —sº’ÏŠøÐÅ,ÿù#©oë‹IéÕÌ'¸œÏ¦¾z“|Iñí RÀ‚)±fž" ¶Ò"7ÔO·èB2$Š_«â‘ãÔËE2¾d¸.½*HÚÖ$=`ÉjÓëp‹'Vdþÿ“ k剀qêã‘Oª 4O*#Í<œX¤ùAšyú)Ù^‘d5÷Šqªâ1’qÞ+dÛú!Y¥ªxrœC>NŒklSÀL²Útœ’ÉòôŶuÛ໬È-õ<✱«kC#Yžê¶ÜÎÕEðI&Ï“ç4¥Lâvªú8ªxD9ñ^d<<%ÔmƒßÕCi·ðð4ã4¥ ˆ[ Û–¢nÝÙ¶uÛ€ìȶ¥¨Ûd·@¶-EÝ6 »²m)ê¶Ù-mKQ· Ènl[Šºm@v dÛRÔm²[ Û–¢nÝÙ¶uÛ€ìȶ¥¨Ûd· pÎFUÎaa%<%·Ý6ø\ öy{Ö£À6.žê¶¼”µ-EÝ6 »²m)ê¶Ý¸Ü"ËÓÛŒdUœ À|œªxò¼]€{{§¸âÃZy².©ˆaDÂU<0$²ExhGOgc.<à$Knï3uíó$À"[©èæ$æêtòà‚WŸpI:½<9´/.}'Çzyš.¾ó¶*@¥L™-zî Ì6âF²R¨Ý¢=Ý¢‚¸=%÷„ò7Õà&ó<’u¢„³yÛ;ñèª ÌÍt†y;,u<%ƒZ5”™çÈ™.püÜ’Ë6œt˜ Ÿó¿ãP+§yµ’EC±R¦eßáÌʼnö‡!âg?ïQ)Ù5=¡ä!Éêy„î3¹°„2áÄrD¦5I¯ ñ7,úÆ¢pÀ0w»*xø…UJÞFˆƒiÈ¥D8EPD„“ìDÍëñèZÚÕ)ƒxGßjyÄc‡pd0,Á(WRÃò2¬5.~–,=Ü`„R)Û§<Ÿ¨Ñ ”ðjg]H)P€ƒx¥Ž¨O’ø¥qÅÈÁÓ¬-CYÇ‹œœ(se†Hè‹X;@Î/q„³ŸKò†üµÀE”Ù'‘Q(Ác® ê«dÙh*Yï-Ü/+æIhªLãí—á,>$Â=“L£-ò<5#Ñ|mcñP~m&-Üž:D¶ÔÝ«80JÆ×±(%ÎRá‚Ïß^È ý5´EO}>ŠnZ’B)ÃaÏ´AJ Oêr\ôK”¤ä¦OÜ H¦Ú5<`Ç5’õÎ6#Yïl3’õÎ6#Yïl3’õÎ6#Yïl3’õÎ6#Yïl«¥ð}?x±¥¯ùHi:zozxnl[-Å–€þöÙËzBª’ïoÃË8.éȶñ—2N‰¤üv”òµ­^²ôkŸK?ÄÁÕ}r dÛ8(¨÷I-·Ûq •2Uw¾pÍÈ-mã§ŠM­Q{ç}Mø¡ƒ‡£- ~ˆtÃH`uòh/V3r dÛê#Æä¥5w¦S»Žãÿ'“‰íÜ?ýÁDŒx(¶Öc¢Æ'¶3%ªÂL‰49Œ{Bµ›Þ{'V3r dÛD(¬/l¦×8„àa¾”M ~I¤$¸÷ïÞº²mB’ÍmçÔªiÀNNH#6ýý±cŸþ°ë«[ Û&$ÙSÛ9 Ûª°Ý š®Lí¹õÕ¥mŸ¾3£±RæØç¤›’vjÄ97?³Ç§Ö×—öôÞ½u dÛ„$#áÇùýGQÕ8 ŠëFk~6¥šÒˆÑt¥•óˆ–²³É¥õÍSÒàƒ‡ãøSûÌ>£QˆMJ™PÈÈ-m¯¿°^=vXèÖŒöôlrN¤Û¦bÔÂ#1’DB‹yØk.îKÓRÆ^É´ðÉzg›‘¬w¶Ézg›‘¬w¶Ézg›‘¬w¶Ézg ÉÊ÷Ý\=©ˆ's—Ÿ4œ¨[’9§ÊJ™ªs-uŸó¦ò€'%¦bÁÓ‹RÖh*ya?ñœ›ÐÜ„&¢¥ìô>[Úàj›ÎR¦ªbÞœO¨Ÿxø¡KV7Oä\2ÁR¦ÂFM<\”ƒ_Åf" ìGÖ«9’S2ùc<ɦM"F6¶ÁÓƒlØSéÉ¥õâ ¢ÇÔqÆN~ö0yË>ÿ䜕¶SÁ©§º]q|’a:õ”–26Q‘TË…³uÈÖ%:7~xï?°\q|’‘ŠÑqÎH)š:l"£Sí U¤Kr§$îŸ|ri©ùPéŠã‘,“¼8>%-¬0S¥Ì´egƒ÷¬Õ!.ŽØ#˜“k”ª SOÌ·JZ3#YÃl‚òþ^<=µ¾žŸZ»|bYO/-‹ŽsX/È;/žw=µ¬ËöÜÚ³ ’+ŽN² 9B¯>x?xðbJ[4Öž±QÏ&ÑãÛ~d±f$ë<d=>›°0¤Rüó|B÷qÎÛ™[/.çÖ«'Ó)ªs>%ᇯ¨[f$“É£¾º$’ÐÐzüÐyBg[ÑòþùdB§}龞ÛÚO¬ÝNl×ý®8JÉâ~Yi QŸŒ„!4(¡[X±÷âûAkvÅñIv0DƒlcõðÖs ÚFã‹fÀ F6­ŸÅf$ë"6ÉJ }<¨6d­ÁHÖE6 l4’µ#™\6¨ä2”4aªM7’ÉeS.YòJ±íF2¹lÉ¢',ôFOȰ‘ Z6‡gÚ£ðr”üÚ³°jãdrÙÄ0cÉ‚ŽJ3É eÃ.À)ɘˆ8&R¶Š[½+ŽZ²tŘþ—‡'\a$KýNÚ²ý+·ÞH&—MqÄýŸÔ]q¬’u#YÙÈ Ù<^ÅûýÁ4†í~[È“W)û 4µÜ6è—Å;\‰ï^%ogs@’ 5%Ž ¥ËßÍØ0lº¹³ËSgó†ïƒÂÉ#ž;›’d¼æÔ ÿ£çoãøp½f Y'l½¦1ÿf³\ÓªòÎsof,}xvv»vêôQ{ùöƒ¸“ q—¤“¸TÅQâ ý»#;%|Ô¢5ÀÕ®òº‚6d(¨ QLO^×èYØTÐV˜ÙÙ€$ ÌAÔÁOÕ‹ÃÑoÑóųÙóºçÀb6»þþââÚÛ¼œÑwÿý›‹}÷Æ]^_tjg³¼A¡ô[‰ÿ,5œnì‡ ÏŸɸ îéŠv×Ýx›Y/?z>¬½»·³®ìlî#åŒræP_¤«Ýu|. ~Ê ß² b0»¹¢`XDÿüë]ý´ùñ53ú³ò^“x„NêéÈN é@8¬p"OÃy¹óI‚#Ê:<Ûý}ô;3¾¤ÏÌÐlá‘îó—oYOúöŠD®w·ZÌèVHÞšHÖ ã¤ÄΦ€%™Šˆ‘eQbzŒâ`q0ˆƒƒA n;%|Ô¢bàúf'Ú…j?é&3ï2 d¦ÜÎf(™ªÛÓ}þuëçk‡(Y{觨=•¬«o8ôT250¥Ì ôR²c®JV6[e+ªâi~ûºùër„rWTÞŒG·ú<‰+âá»Ô¹Õ8šYQ¿RˆƒG³šêox’UŸ[U<õ’Õò04v+ÿ1L×Iµ±+Âs«qfÜ•g=^5l[ÆÅ¯ÅC:H¥ ª:·šÓnNÝvêò$ÄmDú™n¾Bão˪ytÚy4mÙ¡+ Û ˆ±ŒGÒ¡|vêó GbÉ£{ñ~YŠ~Y ÿñ”2ƒ:Éz#Yï`$ëŒd½ƒ‘¬w0’õF²ÞÁHÖ;Éz‡ÿÖ§MS”ê>IEND®B`‚nagios-2.6/html/docs/images/redundancy.png0000664000076500007650000001261707436604446020226 0ustar nagiosnagios‰PNG  IHDR²év“B®tIMEÑ  0ŠC.… pHYsttk$³ÖPLTEBJZcï÷÷ÿÿ÷÷÷ÿÿÿÿ÷÷÷ÿÿÿ!))Þ))ç))ç11Þ)1Þ11Þ91ç)1ç11ç91çB9Þ19Þ99ç19ç9JJJJRJk91k99ss1)s11s91s99s9BsB9s­ss­{sµksµssµ{{{19{9B{B9{­s{­{{µs{µ{„­s””œ”œœœœ¥½½½½½ÆÆÆÆÆ!Æ)Æ!Î!ÞÞÞÿÖÞÿÞÞÿççççççççççÿÞçÿçïïïïïïï÷÷÷÷÷÷ÿÿÿïïÿï÷ÿ÷ïÿ÷ÿÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ«ðªé"IDATxÚí]ýÛ¶¦ÏSîÎ[Ë@‚ÈhÏ?Ô·`I³K—b ¶[wËg —sº’ÏŠøÐÅ,ÿù#©oë‹IéÕÌ'¸œÏ¦¾z“|Iñí RÀ‚)±fž" ¶Ò"7ÔO·èB2$Š_«â‘ãÔËE2¾d¸.½*HÚÖ$=`ÉjÓëp‹'Vdþÿ“ k剀qêã‘Oª 4O*#Í<œX¤ùAšyú)Ù^‘d5÷Šqªâ1’qÞ+dÛú!Y¥ªxrœC>NŒklSÀL²Útœ’ÉòôŶuÛ໬È-õ<✱«kC#Yžê¶ÜÎÕEðI&Ï“ç4¥Lâvªú8ªxD9ñ^d<<%ÔmƒßÕCi·ðð4ã4¥ ˆ[ Û–¢nÝÙ¶uÛ€ìȶ¥¨Ûd·@¶-EÝ6 »²m)ê¶Ù-mKQ· Ènl[Šºm@v dÛRÔm²[ Û–¢nÝÙ¶uÛ€ìȶ¥¨Ûd· pÎFUÎaa%<%·Ý6ø\ öy{Ö£À6.žê¶¼”µ-EÝ6 »²m)ê¶Ý¸Ü"ËÓÛŒdUœ À|œªxò¼]€{{§¸âÃZy².©ˆaDÂU<0$²ExhGOgc.<à$Knï3uíó$À"[©èæ$æêtòà‚WŸpI:½<9´/.}'Çzyš.¾ó¶*@¥L™-zî Ì6âF²R¨Ý¢=Ý¢‚¸=%÷„ò7Õà&ó<’u¢„³yÛ;ñèª ÌÍt†y;,u<%ƒZ5”™çÈ™.püÜ’Ë6œt˜ Ÿó¿ãP+§yµ’EC±R¦eßáÌʼnö‡!âg?ïQ)Ù5=¡ä!Éêy„î3¹°„2áÄrD¦5I¯ ñ7,úÆ¢pÀ0w»*xø…UJÞFˆƒiÈ¥D8EPD„“ìDÍëñèZÚÕ)ƒxGßjyÄc‡pd0,Á(WRÃò2¬5.~–,=Ü`„R)Û§<Ÿ¨Ñ ”ðjg]H)P€ƒx¥Ž¨O’ø¥qÅÈÁÓ¬-CYÇ‹œœ(se†Hè‹X;@Î/q„³ŸKò†üµÀE”Ù'‘Q(Ác® ê«dÙh*Yï-Ü/+æIhªLãí—á,>$Â=“L£-ò<5#Ñ|mcñP~m&-Üž:D¶ÔÝ«80JÆ×±(%ÎRá‚Ïß^È ý5´EO}>ŠnZ’B)ÃaÏ´AJ Oêr\ôK”¤ä¦OÜ H¦Ú5<`Ç5’õÎ6#Yïl3’õÎ6#Yïl3’õÎ6#Yïl3’õÎ6#Yïl«¥ð}?x±¥¯ùHi:zozxnl[-Å–€þöÙËzBª’ïoÃË8.éȶñ—2N‰¤üv”òµ­^²ôkŸK?ÄÁÕ}r dÛ8(¨÷I-·Ûq •2Uw¾pÍÈ-mã§ŠM­Q{ç}Mø¡ƒ‡£- ~ˆtÃH`uòh/V3r dÛê#Æä¥5w¦S»Žãÿ'“‰íÜ?ýÁDŒx(¶Öc¢Æ'¶3%ªÂL‰49Œ{Bµ›Þ{'V3r dÛD(¬/l¦×8„àa¾”M ~I¤$¸÷ïÞº²mB’ÍmçÔªiÀNNH#6ýý±cŸþ°ë«[ Û&$ÙSÛ9 Ûª°Ý š®Lí¹õÕ¥mŸ¾3£±RæØç¤›’vjÄ97?³Ç§Ö×—öôÞ½u dÛ„$#áÇùýGQÕ8 ŠëFk~6¥šÒˆÑt¥•óˆ–²³É¥õÍSÒàƒ‡ãøSûÌ>£QˆMJ™PÈÈ-m¯¿°^=vXèÖŒöôlrN¤Û¦bÔÂ#1’DB‹yØk.îKÓRÆ^É´ðÉzg›‘¬w¶Ézg›‘¬w¶Ézg›‘¬w¶Ézg ÉÊ÷Ý\=©ˆ's—Ÿ4œ¨[’9§ÊJ™ªs-uŸó¦ò€'%¦bÁÓ‹RÖh*ya?ñœ›ÐÜ„&¢¥ìô>[Úàj›ÎR¦ªbÞœO¨Ÿxø¡KV7Oä\2ÁR¦ÂFM<\”ƒ_Åf" ìGÖ«9’S2ùc<ɦM"F6¶ÁÓƒlØSéÉ¥õâ ¢ÇÔqÆN~ö0yË>ÿ䜕¶SÁ©§º]q|’a:õ”–26Q‘TË…³uÈÖ%:7~xï?°\q|’‘ŠÑqÎH)š:l"£Sí U¤Kr§$îŸ|ri©ùPéŠã‘,“¼8>%-¬0S¥Ì´egƒ÷¬Õ!.ŽØ#˜“k”ª SOÌ·JZ3#YÃl‚òþ^<=µ¾žŸZ»|bYO/-‹ŽsX/È;/žw=µ¬ËöÜÚ³ ’+ŽN² 9B¯>x?xðbJ[4Öž±QÏ&ÑãÛ~d±f$ë<d=>›°0¤Rüó|B÷qÎÛ™[/.çÖ«'Ó)ªs>%ᇯ¨[f$“É£¾º$’ÐÐzüÐyBg[ÑòþùdB§}龞ÛÚO¬ÝNl×ý®8JÉâ~Yi QŸŒ„!4(¡[X±÷âûAkvÅñIv0DƒlcõðÖs ÚFã‹fÀ F6­ŸÅf$ë"6ÉJ }<¨6d­ÁHÖE6 l4’µ#™\6¨ä2”4aªM7’ÉeS.YòJ±íF2¹lÉ¢',ôFOȰ‘ Z6‡gÚ£ðr”üÚ³°jãdrÙÄ0cÉ‚ŽJ3É eÃ.À)ɘˆ8&R¶Š[½+ŽZ²tŘþ—‡'\a$KýNÚ²ý+·ÞH&—MqÄýŸÔ]q¬’u#YÙÈ Ù<^ÅûýÁ4†í~[È“W)û 4µÜ6è—Å;\‰ï^%ogs@’ 5%Ž ¥ËßÍØ0lº¹³ËSgó†ïƒÂÉ#ž;›’d¼æÔ ÿ£çoãøp½f Y'l½¦1ÿf³\ÓªòÎsof,}xvv»vêôQ{ùöƒ¸“ q—¤“¸TÅQâ ý»#;%|Ô¢5ÀÕ®òº‚6d(¨ QLO^×èYØTÐV˜ÙÙ€$ ÌAÔÁOÕ‹ÃÑoÑóųÙóºçÀb6»þþââÚÛ¼œÑwÿý›‹}÷Æ]^_tjg³¼A¡ô[‰ÿ,5œnì‡ ÏŸɸ îéŠv×Ýx›Y/?z>¬½»·³®ìlî#åŒræP_¤«Ýu|. ~Ê ß² b0»¹¢`XDÿüë]ý´ùñ53ú³ò^“x„NêéÈN é@8¬p"OÃy¹óI‚#Ê:<Ûý}ô;3¾¤ÏÌÐlá‘îó—oYOúöŠD®w·ZÌèVHÞšHÖ ã¤ÄΦ€%™Šˆ‘eQbzŒâ`q0ˆƒƒA n;%|Ô¢bàúf'Ú…j?é&3ï2 d¦ÜÎf(™ªÛÓ}þuëçk‡(Y{觨=•¬«o8ôT250¥Ì ôR²c®JV6[e+ªâi~ûºùër„rWTÞŒG·ú<‰+âá»Ô¹Õ8šYQ¿RˆƒG³šêox’UŸ[U<õ’Õò04v+ÿ1L×Iµ±+Âs«qfÜ•g=^5l[ÆÅ¯ÅC:H¥ ª:·šÓnNÝvêò$ÄmDú™n¾Bão˪ytÚy4mÙ¡+ Û ˆ±ŒGÒ¡|vêó GbÉ£{ñ~YŠ~Y ÿñ”2ƒ:Éz#Yï`$ëŒd½ƒ‘¬w0’õF²ÞÁHÖ;Éz‡ÿÖ§MS”ê>IEND®B`‚nagios-2.6/html/docs/images/service-dependencies.png0000664000076500007650000005641407436604450022154 0ustar nagiosnagios‰PNG  IHDR¯ª#rGtIMEÑ  $™úø pHYsttk$³ÖPLTEBJZc!!1Þ!1)9)!Ö))Þ))ç)1Þ)1ç)9Þ)9ç))111)Þ1)ç11Þ11ç19Þ19ç1BÞ11999B91Ö91Þ99Þ9$Ÿ£?Þì)ç91ç99ç9Bç99çB1çÞ9çÞBçÞ÷ÿ÷ÿ÷ï÷ÿï÷ÿï÷ÿ÷ÿï÷ÿ÷ÿ÷ÿ÷ÿï÷ÿ÷!÷!ÿ!1ï9ïïï÷÷ï÷÷÷ÿÿ÷ÿÿïçïïï÷ïÿ÷ï÷÷÷ÿÿïÿ÷ÿÿï÷ïÿ÷ï÷÷÷ÿÿïÿ÷ÿÿ!÷ÿ1çç9çç9çï9ïëBççBçï÷ÿÿÿ÷ÿÿÿïÿ÷÷÷ÿÿÿ÷ÿ!ÿÿ!ÿÿ)ï÷9ï÷BïÿB÷÷B÷ÿBÿ÷BÿÿBïÿJ÷÷J÷ÿJÿ÷JÿÿJï÷RïÿR÷÷R÷ÿRÿ÷RÿÿR÷ÿZÿ÷Zsµkkµss­ss­{sµssµ{{­s{­{{µk{µs{µ{„­sŒœ””””””œ”œŒ”œ””œœœ””œ”œœ”¥œœ”œœœœœ¥œ¥œ©¤¨µµ­­µµçï­ïç­ïï­÷ç­÷ï­µ­µµµµ½µµççµçïµç÷µïçµïïµï÷µ÷çµ÷ïµ÷÷µ„½½„ƽŒ½½ŒÆ½µµ½çï½ïï½ï÷½÷ï½„ÆÆŒ½ÆŒÆÆŒÎÆ”ÆÆÿÿÆ„ÆÎŒ½ÎŒÆÎŒÎΔÆÎÿÿÎÖÿÖÞÿÖÿÿÖÞçÞÞÿÞççÞçïÞçÿÞBïçÞççÞÿçççççïççÿçïççBïïççïçïïïçïïïïBï÷÷÷÷÷ÿ÷ÿÿ÷ÎÿÿÖÿÿÞÿÿçÿÿ÷÷ÿ÷ÿÿÿÿÿ ÿìFYŸIDATxÚí½mŒ$Ç™ç—55­íâræ8Ûš)4w {1Öa´==¦¤n¤×CÃÀ.Xdo£j’‡šÎ‡óu£[šÝƒÝðÈhŠÝUWLÏ.·G·¶IŠÒ–N·w«5vÉd `À’l+â°Ï{ûa-àp_bú¼P§ã‰ÈȌȌ|¯Ê—ªçONwW¾UFÄ/Ÿx"â‰HÃF%)ûP\FÙ7P}ŸÕ¼ß0EOòŠª“ך"ûUu!¯¨: yM ´¯•òŠª“*Ï«á(ß²oÞoߎîü©âé3ü\’²V7ŒdÄÆ]•$8Pwý$çÉçO‰ÏRm^C!Ê/Ÿˆî"¶ØÈ"6’{¥dÉLs<ñývS8Æ{¬ˆêÄkÂOS0áÇxu¾ž,IxÝèïÊrÞªÒ¼JvM6qUeTÙ’D›äï–þn'ùöý‰$ξ’èó§J•ç5ð÷¨J+æ:®E%âS¬ +ÛÛTw)<ìDçÍ_‰R4ª¯D) "*k·„Øfå¢g+¨©Î(±½k…|·æ£|†0Ž[Ýàüíû*qŒÿrÑç*t)´ýßbLÎUæ•„Xµ@H𪽎WvRÛñF‰öZ¶ïìÀ­øÏ`ñkmñyßÃ6÷¹gA”+IíûTç¹5NÛ—BÞ°K¶'¢ ¡Ê¼ú͈ºÕïÜ&àÕœ¼–í;ÛÖ\-ôº/ ?¨;q7ìð¶”]œ£PeA¤zOé­q>ÛWªÎY ¯î^ï0"üÃË=¯!§†\-ùAY÷iRøCŸÀzªâiðY·ŠtwzGÙš!¸äj®eÛ ²7<ÃÐoÒDÂÍyá·B&‚ÖªóJd`Ý"i»7(&^˪ƒ ·J [o_g¨ÊAìbmï ¢zZØà’ÊTa¼†öH19Á޾Z«ÒIl‚7 ]ªÎGøç÷î„hGá§¿¦¡\ÃÝL”Á‡–ñ&Ôö]=éy ú_7N×ñßœ«¶JŒè×wöû*¿à™m¹ åÞ¯ß604¡lQ¯¦äë9Ó­Ž»%?/$…nw²! ôÆ+â-pmO"QmÃg½¿ä‰æZòYºêFbk/ئáNwbÊóC#ú hÓWSU< ÚìÖsà,øC­S<õ×"úoö_N~€Øï¸[Ôqg èBx‹9Ï÷x@ ýÁõVå¡¥ICGà[»×_tÄ)Lí“B4×à°Ú{Ð5vK°íwž>ýD»OÚ@°ÿµH%œýâ–JÂù/^Gƒ¿<“]@2¾‰iˆûšçi&&˜M *ÌëØ³}_àpJ{ÉQ&q’)õTa^k¢Iñ ë!Ìê¼B^‹fu^!¯E ³:¯×"…Yª“WT„¼¢ê$äU'!¯¨: yEÕIÈ+ªNB^QuòŠª“WT„¼¢ê$äU'!¯¨: yEÕIÈ+ªNB^QuòŠª“WT„¼¢ê$äU'!¯¨: yEÕIÈ+ªNB^QuòŠª“WT„¼¢ê$äU'à'ûqrrzZü <1N\Ó*¨)TÜÔ j‹à¾ê–S0ž`Û­ÈʪÏÒéôô¤Ä…GZúvãÔ0ŒY£<]š-6ý5§,ݳÆ\ñ)žs¾óäQ-peb5Á‰/á#‘={tðÚþÁàà`0 ‡…jppþÿ‚gÈms_Î×´ÞÐÔœÞÃÃö­,ÝuàUÔ¬ÝÕ¼Ò1KP¯ßï™+ÕþRÓ°o~“fàþËËbuþç…–šËHëh8<<Ü/8µÃá,ÅöüÏËF1}Îùò˽¢Õ§ÿÖè?«o™Ÿ§¼¶Ž‡Pt‡‹…ózÈìL¡–†~u_[÷è—Ÿ^Ð`@s›×+µÐ kÒ2¢öµh\©u…ô×ͳ¯­#Z%òl„g¿pÑr+Eðœ–Ä*ûy®¤tçQs¡póêË/ ¯Èk !¯Èk„¼"¯uòмÖIÈ+òZ'!¯Èk„¼"¯uòмÖIÈ+òZ'!¯Èk„¼"¯uòмÖIÈ+òZ'!¯Èk„¼"¯uòмÖIÈ+òZ'!¯Èk„¼"¯uòмÖIÈ+òZ'!¯Èk„¼"¯uR xÝß?à‹è ÄÒ=,ÓaI˜C矇Ã×`…#z¹$@T’×ÃÃýýC¶Žˆ†¸á_Uhß]òþŽà'–WJ•Õ´úc°PßbË]X«ts·×á{úì8Ž}îZ*›9ìëp¸Ïp¡DøêO´°^;< …ª)z±á`È ý0ÁúFÕâu঑>lLÊðÿÐyR‡ ƒ}gm,í S«C–ÕïZ¦ÕïõM¾,‹e‰½å–î {`sߢ¤Þ\í÷cú±G÷ûý¼¼h‘pÓJ&_nÀóý›`@uå3Ї¼8kÆë¯Alá;øä*–®³:[͉ñ=˜f^MJæmj?M—)Hsmë‚-5ŠW:+`h×@tÇ\k»åµ¯‡ ÙׇCVTŒUÆíð@xjq Y&!µŠ¼‹|3OÇëÁýÿ5}n÷‡ÊjcÌ?¢ÿ±g{*y…ŠÝêui•Ot¹³Àp2â:¿Û1×Ön­ROÀäžüRç…—^sÛ^Bn^¹m…ª} ×ð`sÀÿÊVƒeÿœr¯›?à&î€Î×.8MO7[ÜPx,s¨W°?½ö•!w»w³g™N¯o­qV¹?`YÝ.õz·ÀŸ*û_y™ÙÚµn·ßët­¯€C`­é l:^‡¬aÁMà•V'‚Ÿz,NVjÔ¼Rÿ6ÞØTW–NxÚöuÕ‡È#¨ÿÁÂ2lÙb¤54áSk_¬ÜKíqg”{++ÌÊöz/Ñ/u:ŸZÔçÁœÞîг,jfMs-Ê+NÌëü€oÐÿ¸u=]à u­)ºÌ rP»öÖkèøs¸é>Àܦ2¿upàüxÞÒtòjò&¾ë±ÂOjgE?˜Yj?-^åó5ˆáOJ7üÅ7ÍÜí-`ô|kv¶uLóY6´2ñøßP;sxàT—5ãÕ©hj4˜k0Ól>Ûeþ+µ³Æwfšðn‘w–˜]\f¶÷öoþ÷»ýå&½=–ù½Ü¾æîÏ:5ææÀ¾ñXëè˜Úœó}pïWÿ+·Æµ(oœ{ìoÖ=Z¾GÔ§¥–øÆ=^Ò5ô_÷aB OÓA·îÝ£é>×úR{ïxGGè_ç[¿0ZoÜo4އ‡ÐjݧָõÉ”ñêXQöÓ²–XýÞ3(‰@#µŸ gÏ<\^fÛ©%ý­³ÍïÑ¿©KÍæ2õXÁÖšf­©ýW°´äîÓr{óÍVëÁ¹ÙO(«ûçfÿ­Ñº¾õÑñpxôx럼AkDh3ŸƒR¼ït¼'xEµxeö•½Ëa8‹Ú:>nµŽîµ ¥?bÓçq–~zŒZÕãFãiž¼&ü×iëÏb9ûa±O`;›×Ç%ÆëÛ”Õæ33ÍïÏžY<Û|ç7z«×8Ë‹¦E½‡Úë¬ü.¤íb¼€ ¬±¯«‹ÚúèÁ›ÔÞ<Ñ¢VõÁ¹øwÇ-°û#8šZ6Ø×áa‚ÆVyåý!Ãö|knîo ö¦®ãs­PnŸhýµÑøÃ'f?9îsJ÷¾1ÿê–ióLÞJrƦ~›B -®ïÁ;ÝæšKÔ¾.^aÜ~o®¹~­i.3x]†6k¥õ¡Ã«Ãºrö¿B§XMJáÜì·^£ê¹ÆG÷hé|ë|ãßµ[ߺÐúÑìÒúò˜5»î·øk½þòèÀ·¬¯0 Êó|›Ãáùxãß|“òzÿÞ™Æ=j_? ??>>`”òñØo·à}3çZ?š2^¥!©Û€[Ÿù®ßop)¡`_)©ßcô¾Oϧöõ «,và ÔÛu^¯eškkf¯7ŠñØ7 $hÝø×ÔšÞk4Þ õâÑppŽzG”Òs´EÌ<€7ÿ¨µáqköè€ùq|$¬†ýyFdþ mñÿ|‚ú£7^£´õmJ)õ_? éþwÔ¥>miµà ³Óæ¿°œ²>múƒGÚ£­þPû¹ÈìêûË]k†þu}zk톗ú·nϰu™õ½ò^Ù¼¼Òœ}¢Å<3Já%ãGÇç}úd[G´…ujDÊóŽùøMêɶhëcàÚ™Úõg±Jv@Òà=ª4ݳy|úAà -ÚÂjÁs'ð”>¾Ç[gÔ3xÛÀœ4^MmÕç¸qÿõÊÍÞÌ™KÆ;Ô®¾µ`õ×öµÆºpÌÃe“Öÿ¼}çZú¾¬¼²°¹Cf!yüœˆ]bQ¡´!õº/: âï ;Ň²uýX•y•’îF^)ñ¾‡|„ËIÖp¸¿éöö0—?Ü š4^%®Ø¿ÎM â_{´ÅnŠ£ iÕgÑ.<^¶sÛ=Ù9>¯Œ>ÊFVø×áÐ9^Ä݉’sJšÎ<×Do»¬¯".‚¥¢xƒñ¾òiƒÁ7ydáÁk×}Vµ=¹¼²«kY02Ûñ¯/˜–Ù…8XÊ-ðÝW]ÿJÙ^íw­5pÄñ™Û[C‘íCn0ÝøW3 ãÊñHlÌƆ .vÈÆ‰Ä/WŒ×f.¥À'7®™þÖÒ×!]Rt%˵C/8,Ð{²y5Ÿ¦ù¼yÓ¡Ì×bÑ.”EÖo# /u:àt×`hö%1ê«ÿ•"÷:Ÿ%0`ᯢ„†Nd(X¢CéŸMÏðÐ×ö!vy˜d‚Hµxe±»û¬jçîu÷âÅû‚‡À=Ø ƒ±CøÁ1å¾A´C0Á¼ò¹-Ý—•øWËzžÅˆHmjO»fçw¨a¥¿_úÏ^0{kVoÅ;>+¯N¾ºÓ¶D4=8p6»g8ÁøCî´2®áÏ×ëæ¿ºévÜW_¼/ «Üwâ€áÁåç@F@×߀×K8ï‰çÕñnSÛ 8Z"þuõ÷zæŠ×Y—ÖÿÊËÔy¥ÎCoõ6øîñ™í«c&Ìj0Ïm f°zòÐ?_œ7ö¾ôýÁ`Ÿ5°÷¡„kÆë>O7F÷‡"Û‹÷åñÂqg1sýê¯T<ÓÁ«É ,›YÕžÿJ]Vse…MÌêóˆv wTûý[σýí[^¼lf^y(¯ý¿!Å¿º~í7àG˜;Â=Z'>ô ÉhAåxåÞ«ˆCw½T/ÞwŸÓëîuÒýúЃøp ýWæ °Ñ)«×Y‘â_mLËiLuoŠQ±>Ÿ“зLùøþÍõ Nüë‡^ü+D€Ð²¾ÐúH-§ÇÿëØ?8ÿøãGƒ ÃÃýøé!•ã•»®hv@üë'ÇÎv7Þ÷üãÿ³4&0Ò}í¿0<˜Êþ,ÓüŒ3ûPŠ…Ñ-Ë:Û|{:©Î‘3ð+ŒØ³MÀãÅ=>Ãxì¡è4eQ¿Ò „î³|¾vxx< cç[ó6Ö!³©GÖt?­OÏ7Zǃý_m}ò­×êg_a*áàMžfßÂ^4]‡ˆ@;Ü?OŸSgîÀºÿû år±²<_~tÄfÞc?Ù¼:-{>"м²Ð~pppŸ–Ûë0Vþæ¹Ö¬áD±‘ž£Ã!-ã7x,-×Úñ:€î»Ã£Æ¿¾õÉ›ÃÄ 6àï? Ï)Ð;8×øÑѹFcû0þõß°‘½Ã#g¬ú¸õþ ^±X XzÈb­Õ™æw ˆxøe b°–€Ë·–¨åm|çÊâ™ÙKÍ+ûÞÂjÆk!îp±ùî2'Ë? x¥>­óߤvô>ØÌ_sÄ ÇåA÷ÁÈ:µDoÂÜZ®—`îÈæ#<€øjŸ$˜_1^¹e¼ÐøøÎ7>¸È¢#!6 "€ésúGƒƒ_k@ Ô83ç[ÓhÜKËÓý!K÷ÁÔðÊ*rös¦ù.µ“ï,X½³ÍIóì»0öÚ¹Òl~áfE ,ñˆØ÷ÿC_ð"uW!>–½{Ì3[ÿ€g_¡n£eðñýýÃóç(Ôv4ÞPÿuÖ˜ã¥ÈË­QJô¯û0ÂCí -ɀݯ]üËZçÿïîãƒC‹ÎRyøÚQcΘuÒ}Ü‚Ãõn©ôO`Í&šîok}ÄÒMŸõ)á•I™æµ¡ï<3Ó|ûz‡z«b4ã7Á0!R›º¨Æ?o4—X¤Vózϼñ¯½Û}°¹ ãá³ ÿ’u¼àp莂ƒ¯Fmìñ`øDë³,nùÈlé>ºb?xÌË1õîÞ„¾„ãÆc÷a-·I&TŒWÖõ®õá`nËð‰Çÿ­Ñ ¼6XìŸÑõ·Ÿm¼ñXG,æÛt+äØƒÆcéž>ûÊ©i>\:Û|o±×qã³»lA¿;ÓüÞì™% ’E¸\a|Z]ÊëC× $냵“óJ}°·¯y";ÿš¶+hxÿà›ÙÄ" ÿ"·4 ø1„êÓÎÂ|Ú?n$ˆ¶¯¯|m»s­!ÝGà¿þ }Ni]Oëæá Ÿ˜¥5ÍÖº<ø§³ssnô?Ö¸ôøñƒVkŠüWþÀÃk´~_‚x,gÎ˲õò—›Í/¯Y3ÍïÀ*­õ­åæÜ,µ¿Ë0s–Ϭî¢3“«—%^[ê€ùsG,j°ñ&P õâÛ™×Øì¥ããDÜxÿBã¯Ù<¦Ã}êû݃zµ¬uR;^ùõÈaþØÊo±ô³¹i¬ààüc´vfÏ^ Þ*M7Ìn£9v|öx ,ÝÓÂ+ç©ß·À¶‚Jëú¥gè?ÖÀf¿@”áŸqÿu™z Ô'ø³9à³K}ˆ÷ÀÖ.Òר<ƒ,ý¯Â8:f9òm'Ý0 æÞ>}~?9†všîSÔŸå̈é]¡m§~zTßb¶•YS˜á½ÂÃÏCŸÀ[´u¯&%õÝEð!>;G·./7ß^ê…9 Æ h­ø:P{zþSË©Sÿð~ýæ2ÿõàYº“ÌFפçñÿÐMwðy4^aâ[5Õ; ‘êtúÐ?ûîr¿×Ë0ßÐäÈÑm¿–¶¸ør“ô÷߃ ÑÚÍßð`ôévõ÷xL ¯°ª+_S¨£Ti‰…u ºôÌX—DöÕ =òU‡Sãê­bH/P»ø,xÆbu׃Ãô9‘]ûî‚ZäO¯Î,ìN‡½šiµØº°Ž3›:^›ÇÔïCTàÁðõÔKüàÜC¾DÑ`x € j¼Y8ú€çGúôÙD }o-òIçµÇâªLn%ë‘æ¡2â_Ùª¦ƒwMÞ ^_£çïÖoþs†X,6Ô0¯%‰€Pq?„‰3CþÌë®?Y¼ ƒh­õ;/¬¦…UÐÞûÎcúñ-§S=2ñ s½x(~ýÆ ø Ù¢™|%»”‰‡„ó›"jvZx…5ÜÌ5+ƒ?`vLXüVµXDaZû ëí œEM“ÌÇAv˜lu—ªñÊ}ÖNL²š«ŽWgF±ãQLz{KPkõWWûVjwbfÍÞ­UÇyÍ2?vÀý¶Cî˦•­ä¥óêÇ+(ãAjfÙRœNÈúàP3Ï`Âxu–{äeèÐâ—áMµ~þõàÇ® ò:NM¯yeB^Ó yE^ë$äy­“WäµNB^‘×: yE^ë$äy­“WäµNB^‘×: yE^ë$äy­“WäµNB^‘×: yE^ë$äy­“WäµNB^‘×: yE^ë$äy­“WäµNB^‘×: yE^ë$äy­“*Áë1[ÕmßyÑdÒ|ßò·Çó~¼&ì:ç~zzZ\–ŸœØ6|ß)åu˜á®ó¦›­!¯ú<ÿs»Ètç͵øÕ\ÌQWÚýùˆEÊkì«Xµ5yþ³×rò·û²%Ô³ŠÚ™_ò áYRLöÛŽ}M¿æÐHÒ k5‡t˜æ¼¢w{ «¶g”Eÿëö¬ÔûMñ–~Ybö•¿ uxøÚAÒ5¯XžóÿØÂçy‰ó??)²ÜÜ/‚w0¼–e}ב¥»lÓå—m?¢þ[Ò-“z|ÝÍÔûa•NseVÞ4©}=iÝwVã;L»b–xóq.¯wþkÁf†}]ëþá Û’ïyÒ=d輻¬>ÿÿÔļò›|ôÈÎíôbüÍ~ÓyÛ'e™zÔ¾žLm£$ÍÎÒz†Ö6'…ZYúüë/••nÃ89¡é&eÓ˜LNÁì=‡XÜþ¹9žkÌqÌ”oàxù3ãTäG1¼rGš\4¥¦»H—=ŸNN˜}ÍYBqy¦ß/r‰>ß§â““l žúÈ)>N†+kWO‰/ËCK¾tÃ7×…T÷–íœ'6˳,ûO¼_Fps*Æ ^Fqäß—ó™Ó­~sõ ìï0.ÏBöŸÊe¦¸ß1`k£iMwVy•¤ÝïSÎL7¦´Ü¦5ÝäèäI¹_Õ(x‚›ÖtçQ\ž%ÊÓ|ynLi¹Mkºó(.Ï’åéHxº‚›ÖtgÔñ^ž‘Ôû=åÊr·“·.ÝÞ#Ò´¦;«d\cò4/¯Sih¦5Ýy—g ó4OŽSZnÓšî<ŠË³¤yš?ǧµÌ¦5Ýy”¿5…¼bº‹òZž¦5Ýy„¼–§iMw!¯åiZÓGÈkyšÖtçòZž¦5Ýy„¼–§iMw!¯åiZÓGÈkyšÖtçòZž¦5Ýy„¼–§iMw!¯åiZÓGÈkyšÖtçòZž¦5Ýy„¼–§iMw!¯åiZÓGÈkyšÖtçòZž¦5Ýy„¼–§iMw!¯åiZÓGÈkyšÖtçòZž¦5Ýy„¼–§iMw!¯åiZÓGÈkyšÖtçòZž¦5Ýy„¼–§iMw!¯åiZÓGÈkyšÖtçòZž¦5Ýy„¼–§iMw!¯å)gº‰³N?ñou~“À– X|y-OštGEôÛÂÞ F’^£FB^ËSXºIB¨HÊÝ5G• y-OQéÖÔô%)¯×ò’nø#±êJar!¯å)>Ý™ù›Xp‘×ò”6Ý$t‰<Èw|­YF^Ë“&ÝÎû£Ø+¤ØoçuRü­}âOõ(q°óÃ=Éùv¢^U:°NB^Ë“–WÞ=à@æÐ$þTÉ$îAÞq4ÿ­ðjK¼ÚòÕSÞtÄe'z¢HØe'x¢×òH7áeCD{äI¿ep‰\Àô±ͼòýmCÆ6ÃM{÷"î„„=QvôEd^‰m'y¢×òL·gO$óBÚ.o¶ñ‡0^ ¯:ÒºD"(ô‰"*¸¾'Êw°{‡D¾Åˆ' y-OšÒhÃO¢Ô®„¥´Û2¯†Bƒd¢B+Ûô·LØÉmq9âÖûıÄóU²:Ýc¸Š ËñÝ©NE^ËSXºã 莌’-|6ìHòôB^ËSÊt+%N;ìðèòwÀ f¹òZžüé&Ÿ"µØÔšØ þÉ¢u#›„÷‡¼–§`º‰Ô>a½?Qñ¼¹¯¹®b¿Æ“¹¦DÝ<Sgéö#¯#M·4ÐNlµ©-v‰NWýøz@>žF‘‹’à‰’Ï EOŒòZž|éÁ*ú¡,h‹3<àö1\ÚéƒáÁ¶‹3GrÓÞe‡©³B"yõzÞ‰ŸWÛ ˜ë¦ºÔhÈÿvþ’r+?¯š; >Q¶ ™¸Ï1ä»Í˜géöÒ¾¦hÑæ›Z_ŽCxUS1²)í"mwÞ«OÝêØÀb´¼ºwè¢l…WöDÙê½8F_Û¬y–nÿxý‚Ó¯*aøŒ‘HÇ«:.¯ì·KtÊ#ø†`€Í«0cùÒ*Åà’À-ò-mq[†d޽Ôyu“Ákþñ1^m鄦âEà’½b»<¶]ûªšWѵ;¥¡OQv‘Àö‘t¦¿j¼f ×ðõV‡LFwQ—€llÎe©)ôëax°ä¾é°'ŠÛ–6È}nD¹í ÄWW^¥¸H5JGD‹úÐh;Gµ}yÈ+¢„3Ú¼X÷2”úk“®Íâ«w2µˆŽ˜ˆ;Œúòä7V1^ÙGŸK&@S&=¯Ý}^Ýk„òêoØ/Mÿ«ú9¼ô#F• IúI¡«úsR”Aõx5 Ñ L6G4Ðígë—O'ž=öp­€?P‘n‹(å¿ÅœW¨"¯º9¢¢c$AGº-»2¯Dg^ËsÒå\IF´jª"¯î’cï7¯DÇ«í‘.ϯNƒÍ»[<÷µ\w v}¨Ö<™Rz+Ä«psDÿ‡áy©>kVq©Tè›#Úv̱8°2ý¯$tÿ”âP…x•üx»ÉçwŠmÅ'Εpõ ¯r™ ûZ†tý¯N¯©¯K]îbƒSëTŠWö!jF›ªéHwÕ&y2(·Úþ«Wg¼ÀV"TlïosÅ(ÔªŽª¯j°/Q{5feYª@ι‘ µÜ‰uÍ­!Ã;æµZ¼zJÏEtņa#Òí¸mS¢ð*ª"zþ+ªŠò:Òñj(Ö÷¿¼{JUa^IÌçHÕáeSÁñ-©¾W㪤öVé¼fÏWø™7ÏRï-¯š¢É&°%ŸLZ!е9Wó÷·Dk“Çrî‡}ã¥í3ÚÚ¢K*0WÓÈi¡Ç¯ú×êþòøU%^¥ƒ43ÚBºü£ï« èFÄ膯ʾeeIaö‚ã$kâ³+¶ûËgqÔþó|y–vÿì«4%'‹E®;ñ•ÊŒ6i°ÖëþÁÊÎÜж¼³*v-õ}”M,»igÄFÖôVq/Ôö­_l(i´yVÖx¬oèUÚ"F¬¤x¯!½ívÕzÛóÜFè²îà¶æéóÍxª¼Yî¼3âšTy¤†¤ÇµJ¼ŠO”Þ*¶×¶mH.t!ÃíÀ4Ü-Uím׌¤PIcr®¥p>©ª£ßÁ'wž¥Ü?^I[©,Á.í@h ¿Ž2@äöýTµ·=ØŸe¶TâÁ’ï9gì ÆÐ}„ðš%’³B¼ºþ€!'Z~/Š?´ÅßÛN*„kX–>¿"³~Eœ?º(È«\C-ŽL—?ÏRìK{Km;ù)Vݦ¶ ‚¨ g•zÛ“æœ4w=Ùt“àÆ1ëaÊЮ jù,Nú;¬¯É )Œø2­ZÍžs‰Öš$i³`4·¬˜ŽÀ;Þl7ØSß$ Zœ´w]1^=Åv@Æ't<Ë—N‰ì«ï³ns%“N™o»²¼†¥3r¼²^%—)ç¢B?£Ì K Çž’úþ*ÅkÂA°DÖ‹ÖL9çZã"„Gª,ß! L¾Ïó*!è·° n,’CàÞ™!Zz7J”,ö1C^ËS0Ý£ómC„šð¾5­G3:ŸàžågÅûRg!°ÒS°‡ÖýÁ'ûªwÞÌæ0×y-Oz^¥ÑyyuÊøÑùvþÑù÷ìÖé¾"ÚÒ}z•¾mK+ðé* b+˜o„F$!¯å)ŒWy 3„Wï½Ûb•%"Š_ uûG]nGåU‰P{¯ÚpåCÿµº ¤;0Ìî¥L0:ï{yûhå½>)d¥'Ã~½ê]û„¿DG ¯åIË«» ³ßlÉý8eϸx•Í«¡Àé|wIÜnªClkžKµ#êÖ‘×ò¤Iw !,én9ð© F©n¿7K¹Šö‹í!¨1¯þ7T®p³¤»”ñª´"º_1G)[¦e|K3Öš6h«BÊ“s%ÅPhßjy°‚ëd®?àÏ’$\¢V¤Æ¤[JNR,’¥DaÀaoàIxjž[¨4¯n†DDÂh<¾èEÞª£´9—2ÆI©SðŸî^"ârÓ$&é}U’WÿóŸåÕ÷ù¤›¨£ói&^÷f¢ÑyõMO$ÿ BÌjQ¥äYÚýãà5[œe²mU’6ÞEün;Û ¯l iò°4›JŒ7ÿXSŠÑùdÒ†Æ:7ÆHæBTWÙ"(ÃÒæÄ¿HTÈOe|Ny ‰¿+Ræ’ƒJ|ÙíTŒ²ßVHç9Äy3ì¯!•äÕP­CØ ¤Œ­zÌØbêF*Ýx¬¡¦^ÓᩎÎ+CšÑyo—n9œŒ÷ìüÏnÃ]ßÉùÀ¿Î°áÿÛ0ä in§z¼FÇÔ‰"2œÇU*âV‰ŠQ©®´ñr£ÜW~‘¡Ì?:Ÿäž§¶t“âƒ!pîÍÙî¾C„xg|Cy¥Ii'Yñ†H+4ñŸm1(•êJïØÁÑypY½D)&Ò[œA7:¯†¿Ø¶ zÖ{vùâàù–%1¤t)/wJÉ;FY*sž¥Ý?^³­xCôF¥² Ü[Ì輷̄⾾MÊè¼x ƒ/xÏxÏ®Ã%8 çÕG³ì6u}¨äOOUyUšK’ítö¦mhâî|F¥¢ çÕ}ôܘAþ+jt¾­]¡UúÛk¿Ú9ì«oÑ'e!ŸµTUi»¥˜×êñêöë@dû O á忥¬?ä§ÂJqs1ë.Žß”³CÉÁ˳¯~Ry±ñc ÛR:†8ÇõüÑäYi¼J±IíŠÔ7Éä)µã5q'rÚÁ¡Q÷íë×? ËJÊ š“úòž7ÙTáA]ºÇv»#ºpÜ:ež_›æ:ɪ¯áb…¡Aºµªx’e‹Ôz"IUâ5&iÁÁ‘tP9br®‚¯Ü(_Õâ5ðÀÿ ³Ø¥ iKàÅU«¼˜½Fð˜jøãbeiÛYÑ\Þ>æ;¬¯ÚŒ!ÿÞû¶6SšötIг¯š~'£ÌãU4)˜"^Åc±âoP2&¦Îüi»Ò B@Žo‰»t†Üyž2’ª§rlwíOiï°àEÎUàn«¡*ñJ?ƒÊWpÕ²Ta9WèK_RÊ7`Sø­V‰×`ºµaqÁtU_3M›îpUéþGõV¢ìª¯ºt6‘-ãÏÙ ò–Q›‰fp»òª¯‘Ëf”÷äuj›îŠ?eøÙ•äÕH~h5Q‰)HUäÕHql5Ii)JäUDÔ‰->Ì#FVKʧqh’ÒR”ªÈ«-FúÜØ5e\}b4Ii)JÕãU˜Qß2a•‰P&)-E©Ê¼¶m‰×‘}[u4Ii)JÕäU¨F&Θ¬Ä¤*ójKë„N`sk²S*Ä+Q>黪¤ÉJM1ª¯¾š!¿Ñ¿Á·T!¯éU1^Ó¾§ÖB^Ó«b¼N•¦5Ýy„¼–§iMwUŠ×j…ÿ]ÈkzU‰×©€T“nTrU‰×iÓ´¦;×ò4­éÎ#䵡}½×ñ y½×ñ y½×ñ y½×ñ y½×ñ y½×ñ y½×ñ y½×ñ y½×ñ y½×ñ y½×ñ y½×ñ y½×ñ y½×ñ y½×ñ y½ðúèôè>œŽç;"Å¿¾úä¤èìÑ îâ”ÝÍ ýqKcâõ¿ úí*‘…*‘}=ÉJÎrƒï¦ÏË#çc¦Gf´ùñèQä͌վžžž:÷Rvnª$öõä<͸•ÍÀnþz}q9¤»øG3Ä~}à˜x=9‘ ¡BùRˆð Or®\ÉÍë)+Ÿ*•Œ¸—È[¯îcòèQÒKMŒ’ø†1—sRy¾ógå2*_.£ñ©o¾5ÊΉ”„׿²µz³g™f¯×§?‹Vgæ_C ‡×|§U°²XCç„æK·×y©èüèõ,Ë2_x¡7óÃÍT ? TÿµyÅ|yÍê÷˜,«—V&ý/‡¾röÿýe(â zCÍÈ—±¥;âüNLÍ—GÓæ$²¯K½Uš{fÆÜï÷úüWF}=9ñúÔÊ–Û½Ö¼ÖZ',[ò¦;ü|ne{gÿMÙYQ¼ñºÀË$ŸµÈ®™Š– Í—’rÄB^#Ž@^õB^‹òš]ÈkñB^³ y-^Èkv!¯Å yÍ.äµx!¯Ù…¼/ä5»×â…¼fòZ¼×ìB^‹òš]ÈkñB^³ y-^Èkv!¯Å yÍ.äµx!¯Ù…¼/ä5»×â…¼fòZ¼×ìB^‹òš]ÈkñB^³ y-^Èkv!¯Å yÍ.äµx!¯Ù…¼/ä5»×â5^a±‘[by~LŸ­®aé×Øè¬˜ß»b&Z†£n¼ö½| I›Å·›¦óÏê÷ûf×|V_B^£4^­^¿¿fuÅ, V,ê÷Ù(<Í‚=·h†?oYk ÍS½x«\õ)„ÖÚËÝ~`¿eõ{«ðLËxÓþ}äû‰ry:"šW¶$µ%ÎjO̪€ÍXY1»”IË–ÉVàz©ÃÖ€J´XO½xíyvó&Md°úè¬tL ’¯*$~0ËzëæêÍ$9‚¼Fç¿ö!Ã_4>šíÖÚšƒq¯ë?ÿÝ^оtéOŠrŸ)Áúq5ãU¤¨™aué祵5ç8r™]Xÿñå5´¯Q¯Ý>-È{Èö3ü åÐ º§tËí>”bŸÙÚ«ÈÕŒWH9#µwkU›gô!í‚S@3äu`Ín7ѪzÈkÔ±þ¥¯{ÛäùîTñ̶XúÕ&owû·x 1Wbòx…§ì%äËË–æežüE­,wØi] Û[1}5{Ïó],çW̾ƒ,³­ý ‹Ê*?w{¶^¼²g;¥/š¡©³ ÑÇ2ŸÈdÑO¼h)òuD ¯ÔkiFsÙie°Ö-[½ÞõfsÙørV9¸Èض¬åS;^y•Ùy‰åË‚ÿ€Ž¹Ül>ãÍW,ïÀ6Xã½¹„¼Fiþ@r¿ßi¾³ÀušÙYBé@Ë~ìÜîÂÞgšÍÅÅfsÉâ×ëO\{«Ç»¨X¾,÷{4_–¸—Dýøù!ŽºIÙëÜf{iž,Äfòšàˆ¸þJ ³)½³ÍKÆ; 3ÌR<\^fÖe¹yiŽî7Ï6öÃ%ˤG_¡ 6ß^à•ߤñjº½Yךs–/Ï—¹9ã½Eš/³ÍÏ/6çh¾¬tèÖK—ÍΙ3 bålä5L£ߺ9¿lõ®Ðò¡4.Ÿm>|v¦ù.-c®¹4Óüï®Í4ðÙæâL­jêÂëæ‹ô˜eÓê%*zñJí&'–Ú×Y£yíäË'_–Ïžùïžm6h½¶ùÖâÙæŸ}¶¹pYÖkܾ&ê’F^£Žˆõ_;Ü}–ú´\Î6ß_à¿`ðRê÷éçk_€±šg–úý™æw®±±…Q uãµç…€E=³ü[4í3Í÷éï%‘/ïþý•þý¼õ“µÄý×…$0òuDŒÿÊœ³ÚŠú.¼1êRsy†ZZ.ÏÌ4ÿJéÝ….my±Ò¸bö– ­A½ƒ‡KÐ0ž@ûʪ ËqåÁøg x“Vs‘æËµµ×gšÂòå­…žhe-Z@îë/@û¡‘Äg±úo¦ù½FóŒÃBIÐVÕêg¨ykµ=LZE~w‘··â ¨n¼š¦ˆô¹ÕëÐ'ùO.±šÞ:Ëó…×;×!—n®¥;Ðë|žZÚ~Âw !¯QGÄÅ»@]gÑÒøSj'(Ôc}Ÿ¶«fx?À—Ï6ߣ¶ä» æ§-Ypô³àÍ­™½Õž9yýY²TàÏ[ýVû/Ÿáþ€us†{”Ú‡/Ô“¥~ÔÓ\Dÿ5F2¾Õcþë³½>Ô~Á¢^ëКµ¾è?h›lßûËfoÕ€ï/ôøx$ *œ(^ÙuÖYž/,€Î·èSJóe‰æË´½´Žay¶Ô£~ÒÜß‚¼†+¯ðfÈ®Ù[éôxP‘ÿêì÷Y ª»ýÁ[Ý>„ÜM }eýª}膶Ü-J<°;ª¿!†Ë€BAÏŠi†–Ï+aÿ;’°C²^:\9í«éŒ$ŠðWˆí{ïüc¡/ÒÑ]S7!`–…vz¿mMbÿkò¥ßƒØn0˜~¾ÉiØ ã²ðhšìE’ôÿß¶"-‘W±‘$96å—ù®‘‹Whߦ­¨Ñrâ_áÓK¬á`‚1½‚tÊìæêÍ›lXÒ‚ ¦ ìÏ‚|‡¶óRÇ=ðâ­µµ5«·B?›îÑ"žûžk`Ëâ•:rm^ØÎþ¶ùkÂéßm±Å¶Ý·‡{½]¶8 Í~ó„ÿ¡^Õ½’ÿâï1ŒWàÑêu™ÑèIñ¯PRÏ‹˜®!@/Ó¥eÍ íXí'訯VêŽ.%’’H ƿй¹*|ˆÜ¦yÐí¿LÏcU7~²\y¼º¿áO 4÷£òƒo?Ú†z Cº‘O"Î?ÝÄßc¨}eõÛmˆž£Ù|ÛuvZÌnX¾n‹mwba­¯mš<ŽÐì¾Ô Ä›æïÆc¡Y&Dýô!†à¥•¸m3&_JâÕ%È0$\\8âî:ÁŽ “éšWvñ§ÿwgµ¸æô_¾^‡Ïpqã_©ãÿ±øy9ßY:„vLvÆêjßê$0¯¯½îËÜ€T:!À^vkï.f¥c:ÞÚ$ñêÄ¿þ mQΰ¸,_<° ñ½[ÐS`:³‡>Ãb0Ïž™¥ùòöògØS]Áö–äzúy•Zaš-mC¸«îImafý¸+W ÞBüMyu„>>"ÀFl®˜¿#l ŒÕ˜Ý™æÛ×nÂYPÒ¹FK‹zk´Y<Ì ² ÞºÖWjG;&Ä÷,/ó|ù›æ¯QL6*MŸ×w—(¿UàŽú ‹,Nƨ߇A6ò%çsUx•ýUŸ orÉ¿gl¡¿VÚã»L´ûš‹WªÛË4Ï6ßfqÉ2 1ï-÷_æ±ÓJi©Í²xÉé[g›ïBY..ÓýV'~s½xe=ÎÍ—…™æ;×:½³ÍïÑ´C”Zï%6BKëw¾yñþÒBÓhÀøµa|g©ß?{æ]ÆëBóíÖÿZ9^å~*×Á$mÖ?e«U~ho–s)æU(bR#NÞ컇ø» ã•eé ‹â|÷J¯?Óü>ý‚q/ÂüØ÷§ôe÷YZBËg›ßýlózÅ}¼[YÙ$é ¨¯lÖ+Äó@:{ÄÆw)³fç:Ë—³MšKWYõÝFs‘ºý}ê'ÀH-Ëo¬:¼Ê"vÚáwLˆDÞ“ðbyýn+Þ¹ò»ô¯ið™.k‹˜5þ9ßre†ÅÑÒúŒÅrÿõíߤþÁoõ{×ÿÊ:õÎ2¿³ñ?˜ã>S¿1®s4ñÊ·,œed>Ëâ…ú=>/ã-Øól%y%¡›I’ã_0âyì+ôPŸkü.IJÙ/ßqÍè: qžÏ€%]`3cšg–×èI3´ÁŽü'´œºg_{}r¦¶òˆìÒ¿þj¯ñö–ÕeQY×D¾À¾ëçÁ¯‡9DÍà·kVÏp•‚Gǘ ªšR<>î+òùσ?qG×ÜÛÂfY½G[ÃÏR›ú/`ö§¹Òƒr¡[Ÿý2k-O¯7é“ ùòeðÓ¡—„æË2‹¹|y™ER?‰æ ´Æú·Ÿ8÷9Ëòeɉ¶ôúý*Ä+ û4p w@AÎöøﳘ×å3g ¯¯=¶Z¼×!šŽ–Ô³`_hÊÚ½pŽ3×ka×'dýÏÔwýüßwf/ó¾š#0·b•¦Ÿ>¹Ïò2ïÒÚél€¯Àòå7CäKý”Q-$?ŸÁósÙ×Ì…Yg› ã;lŽXÓ>›•þØ» ¼’Åz.p ¾ø¯À9mOž}uòåáRÿæLsÖøÎu÷Ù\aíPšþw®@¾¼½Äýæ=,ñ¹3' } •´¯ ?BrpŠí"õ¥ÅŸèúQGe/°Dl@šYóŽx”eqz'/>«Óé2h™ù%Z°EM/ð*†ªÆ«*¹—ÕV{³ÔX5 Dº!Û3ð*‚ÁÔϤ-ËrNþL¢h—ºñ ±/¿’l±PMþ|Æô,«¥ `«¯¤íõÉy°ÀVb]ä(,~®û?€pþs6:—Müo»®¬˜Ï'X%¨>£½Ã?º fpÕ‹WX±æùž)ætg0°7;Ï[k¦qj%x%’EU†¤Ñ/ÝjHî€Ì«á iKÁâƒaÛºA®ô¼šNp,a~;ÑzB±ÒX³¬þïM\¼ ÌK³ÌnŸþZÉB&ý¹Óÿ½—×zN@qUyµ^åÁ-bøb³<—@ªÞ ×€f_]sK„‰µGd_y±üƒ~wÍ\I°¦¯0ÄhƒÕá…ÕÕÎÄù¯AÀz ø¬˜Ôê÷V:«««Î\#íúÅÕàÕ_ù3ùc]œ+v¼j.=×p84”ÿGÆ«3SËtr.e}ç͹³Ì5kã_yögáy¶ÖÜ|©x{Ëh+!vD¬‹á?ÒÝÿɼªÿû¿1þž‚öµÏ"9»0k®ÞJoAx¡ö-ˆØž< ku­þ­Õ[b}×´YÓçÑï]6-A?_¨*¼jœR1µ@ìj{vÖ×CÀ)%‡žm°ÛS>1¡è5Èâ¿z“_¡ýšTq-pñ&¯ÿµï%Ôävú,â¿ÂW;® ¯>åP´î¾/.‡ð}qc•vxyÍ.äuÜÑx,òÊ„¼ Q®—¼"¯c— ,òš]ÈkñB^³ y-^Èkv!¯c×ú_‘W!äµx!¯Ù…¼/ä5»×fµbôF(ä5J €U§ÏêOÇþב yM$¢Îà_Ä úO.ä5»×±)Ô8#¯Ù…¼êä_=Kš2ËÿrµÝ_1KÈËWÿ~ä5DÈ«NêjÄòêÆ|¹mi'‘‚°tÓj ò:J!¯¹vRYiÛ¿0±D©oMCÿ´Zÿåãoy òªPF‚:KKs»Ý£«¸Ó‘ב yõ‹øL£îu¾5ŠI¯¾ µlOì= ¯aB^5ÓaýküEE¶Ge`xÈ´Zõòñ7€¼†y *0?V‡«dìòêõãïy ò”Ã!Þònšæ–>%»Èkv!¯  !Š+¯§ÍEoчëë<ï¾dÚä/7Ì*©\NÊÎ~qôFNšËý ‹aäΗ?½ß;û¯ËέÔÈ*º?ìs¤’ÙW¾„Y‚EÊºí¼Ø˜ý×Ë´Œ!WÅìëÉÉ lèsÜ˰ [Î|ñV<,?_ƒªHÜYÉ\†,ñY'ͫ߻Í×Äv_"¯žóŸé¼ê$éyý7§eŒ,ׯÓçØ2­çÓ&'w¾ˆ×öR^ONJÈ€È{m±²¬7 +¿ÎÙEÜ%µBÖŽ—úÚ¢o ÓxÁM¶Æy¯•ˆå±rWzVïžúh)Q±_ðŽç¥Ïi“”/_úÜf”i_½*6Å^hìíðÖ#ô-—zíøÀëâ9w ®1g”$»˜:·rBï¬QV–¸ùRNÆ8‹»ûÊt¶ÈÖR2“|SÛßáÊV'lÛ®QöuÕú¿8þÖ¨m{D³å—ji%Ó/}EŒ˜¿Èî¡"–™{B­þ/³\a$ùRÖCLdwÀ«bû‚æÕa7díx}‹Ç»_‰x¥5`æ :aßš;gyR\]æ0o™ó…e„ø—íiÉ/_h ŽW?rÁµãI×¶¼v¼ö‹ão͆‚q”Á»ûæÄ:UJµ|l½''×½äÈ—SxPN•˜.~¼$½qU[¬OÚ‘kÇ;A‡ò7¾8þÖ²¦‰ˆ›Ê ì„iòÅÕu¨‚þUàÝsC,sš³´ÑÚcåÕ½Íú–ËUë| :«ÜÒ¥q/o¶Õ.+ñ>Ê»¸Q\oŽ¿·¼I«sÁŒO’/ÄYEÀ?Q;ð"îD£Xñ›WcBÊeÔšŒ|I8”3–•0:†© ^ë^0#×ÄäK0BBµ¢¯’ðÈ1ójÀÛjX¹ä}µødibò%äóIÏK}ÔøyC2RÕ;_¸£ÑqÛÙŸÒñòjÔ»\Æ&Ì´oàôW@cïÉ&S˜/>¹=]ÁMaŸÃ/’ÿ6Pª0_lÑçÊÿ3ë­¬•iýÜ·TvžTT˜/¶x¯±ûÞXΨôwðøø+æ¿'”F˜/¶B´=÷Õw"¯æ ËÂ3Âá•x‘46òZ)a¾Hµ>ü"²SàøÁâ/™ÿ¦Pa¾8Øìã…mÉø>ùÜ÷Tv¦TT˜/ Q@^ËS\¾$…O?V”zx¿:B^ËS|¾h´¢Öó!vÂõby-OÁƯ!&ˆª 5²Y9Ê7{/la¢^Uš2X/!¯åIëû[šº¯LÙÌ+5¤ê5^£¨“×ò7Ü?d üSù¼EÖe“©àJˆáŸE${LÚFMqE^KTWe®¾\ïÛaæU™¶/]Ãh“°‰ÖêÂõr_‘×e_mÅN±CxUV¥°Å»«’, P+!¯åIË«;ÅTgIW—JãZiuù̳²ÀJýT¯|&ˆ¦ÜÖ·‚‰R€ÁV°XÏ}›ƒjFªÛ öç‹DVpF¿¦É埶o˸*pú®ên®™3`—ÃkX+Xx\ļ¶)a+˜øN²+].| íÍrŸQe™ é9&~^mWå2«×LÅó*yiòê4¾f¬T ¡­`Q$¾õEd{Ü_VEbÓäldO? ~Š8™D^´â*ƒW+¸-ñÖV †!^’Ò ö÷Úè[Á-]ÎêŒXˆB«Dskª²ì+oVµ³ÕÊÎÖ¶‚•V…â—_ug{ëJRhÎ&IÇ¿ 2•µ¶¨ªÊó”V°²´"‘^®Å­`[¼–4¾LÜ&w%5:÷QDPÕDçTá¼Ê~j\+˜$n·Ý® ¯³À¨ú NäÍ©ö2ü Þ]÷ú¶:©^´‚m}+ضî@[Áš“{áÜn=]6Øþ„…7,åÃjHhlž¥>b$W˜ +©ù¢tÚ©­¿SOê Ô_ËN¶¯n*—שAS+-¯ªë#÷î)znCÜK‰ÉûÞß‚ù²:Î<ËpÄX®0Š—7V\úø¯©è3Q:õÔ1[â8ûbê>û[ÌÞC^GôYú t?ÖFúøÅíïÔSüWaFÝ%¨øß†3Ä]vBǘgYŽH{… s¡‡q¯v¬µ‚¼·ßDÚ¤x¢S8£*Ò•‚¼†|OUŠ}ÍÞ &îõ&€â ¯rŸCèïÔ“ûíØ•üS÷¥ üÆDdVHže9"åøˆ¿Á‡¿Ú#ÚV°Úy0)ö"ü9–²Ê¢V©Ïnï5sa‰ÛÞŽ«cw'×Òâ³R¶‚Å™^u7U;tzz³Ê,PÚ &Ǭæa2Œ {j©2yU[Ámƒø[Á¶hûºÉk­IIG‘*‰W+ØÖ·‚Ý8d÷:h_§[eðÞ v¸Û¿rLŒôÿ$h¤É˜ 6U”JioéZÁnð¶­L°W ±Üö.S«]áñØ8M@2_& ;©,^“hÚb„k"£·FÆëåIœêa_'³@&Ä­)Tõàu2…ù’^ÈkyÂ|I/äµEže:"ÝXö·•lu‹¥í²r¯âÔ׸~“pÅŽLbK‹«p^c¬™"+W±#zôuri­ÆxlڽɎ¨¾ù“¨ÄÕ“9!ªÀxÁÔªÖ•CI*ɾF¾nÚýœëÚ=¸`éý¢l¿æ5Îòð‰s•°Åõ‰ßuªyóT—g™ŽH~9 Îùá{£†Ø¥ éLPÖ Y}¼‹í¬–ï FÜR·µËiKYšž?Á0ñõÊ£Ø<ËpDö+è$ßam }är­¤/¿Ýâíñ¬¥8¸ñ0j£”hà ¼ÁÃgZ‘¼:Ù4ºZÏéÜj‹¾.¹Ö«A™èâ]”±j/cˆÏ¼*½|Ò üй¶·K󊹚ª¬x;’W_­§ ßø¢’äZÕ¤õ *±¯bH6êA&Ê)rG51#,¬8¯«Å³œ4ϲ‘ð ®yuãWT+VëùË@ýÁ.׿Lþ"®¸4¼[©ÜŒqí«÷’9Ël1Ô"mjK» ®Ô–Ø2Æ·Bk=[_ë÷-òA^áÎ9íúñêfƒ!ò„«é žEÃ÷ÈóQà ˆÎ8ÔT¥ŒÇŠðÀ0^¥w£¹Ç¥ÖÓó*¹u0 a¼* ÒŒö‰ÍÄÝ£³¸ÀZùJ ó,Óé®à™‘@­g{ekËÀkÛ<à '¨K‘„ݦ¯S$ËôŠ:<®™Ttÿ+ñœ4N[mc„Õz^;Ã{#G ®¬K­{1“´cû›'Úrâ]ÒÔzüh];£­Œá—(.Rƒ²Òæ¬~¬$TÄí¡Nt~ÝT|ÿkôLØ|\¯×rDæ¬.f0Ô ’:$w$*Ú¾êVRåÏû¸%2ê[TuðYª¦*Ä»¨vÌÉöWE±qk$ô@w7‰;`ÂT¯ÚÅ[tRü0bO\þës6òé•rAÎ#æ”ÉQ¹ñ.Ó-#øÙùŸ5ÿlïφôªgCÞ®cÈ&-ï çUߎHôE±vºf ò*8µ 1FåìèçÕðÓ,8mg¼¯ìTŽ7ϲ‘á )X ÷ÒêÕ”–WCìbu²Ñ¦”§WÙe¸çðc Þ‰R ã[Ôtä©õˆ[ëµÅNRÏBÑÄ»Hã¦ròý¼ÚDvhFˆÎv7lyÍýJ­g§¬õˆ¯Ö‡×²TÂxu9O¨Â­—‹~ûë>Àê•êZý$ʳ,G¤»‚¿ÖóqêA®6‘JL©õˆTë‘ áÕu‡Ê«—Q®áUê{í1Êù“£¢ãRÕzþBSÝ/l ¦e’ò¦c’ê7$Òyh_s|GX­'{¶¶“ßmõPýè]©–%ÈÙÀÌJ5@2¯ÁsBD¼Ìœ?àÕ[ºZO-–µ^ UÔ]O­¥õgE\[‹™N1ýɾîºé‰i‰R…xõ¦ÏN®‘ùât†¨®A=«‘‘ªB¼ªš`Cò…„î5¦"["UY^§@Á|1Üá)VÍb“ð×§Öêñê6‘§ hþ«4„òÿÔ«j¼N“ 1ôŸ…?Ý­Èky"éyu†Pd^ŵ²o¸B^Ë“†Wý@,º®×òô_…5D\¼òf£¼–©”C«(y-S1ã[(×òš/ÞŒBdØ'äµ­ùç(9Û…[Wà•y°Oý]ÙùP¼×ìšß|ŠVüiòš]ÈkñB^³ y-^Èkv!¯Å yÍ.äµx!¯Ù…¼/ä5»×â…¼fòZ¼×ìB^‹òš]ÈkñB^³ y-^Èkv!¯Å yÍ.äµx!¯Ù…¼/ä5»×â…¼fòZ¼×ìB^‹òš]ÈkñB^³ y-^Èkv!¯Å yÍ.äµx!¯Ù…¼/ä5»×â…¼fòZ¼×ì áusgw›-÷êúæÖî:ýockww}gÖÞ¤mnîÞÙݤ¿·`ïîîWw¶_¹³½I7oÜÙÚÝIÎ?òšíˆñ_¡šÒóÊ×^Ù¡øŒë;ѯòeb7`å«ug}ÁW·ù‡Ý;_Ûú/(§;°ßAy òš]!öukkëk°†àÆÖæÅr{0åK`RSË~ïR€¿¶±{çÎúÎÖ»5ÃðÖF ÿyÍvÄø¯PM…ð Ö• þzjÞ0`U8ê#ü#XÛxì(µ¼7æ/Þ ‡¬Së»qÇYÎõî<,ñþW{›Èk„×ì áŒé+¯lï®ïÍÏßØÞ¾:ÿãë›@ñúî?^ßÝÞØçu,éöm†7,)¿±wùò×7v×·“¯ ‡¼f;büW¨¦ÂÚ[Ô/v÷ÆÅ‹{Ô9 þÕË`9¯ÎÏÎÍÍ}ºwc~nîòsÏͳówwv®^ž3>½±»ýÜÅ'Áæ2ÃŒ¼† yÍ®Pÿ•ÙÌ­§çgg矾³}wþòÓwç/>wõâO(³?¹±7?kÌï=5ÿé«ÿüÒü»óÀíË¿þô+»Û;ØÞŠòš]¡ý¯ÛlìíW6®RŸtþîsóORFçÿË/ÎúôӔͫOþå•’{ww—n¿KyÞÛÿµa4>}:ùzÝÈk¶#Æ…j*´ÿu{þmßÙÚÜ¢>€ñçìeYŸûõdoPŸösó?œ^?¥õÿ ÖÊšnûÎÞåù§ww6± RÈkv…Ù×íWàu»››ðzƒ­§.ÿ°}yz®^þØ×½§.þ¹1ÿõ§æzwãÎ×/Ïßk¼»N½‚=îM ¯áB^³+ª½ͬ§/_Þ[ß¹:ÿ?PçƒEýñÞ.ý<ÔRoö_ݸz<ê<·C=ÚÞÚL³À<òšíˆñ_¡š ß‚V>·}õIZ×ïínþÔ7ýñÞÕËŸîmí~ñâ“{{O¥àìP~¹Oï®ï‚§°½›&yÍvÄø¯PM…Ç»0f©ËvXÞ‚O08»Î;®6^ÝÞÞØä/™Ùf#Ô:#¯B^³+¬?‹:°[[0LE™Ü¾Á,ð6B å6‹…Ù]u›A¹¾Ëì0§{ÆØXò!ä5»ÂÆc)›,^`ç«€äæÎúö«Dpb¨]uƒÚÞ­-ºƒ½ –^cgûkw(ͻɇc‘׌GŒÿ ÕTÄx,¥zþ7 –€Á"³67QfI·™íÝÝ ¦—î§Lo;aYÛÈk´ áuB5¿·¡ãºPáŲ̎nnnˆÕ:µ®ëÌÝÝŒ©pB ÁoR§Þ¿¹`sraDB £¼ƒõ/Η%¨^m›ŒâѪœæ÷¶·ÖƒÃ§ÛÛ–½Ã¯Á–òƒ¯²ð€DÕ²;Xáæ.mrQ¿cÛŒn xw;êŠÛÓh_㕟×ɤ•¿ŸÂVýþx¥Ôò~°¶©wJAÜ€`XÆ%|}‹5´¶î@Œ,t ¼²½ùÕ]À•z·[wèŽ f¥Ô›;È«¬X˜&ÕûÌ­Gó7´þëæÖƺõK[[»?ð³§_Ù^çý[-°»ûÔåÿóÆÎÖ#øÕuèOøsv¾zõò%ã§w¿Vw‹Ï6ˆê-˜J^c5^'ÔÀR€÷«ú ÿ¯Ï_ÜÛ» qY@õõ]·(OÓO[[éB-)sg©ûþ«‹ôJ”hJ3ŒuíQžïnßá“¢ýš±§eçB¡J@Ú×0AÿÀº~þÖöùŸÞ}jþÓç¨|ò/Œ‹”ÁÿãéWéÖ‹ôœ«óŸÒÏ0ªu—q]¿düìëÛw®^þÙu îìÍÿô9˜£¸ÃßÄþ€£dfoT¼Nž‘ßÛÐO¤­««OþäÆÕù¿ÚÛý‡_¼øÃK—æ~غøÜÎösóOîmm^ÿ JésóóO?5ÿÓ½«ó?„1Û ð~|FÁö.ÏÓc¹eÝŽˆ^'/W#”(±#âu36¤? Ü;}õÔåŸ=½ öuîòs7æ/ïmRÿÕ˜5ææ~8{ñî'ŸÜû"õg·ÈíÏÍÿì.ô€± 3cƺ¦Í¾&úa ‹Ï¢M««—aþË_Q?у0‡`ïDgßØÙ„-!J›RüYcþ?åñY[à?lon­ß½xñ†³>Ad‹ yÕ y SH|Ö+¯llm=5ÿ¯î^½øãçÖ·žºü¿Îñv׿P»µûÔå‚?pqþîîöˆñ†ë›;;W/þ/wií¿u÷×ý®³LÚ×ÔB^ï½»³KÛNw÷._ÞNo\œŽE·BMww‹z¬s—÷nÀ̘ùŸR/÷/óO¿º»³}—EÆ^†~…»…À–‰A^S y S¯ë»ÿpgçîü§{0—Û0þêî×çy¼ö.ëÏ‚^ÖO÷`ÏOöXÿÀ]˜y@[f;;;Ÿ{Ò˜ýÉÝ»zcýÃHnt0,òªò¦PûºÃf·ÜpBWÖY·Ô+ 1¶” Ìî‚ÍtÃ&ø¨[|fÁ ×RÛüõ 6µ{;rz òªò¦p`{}wëKwîì®ïlCDÖúúƼ6X÷6¯è©ÝÚYuV|ƒ1\z^ýÒWa v‹÷4D8±È«NÈk˜Bý­]±¬Û«¼Õ´¾Ã£v Ž{âcÙx,`°¼bø;jsëÎ+ÛlÕloeò¦Pû øÛÜü ‡Ý¸Ã¦lorO`[ ‚ín²™‰l¸-¶* µ©›,~vfΰÅa×tB^ÄëWQÈk˜×* y òZE!¯aB^«(ä5LÈk…¼† y­¢×0!¯Uò&䵊B^ļVQÈk˜×* y òZE!¯aB^«(ä5LÈk…¼† y­¢×0!¯Uò&䵊B^ļVQÈk˜×* y òZE!¯aB^«(ä5LÈk…¼† y­¢×0!¯Uò&䵊B^ļVQÈk˜×* y òZE!¯aB^«(ä5LÈk…¼† y­¢×0!¯Uò&䵊B^Ãd”­²3 ’Â\ ×¾´±öúÿ¿#S²HIEND®B`‚nagios-2.6/html/docs/images/statetransitions.png0000664000076500007650000000535407436604451021504 0ustar nagiosnagios‰PNG  IHDR±µæè1!tIMEÑ³ç˜ pHYs  ÒÝ~üäPLTEÿÿÿÞÞÞÖÖÖ÷÷÷ÎÎÎZZZBBBccc”””œœœÆÆÆïïŒ)))JJJ999„„„¥¥¥çççsss!!!RRR111{{{½½½kkk­­­µµµÿïÖÖÿÖ)ÿ)!ÿ!ÿÿÖÿÿ)ÿÿ!ÿœ)ÿœ!ÿÖÖÿ))ÿ!!ÿÿÿÿÿÿÿŒÿŒÿÿÿÿ”ÿÿÿÖÖÿœœÿççÿ{{ÿÞÞÿRRÿµµÿ½½ÿBBÿ””ÿZZÿssÿ­­ÿccÿïïÿÎÎÿkkÿŒŒÿ¥¥ÿ„„ÿv8S ›IDATxÚí‰bÚF†w!d@ ’97nS·i𦗓6½·IûþïS+£E‘ÐŽ™?†àŸYfµ£2ÆŒ‘° H˜ëú)C:BD ›ˆ61l"bØD݉ˆa“ÂÄÆ¶Óþó†ãÇì‡î_׈9˜¦K)L̃+vËæ ‡Ç¬ôÔÌÞ>8:#bGM Üúc²K-.»iEÓbÊ›€½ŠnXçëA¸„Ó%LC‡«h9×ô>ìîÎŽ‰öz}À¾ŠogƒÁãùIPðÍÕv»a¦ácѰ]šíš#:“ÂÄæÁ’éfpÀñá’m,ú¬v´” ˜›àïïÎ ï÷7Aè$¾ J‰m¬LÐÌ þŸ@/|Ì0 ¹Ì`4†Y1¢3)LŒ­‚g3ŒÛÂ`/ªÅưfëÀ —rQÑ$wçÆDL̵,{.hOÌÊY¡ÍÁ[,Gl–•¤O#:“ÊÄÛØñRŇváe0á.ßöËÉÒ» c»€©™.}6(!ÆŠAl¼ØŽsÄ —]DgR›ê#žk8Ñ8p¹ò‡vrwnLx?ë*­±ìV§Ä²AÑSbcã…[#:“ÂÄlØ}É {ÐH ZW¼Â.Žã>6Ö¢>߀–ZíÈå‚rÄ’ ÝųàI†Åi’>–èL ëyÁ«a#( ËˆŽ wëlÀínœ~rwnÌœël¾åFÞÎåˆmvA»KoÊÁÑX2,9V\ ŠIab¤R1l"bØD݉ˆaÃ&"†MD ›ˆ61l"bØD݉ˆaææ‰ýú:¸zÿ»Œ[ÚPÆ6©¿…ûð‘½{'å–‡6”±A äoØÇ?>¾½ÿ[Ê-m(cƒÈß±÷÷÷þ“sËCÊØÆ ò·@ìŸwÿ•sËCÊØÆ ò·@ìïû»wÿî›%n©y¼j=LC¹Ož¿£ûwïïßHºå¡ elcP÷ùÛ öú¯w²nyhCÛÔ}þ6ˆýþÇŸ²nyhCÛÔ}þ6ˆýúö7Y·<´¡Œm ê>+g©~¹“viæ5l­‡i(÷‰ó·Bìõi÷u3Í¿ÖÃ4”ûÄù[!v'ï6ô4¯õ0Í•Ø)óWs×Çÿj+©MUÓ&þR©D•Ä–DL-QaS5±­žT"ª1l¢>†MTcØ$ÓÇ®s Ìj£‰s8í4O•_¢Æ®ŸGú&¾úùšUè:;…h§¦øà-å—èc×Ï¿Éèy˜¹Êè@âN;͓嗪1"¦P~‰>FÄ”ÊO5†-?õ1lù©Æ°å§>†-?Õ¶üÔǰå§Ö_ æêÀœô½ÔÇTË/óÂÏ O?ÒŸjLµü1®ÓR‡ú˜jùK‰Ò.¦S-¿@l~Êøpÿ-õ1Õò‹ÇŠCνì‘Õ˜ZùËîÓà§>¦Z~°œC5¦Zþ1=þkÛ½A}Lµüb«Ïì©ÆË_¾WLE}Lµü±1Ïý¥¡º5vSšÄJfY×êŽØ Äjõ±›¡¾Ý_½hY+Îò§›•zÒV‡{E×ÞhÓ ±Z5vóâÛœT%&̲¶Õ1Û¼„̟תÙLjØéˆ™vÏæ)1ª1Õ‰EÊÝ×ìcD ×9"ÖÝ9êcjkêœëîœõ1µ‰™Æ.ùÒÌ£Sš˜¾ÉÀI‰QS›hlÍ{&+""ÖçÃÜ{©¨©MÌ v‰&Ëî©ÆÔ&f.ùŒ1;ýDˆ&ûØ“‚ˆXÄ5Yc/óú‘ˆµC¬±>öäåw9½|BÄZ!ÖX±Ók®1ª1"VJŒú6bTcȈQÃFŒj 1êc؈Q!#F} ±–kì6/&k JbÛUƒX«}ìöU¤ïwW?Ü&Vâd¬l”è`$&³]ªÕØí«ï³zu+i‰NbÕÛu<±vûkžÕ:b-÷1"F5vîĨa#F5†Žõ1lĨÆ£>†XPcŸ=}ºÿzúY¹Ò`7ŸñEî+$öìËàß³äò峨W_ùúêVÒqÕÓ,™em«N~™íªÓÇÂÿ,öézRi|ªš˜å©uôœ%j¬ëm"å$ÑǺž")§êÛh¤NåGÌúŽ£ç¾¶ùoȨpÄQÒaRE'29’“§îÀzëæ8³ãˆ…­Ñ²¢KríyVމÎ8*¸½¼“Œ<èHeL†=ìHe/y¹­‹­O_7áФš˜ Ï«2Jœ2K.Ln`IÉM²9«Þº ªClYe”8e–\˜ÜÀ“’›dsV½uD5v2«»#u*"†MD ›ˆ61l:žØJ¯ã”{¤ãu<1€:N¹G*Hâi}4±Ü§áK;å©(‰5¢SI2Ok"¦”¨Æ°‰ˆaS+Ä8”9W6Øæ˜r/žcüEb1±x)]·4„KlΣ#PrŽ}°sÎ*H¼ÆÅãJ"–*|ZÇKiÀŒ²šç<4½rW¨s-ó—v²lbsH»riøÅq‹«V¸”îxj›ºÅ‡ÛÀ¤WÚ NIû¿jEKÙ41a¨/ôI-ó ѱ¦c"V©x)' ïÅ®åUÇįé Y…â¥lúÈC þ½ÔEÎñù ôÊq$AñR6xtŸ ¬eÚàôjŒ#ýD›ˆ61l"bØD݉ˆaÃ&"†MgKÌšo4×t=ãu¶Ä˜»X.í©1›}¸ÇIlwÆ¹âŒØÊãË…á9¶ï ×ãÖCQr“˜äéËÁÜñç–ÕÓæ#cèØ¶¯³ñªï*ýI.šXTf>ðË)ߎÙÀãÜ+œw/lo÷fËÕ®Fë¡ïO|¸͵¾š%÷ø‰mzóp6MþÓ_,ýÌ÷–¥­Æ—AÅM–¶n,Â’ëz[ [Æ;1–\xùSÝ!, »ÁÛß\Lm€íD_/Vj•ÚY+YúÁF÷ç{ØÒö=#Ø3öÔ¢m;bŒ„wž˜ž= ÷z«oÎg†7±qøR­ë-xpËØÙs‡ô\Sê-–ž£r–Á!þ¥òŠìñ“uaÃdêØNpL?75KuT;/1m¨Ñ5âÔùëõq‘Jt¾Ä°ŠˆaÃ&"†MD ›ˆ61l"bØD݉ˆaS|Š›„H]?eHGëÇ4¶µm€·ÕIEND®B`‚nagios-2.6/html/docs/images/statetransitions2.png0000664000076500007650000000526407436604451021566 0ustar nagiosnagios‰PNG  IHDR˲†ÈtIMEÑÄ× pHYs  ÒÝ~ücPLTEÿÿÿÞÞÞÖÖÖ÷÷÷ÎÎÎZZZBBBccc”””œœœÆÆÆïïŒ)))JJJ999„„„¥¥¥çççsss!!!RRR111{{{½½½kkk­­­µµµÆ+\Íì äIDATxÚí‹‚¢: †AD¹£à¾ÿSn[. Ta˜r+ùÏÑÙ i|¦d(!(u(5ÄXÎýaBI²TGÈR!Ku„,Õ²TGÈR!Ku´N–.ìÉ $dîk_Þv>ìTi×Ì ²Ëþ{l^§à_|¾¯oJ­“e )Ñi”u’BüÚË»ÑØ_({x’'ÜêM爘k†,‡ê }ep&} ÷ëC¾¼ìAÛ¡ ¤¢%päÛAÖÈòͬˆæ¤wbÇaøÐò˜ž{f?¬,{òa’hÅrºÌ/ãî‚sçûÏö€Óp.Âùû%)è/Ï,KÉ)0öÌ7ãŽ0{¦ÇtZ'K–Ê Z+CЈ –O•Ç“þû‘³Œt6„6¾<.–1Q¨`œHî¤dÏêî»sž‚ej¿9]Oô'-Ù'HH¾®üu…£צÇtZ'K’€OS“½;ì HÓJôßvÛ Šq¹¼\Æu§YÇ‚Öéá4‹ð,íw'›™CH,›ÔXº`Ûùv¼{L§•²|€?ôݳ<ެǵþª//”:åà —SÓ¹Tïu'be™õe¥ÇtZ)K‹ÆûIbyjÑTÊ÷…§•m7ãZ./—•b#5wY.6œIÕeñþîÄ^ZjÒö­¼¼5=¦ÓJYî d?-¡%±¶(wæ{|ózš/§Ë~J–=«ñÙù spA?6‹ð¼X–NÅ+ÓŽ‚+›±ŸQU/ß=¦ÓJY²bDö¹·Í0DZï'~hTË/³J–»8ƒÌÔr? ͦsžË´p*^»Kž^­£<Ž´¦ÇtZ+˯û4åÀ¶ ©Æ2KËK1·qÙË·s’yëeï„Û.Ëb²±CÑ„yù§cJdÙV•Žé n)7U/eSn—åUe2ƒ=dÜ$%/?“MdÙPu‰€Ý#âqÓ¯óòÓH)ÚpdùûFB–=ñpê Êé:IàBô¸¯à ‡,å4±|°¸Cý¾õŠe O6/ϧû :K²­‘ˆeèk@ôºµºDPAX/‘åh„,- ´cV³ø±¥èмÌ'Îv‹,Gk$bóAÒ¬ÙòsÊrŸ@YJ1/GëKK_íœêór¼¾&¿Gór´¾ä°tãó½ßìãîÇ"Ëщï©tÌc7'ÌËñú’Ãr—Fÿƒ’K‹õr¬¾$ÖKßí{d9Z£6Ký»|œíjŠõr¼¾ä°d÷¥C¥ÝÏż¯/YÇ>YÔï¹°X/ÇëKK~Üãý¤Ýç%˜—ãõ%¯^ržIWS¬—ãõ%ó8ÖÁãØW/ïüòá…x~)mí³_÷I^÷™oõ2¯Çj½šb½¯/üžDZ\6ÈëåX}a^J‹ËöXb½­/ÌKiqÙ K¬—cõ…y)-.Ûc‰õr´¾0/¥Åeƒ,±^ŽÕ楴¸l%ÖËÑú¼”— ²Äz9V_˜—Òâ²=–X/Gë óRZ\6ÈëåX}a^J‹ËöXb½­¯éó2Õ/º•=LBÛ@ èJâÚ‡õÕ³Q ‹¥}H<ϨýŸÕõ¸¡ÃÒnÕÛ­WCÆ¥ná.ß,í&Âuµûm6ë««a+n­ õìyWY,)MbÛüU¾Ç±]·ä†ï–v+úÎluKÙò«E¸ÆKÃR6ûlaM:×.èG¸w—¦%÷ú·KžIão~þIJ¥8î2,"S?·~ lT¿”g·¦$³¼u‘©Ÿ[¿†6ªßFÊ3 ‹[S˜—" æ%j^!Ku„,Õ²TGÈRIey7†XÄ6Ô¯%•%À‹Ø†j¨û/“eû1ë},bª©îa^®D=>ðÈr-¼TGÈRMÌ2‘åé€súâ#¶‘r* ªP¾¦­lx‰,ý7P³°ÀœšåN7éÞjgµy‘åK쟇ò5l]ò¯ûèFçÀj„:dMÛAjßT$ R5O^CòYB›Éšç¹ûöc0£#²ì å§ÁJ>ËKÐ\Q î®á”µ,ûަÝ⡜ŽekDÕ!iUj½˜C󥋅,;•‡ÒlŒmWǸۧœlq¾0­By(§;öiqbO£j–$¼ƒÑÙÕRÊIÎIÊ>»:<9àí´C}~­Ž¥:B–êYª#d©Ž¥:B–êYª#dÙ–í§z`÷›¤eIB–Ñíæ\Ì£uÚ+Bº9–Å5üŽë…÷8¼Efì9‰wxX©¾[CšnŽeÏ˾šï%¾mïtÿh<ÇI ójÝ÷A÷´ 3îÙ&Kžš „?—0³ˆ‡aÜøê!8;qqS’èÏãã$n’G_ß/2M7Í2Ýø;Ét½ý-Ü>ºEmýnýÐ,uoŽaF,MçÞ—úŽ‘ ³$å+ j ªZ°OÏ sGÔsF©vŒ KÆREKįìZ™”7'‰M:ÎîÅ‘ïA–@b8¶î@:ÅΕ¡š½?ùWÓÈ‹¥ÅN=çÞƒO;F%ÐÁ4£VüvÑ->å½=1ùYúA,Ù$˲ϸÏñ虈Òí…C,„,҆ɯú,òÔ㣥@»ýª–B–êYª#d©Ž¥:B–êYª#d©Ž¥:B–êYª£ü;”šûÄ’¨ÿ. §èç æIEND®B`‚nagios-2.6/html/docs/about.html0000664000076500007650000001041607743356403016110 0ustar nagiosnagios About Nagios

    About Nagios®


    What Is This?

    Nagios® is a system and network monitoring application. It watches hosts and services that you specify, alerting you when things go bad and when they get better.

    Nagios was originally designed to run under Linux, although it should work under most other unices as well.

    Some of the many features of Nagios® include:

    • Monitoring of network services (SMTP, POP3, HTTP, NNTP, PING, etc.)
    • Monitoring of host resources (processor load, disk usage, etc.)
    • Simple plugin design that allows users to easily develop their own service checks
    • Parallelized service checks
    • Ability to define network host hierarchy using "parent" hosts, allowing detection of and distinction between hosts that are down and those that are unreachable
    • Contact notifications when service or host problems occur and get resolved (via email, pager, or user-defined method)
    • Ability to define event handlers to be run during service or host events for proactive problem resolution
    • Automatic log file rotation
    • Support for implementing redundant monitoring hosts
    • Optional web interface for viewing current network status, notification and problem history, log file, etc.

    System Requirements

    The only requirement of running Nagios is a machine running Linux (or UNIX variant) and a C compiler. You will probably also want to have TCP/IP configured, as most service checks will be performed over the network.

    You are not required to use the CGIs included with Nagios. However, if you do decide to use them, you will need to have the following software installed...

    1. A web server (preferrably Apache)
    2. Thomas Boutell's gd library version 1.6.3 or higher (required by the statusmap and trends CGIs)

    Licensing

    Nagios® is licensed under the terms of the GNU General Public License Version 2 as published by the Free Software Foundation. This gives you legal permission to copy, distribute and/or modify Nagios under certain conditions. Read the 'LICENSE' file in the Nagios distribution or read the online version of the license for more details.

    Nagios® is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.

    Acknowledgements

    Several people have contributed to Nagios by either reporting bugs, suggesting improvements, writing plugins, etc. A list of some of the many contributors to the development of Nagios can be found at http://www.nagios.org.

    Downloading The Latest Version

    You can check for new versions of Nagios at http://www.nagios.org.



    Nagios and the Nagios logo are trademarks of Ethan Galstad. All other trademarks, servicemarks, registered trademarks, and registered servicemarks may be the property of their respective owner(s).
    nagios-2.6/html/docs/adaptive.html0000664000076500007650000001511107760540150016561 0ustar nagiosnagios Adaptive Monitoring

    Adaptive Monitoring


    Introduction

    Nagios allows you to change certain commands and host and service check attributes during runtime. I'll refer to this feature as "adaptive monitoring". Please note that the adaptive monitoring features found in Nagios will probably not be of much use to 99% of users, but they do allow you to do some neat things.

    What Can Be Changed?

    The following service check attributes can be changed during runtime:

    • Check command (and command arguments)
    • Event handler command (and command arguments)
    • Check interval
    • Max check attempts

    The following host check attributes can be changed during runtime:

    • Check command (and command arguments)
    • Event handler command (and command arguments)
    • Check interval
    • Max check attempts

    The following global attributes can be changed during runtime:

    • Global host event handler command (and command arguments)
    • Global service event handler command (and command arguments)

    External Commands For Adaptive Monitoring

    In order to change global or host- or service-specific attributes during runtime, you must submit the appropriate external command to Nagios via the external command file. The table below lists the different attributes that may be changed during runtime, along with the external command to accomplish the job.

    NOTE: When changing check commands or event handler commands, it is important to note that these commands must have been configured using command definitions before Nagios was started. Any request to change an check or event event handler command to use a command which has not been defined is ignore. Also of note, you specify command arguments along with the actual command name - just seperate individual arguments from the command name (and from each other) using bang (!) characters. More information on how arguments in command definitions are processed during runtime can be found in the documentation on macros.

    AttributeExternal CommandNotes
    Service check command CHANGE_SVC_CHECK_COMMAND:command_name Changes the service's current check command to whatever you specify in the command_name argument.
    Service event handler CHANGE_SVC_EVENT_HANDLER:command_name Changes the service's current event handler command to whatever you specify in the command_name argument.
    Service check interval CHANGE_NORMAL_SVC_CHECK_INTERVAL:interval Changes the service's normal check interval to be whatever you specify in the interval argument.
    Service check retry interval CHANGE_RETRY_SVC_CHECK_INTERVAL:interval Changes the services' retry check interval to be whatever you specify in the interval argument.
    Max service check attempts CHANGE_MAX_SVC_CHECK_ATTEMPTS:attempts Changes the maximum number of check attempts for the service to whatever you specify in the attempts argument.
    Host check command CHANGE_HOST_CHECK_COMMAND:command_name Changes the host's current check command to whatever you specify in the command_name argument.
    Host event handler CHANGE_HOST_EVENT_HANDLER:command_name Changes the host's current event handler command to whatever you specify in the command_name argument.
    Host check interval CHANGE_NORMAL_HOST_CHECK_INTERVAL:interval Changes the host's check interval to be whatever you specify in the interval argument.
    Max host check attempts CHANGE_MAX_HOST_CHECK_ATTEMPTS:attempts Changes the maximum number of check attempts for the host to whatever you specify in the attempts argument.
    Global host event handler CHANGE_GLOBAL_HOST_EVENT_HANDLER;command_name Changes the current global host event handler command to whatever you specify in the command_name argument.
    Global service event handler CHANGE_GLOBAL_SVC_EVENT_HANDLER;command_name Changes the current global service event handler command to whatever you specify in the command_name argument.

    nagios-2.6/html/docs/addons.html0000664000076500007650000000164507743356403016252 0ustar nagiosnagios Nagios Addons

    Nagios Addons


    Several "addons" are available for Nagios on the Nagios downloads page - http://www.nagios.org/download/.

    Addons are available for:

    • Managing the config files through a web interface
    • Monitoring remote hosts (*NIX, Windows, etc.)
    • Submitting passive checks from remote hosts
    • Simplifying/extending the notification logic
    • ...and much more


    nagios-2.6/html/docs/beginners.html0000664000076500007650000000550007743356403016750 0ustar nagiosnagios Advice for Beginners

    Advice for Beginners


    Congrats on choosing to try Nagios! Nagios is quite powerful and flexible, but unfortunately its not very friendly to newbies. Why? Because it takes a lot of work to get it installed and configured properly. That being said, if you stick with it and manage to get it up and running, you'll never want to be without it. :-) Here are some very important things to keep in mind for those of you who are first-time users of Nagios:

    1. Relax - its going to take some time. Don't expect to be able to compile Nagios and start it up right off the bat. Its not that easy. In fact, its pretty difficult. If you don't want to spend time learning how things work and getting things running smoothly, don't bother using this software. Instead, pay someone to monitor your network for you or hire someone to install Nagios for you. :-)

    2. Read the documentation. Nagios is difficult enough to configure when you've got a good grasp of what's going on, and nearly impossible if you don't. Do yourself a favor and read before blindly attempting to install and run Nagios. If you're the type who doesn't want to take the time to read the documentation, you'll probably find that others won't find the time to help you out when you have problems. RTFM.

    3. Use the sample config files. Sample configuration files are provided with Nagios. Look at them, modify them for your particular setup and test them! The sample files are just that - samples. There's a very good chance that they won't work for you without modifications. Sample config files can be found in the sample-config/ subdirectory of the Nagios distribution.

    4. Seek the help of others. If you've read the documentation, reviewed the sample config files, and are still having problems, try sending a descriptive email message describing your problems to the nagios-users mailing list. Due to the amount of work that I have to do for this project, I am unable to answer most of the questions that get sent directly to me, so your best source of help is going to be the mailing list. If you've done some background reading and you provide a good problem description, odds are that someone will give you some pointers on getting things working properly.


    nagios-2.6/html/docs/cgiauth.html0000664000076500007650000002454210342163030016404 0ustar nagiosnagios Authentication And Authorization In The CGIs

    Authentication And Authorization In The CGIs


    Notes

    Throughout these instructions I will be assuming that you are running the Apache web server on your machine. If you are running some other web server, you will have to make some adjustments.

    Definitions

    Throughout these instructions I will be using the following terms, so you should understand what they mean...

    • An authenticated user is an someone who has authenticated to the web server with a username and password and has been granted access to the Nagios web interface.
    • An authenticated contact is an authenticated user whose username matches the short name of a contact definition in your object configuration file(s).

    Index

    Setting up authenticated users
    Enabling authentication/authorization functionality in the CGIs
    Default permissions to CGI information
    Granting additional permissions to CGI information
    Authentication on secure web servers

    Setting Up Authenticated Users

    If you haven't done so already, you'll need to add the appropriate entries to your web server config file to enable basic authentication for the CGI and HTML portions of the Nagios web interface. Instructions for doing so can be found here.

    Now that you've configured your web server to require authentication for the Nagios web interface, you'll need to specify who has access. This is done by using the htpasswd command supplied with Apache.

    Running the following command will create a new file called htpasswd.users in the /usr/local/nagios/etc directory. It will also create an username/password entry for nagiosadmin. You will be asked to provide a password that will be used when nagiosadmin authenticates to the web server.

    htpasswd -c /usr/local/nagios/etc/htpasswd.users nagiosadmin

    Continue adding more users until you've created an account for everyone you want to access the CGIs. Use the following command to add additional users, replacing <username> with the actual username you want to add. Note that the -c option is not used, since you already created the initial file.

    htpasswd /usr/local/nagios/etc/htpasswd.users <username>

    Okay, so you're done with the first part of what needs to be done. At this point you should be prompted for a username and password if you point your web browser to the Nagios web interface. If you have problems getting user authentication to work at this point, read your webserver documentation for more info.

    Enabling Authentication/Authorization Functionality In The CGIs

    The next thing you need to do is make sure that the CGIs are configured to use the authentication and authorization functionality in determining what information and/or commands users have access to. This is done be setting the use_authentication variable in the CGI configuration file to a non-zero value. Example:

    use_authentication=1

    Okay, you're now done with setting up basic authentication/authorization functionality in the CGIs.

    Default Permissions To CGI Information

    So what default permissions do users have in the CGIs by default when the authentication/authorization functionality is enabled?

    CGI Data Authenticated Contacts* Other Authenticated Users*
    Host Status Information Yes No
    Host Configuration Information Yes No
    Host History Yes No
    Host Notifications Yes No
    Host Commands Yes No
    Service Status Information Yes No
    Service Configuration Information Yes No
    Service History Yes No
    Service Notifications Yes No
    Service Commands Yes No
    All Configuration Information No No
    System/Process Information No No
    System/Process Commands No No

    Authenticated contacts* are granted the following permissions for each service for which they are contacts (but not for services for which they are not contacts)...

    • Authorization to view service status information
    • Authorization to view service configuration information
    • Authorization to view history and notifications for the service
    • Authorization to issue service commands

    Authenticated contacts* are granted the following permissions for each host for which they are contacts (but not for hosts for which they are not contacts)...

    • Authorization to view host status information
    • Authorization to view host configuration information
    • Authorization to view history and notifications for the host
    • Authorization to issue host commands
    • Authorization to view status information for all services on the host
    • Authorization to view configuration information for all services on the host
    • Authorization to view history and notification information for all services on the host
    • Authorization to issue commands for all services on the host

    It is important to note that by default no one is authorized for the following...

    You will undoubtably want to access this information, so you'll have to assign additional rights for yourself (and possibly other users) as described below...

    Granting Additional Permissions To CGI Information

    You can grant authenticated contacts or other authenticated users permission to additional information in the CGIs by adding them to various authorization variables in the CGI configuration file. I realize that the available options don't allow for getting really specific about particular permissions, but its better than nothing..

    Additional authorization can be given to users by adding them to the following variables in the CGI configuration file...

    CGI Authorization Requirements

    If you are confused about the authorization needed to access various information in the CGIs, read the Authorization Requirements section for each CGI as described here.

    Authentication On Secured Web Servers

    If your web server is located in a secure domain (i.e., behind a firewall) or if you are using SSL, you can define a default username that can be used to access the CGIs. This is done by defining the default_user_name option in the CGI configuration file. By defining a default username that can access the CGIs, you can allow users to access the CGIs without necessarily having to authenticate to the web server.. You may want to use this to avoid having to use basic web authentication, as basic authentication transmits passwords in clear text over the Internet.

    Important: Do not define a default username unless you are running a secure web server and are sure that everyone who has access to the CGIs has been authenticated in some manner! If you define this variable, anyone who has not authenticated to the web server will inherit all rights you assign to this user!


    nagios-2.6/html/docs/cgiincludes.html0000664000076500007650000000622610170655663017271 0ustar nagiosnagios Custom CGI Headers and Footers

    Custom CGI Headers and Footers


    Introduction

    If you're doing custom installs of Nagios for clients, you may want to have a custom header and/or footer displayed in the output of the CGIs. This is particularly useful for displaying support contact information, etc. to the end user.

    It is important to note that, unless the custom header and footer files are executable, they are not processed in any way before they are displayed. The contents of the header and footer include files are simply read and displayed in the CGI output. That means they can only contain information a web browser can understand (HTML, JavaScript, etc.).

    If the custom header and footer files are executable, then the files are executed and their output returned to the user, so they should output valid HTML. Using this you can run your own custom designed CGI to insert data into the nagios display. This has been used to insert graphs from rrdtool using ddraw and command menus into the nagios display pane. The execuable customer header and footer files are run with the same CGI environment as the main nagios cgi, so your files can parse the query information, authenticated user information etc. to produce appropriate output.

    How Does It Work?

    You can include custom headers and footers in the output of the CGIs by dropping some appropriately named HTML files in the ssi/ subdirectory of the Nagios HTML directory (i.e. /usr/local/nagios/share/ssi).

    Custom headers are included immediately after the <BODY> tag in the CGI output, while custom footers are included immediately before the closing </BODY> tag.

    There are two types of customer headers and footers:

    • Global headers/footers. These files should be named common-header.ssi and common-footer.ssi, respectively. If these files exist, they will be included in the output of all CGIs.

    • CGI-specific headers/footers. These files should be named in the format CGINAME-header.ssi and CGINAME-footer.ssi, where CGINAME is the physical name of the CGI without the .cgi extension. For example, the header and footer files for the alert summary CGI (summary.cgi) would be named summary-header.ssi and summary-footer.ssi, respectively.

    You are not required to use any custom headers or footers. You can use only a global header if you wish. You can use only CGI-specific headers and a global footer if you wish. Whatever you want. Really.


    nagios-2.6/html/docs/cgis.html0000664000076500007650000007110607743356403015726 0ustar nagiosnagios Information On The CGIs

    Information On The CGIs


    Introduction

    The various CGIs distributed with Nagios are described here, along with the authorization requirements for accessing and using each CGI. By default the CGIs require that you have authenticated to the web server and are authorized to view any information you are requesting. For more information on configuring your web server and CGI configuration file to allow for this, read the sections on setting up the web interface and CGI authorization.

    Index

    Status CGI
    Status map CGI
    WAP interface CGI
    Status world CGI (VRML)
    Tactical overview CGI
    Network outages CGI
    Configuration CGI
    Command CGI
    Extended information CGI
    Event log CGI
    Alert history CGI
    Notifications CGI
    Trends CGI
    Availability reporting CGI
    Alert histogram CGI
    Alert summary CGI

    Status CGI
    Status CGI - Details Status CGI - Overview Status CGI - Summary Status CGI - Grid
    File Name: status.cgi

    Description:
    This is the most important CGI included with Nagios. It allows you to view the current status of all hosts and services that are being monitored. The status CGI can produce two main types of output - a status overview of all host groups (or a particular host group) and a detailed view of all services (or those associated with a particular host). Pretty icons can be associated with hosts by defining extended host and service information entries.

    Authorization Requirements:

    Status Map CGI
    Status Map CGI
    File Name: statusmap.cgi

    Description:
    This CGI creates a map of all hosts that you have defined on your network. The CGI uses Thomas Boutell's gd library (version 1.6.3 or higher) to create a PNG image of your network layout. The coordinates used when drawing each host (along with the optional pretty icons) are taken from extended host information definitions. If you'd prefer to let the CGI automatically generate drawing coordinates for you, use the default_statusmap_layout directive to specify a layout algorithm that should be used. If you can't seem to find this CGI, or if you have get errors when trying to compile or run it, read this FAQ.

    Authorization Requirements:

    • If you are authorized for all hosts you can view all hosts.
    • If you are an authenticated contact you can view hosts for which you are a contact.

    Note: Users who are not authorized to view specific hosts will see unknown nodes in those positions. I realize that they really shouldn't see anything there, but it doesn't make sense to even generate the map if you can't see all the host dependencies...

    WAP Interface CGI
    WAP Interface CGI
    File Name: statuswml.cgi

    Description:
    This CGI serves as a WAP interface to network status information. If you have a WAP-enable device (i.e. an Internet-ready cellphone), you can view status information while you're on the go. Different status views include hostgroup summary, hostgroup overview, host detail, service detail, all problems, and unhandled problems. In addition to viewing status information, you can also disable notifications and checks and acknowledge problems from your cellphone. Pretty cool, huh?

    Authorization Requirements:

    Status World CGI (VRML)
    3-D Status Map CGI
    File Name: statuswrl.cgi

    Description:
    This CGI creates a 3-D VRML model of all hosts that you have defined on your network. Coordinates used when drawing the hosts (as well as pretty texture maps) are defined using extended host information definitions. If you'd prefer to let the CGI automatically generate drawing coordinates for you, use the default_statuswrl_layout directive to specify a layout algorithm that should be used. You'll need a VRML browser (like Cortona, Cosmo Player or WorldView) installed on your system before you can actually view the generated model.

    Authorization Requirements:

    • If you are authorized for all hosts you can view all hosts.
    • If you are an authenticated contact you can view hosts for which you are a contact.

    Note: Users who are not authorized to view specific hosts will see unknown nodes in those positions. I realize that they really shouldn't see anything there, but it doesn't make sense to even generate the map if you can't see all the host dependencies...

    Tactical Overview CGI
    Tactical Overview CGI
    File Name: tac.cgi

    Description:
    This CGI is designed to server as a "birds-eye view" of all network monitoring activity. It allows you to quickly see network outages, host status, and service status. It distinguishes between problems that have been "handled" in some way (i.e. been acknowledged, had notifications disabled, etc.) and those which have not been handled, and thus need attention. Very useful if you've got a lot of hosts/services you're monitoring and you need to keep a single screen up to alert you of problems.

    Authorization Requirements:

    Network Outages CGI
    Network Outages CGI
    File Name: outages.cgi

    Description:
    This CGI will produce a listing of "problem" hosts on your network that are causing network outages. This can be particularly useful if you have a large network and want to quickly identify the source of the problem. Hosts are sorted based on the severity of the outage they are causing. More information on how the network outage CGI works can be found here.

    Authorization Requirements:

    • If you are authorized for all hosts you can view all hosts.
    • If you are an authenticated contact you can view hosts for which you are a contact.

    Configuration CGI
    Configuration CGI
    File Name: config.cgi

    Description:
    This CGI allows you to view objects (i.e. hosts, host groups, contacts, contact groups, time periods, services, etc.) that you have defined in your object configuration file(s).

    Authorization Requirements:

    Command CGI
    Command CGI
    File Name: cmd.cgi

    Description:
    This CGI allows you to send commands to the Nagios process. Although this CGI has several arguments, you would be better to leave them alone. Most will change between different revisions of Nagios. Use the extended information CGI as a starting point for issuing commands.

    Authorization Requirements:

    Notes:

    • If you have chosen not to use authentication with the CGIs, this CGI will not allow anyone to issue commands to Nagios. This is done for your own protection. I would suggest removing this CGI altogether if you decide not to use authentication with the CGIs.
    • In order for the CGI to issue commands to Nagios, you will have to set the proper file and directory permissions as described in this FAQ.

    Extended Information CGI
    Extended Information CGI - Process Information Extended Information CGI - Performance Information Extended Information CGI - Host Information Extended Information CGI - Service Information
    File Name: extinfo.cgi

    Description:
    This CGI allows you to view Nagios process information, host and service state statistics, host and service comments, and more. It also serves as a launching point for sending commands to Nagios via the command CGI. Although this CGI has several arguments, you would be better to leave them alone - they are likely to change between different releases of Nagios. You can access this CGI by clicking on the 'Network Health' and 'Process Information' links on the side navigation bar, or by clicking on a host or service link in the output of the status CGI.

    Authorization Requirements:

    Event Log CGI
    Event Log CGI
    File Name: showlog.cgi

    Description:
    This CGI will display the log file. If you have log rotation enabled, you can browse notifications present in archived log files by using the navigational links near the top of the page.

    Authorization Requirements:

    Alert History CGI
    Alert History CGI
    File Name: history.cgi

    Description:
    This CGI is used to display the history of problems with either a particular host or all hosts. The output is basically a subset of the information that is displayed by the log file CGI. You have the ability to filter the output to display only the specific types of problems you wish to see (i.e. hard and/or soft alerts, various types of service and host alerts, all types of alerts, etc.). If you have log rotation enabled, you can browse history information present in archived log files by using the navigational links near the top of the page.

    Authorization Requirements:

    • If you are authorized for all hosts you can view history information for all hosts and all services.
    • If you are authorized for all services you can view history information for all services.
    • If you are an authenticated contact you can view history information for all services and hosts for which you are a contact.

    Notifications CGI
    Notifications CGI
    File Name: notifications.cgi

    Description:
    This CGI is used to display host and service notifications that have been sent to various contacts. The output is basically a subset of the information that is displayed by the log file CGI. You have the ability to filter the output to display only the specific types of notifications you wish to see (i.e. service notifications, host notifications, notifications sent to specific contacts, etc). If you have log rotation enabled, you can browse notifications present in archived log files by using the navigational links near the top of the page.

    Authorization Requirements:

    • If you are authorized for all hosts you can view notifications for all hosts and all services.
    • If you are authorized for all services you can view notifications for all services.
    • If you are an authenticated contact you can view notifications for all services and hosts for which you are a contact.

    Trends CGI
    Trends CGI
    File Name: trends.cgi

    Description:
    This CGI is used to create a graph of host or service states over an arbitrary period of time. In order for this CGI to be of much use, you should enable log rotation and keep archived logs in the path specified by the log_archive_path directive. The CGI uses Thomas Boutell's gd library (version 1.6.3 or higher) to create the trends image. If you can't seem to find this CGI or if you have get errors when trying to compile or run it, read this FAQ.

    Authorization Requirements:

    • If you are authorized for all hosts you can view trends for all hosts and all services.
    • If you are authorized for all services you can view trends for all services.
    • If you are an authenticated contact you can view trends for all services and hosts for which you are a contact.

    Availability Reporting CGI
    Availability CGI - Hostgroup Availability CGI - Host
    File Name: avail.cgi

    Description:
    This CGI is used to report on the availability of hosts and services over a user-specified period of time. In order for this CGI to be of much use, you should enable log rotation and keep archived logs in the path specified by the log_archive_path directive.

    Authorization Requirements:

    • If you are authorized for all hosts you can view availability data for all hosts and all services.
    • If you are authorized for all services you can view availability data for all services.
    • If you are an authenticated contact you can view availability data for all services and hosts for which you are a contact.

    Alert Histogram CGI
    Alert Histogram CGI
    File Name: histogram.cgi

    Description:
    This CGI is used to report on the availability of hosts and services over a user-specified period of time. In order for this CGI to be of much use, you should enable log rotation and keep archived logs in the path specified by the log_archive_path directive. The CGI uses Thomas Boutell's gd library (version 1.6.3 or higher) to create the histogram image. If you can't seem to find this CGI or if you have get errors when trying to compile or run it, read this FAQ.

    Authorization Requirements:

    • If you are authorized for all hosts you can view histograms for all hosts and all services.
    • If you are authorized for all services you can view histograms for all services.
    • If you are an authenticated contact you can view histograms for all services and hosts for which you are a contact.

    Alert Summary CGI
    Alert Summary CGI
    File Name: summary.cgi

    Description:
    This CGI provides some generic reports about host and service alert data, including alert totals, top alert producers, etc.

    Authorization Requirements:

    • If you are authorized for all hosts you can view summary information for all hosts and all services.
    • If you are authorized for all services you can view summary information for all services.
    • If you are an authenticated contact you can view summary information for all services and hosts for which you are a contact.


    nagios-2.6/html/docs/checkscheduling.html0000664000076500007650000005522510141063404020106 0ustar nagiosnagios Service Check Scheduling

    Service Check Scheduling


    Index

    Introduction
    Configuration options
    Initial scheduling
    Inter-check delay
    Service interleaving
    Max concurrent service checks
    Time restraints
    Normal scheduling
    Scheduling during problems
    Host checks
    Scheduling delays
    Scheduling example
    Service definition options that affect scheduling

    Introduction

    I've gotten a lot of questions regarding how service checks are scheduled in certain situations, along with how the scheduling differs from when the checks are actually executed and their results are processed. I'll try to go into a little more detail on how this all works...

    Configuration Options

    Before we begin, there are several configuration options that affect how service checks are scheduled, executed, and processed. For starters, each service definition contains three options that determine when and how each specific service check is scheduled and executed. Those three options include:

    • normal_check_interval
    • retry_check_interval
    • check_period

    There are also four configuration options in the main configuration file that affect service checks. These include:

    We'll go into more detail on how all these options affect service check scheduling as we progress. First off, let's see how services are initially scheduled when Nagios first starts or restarts...

    Initial Scheduling

    When Nagios (re)starts, it will attempt to schedule the initial check of all services in a manner that will minimize the load imposed on the local and remote hosts. This is done by spacing the initial service checks out, as well as interleaving them. The spacing of service checks (also known as the inter-check delay) is used to minimize/equalize the load on the local host running Nagios and the interleaving is used to minimize/equalize load imposed on remote hosts. Both the inter-check delay and interleave functions are discussed below.

    Even though service checks are initially scheduled to balance the load on both the local and remote hosts, things will eventually give in to the ensuing chaos and be a bit random. Reasons for this include the fact that services are not all checked at the same interval, some services take longer to execute than others, host and/or service problems can alter the timing of one or more service checks, etc. At least we try to get things off to a good start. Hopefully the initial scheduling will keep the load on the local and remote hosts fairly balanced as time goes by...

    Note: If you want to view the initial service check scheduling information, start Nagios using the -s command line option. Doing so will display basic scheduling information (inter-check delay, interleave factor, first and last service check time, etc) and will create a new status log that shows the exact time that all services are initially scheduled. Because this option will overwrite the status log, you should not use it when another copy of Nagios is running. Nagios does not start monitoring anything when this argument is used.

    Inter-Check Delay

    As mentioned before, Nagios attempts to equalize the load placed on the machine that is running Nagios by equally spacing out initial service checks. The spacing between consecutive service checks is called the inter-check delay. By giving a value to the inter_check_delay_method variable in the main config file, you can modify how this delay is calculated. I will discuss how the "smart" calculation works, as this is the setting you will want to use for normal operation.

    When using the "smart" setting of the inter_check_delay_method variable, Nagios will calculate an inter-check delay value by using the following calculation:

    inter-check delay = (average check interval for all services) / (total number of services)

    Let's take an example. Say you have 1,000 services that each have a normal check interval of 5 minutes (obviously some services are going to be checked at different intervals, but let's look at an easy case...). The total check interal time for all services is 5,000 (1,000 * 5). That means that the average check interval for each service is 5 minutes (5,000 / 1,000). Give that information, we realize that (on average) we need to re-check 1,000 services every 5 minutes. This means that we should use an inter-check delay of 0.005 minutes (0.3 seconds) when spacing out the initial service checks. By spacing each service check out by 0.3 seconds, we can somewhat guarantee that Nagios is scheduling and/or executing 3 new service checks every second. By spacing the checks out evenly over time like this, we can hope that the load on the local server that is running Nagios remains somewhat balanced.

    Service Interleaving

    As discussed above, the inter-check delay helps to equalize the load that Nagios imposes on the local host. What about remote hosts? Is it necessary to equalize load on remote hosts? Why? Yes, it is important and yes, Nagios can help out with this. Equalizing load on remote hosts is especially important with the advent of service check parallelization. If you monitor a large number of services on a remote host and the checks were not spread out, the remote host might think that it was the victim of a SYN attack if there were a lot of open connections on the same port. Plus, attempting to equalize the load on hosts is just a nice thing to do...

    By giving a value to the service_interleave_factor variable in the main config file, you can modify how the interleave factor is calculated. I will discuss how the "smart" calculation works, as this will probably be the setting you will want to use for normal operation. You can, however, use a pre-set interleave factor instead of having Nagios calculate one for you. Also of note, if you use an interleave factor of 1, service check interleaving is basically disabled.

    When using the "smart" setting of the service_interleave_factor variable, Nagios will calculate an interleave factor by using the following calculation:

    interleave factor = ceil ( total number of services / total number of hosts )

    Let's take an example. Say you have a total of 1,000 services and 150 hosts that you monitor. Nagios would calculate the interleave factor to be 7. This means that when Nagios schedules initial service checks it will schedule the first one it finds, skip the next 6, schedule the next one, and so on... This process will keep repeating until all service checks have been scheduled. Since services are sorted (and thus scheduled) by the name of the host they are associated with, this will help with minimizing/equalizing the load placed upon remote hosts.

    The images below depict how service checks are scheduled when they are not interleaved (service_interleave_factor=1) and when they are interleaved with the service_interleave_factor variable equal to 4.

    Non-Interleaved Checks:Interleaved Checks:
    Non-Interleaved Checks Interleaved Checks
    Non-Interleaved Checks Interleaved Checks
    Interleaved Checks

    Maximum Concurrent Service Checks

    In order to prevent Nagios from consuming all of your CPU resources, you can restrict the maximum number of concurrent service checks that can be running at any given time. This is controlled by using the max_concurrent_checks option in the main config file.

    The good thing about this setting is that you can regulate Nagios' CPU usage. The down side is that service checks may fall behind if this value is set too low. When it comes time to execute a service check, Nagios will make sure that no more than x service checks are either being executed or waiting to have their results processed (where x is the number of checks you specified for the max_concurrent_checks option). If that limit has been reached, Nagios will postpone the execution of any pending checks until some of the previous checks have completed. So how does one determine a reasonable value for the max_concurrent_checks option?

    First off, you need to know the following things...

    • The inter-check delay that Nagios uses to initially schedule service checks (use the -s command line argument to check this)
    • The frequency (in seconds) of service reaper events, as specified by the service_reaper_frequency variable in the main config file.
    • A general idea of the average time that service checks actually take to execute (most plugins timeout after 10 seconds, so the average is probably going to be lower)

    Next, use the following calculation to determine a reasonable value for the maximum number of concurrent checks that are allowed...

    max. concurrent checks = ceil( max( service reaper frequency , average check execution time ) / inter-check delay )

    The calculated number should provide a reasonable starting point for the max_concurrent_checks variable. You may have to increase this value a bit if service checks are still falling behind schedule or decrease it if Nagios is hogging too much CPU time.

    Let's say you are monitoring 875 services, each with an average check interval of 2 minutes. That means that your inter-check delay is going to be 0.137 seconds. If you set the service reaper frequency to be 10 seconds, you can calculate a rough value for the max. number of concurrent checks as follows (I'll assume that the average execution time for service checks is less than 10 seconds) ...

    max. concurrent checks = ceil( 10 / 0.137 )

    In this case, the calculated value is going to be 73. This makes sense because (on average) Nagios are going to be executing just over 7 new service checks per second and it only processes service check results every 10 seconds. That means at given time there will be a just over 70 service checks that are either being executed or waiting to have their results processed. In this case, I would probably recommend bumping the max. concurrent checks value up to 80, since there will be delays when Nagios processes service check results and does its other work. Obviously, you're going to have test and tweak things a bit to get everything running smoothly on your system, but hopefully this provided some general guidelines...

    Time Restraints

    The check_period option determines the time period during which Nagios can run checks of the service. Regardless of what status a particular service is in, if the time that it is actually executed is not a vaid time within the time period that has been specified, the check will not be executed. Instead, Nagios will reschedule the service check for the next valid time in the time period. If the check can be run (e.g. the time is valid within the time period), the service check is executed.

    Note: Even though a service check may not be able to be executed at a given time, Nagios may still schedule it to be run at that time. This is most likely to happen during the initial scheduling of services, although it may happen in other instances as well. This does not mean that Nagios will execute the check! When it comes time to actually execute a service check, Nagios will verify that the check can be run at the current time. If it cannot, Nagios will not execute the service check, but will instead just reschedule it for a later time. Don't let this one throw you confuse you! The scheduling and execution of service checks are two distinctly different (although related) things.

    Normal Scheduling

    In an ideal world you wouldn't have network problems. But if that were the case, you wouldn't need a network monitoring tool. Anyway, when things are running smoothly and a service is in an OK state, we'll call that "normal". Service checks are normally scheduled at the frequency specified by the check_interval option. That's it. Simple, huh?

    Scheduling During Problems

    So what happens when there are problems with a service? Well, one of the things that happens is the service check scheduling changes. If you've configured the max_attempts option of the service definition to be something greater than 1, Nagios will recheck the service before deciding that a real problem exists. While the service is being rechecked (up to max_attempts times) it is considered to be in a "soft" state (as described here) and the service checks are rescheduled at a frequency determined by the retry_interval option.

    If Nagios rechecks the service max_attempts times and it is still in a non-OK state, Nagios will put the service into a "hard" state, send out notifications to contacts (if applicable), and start rescheduling future checks of the service at a frequency determined by the check_interval option.

    As always, there are exceptions to the rules. When a service check results in a non-OK state, Nagios will check the host that the service is associated with to determine whether or not is up (see the note below for info on how this is done). If the host is not up (i.e. it is either down or unreachable), Nagios will immediately put the service into a hard non-OK state and it will reset the current attempt number to 1. Since the service is in a hard non-OK state, the service check will be rescheduled at the normal frequency specified by the check_interval option instead of the retry_interval option.

    Host Checks

    Unlike service checks, host checks are not scheduled on a regular basis. Instead they are run on demand, as Nagios sees a need. This is a common question asked by users, so it needs to be clarified.

    One instance where Nagios checks the status of a host is when a service check results in a non-OK status. Nagios checks the host to decide whether or not the host is up, down, or unreachable. If the first host check returns a non-OK state, Nagios will keep pounding out checks of the host until either (a) the maximum number of host checks (specified by the max_attempts option in the host definition) is reached or (b) a host check results in an OK state.

    Also of note - when Nagios is check the status of a host, it holds off on doing anything else (executing new service checks, processing other service check results, etc). This can slow things down a bit and cause pending service checks to be delayed for a while, but it is necessary to determine the status of the host before Nagios can take any further action on the service(s) that are having problems.

    Scheduling Delays

    It should be noted that service check scheduling and execution is done on a best effort basis. Individual service checks are considered to be low priority events in Nagios, so they can get delayed if high priority events need to be executed. Examples of high priority events include log file rotations, external command checks, and service reaper events. Additionally, host checks will slow down the execution and processing of service checks.

    Scheduling Example

    The scheduling of service checks, their execution, and the processing of their results can be a bit difficult to understand, so let's look at a simple example. Look at the diagram below - I'll refer to it as I explain how things are done.

    Image 5.

    First off, the Xn events are service reaper events that are scheduled at a frequency specified by the service_reaper_frequency option in the main config file. Service reaper events do the work of gathering and processing service check results. They serve as the core logic for Nagios, kicking off host checks, event handlers and notifications as necessary.

    For the example here, a service has been scheduled to be executed at time A. However, Nagios got behind in its event queue, so the check was not actually executed until time B. The service check finished executing at time C, so the difference between points C and B is the actual amount of time that the check was running.

    The results of the service check are not processed immediately after the check is done executing. Instead, the results are saved for later processing by a service reaper event. The next service reaper event occurs at time D, so that is approximately the time that the results are processed (the actual time may be later than D since other service check results may be processed before this one).

    At the time that the service reaper event processes the service check results, it will reschedule the next service check and place it into Nagios' event queue. We'll assume that the service check resulted in an OK status, so the next check at time E is scheduled after the originally scheduled check time by a length of time specified by the check_interval option. Note that the service is not rescheduled based off the time that it was actually executed! There is one exception to this (isn't there always?) - if the time that the service check is actually executed (point B) occurs after the next service check time (point E), Nagios will compensate by adjusting the next check time. This is done to ensure that Nagios doesn't go nuts trying to keep up with service checks if it comes under heavy load. Besides, what's the point of scheduling something in the past...?

    Service Definition Options That Affect Scheduling

    Each service definition contains a normal_check_interval and retry_check_interval option. Hopefully this will clarify what these two options do, how they relate to the max_check_attempts option in the service definition, and how they affect the scheduling of the service.

    First off, the normal_check_interval option is the interval at which the service is checked under "normal" circumstances. "Normal" circumstances mean whenever the service is in an OK state or when its in a hard non-OK state.

    When a service first changes from an OK state to a non-OK state, Nagios gives you the ability to temporarily slow down or speed up the interval at which subsequent checks of that service will occur. When the service first changes state, Nagios will perform up to max_check_attempts-1 retries of the service check before it decides its a real problem. While the service is being retried, it is scheduled according to the retry_check_interval option, which might be faster or slower than the normal normal_check_interval option. While the service is being rechecked (up to max_check_attempts-1 times), the service is in a soft state. If the service is rechecked max_check_attempts-1 times and it is still in a non-OK state, the service turns into a hard state and is subsequently rescheduled at the normal rate specified by the check_interval option.

    On a side note, it you specify a value of 1 for the max_check_attempts option, the service will not ever be checked at the interval specified by the retry_check_interval option. Instead, it immediately turns into a hard state and is subsequently rescheduled at the rate specified by the normal_check_interval option.


    nagios-2.6/html/docs/clusters.html0000664000076500007650000002244610024240766016636 0ustar nagiosnagios Monitoring Service and Host Clusters

    Monitoring Service and Host Clusters


    Introduction

    Several people have asked how to go about monitoring clusters of hosts or services, so I decided to write up a little documentation on how to do this. Its fairly straightforward, so hopefully you find things easy to understand...

    First off, we need to define what we mean by a "cluster". The simplest way to understand this is with an example. Let's say that your organization has five hosts which provide redundant DNS services to your organization. If one of them fails, its not a major catastrophe because the remaining servers will continue to provide name resolution services. If you're concerned with monitoring the availability of DNS service to your organization, you will want to monitor five DNS servers. This is what I consider to be a service cluster. The service cluster consists of five separate DNS services that you are monitoring. Although you do want to monitor each individual service, your main concern is with the overall status of the DNS service cluster, rather than the availability of any one particular service.

    If your organization has a group of hosts that provide a high-availability (clustering) solution, I would consider those to be a host cluster. If one particular host fails, another will step in to take over all the duties of the failed server. As a side note, check out the High-Availability Linux Project for information on providing host and service redundancy with Linux.

    Plan of Attack

    There are several ways you could potentially monitor service or host clusters. I'll describe the method that I believe to be the easiest. Monitoring service or host clusters involves two things:

    • Monitoring individual cluster elements
    • Monitoring the cluster as a collective entity

    Monitoring individual host or service cluster elements is easier than you think. In fact, you're probably already doing it. For service clusters, just make sure that you are monitoring each service element of the cluster. If you've got a cluster of five DNS servers, make sure you have five separate service definitions (probably using the check_dns plugin). For host clusters, make sure you have configured appropriate host definitions for each member of the cluster (you'll also have to define at least one service to be monitored for each of the hosts). Important: You're going to want to disable notifications for the individual cluster elements (host or service definitions). Even though no notifications will be sent about the individual elements, you'll still get a visual display of the individual host or service status in the status CGI. This will be useful for pinpointing the source of problems within the cluster in the future.

    Monitoring the overall cluster can be done by using the previously cached results of cluster elements. Although you could re-check all elements of the cluster to determine the cluster's status, why waste bandwidth and resources when you already have the results cached? Where are the results cached? Cached results for cluster elements can be found in the status file (assuming you are monitoring each element). The check_cluster2 plugin is designed specifically for checking cached host and service states in the status file. Important: Although you didn't enable notifications for individual elements of the cluster, you will want them enabled for the overall cluster status check.

    Using the check_cluster2 Plugin

    The check_cluster2 plugin is designed to report the overall status of a host or service cluster by checking the status information of each individual host or service cluster elements.

    More to come... The check_cluster2 plugin can be found in the contrib directory of the Nagios Plugins release at http://sourceforge.net/projects/nagiosplug/.

    Monitoring Service Clusters

    Let's say you have three DNS servers that provide redundant services on your network. First off, you need to be monitoring each of these DNS servers seperately before you can monitor them as a cluster. I'll assume that you already have three seperate services (all called "DNS Service") associated with your DNS hosts (called "host1", "host2" and "host3").

    In order to monitor the services as a cluster, you'll need to create a new "cluster" service. However, before you do that, make sure you have a service cluster check command configured. Let's assume that you have a command called check_service_cluster defined as follows:

    define command{
    	command_name	check_service_cluster
    	command_line	/usr/local/nagios/libexec/check_cluster2 --service -l $ARG1$ -w $ARG2$ -c $ARG3$ -d $ARG4$ 
    	}
    

    Now you'll need to create the "cluster" service and use the check_service_cluster command you just created as the cluster's check command. The example below gives an example of how to do this. The example below will generate a CRITICAL alert if 2 or more services in the cluster are in a non-OK state, and a WARNING alert if only 1 of the services is in a non-OK state. If all the individual service members of the cluster are OK, the cluster check will return an OK state as well.

    
    
    define service{
    	...
    	check_command	check_service_cluster!"DNS Cluster"!1!2!$SERVICESTATEID:host1:DNS Service$,$SERVICESTATEID:host2:DNS Service$,$SERVICESTATEID:host3:DNS Service$
    	...
    	}
    
    
    

    It is important to notice that we are passing a comma-delimited list of on-demand service state macros to the $ARG4$ macro in the cluster check command. That's important! Nagios will fill those on-demand macros in with the current service state IDs (numerical values, rather than text strings) of the individual members of the cluster.

    Monitoring Host Clusters

    Monitoring host clusters is very similiar to monitoring service clusters. Obviously, the main difference is that the cluster members are hosts and not services. In order to monitor the status of a host cluster, you must define a service that uses the check_cluster2 plugin. The service should not be associated with any of the hosts in the cluster, as this will cause problems with notifications for the cluster if that host goes down. A good idea might be to associate the service with the host that Nagios is running on. After all, if the host that Nagios is running on goes down, then Nagios isn't running anymore, so there isn't anything you can do as far as monitoring (unless you've setup redundant monitoring hosts)...

    Anyway, let's assume that you have a check_host_cluster command defined as follows:

    define command{
    	command_name	check_host_cluster
    	command_line	/usr/local/nagios/libexec/check_cluster2 --host -l $ARG1$ -w $ARG2$ -c $ARG3$ -d $ARG4$ 
    	}
    

    Let's say you have three hosts (named "host1", "host2" and "host3") in the host cluster. If you want Nagios to generate a warning alert if one host in the cluster is not UP or a critical alert if two or more hosts are not UP, the the service you define to monitor the host cluster might look something like this:

    
    
    define service{
    	...
    	check_command	check_host_cluster!"Super Host Cluster"!1!2!$HOSTSTATEID:host1$,$HOSTSTATEID:host2$,$HOSTSTATEID:host3$
    	...
    	}
    
    
    

    It is important to notice that we are passing a comma-delimited list of on-demand host state macros to the $ARG4$ macro in the cluster check command. That's important! Nagios will fill those on-demand macros in with the current host state IDs (numerical values, rather than text strings) of the individual members of the cluster.

    That's it! Nagios will periodically check the status of the host cluster and send notifications to you when its status is degraded (assuming you've enabled notification for the service). Note that for thehost definitions of each cluster member, you will most likely want to disable notifications when the host goes down . Remeber that you don't care as much about the status of any individual host as you do the overall status of the cluster. Depending on your network layout and what you're trying to accomplish, you may wish to leave notifications for unreachable states enabled for the host definitions.


    nagios-2.6/html/docs/commandfile.html0000664000076500007650000001235507743356403017260 0ustar nagiosnagios External Command File Permissions

    External Command File Permissions


    Notes

    These instructions assume that you've installed Nagios on a dedicated monitoring/admin box that doesn't contain normal user accounts (i.e. isn't a public machine). If you've installed Nagios on a public/multi-user machine, I would suggest setting more restrictive permissions on the external command file and using something like CGIWrap to run the CGIs as a specific user. Failing to do so may allow normal users to control Nagios through the external command file! I'm guessing you don't want that. More information on securing Nagios can be found here.

    Introduction

    One of the most common problems people have seems to be with setting proper permissions for the external command file. You need to set the proper permission on the /usr/local/nagios/var/rw directory (or whatever the path portion of the command_file directive in your main configuration file is set to). I'll show you how to do this. Note: You must be root in order to do some of these steps...

    Users and Groups

    First, find the user that your web server process is running as. On many systems this is the user nobody, although it will vary depending on what OS/distribution you are running. You'll also need to know what user Nagios is effectively running as - this is specified with the nagios_user variable in the main config file.

    Next we're going to create a new group whose members include the user the web server is running as and the user Nagios is running as. Let's say we call this new group 'nagiocmd' (you can name it differently if you wish). On RedHat Linux you can use the following command to add a new group (other systems may differ):

    /usr/sbin/groupadd nagiocmd

    Next, add the web server user (nobody or apache, etc) and the Nagios user (nagios) to the newly created group with the following commands:

    /usr/sbin/usermod -G nagiocmd nagios
    /usr/sbin/usermod -G nagiocmd nobody

    Creating the directory

    Next, create the directory where the command file should be stored. By default, this is /usr/local/nagios/var/rw, although it can be changed by modifying the path specified in thecommand_file directory.

    mkdir /usr/local/nagios/var/rw

    Setting directory permissions

    Next, change the ownership of the directory that will be used to hold the command file...

    chown nagios.nagiocmd /usr/local/nagios/var/rw

    Make sure the Nagios user has full permissions on the directory...

    chmod u+rwx /usr/local/nagios/var/rw

    Make sure the group we created has full permissions on the directory.

    chmod g+rwx /usr/local/nagios/var/rw

    In order to force newly created files in the directory to inherit the group permissions from the directory, we need to enable the group sticky bit on the directory...

    chmod g+s /usr/local/nagios/var/rw

    Verifying the permissions

    Check the permissions on the rw/ subdirectory by running 'ls -al /usr/local/nagios/var'. You should see something similiar to the following:

    drwxrws---   2 nagios nagiocmd     1024 Aug 11 16:30 rw
    

    Note that the user nagios is the owner of the directory and the group nagiocmd is the group owner of the directory. The nagios user has rwx permissions and group nagiocmd has rw permissions on the directory. Also, note that the group sticky bit is enabled. That's what we want...

    Restart your web server

    Once you set the proper permission on the directory containing the external command file, make sure to restart your web server. If you fail to do this, Apache will not be able to write to the external command file, even though the user it runs as is a member of the nagiocmd group.

    Additional notes...

    If you supplied the --with-command-grp=somegroup option when running the configure script, you can create the directory to hold the command file and set the proper permissions automatically by running 'make install-commandmode'.


    nagios-2.6/html/docs/config.html0000664000076500007650000000671307743356403016250 0ustar nagiosnagios Configuring Nagios

    Configuring Nagios


    Configuration Overview

    There are several different configuration files that you're going to need to create or edit before you start monitoring anything. They are described below...

    Main Configuration File

    The main configuration file (usually /usr/local/nagios/etc/nagios.cfg) contains a number of directives that affect how Nagios operates. This config file is read by both the Nagios process and the CGIs. This is the first configuration file you're going to want to create or edit.

    Documentation for the main configuration file can be found here.

    A sample main configuration file is generated automatically when you run the configure script before compiling the binaries. Look for it either in the distribution directory or the etc/ subdirectory of your installation. When you install the sample config files using the make install-config command, a sample main configuration file will be placed into your settings directory (usually /usr/local/nagios/etc). The default name of the main configuration file is nagios.cfg.

    Resource File(s)

    Resource files can be used to store user-defined macros. Resource files can also contain other information (like database connection settings), although this will depend on how you've compiled Nagios. The main point of having resource files is to use them to store sensitive configuration information and not make them available to the CGIs.

    You can specify one or more optional resource files by using the resource_file directive in the main configuration file.

    Object Definition Files

    Object definition files are used to define hosts, services, hostgroups, contacts, contactgroups, commands, etc. This is where you define what things you want monitor and how you want to monitor them.

    Documentation for the object definition files can be found here.

    CGI Configuration File

    The CGI configuration file (usually /usr/local/nagios/etc/cgi.cfg) contains a number of directives that affect the operation of the CGIs.

    Documentation for the CGI configuration file can be found here.

    A sample CGI configuration file is generated automatically when you run the configure script before compiling the binaries. When you install the sample config files using the make install-config command, the CGI configuration file will be placed in the same directory as the main and host config files (usually /usr/local/nagios/etc). The default name of the CGI configuration file is cgi.cfg.


    nagios-2.6/html/docs/configcgi.html0000664000076500007650000005521210342163030016706 0ustar nagiosnagios CGI Configuration File Options

    CGI Configuration File Options


    Notes

    When creating and/or editing configuration files, keep the following in mind:

    1. Lines that start with a '#' character are taken to be comments and are not processed
    2. Variables names must begin at the start of the line - no white space is allowed before the name
    3. Variable names are case-sensitive

    Sample Configuration

    A sample CGI configuration file is created when you run the configure script - you can find the sample config file in the sample-config/ subdirectory of the Nagios distribution.

    Config File Location

    By default, Nagios expects the CGI configuration file to be named cgi.cfg and located in the config file directory along with the main config file. If you need to change the name of the file or its location, you can configure Apache to pass an environment variable named NAGIOS_CGI_CONFIG (which points to the correct location) to the CGIs. See the Apache documentation for information on how to do this.

    Index

    Main configuration file location
    Physical HTML path
    URL HTML path

    Authentication usage
    Default user name
    System/process information access
    System/process command access
    Configuration information access
    Global host information access
    Global host command access
    Global service information access
    Global service command access

    Statusmap CGI background image
    Default statusmap layout method
    Statuswrl CGI include world
    Default statuswrl layout method

    CGI refresh rate
    Audio alerts

    Ping syntax

    Main Configuration File Location

    Format: main_config_file=<file_name>
    Example: main_config_file=/usr/local/nagios/etc/nagios.cfg

    This specifies the location of your main configuration file. The CGIs need to know where to find this file in order to get information about configuration information, current host and service status, etc.

    Physical HTML Path

    Format: physical_html_path=<path>
    Example: physical_html_path=/usr/local/nagios/share

    This is the physical path where the HTML files for Nagios are kept on your workstation or server. Nagios assumes that the documentation and images files (used by the CGIs) are stored in subdirectories called docs/ and images/, respectively.

    URL HTML Path

    Format: url_html_path=<path>
    Example: url_html_path=/nagios

    If, when accessing Nagios via a web browser, you point to an URL like http://www.myhost.com/nagios, this value should be /nagios. Basically, its the path portion of the URL that is used to access the Nagios HTML pages.

    Authentication Usage

    Format: use_authentication=<0/1>
    Example: use_authentication=1

    This option controls whether or not the CGIs will use the authentication and authorization functionality when determining what information and commands users have access to. I would strongly suggest that you use the authentication functionality for the CGIs. If you decide not to use authentication, make sure to remove the command CGI to prevent unauthorized users from issuing commands to Nagios. The CGI will not issue commands to Nagios if authentication is disabled, but I would suggest removing it altogether just to be on the safe side. More information on how to setup authentication and configure authorization for the CGIs can be found here.

    • 0 = Don't use authentication functionality
    • 1 = Use authentication and authorization functionality (default)

    Default User Name

    Format: default_user_name=<username>
    Example: default_user_name=guest

    Setting this variable will define a default username that can access the CGIs. This allows people within a secure domain (i.e., behind a firewall) to access the CGIs without necessarily having to authenticate to the web server. You may want to use this to avoid having to use basic authentication if you are not using a secure server, as basic authentication transmits passwords in clear text over the Internet.

    Important: Do not define a default username unless you are running a secure web server and are sure that everyone who has access to the CGIs has been authenticated in some manner! If you define this variable, anyone who has not authenticated to the web server will inherit all rights you assign to this user!

    System/Process Information Access

    Format: authorized_for_system_information=<user1>,<user2>,<user3>,...<usern>
    Example: authorized_for_system_information=nagiosadmin,theboss

    This is a comma-delimited list of names of authenticated users who can view system/process information in the extended information CGI. Users in this list are not automatically authorized to issue system/process commands. If you want users to be able to issue system/process commands as well, you must add them to the authorized_for_system_commands variable. More information on how to setup authentication and configure authorization for the CGIs can be found here.

    System/Process Command Access

    Format: authorized_for_system_commands=<user1>,<user2>,<user3>,...<usern>
    Example: authorized_for_system_commands=nagiosadmin

    This is a comma-delimited list of names of authenticated users who can issue system/process commands via the command CGI. Users in this list are not automatically authorized to view system/process information. If you want users to be able to view system/process information as well, you must add them to the authorized_for_system_information variable. More information on how to setup authentication and configure authorization for the CGIs can be found here.

    Configuration Information Access

    Format: authorized_for_configuration_information=<user1>,<user2>,<user3>,...<usern>
    Example: authorized_for_configuration_information=nagiosadmin

    This is a comma-delimited list of names of authenticated users who can view configuration information in the configuration CGI. Users in this list can view information on all configured hosts, host groups, services, contacts, contact groups, time periods, and commands. More information on how to setup authentication and configure authorization for the CGIs can be found here.

    Global Host Information Access

    Format: authorized_for_all_hosts=<user1>,<user2>,<user3>,...<usern>
    Example: authorized_for_all_hosts=nagiosadmin,theboss

    This is a comma-delimited list of names of authenticated users who can view status and configuration information for all hosts. Users in this list are also automatically authorized to view information for all services. Users in this list are not automatically authorized to issue commands for all hosts or services. If you want users able to issue commands for all hosts and services as well, you must add them to the authorized_for_all_host_commands variable. More information on how to setup authentication and configure authorization for the CGIs can be found here.

    Global Host Command Access

    Format: authorized_for_all_host_commands=<user1>,<user2>,<user3>,...<usern>
    Example: authorized_for_all_host_commands=nagiosadmin

    This is a comma-delimited list of names of authenticated users who can issue commands for all hosts via the command CGI. Users in this list are also automatically authorized to issue commands for all services. Users in this list are not automatically authorized to view status or configuration information for all hosts or services. If you want users able to view status and configuration information for all hosts and services as well, you must add them to the authorized_for_all_hosts variable. More information on how to setup authentication and configure authorization for the CGIs can be found here.

    Global Service Information Access

    Format: authorized_for_all_services=<user1>,<user2>,<user3>,...<usern>
    Example: authorized_for_all_services=nagiosadmin,theboss

    This is a comma-delimited list of names of authenticated users who can view status and configuration information for all services. Users in this list are not automatically authorized to view information for all hosts. Users in this list are not automatically authorized to issue commands for all services. If you want users able to issue commands for all services as well, you must add them to the authorized_for_all_service_commands variable. More information on how to setup authentication and configure authorization for the CGIs can be found here.

    Global Service Command Access

    Format: authorized_for_all_service_commands=<user1>,<user2>,<user3>,...<usern>
    Example: authorized_for_all_service_commands=nagiosadmin

    This is a comma-delimited list of names of authenticated users who can issue commands for all services via the command CGI. Users in this list are not automatically authorized to issue commands for all hosts. Users in this list are not automatically authorized to view status or configuration information for all hosts. If you want users able to view status and configuration information for all services as well, you must add them to the authorized_for_all_services variable. More information on how to setup authentication and configure authorization for the CGIs can be found here.

    Statusmap CGI Background Image

    Format: statusmap_background_image=<image_file>
    Example: statusmap_background_image=smbackground.gd2

    This option allows you to specify an image to be used as a background in the statusmap CGI if you use the user-supplied coordinates layout method. The background image is not be available in any other layout methods. It is assumed that the image resides in the HTML images path (i.e. /usr/local/nagios/share/images). This path is automatically determined by appending "/images" to the path specified by the physical_html_path directive. Note: The image file can be in GIF, JPEG, PNG, or GD2 format. However, GD2 format (preferably in uncompressed format) is recommended, as it will reduce the CPU load when the CGI generates the map image.

    Default Statusmap Layout Method

    Format: default_statusmap_layout=<layout_number>
    Example: default_statusmap_layout=4

    This option allows you to specify the default layout method used by the statusmap CGI. Valid options are:

    <layout_number> ValueLayout Method
    0User-defined coordinates
    1Depth layers
    2Collapsed tree
    3Balanced tree
    4Circular
    5Circular (Marked Up)
    6Circular (Balloon)

    Statuswrl CGI Include World

    Format: statuswrl_include=<vrml_file>
    Example: statuswrl_include=myworld.wrl

    This option allows you to include your own objects in the generated VRML world. It is assumed that the file resides in the path specified by the physical_html_path directive. Note: This file must be a fully qualified VRML world (i.e. you can view it by itself in a VRML browser).

    Default Statuswrl Layout Method

    Format: default_statuswrl_layout=<layout_number>
    Example: default_statuswrl_layout=4

    This option allows you to specify the default layout method used by the statuswrl CGI. Valid options are:

    <layout_number> ValueLayout Method
    0User-defined coordinates
    2Collapsed tree
    3Balanced tree
    4Circular

    CGI Refresh Rate

    Format: refresh_rate=<rate_in_seconds>
    Example: refresh_rate=90

    This option allows you to specify the number of seconds between page refreshes for the status, statusmap, and extinfo CGIs.

    Audio Alerts

    Formats: host_unreachable_sound=<sound_file>
    host_down_sound=<sound_file>
    service_critical_sound=<sound_file>
    service_warning_sound=<sound_file>
    service_unknown_sound=<sound_file>
    Examples: host_unreachable_sound=hostu.wav
    host_down_sound=hostd.wav
    service_critical_sound=critical.wav
    service_warning_sound=warning.wav
    service_unknown_sound=unknown.wav

    These options allow you to specify an audio file that should be played in your browser if there are problems when you are viewing the status CGI. If there are problems, the audio file for the most critical type of problem will be played. The most critical type of problem is on or more unreachable hosts, while the least critical is one or more services in an unknown state (see the order in the example above). Audio files are assumed to be in the media/ subdirectory in your HTML directory (i.e. /usr/local/nagios/share/media).

    Ping Syntax

    Format: ping_syntax=<command>
    Example: ping_syntax=/bin/ping -n -U -c 5 $HOSTADDRESS$

    This option determines what syntax should be used when attempting to ping a host from the WAP interface (using the statuswml CGI. You must include the full path to the ping binary, along with all required options. The $HOSTADDRESS$ macro is substituted with the address of the host before the command is executed.


    nagios-2.6/html/docs/configextinfo.html0000664000076500007650000000262707743356403017645 0ustar nagiosnagios Extended Information Configuration

    Extended Information Configuration


    What is Extended Information?

    Extended information consists of optional definitions for hosts and services that is used by the CGIs in the following ways:

    • to provide URLs to additional information about the host or service
    • to add pretty icons to the hosts and services displayed in the web interface
    • to draw hosts in the statusmap and statuswrl CGIs at user-defined 2-D and 3-D coordinates

    Where is Extended Information Defined?

    Extended information definitions are stored in object configuration files along with definitions for hosts, services, contacts, etc. You can use templates to define entries for multiple hosts and services quickly and easily.


    nagios-2.6/html/docs/configmain.html0000664000076500007650000031231310520557234017101 0ustar nagiosnagios Main Configuration File Options

    Main Configuration File Options


    Notes

    When creating and/or editing configuration files, keep the following in mind:

    1. Lines that start with a '#' character are taken to be comments and are not processed
    2. Variables names must begin at the start of the line - no white space is allowed before the name
    3. Variable names are case-sensitive

    Sample Configuration

    A sample main configuration file is created in the base directory of the Nagios distribution when you run the configure script. The default name of the main configuration file is nagios.cfg - its usually placed in the etc/ subdirectory of you Nagios installation (i.e. /usr/local/nagios/etc/).

    Index

    Log file
    Object configuration file
    Object configuration directory
    Object cache file
    Resource file
    Temp file

    Status file
    Aggregated status updates option
    Aggregated status data update interval

    Nagios user
    Nagios group

    Notifications option
    Service check execution option
    Passive service check acceptance option
    Host check execution option
    Passive host check acceptance option
    Event handler option

    Log rotation method
    Log archive path

    External command check option
    External command check interval
    External command file

    Comment file
    Downtime file
    Lock file

    State retention option
    State retention file
    Automatic state retention update interval
    Use retained program state option
    Use retained scheduling info option

    Syslog logging option
    Notification logging option
    Service check retry logging option
    Host retry logging option
    Event handler logging option
    Initial state logging option
    External command logging option
    Passive check logging option

    Global host event handler
    Global service event handler

    Inter-check sleep time
    Service inter-check delay method
    Maximum service check spread
    Service interleave factor
    Maximum concurrent service checks
    Service reaper frequency
    Host inter-check delay method
    Maximum host check spread
    Timing interval length
    Auto-rescheduling option
    Auto-rescheduling interval
    Auto-rescheduling window

    Aggressive host checking option

    Flap detection option
    Low service flap threshold
    High service flap threshold
    Low host flap threshold
    High host flap threshold

    Soft service dependencies option

    Service check timeout
    Host check timeout
    Event handler timeout
    Notification timeout
    Obsessive compulsive service processor timeout
    Obsessive compulsive host processor timeout
    Performance data processor command timeout

    Obsess over services option
    Obsessive compulsive service processor command
    Obsess over hosts option
    Obsessive compulsive host processor command

    Performance data processing option
    Host performance data processing command
    Service performance data processing command
    Host performance data file
    Service performance data file
    Host performance data file template
    Service performance data file template
    Host performance data file mode
    Service performance data file mode
    Host performance data file processing interval
    Service performance data file processing interval
    Host performance data file processing command
    Service performance data file processing command

    Orphaned service check option

    Service freshness checking option
    Service freshness check interval
    Host freshness checking option
    Host freshness check interval

    Date format

    Illegal object name characters
    Illegal macro output characters

    Regular expression matching option
    True regular expression matching option

    Administrator email address
    Administrator pager

    Log File

    Format: log_file=<file_name>
    Example: log_file=/usr/local/nagios/var/nagios.log

    This variable specifies where Nagios should create its main log file. This should be the first variable that you define in your configuration file, as Nagios will try to write errors that it finds in the rest of your configuration data to this file. If you have log rotation enabled, this file will automatically be rotated every hour, day, week, or month.

    Object Configuration File

    Format: cfg_file=<file_name>
    Example: cfg_file=/usr/local/nagios/etc/hosts.cfg
    cfg_file=/usr/local/nagios/etc/services.cfg
    cfg_file=/usr/local/nagios/etc/commands.cfg

    This directive is used to specify an object configuration file containing object definitions that Nagios should use for monitoring. Object configuration files contain definitions for hosts, host groups, contacts, contact groups, services, commands, etc. You can seperate your configuration information into several files and specify multiple cfg_file= statements to have each of them processed.

    Object Configuration Directory

    Format: cfg_dir=<directory_name>
    Example: cfg_dir=/usr/local/nagios/etc/commands
    cfg_dir=/usr/local/nagios/etc/services
    cfg_dir=/usr/local/nagios/etc/hosts

    This directive is used to specify a directory which contains object configuration files that Nagios should use for monitoring. All files in the directory with a .cfg extension are processed as object config files. Additionally, Nagios will recursively process all config files in subdirectories of the directory you specify here. You can seperate your configuration files into different directories and specify multiple cfg_dir= statements to have all config files in each directory processed.

    Object Cache File

    Format: object_cache_file=<file_name>
    Example: object_cache_file_file=/usr/local/nagios/var/objects.cache

    This directive is used to specify a file in which a cached copy of object definitions should be stored. The cache file is (re)created every time Nagios is (re)started and is used by the CGIs. It is intended to speed up config file caching in the CGIs and allow you to edit the source object config files while Nagios is running without affecting the output displayed in the CGIs.

    Resource File

    Format: resource_file=<file_name>
    Example: resource_file=/usr/local/nagios/etc/resource.cfg

    This is used to specify an optional resource file that can contain $USERn$ macro definitions. $USERn$ macros are useful for storing usernames, passwords, and items commonly used in command definitions (like directory paths). The CGIs will not attempt to read resource files, so you can set restrictive permissions (600 or 660) on them to protect sensitive information. You can include multiple resource files by adding multiple resource_file statements to the main config file - Nagios will process them all. See the sample resource.cfg file in the base of the Nagios directory for an example of how to define $USERn$ macros.

    Temp File

    Format: temp_file=<file_name>
    Example: temp_file=/usr/local/nagios/var/nagios.tmp

    This is a temporary file that Nagios periodically creates to use when updating comment data, status data, etc. The file is deleted when it is no longer needed.

    Status File

    Format: status_file=<file_name>
    Example: status_file=/usr/local/nagios/var/status.dat

    This is the file that Nagios uses to store the current status of all monitored services. The status of all hosts associated with the service you monitor are also recorded here. This file is used by the CGIs so that current monitoring status can be reported via a web interface. The CGIs must have read access to this file in order to function properly. This file is deleted every time Nagios stops and recreated when it starts.

    Aggregated Status Updates Option

    Format: aggregate_status_updates=<0/1>
    Example: aggregate_status_updates=1

    This option determines whether or not Nagios will aggregate updates of host, service, and program status data. If you do not enable this option, status data is updated every time a host or service checks occurs. This can result in high CPU loads and file I/O if you are monitoring a lot of services. If you want Nagios to only update status data (in the status file) every few seconds (as determined by the status_update_interval option), enable this option. If you want immediate updates, disable it. I would highly recommend using aggregated updates (even at short intervals) unless you have good reason not to. Values are as follows:

    • 0 = Disable aggregated updates
    • 1 = Enabled aggregated updates (default)

    Aggregated Status Update Interval

    Format: status_update_interval=<seconds>
    Example: status_update_interval=15

    This setting determines how often (in seconds) that Nagios will update status data in the status file. The minimum update interval is five seconds. If you have disabled aggregated status updates (with the aggregate_status_updates option), this option has no effect.

    Nagios User

    Format: nagios_user=<username/UID>
    Example: nagios_user=nagios

    This is used to set the effective user that the Nagios process should run as. After initial program startup and before starting to monitor anything, Nagios will drop its effective privileges and run as this user. You may specify either a username or a UID.

    Nagios Group

    Format: nagios_group=<groupname/GID>
    Example: nagios_group=nagios

    This is used to set the effective group that the Nagios process should run as. After initial program startup and before starting to monitor anything, Nagios will drop its effective privileges and run as this group. You may specify either a groupname or a GID.

    Notifications Option

    Format: enable_notifications=<0/1>
    Example: enable_notifications=1

    This option determines whether or not Nagios will send out notifications when it initially (re)starts. If this option is disabled, Nagios will not send out notifications for any host or service. Note: If you have state retention enabled, Nagios will ignore this setting when it (re)starts and use the last known setting for this option (as stored in the state retention file), unless you disable the use_retained_program_state option. If you want to change this option when state retention is active (and the use_retained_program_state is enabled), you'll have to use the appropriate external command or change it via the web interface. Values are as follows:

    • 0 = Disable notifications
    • 1 = Enable notifications (default)

    Service Check Execution Option

    Format: execute_service_checks=<0/1>
    Example: execute_service_checks=1

    This option determines whether or not Nagios will execute service checks when it initially (re)starts. If this option is disabled, Nagios will not actively execute any service checks and will remain in a sort of "sleep" mode (it can still accept passive checks unless you've disabled them). This option is most often used when configuring backup monitoring servers, as described in the documentation on redundancy, or when setting up a distributed monitoring environment. Note: If you have state retention enabled, Nagios will ignore this setting when it (re)starts and use the last known setting for this option (as stored in the state retention file), unless you disable the use_retained_program_state option. If you want to change this option when state retention is active (and the use_retained_program_state is enabled), you'll have to use the appropriate external command or change it via the web interface. Values are as follows:

    • 0 = Don't execute service checks
    • 1 = Execute service checks (default)

    Passive Service Check Acceptance Option

    Format: accept_passive_service_checks=<0/1>
    Example: accept_passive_service_checks=1

    This option determines whether or not Nagios will accept passive service checks when it initially (re)starts. If this option is disabled, Nagios will not accept any passive service checks. Note: If you have state retention enabled, Nagios will ignore this setting when it (re)starts and use the last known setting for this option (as stored in the state retention file), unless you disable the use_retained_program_state option. If you want to change this option when state retention is active (and the use_retained_program_state is enabled), you'll have to use the appropriate external command or change it via the web interface. Values are as follows:

    • 0 = Don't accept passive service checks
    • 1 = Accept passive service checks (default)

    Host Check Execution Option

    Format: execute_host_checks=<0/1>
    Example: execute_host_checks=1

    This option determines whether or not Nagios will execute on-demand and regularly scheduled host checks when it initially (re)starts. If this option is disabled, Nagios will not actively execute any host checks, although it can still accept passive host checks unless you've disabled them). This option is most often used when configuring backup monitoring servers, as described in the documentation on redundancy, or when setting up a distributed monitoring environment. Note: If you have state retention enabled, Nagios will ignore this setting when it (re)starts and use the last known setting for this option (as stored in the state retention file), unless you disable the use_retained_program_state option. If you want to change this option when state retention is active (and the use_retained_program_state is enabled), you'll have to use the appropriate external command or change it via the web interface. Values are as follows:

    • 0 = Don't execute host checks
    • 1 = Execute host checks (default)

    Passive Host Check Acceptance Option

    Format: accept_passive_host_checks=<0/1>
    Example: accept_passive_host_checks=1

    This option determines whether or not Nagios will accept passive host checks when it initially (re)starts. If this option is disabled, Nagios will not accept any passive host checks. Note: If you have state retention enabled, Nagios will ignore this setting when it (re)starts and use the last known setting for this option (as stored in the state retention file), unless you disable the use_retained_program_state option. If you want to change this option when state retention is active (and the use_retained_program_state is enabled), you'll have to use the appropriate external command or change it via the web interface. Values are as follows:

    • 0 = Don't accept passive host checks
    • 1 = Accept passive host checks (default)

    Event Handler Option

    Format: enable_event_handlers=<0/1>
    Example: enable_event_handlers=1

    This option determines whether or not Nagios will run event handlers when it initially (re)starts. If this option is disabled, Nagios will not run any host or service event handlers. Note: If you have state retention enabled, Nagios will ignore this setting when it (re)starts and use the last known setting for this option (as stored in the state retention file), unless you disable the use_retained_program_state option. If you want to change this option when state retention is active (and the use_retained_program_state is enabled), you'll have to use the appropriate external command or change it via the web interface. Values are as follows:

    • 0 = Disable event handlers
    • 1 = Enable event handlers (default)

    Log Rotation Method

    Format: log_rotation_method=<n/h/d/w/m>
    Example: log_rotation_method=d

    This is the rotation method that you would like Nagios to use for your log file. Values are as follows:

    • n = None (don't rotate the log - this is the default)
    • h = Hourly (rotate the log at the top of each hour)
    • d = Daily (rotate the log at midnight each day)
    • w = Weekly (rotate the log at midnight on Saturday)
    • m = Monthly (rotate the log at midnight on the last day of the month)

    Log Archive Path

    Format: log_archive_path=<path>
    Example: log_archive_path=/usr/local/nagios/var/archives/

    This is the directory where Nagios should place log files that have been rotated. This option is ignored if you choose to not use the log rotation functionality.

    External Command Check Option

    Format: check_external_commands=<0/1>
    Example: check_external_commands=1

    This option determines whether or not Nagios will check the command file for commands that should be executed. This option must be enabled if you plan on using the command CGI to issue commands via the web interface. Third party programs can also issue commands to Nagios by writing to the command file, provided proper rights to the file have been granted as outlined in this FAQ. More information on external commands can be found here.

    • 0 = Don't check external commands (default)
    • 1 = Check external commands

    External Command Check Interval

    Format: command_check_interval=<xxx>[s]
    Example: command_check_interval=1

    If you specify a number with an "s" appended to it (i.e. 30s), this is the number of seconds to wait between external command checks. If you leave off the "s", this is the number of "time units" to wait between external command checks. Unless you've changed the interval_length value (as defined below) from the default value of 60, this number will mean minutes.

    Note: By setting this value to -1, Nagios will check for external commands as often as possible. Each time Nagios checks for external commands it will read and process all commands present in the command file before continuing on with its other duties. More information on external commands can be found here.

    External Command File

    Format: command_file=<file_name>
    Example: command_file=/usr/local/nagios/var/rw/nagios.cmd

    This is the file that Nagios will check for external commands to process. The command CGI writes commands to this file. Other third party programs can write to this file if proper file permissions have been granted as outline in here. The external command file is implemented as a named pipe (FIFO), which is created when Nagios starts and removed when it shuts down. If the file exists when Nagios starts, the Nagios process will terminate with an error message. More information on external commands can be found here.

    Downtime File

    Format: downtime_file=<file_name>
    Example: downtime_file=/usr/local/nagios/var/downtime.dat

    This is the file that Nagios will use for storing scheduled host and service downtime information. Comments can be viewed and added for both hosts and services through the extended information CGI.

    Comment File

    Format: comment_file=<file_name>
    Example: comment_file=/usr/local/nagios/var/comment.dat

    This is the file that Nagios will use for storing service and host comments. Comments can be viewed and added for both hosts and services through the extended information CGI.

    Lock File

    Format: lock_file=<file_name>
    Example: lock_file=/tmp/nagios.lock

    This option specifies the location of the lock file that Nagios should create when it runs as a daemon (when started with the -d command line argument). This file contains the process id (PID) number of the running Nagios process.

    State Retention Option

    Format: retain_state_information=<0/1>
    Example: retain_state_information=1

    This option determines whether or not Nagios will retain state information for hosts and services between program restarts. If you enable this option, you should supply a value for the state_retention_file variable. When enabled, Nagios will save all state information for hosts and service before it shuts down (or restarts) and will read in previously saved state information when it starts up again.

    • 0 = Don't retain state information
    • 1 = Retain state information (default)

    State Retention File

    Format: state_retention_file=<file_name>
    Example: state_retention_file=/usr/local/nagios/var/retention.dat

    This is the file that Nagios will use for storing service and host state information before it shuts down. When Nagios is restarted it will use the information stored in this file for setting the initial states of services and hosts before it starts monitoring anything. This file is deleted after Nagios reads in initial state information when it (re)starts. In order to make Nagios retain state information between program restarts, you must enable the retain_state_information option.

    Automatic State Retention Update Interval

    Format: retention_update_interval=<minutes>
    Example: retention_update_interval=60

    This setting determines how often (in minutes) that Nagios will automatically save retention data during normal operation. If you set this value to 0, Nagios will not save retention data at regular intervals, but it will still save retention data before shutting down or restarting. If you have disabled state retention (with the retain_state_information option), this option has no effect.

    Use Retained Program State Option

    Format: use_retained_program_state=<0/1>
    Example: use_retained_program_state=1

    This setting determines whether or not Nagios will set various program-wide state variables based on the values saved in the retention file. Some of these program-wide state variables that are normally saved across program restarts if state retention is enabled include the enable_notifications, enable_flap_detection, enable_event_handlers, execute_service_checks, and accept_passive_service_checks options. If you do not have state retention enabled, this option has no effect.

    • 0 = Don't use retained program state
    • 1 = Use retained program state (default)

    Use Retained Scheduling Info Option

    Format: use_retained_scheduling_info=<0/1>
    Example: use_retained_scheduling_info=1

    This setting determines whether or not Nagios will retain scheduling info (next check times) for hosts and services when it restarts. If you are adding a large number (or percentage) of hosts and services, I would recommend disabling this option when you first restart Nagios, as it can adversely skew the spread of initial checks. Otherwise you will probably want to leave it enabled.

    • 0 = Don't use retained scheduling info
    • 1 = Use retained scheduling info (default)

    Syslog Logging Option

    Format: use_syslog=<0/1>
    Example: use_syslog=1

    This variable determines whether messages are logged to the syslog facility on your local host. Values are as follows:

    • 0 = Don't use syslog facility
    • 1 = Use syslog facility

    Notification Logging Option

    Format: log_notifications=<0/1>
    Example: log_notifications=1

    This variable determines whether or not notification messages are logged. If you have a lot of contacts or regular service failures your log file will grow relatively quickly. Use this option to keep contact notifications from being logged.

    • 0 = Don't log notifications
    • 1 = Log notifications

    Service Check Retry Logging Option

    Format: log_service_retries=<0/1>
    Example: log_service_retries=1

    This variable determines whether or not service check retries are logged. Service check retries occur when a service check results in a non-OK state, but you have configured Nagios to retry the service more than once before responding to the error. Services in this situation are considered to be in "soft" states. Logging service check retries is mostly useful when attempting to debug Nagios or test out service event handlers.

    • 0 = Don't log service check retries
    • 1 = Log service check retries

    Host Check Retry Logging Option

    Format: log_host_retries=<0/1>
    Example: log_host_retries=1

    This variable determines whether or not host check retries are logged. Logging host check retries is mostly useful when attempting to debug Nagios or test out host event handlers.

    • 0 = Don't log host check retries
    • 1 = Log host check retries

    Event Handler Logging Option

    Format: log_event_handlers=<0/1>
    Example: log_event_handlers=1

    This variable determines whether or not service and host event handlers are logged. Event handlers are optional commands that can be run whenever a service or hosts changes state. Logging event handlers is most useful when debugging Nagios or first trying out your event handler scripts.

    • 0 = Don't log event handlers
    • 1 = Log event handlers

    Initial States Logging Option

    Format: log_initial_states=<0/1>
    Example: log_initial_states=1

    This variable determines whether or not Nagios will force all initial host and service states to be logged, even if they result in an OK state. Initial service and host states are normally only logged when there is a problem on the first check. Enabling this option is useful if you are using an application that scans the log file to determine long-term state statistics for services and hosts.

    • 0 = Don't log initial states (default)
    • 1 = Log initial states

    External Command Logging Option

    Format: log_external_commands=<0/1>
    Example: log_external_commands=1

    This variable determines whether or not Nagios will log external commands that it receives from the external command file. Note: This option does not control whether or not passive service checks (which are a type of external command) get logged. To enable or disable logging of passive checks, use the log_passive_service_checks option.

    • 0 = Don't log external commands
    • 1 = Log external commands (default)

    Passive Check Logging Option

    Format: log_passive_checks=<0/1>
    Example: log_passive_checks=1

    This variable determines whether or not Nagios will log passive host and service checks that it receives from the external command file. If you are setting up a distributed monitoring environment or plan on handling a large number of passive checks on a regular basis, you may wish to disable this option so your log file doesn't get too large.

    • 0 = Don't log passive checks
    • 1 = Log passive checks (default)

    Global Host Event Handler Option

    Format: global_host_event_handler=<command>
    Example: global_host_event_handler=log-host-event-to-db

    This option allows you to specify a host event handler command that is to be run for every host state change. The global event handler is executed immediately prior to the event handler that you have optionally specified in each host definition. The command argument is the short name of a command that you define in your object configuration file. The maximum amount of time that this command can run is controlled by the event_handler_timeout option. More information on event handlers can be found here.

    Global Service Event Handler Option

    Format: global_service_event_handler=<command>
    Example: global_service_event_handler=log-service-event-to-db

    This option allows you to specify a service event handler command that is to be run for every service state change. The global event handler is executed immediately prior to the event handler that you have optionally specified in each service definition. The command argument is the short name of a command that you define in your object configuration file. The maximum amount of time that this command can run is controlled by the event_handler_timeout option. More information on event handlers can be found here.

    Inter-Check Sleep Time

    Format: sleep_time=<seconds>
    Example: sleep_time=1

    This is the number of seconds that Nagios will sleep before checking to see if the next service or host check in the scheduling queue should be executed. Note that Nagios will only sleep after it "catches up" with queued service checks that have fallen behind.

    Service Inter-Check Delay Method

    Format: service_inter_check_delay_method=<n/d/s/x.xx>
    Example: service_inter_check_delay_method=s

    This option allows you to control how service checks are initially "spread out" in the event queue. Using a "smart" delay calculation (the default) will cause Nagios to calculate an average check interval and spread initial checks of all services out over that interval, thereby helping to eliminate CPU load spikes. Using no delay is generally not recommended unless you are testing the service check parallelization functionality. Using no delay will cause all service checks to be scheduled for execution at the same time. This means that you will generally have large CPU spikes when the services are all executed in parallel. More information on how to estimate how the inter-check delay affects service check scheduling can be found here. Values are as follows:

    • n = Don't use any delay - schedule all service checks to run immediately (i.e. at the same time!)
    • d = Use a "dumb" delay of 1 second between service checks
    • s = Use a "smart" delay calculation to spread service checks out evenly (default)
    • x.xx = Use a user-supplied inter-check delay of x.xx seconds

    Maximum Service Check Spread

    Format: max_service_check_spread=<minutes>
    Example: max_service_check_spread=30

    This option determines the maximum number of minutes from when Nagios starts that all services (that are scheduled to be regularly checked) are checked. This option will automatically adjust the service inter-check delay (if necessary) to ensure that the initial checks of all services occur within the timeframe you specify. In general, this option will not have an affect on service check scheduling if scheduling information is being retained using the use_retained_scheduling_info option. Default value is 30 (minutes).

    Service Interleave Factor

    Format: service_interleave_factor=<s|x>
    Example: service_interleave_factor=s

    This variable determines how service checks are interleaved. Interleaving allows for a more even distribution of service checks, reduced load on remote hosts, and faster overall detection of host problems. With the introduction of service check parallelization, remote hosts could get bombarded with checks if interleaving was not implemented. This could cause the service checks to fail or return incorrect results if the remote host was overloaded with processing other service check requests. Setting this value to 1 is equivalent to not interleaving the service checks (this is how versions of Nagios previous to 0.0.5 worked). Set this value to s (smart) for automatic calculation of the interleave factor unless you have a specific reason to change it. The best way to understand how interleaving works is to watch the status CGI (detailed view) when Nagios is just starting. You should see that the service check results are spread out as they begin to appear. More information on how interleaving works can be found here.
    • x = A number greater than or equal to 1 that specifies the interleave factor to use. An interleave factor of 1 is equivalent to not interleaving the service checks.
    • s = Use a "smart" interleave factor calculation (default)

    Maximum Concurrent Service Checks

    Format: max_concurrent_checks=<max_checks>
    Example: max_concurrent_checks=20

    This option allows you to specify the maximum number of service checks that can be run in parallel at any given time. Specifying a value of 1 for this variable essentially prevents any service checks from being parallelized. Specifying a value of 0 (the default) does not place any restrictions on the number of concurrent checks. You'll have to modify this value based on the system resources you have available on the machine that runs Nagios, as it directly affects the maximum load that will be imposed on the system (processor utilization, memory, etc.). More information on how to estimate how many concurrent checks you should allow can be found here.

    Service Reaper Frequency

    Format: service_reaper_frequency=<frequency_in_seconds>
    Example: service_reaper_frequency=10

    This option allows you to control the frequency in seconds of service "reaper" events. "Reaper" events process the results from parallelized service checks that have finished executing. These events consitute the core of the monitoring logic in Nagios.

    Host Inter-Check Delay Method

    Format: host_inter_check_delay_method=<n/d/s/x.xx>
    Example: host_inter_check_delay_method=s

    This option allows you to control how host checks that are scheduled to be checked on a regular basis are initially "spread out" in the event queue. Using a "smart" delay calculation (the default) will cause Nagios to calculate an average check interval and spread initial checks of all hosts out over that interval, thereby helping to eliminate CPU load spikes. Using no delay is generally not recommended. Using no delay will cause all host checks to be scheduled for execution at the same time. More information on how to estimate how the inter-check delay affects host check scheduling can be found here.Values are as follows:

    • n = Don't use any delay - schedule all host checks to run immediately (i.e. at the same time!)
    • d = Use a "dumb" delay of 1 second between host checks
    • s = Use a "smart" delay calculation to spread host checks out evenly (default)
    • x.xx = Use a user-supplied inter-check delay of x.xx seconds

    Maximum Host Check Spread

    Format: max_host_check_spread=<minutes>
    Example: max_host_check_spread=30

    This option determines the maximum number of minutes from when Nagios starts that all hosts (that are scheduled to be regularly checked) are checked. This option will automatically adjust the host inter-check delay (if necessary) to ensure that the initial checks of all hosts occur within the timeframe you specify. In general, this option will not have an affect on host check scheduling if scheduling information is being retained using the use_retained_scheduling_info option. Default value is 30 (minutes).

    Timing Interval Length

    Format: interval_length=<seconds>
    Example: interval_length=60

    This is the number of seconds per "unit interval" used for timing in the scheduling queue, re-notifications, etc. "Units intervals" are used in the object configuration file to determine how often to run a service check, how often of re-notify a contact, etc.

    Important: The default value for this is set to 60, which means that a "unit value" of 1 in the object configuration file will mean 60 seconds (1 minute). I have not really tested other values for this variable, so proceed at your own risk if you decide to do so!

    Auto-Rescheduling Option

    Format: auto_reschedule_checks=<0/1>
    Example: auto_reschedule_checks=1

    This option determines whether or not Nagios will attempt to automatically reschedule active host and service checks to "smooth" them out over time. This can help to balance the load on the monitoring server, as it will attempt to keep the time between consecutive checks consistent, at the expense of executing checks on a more rigid schedule.

    WARNING: THIS IS AN EXPERIMENTAL FEATURE AND MAY BE REMOVED IN FUTURE VERSIONS. ENABLING THIS OPTION CAN DEGRADE PERFORMANCE - RATHER THAN INCREASE IT - IF USED IMPROPERLY!

    Auto-Rescheduling Interval

    Format: auto_rescheduling_interval=<seconds>
    Example: auto_rescheduling_interval=30

    This option determines how often (in seconds) Nagios will attempt to automatically reschedule checks. This option only has an effect if the auto_reschedule_checks option is enabled. Default is 30 seconds.

    WARNING: THIS IS AN EXPERIMENTAL FEATURE AND MAY BE REMOVED IN FUTURE VERSIONS. ENABLING THE AUTO-RESCHEDULING OPTION CAN DEGRADE PERFORMANCE - RATHER THAN INCREASE IT - IF USED IMPROPERLY!

    Auto-Rescheduling Window

    Format: auto_rescheduling_window=<seconds>
    Example: auto_rescheduling_window=180

    This option determines the "window" of time (in seconds) that Nagios will look at when automatically rescheduling checks. Only host and service checks that occur in the next X seconds (determined by this variable) will be rescheduled. This option only has an effect if the auto_reschedule_checks option is enabled. Default is 180 seconds (3 minutes).

    WARNING: THIS IS AN EXPERIMENTAL FEATURE AND MAY BE REMOVED IN FUTURE VERSIONS. ENABLING THE AUTO-RESCHEDULING OPTION CAN DEGRADE PERFORMANCE - RATHER THAN INCREASE IT - IF USED IMPROPERLY!

    Aggressive Host Checking Option

    Format: use_aggressive_host_checking=<0/1>
    Example: use_aggressive_host_checking=0

    Nagios tries to be smart about how and when it checks the status of hosts. In general, disabling this option will allow Nagios to make some smarter decisions and check hosts a bit faster. Enabling this option will increase the amount of time required to check hosts, but may improve reliability a bit. Unless you have problems with Nagios not recognizing that a host recovered, I would suggest not enabling this option.

    • 0 = Don't use aggressive host checking (default)
    • 1 = Use aggressive host checking

    Flap Detection Option

    Format: enable_flap_detection=<0/1>
    Example: enable_flap_detection=0

    This option determines whether or not Nagios will try and detect hosts and services that are "flapping". Flapping occurs when a host or service changes between states too frequently, resulting in a barrage of notifications being sent out. When Nagios detects that a host or service is flapping, it will temporarily suppress notifications for that host/service until it stops flapping. Flap detection is very experimental at this point, so use this feature with caution! More information on how flap detection and handling works can be found here. Note: If you have state retention enabled, Nagios will ignore this setting when it (re)starts and use the last known setting for this option (as stored in the state retention file), unless you disable the use_retained_program_state option. If you want to change this option when state retention is active (and the use_retained_program_state is enabled), you'll have to use the appropriate external command or change it via the web interface.

    • 0 = Don't enable flap detection (default)
    • 1 = Enable flap detection

    Low Service Flap Threshold

    Format: low_service_flap_threshold=<percent>
    Example: low_service_flap_threshold=25.0

    This option is used to set the low threshold for detection of service flapping. For more information on how flap detection and handling works (and how this option affects things) read this.

    High Service Flap Threshold

    Format: high_service_flap_threshold=<percent>
    Example: high_service_flap_threshold=50.0

    This option is used to set the low threshold for detection of service flapping. For more information on how flap detection and handling works (and how this option affects things) read this.

    Low Host Flap Threshold

    Format: low_host_flap_threshold=<percent>
    Example: low_host_flap_threshold=25.0

    This option is used to set the low threshold for detection of host flapping. For more information on how flap detection and handling works (and how this option affects things) read this.

    High Host Flap Threshold

    Format: high_host_flap_threshold=<percent>
    Example: high_host_flap_threshold=50.0

    This option is used to set the low threshold for detection of host flapping. For more information on how flap detection and handling works (and how this option affects things) read this.

    Soft Service Dependencies Option

    Format: soft_state_dependencies=<0/1>
    Example: soft_state_dependencies=0

    This option determines whether or not Nagios will use soft service state information when checking service dependencies. Normally Nagios will only use the latest hard service state when checking dependencies. If you want it to use the latest state (regardless of whether its a soft or hard state type), enable this option.

    • 0 = Don't use soft service state dependencies (default)
    • 1 = Use soft service state dependencies

    Service Check Timeout

    Format: service_check_timeout=<seconds>
    Example: service_check_timeout=60

    This is the maximum number of seconds that Nagios will allow service checks to run. If checks exceed this limit, they are killed and a CRITICAL state is returned. A timeout error will also be logged.

    There is often widespread confusion as to what this option really does. It is meant to be used as a last ditch mechanism to kill off plugins which are misbehaving and not exiting in a timely manner. It should be set to something high (like 60 seconds or more), so that each service check normally finishes executing within this time limit. If a service check runs longer than this limit, Nagios will kill it off thinking it is a runaway processes.

    Host Check Timeout

    Format: host_check_timeout=<seconds>
    Example: host_check_timeout=60

    This is the maximum number of seconds that Nagios will allow host checks to run. If checks exceed this limit, they are killed and a CRITICAL state is returned and the host will be assumed to be DOWN. A timeout error will also be logged.

    There is often widespread confusion as to what this option really does. It is meant to be used as a last ditch mechanism to kill off plugins which are misbehaving and not exiting in a timely manner. It should be set to something high (like 60 seconds or more), so that each host check normally finishes executing within this time limit. If a host check runs longer than this limit, Nagios will kill it off thinking it is a runaway processes.

    Event Handler Timeout

    Format: event_handler_timeout=<seconds>
    Example: event_handler_timeout=60

    This is the maximum number of seconds that Nagios will allow event handlers to be run. If an event handler exceeds this time limit it will be killed and a warning will be logged.

    There is often widespread confusion as to what this option really does. It is meant to be used as a last ditch mechanism to kill off commands which are misbehaving and not exiting in a timely manner. It should be set to something high (like 60 seconds or more), so that each event handler command normally finishes executing within this time limit. If an event handler runs longer than this limit, Nagios will kill it off thinking it is a runaway processes.

    Notification Timeout

    Format: notification_timeout=<seconds>
    Example: notification_timeout=60

    This is the maximum number of seconds that Nagios will allow notification commands to be run. If a notification command exceeds this time limit it will be killed and a warning will be logged.

    There is often widespread confusion as to what this option really does. It is meant to be used as a last ditch mechanism to kill off commands which are misbehaving and not exiting in a timely manner. It should be set to something high (like 60 seconds or more), so that each notification command finishes executing within this time limit. If a notification command runs longer than this limit, Nagios will kill it off thinking it is a runaway processes.

    Obsessive Compulsive Service Processor Timeout

    Format: ocsp_timeout=<seconds>
    Example: ocsp_timeout=5

    This is the maximum number of seconds that Nagios will allow an obsessive compulsive service processor command to be run. If a command exceeds this time limit it will be killed and a warning will be logged.

    Obsessive Compulsive Host Processor Timeout

    Format: ochp_timeout=<seconds>
    Example: ochp_timeout=5

    This is the maximum number of seconds that Nagios will allow an obsessive compulsive host processor command to be run. If a command exceeds this time limit it will be killed and a warning will be logged.

    Performance Data Processor Command Timeout

    Format: perfdata_timeout=<seconds>
    Example: perfdata_timeout=5

    This is the maximum number of seconds that Nagios will allow a host performance data processor command or service performance data processor command to be run. If a command exceeds this time limit it will be killed and a warning will be logged.

    Obsess Over Services Option

    Format: obsess_over_services=<0/1>
    Example: obsess_over_services=1

    This value determines whether or not Nagios will "obsess" over service checks results and run the obsessive compulsive service processor command you define. I know - funny name, but it was all I could think of. This option is useful for performing distributed monitoring. If you're not doing distributed monitoring, don't enable this option.

    • 0 = Don't obsess over services (default)
    • 1 = Obsess over services

    Obsessive Compulsive Service Processor Command

    Format: ocsp_command=<command>
    Example: ocsp_command=obsessive_service_handler

    This option allows you to specify a command to be run after every service check, which can be useful in distributed monitoring. This command is executed after any event handler or notification commands. The command argument is the short name of a command definition that you define in your object configuration file. The maximum amount of time that this command can run is controlled by the ocsp_timeout option. More information on distributed monitoring can be found here. This command is only executed if the obsess_over_services option is enabled globally and if the obsess_over_service directive in the service definition is enabled.

    Obsess Over Hosts Option

    Format: obsess_over_hosts=<0/1>
    Example: obsess_over_hosts=1

    This value determines whether or not Nagios will "obsess" over host checks results and run the obsessive compulsive host processor command you define. I know - funny name, but it was all I could think of. This option is useful for performing distributed monitoring. If you're not doing distributed monitoring, don't enable this option.

    • 0 = Don't obsess over hosts (default)
    • 1 = Obsess over hosts

    Obsessive Compulsive Host Processor Command

    Format: ochp_command=<command>
    Example: ochp_command=obsessive_host_handler

    This option allows you to specify a command to be run after every host check, which can be useful in distributed monitoring. This command is executed after any event handler or notification commands. The command argument is the short name of a command definition that you define in your object configuration file. The maximum amount of time that this command can run is controlled by the ochp_timeout option. More information on distributed monitoring can be found here. This command is only executed if the obsess_over_hosts option is enabled globally and if the obsess_over_host directive in the host definition is enabled.

    Performance Data Processing Option

    Format: process_performance_data=<0/1>
    Example: process_performance_data=1

    This value determines whether or not Nagios will process host and service check performance data.

    • 0 = Don't process performance data (default)
    • 1 = Process performance data

    Host Performance Data Processing Command

    Format: host_perfdata_command=<command>
    Example: host_perfdata_command=process-host-perfdata

    This option allows you to specify a command to be run after every host check to process host performance data that may be returned from the check. The command argument is the short name of a command definition that you define in your object configuration file. This command is only executed if the process_performance_data option is enabled globally and if the process_perf_data directive in the host definition is enabled.

    Service Performance Data Processing Command

    Format: service_perfdata_command=<command>
    Example: service_perfdata_command=process-service-perfdata

    This option allows you to specify a command to be run after every service check to process service performance data that may be returned from the check. The command argument is the short name of a command definition that you define in your object configuration file. This command is only executed if the process_performance_data option is enabled globally and if the process_perf_data directive in the service definition is enabled.

    Host Performance Data File

    Format: host_perfdata_file=<file_name>
    Example: host_perfdata_file=/usr/local/nagios/var/host-perfdata.dat

    This option allows you to specify a file to which host performance data will be written after every host check. Data will be written to the performance file as specified by the host_perfdata_file_template option. Performance data is only written to this file if the process_performance_data option is enabled globally and if the process_perf_data directive in the host definition is enabled.

    Service Performance Data File

    Format: service_perfdata_file=<file_name>
    Example: service_perfdata_file=/usr/local/nagios/var/service-perfdata.dat

    This option allows you to specify a file to which service performance data will be written after every service check. Data will be written to the performance file as specified by the service_perfdata_file_template option. Performance data is only written to this file if the process_performance_data option is enabled globally and if the process_perf_data directive in the service definition is enabled.

    Host Performance Data File Template

    Format: host_perfdata_file_template=<template>
    Example: host_perfdata_file_template=[HOSTPERFDATA]\t$TIMET$\t$HOSTNAME$\t$HOSTEXECUTIONTIME$\t$HOSTOUTPUT$\t$HOSTPERFDATA$

    This option determines what (and how) data is written to the host performance data file. The template may contain macros, special characters (\t for tab, \r for carriage return, \n for newline) and plain text. A newline is automatically added after each write to the performance data file.

    Service Performance Data File Template

    Format: service_perfdata_file_template=<template>
    Example: service_perfdata_file_template=[SERVICEPERFDATA]\t$TIMET$\t$HOSTNAME$\t$SERVICEDESC$\t$SERVICEEXECUTIONTIME$\t$SERVICELATENCY$\t$SERVICEOUTPUT$\t$SERVICEPERFDATA$

    This option determines what (and how) data is written to the service performance data file. The template may contain macros, special characters (\t for tab, \r for carriage return, \n for newline) and plain text. A newline is automatically added after each write to the performance data file.

    Host Performance Data File Mode

    Format: host_perfdata_file_mode=<mode>
    Example: host_perfdata_file_mode=a

    This option determines whether the host performance data file is opened in write or append mode. Unless the file is a named pipe, you will probably want to use the default mode of append.

    • a = Open file in append mode (default)
    • w = Open file in write mode

    Service Performance Data File Mode

    Format: service_perfdata_file_mode=<mode>
    Example: service_perfdata_file_mode=a

    This option determines whether the service performance data file is opened in write or append mode. Unless the file is a named pipe, you will probably want to use the default mode of append.

    • a = Open file in append mode (default)
    • w = Open file in write mode

    Host Performance Data File Processing Interval

    Format: host_perfdata_file_processing_interval=<seconds>
    Example: host_perfdata_file_processing_interval=0

    This option allows you to specify the interval (in seconds) at which the host performance data file is processed using the host performance data file processing command. A value of 0 indicates that the performance data file should not be processed at regular intervals.

    Service Performance Data File Processing Interval

    Format: service_perfdata_file_processing_interval=<seconds>
    Example: service_perfdata_file_processing_interval=0

    This option allows you to specify the interval (in seconds) at which the service performance data file is processed using the service performance data file processing command. A value of 0 indicates that the performance data file should not be processed at regular intervals.

    Host Performance Data File Processing Command

    Format: host_perfdata_file_processing_command=<command>
    Example: host_perfdata_file_processing_command=process-host-perfdata-file

    This option allows you to specify the command that should be executed to process the host performance data file. The command argument is the short name of a command definition that you define in your object configuration file. The interval at which this command is executed is determined by the host_perfdata_file_processing_interval directive.

    Service Performance Data File Processing Command

    Format: service_perfdata_file_processing_command=<command>
    Example: service_perfdata_file_processing_command=process-service-perfdata-file

    This option allows you to specify the command that should be executed to process the service performance data file. The command argument is the short name of a command definition that you define in your object configuration file. The interval at which this command is executed is determined by the service_perfdata_file_processing_interval directive.

    Orphaned Service Check Option

    Format: check_for_orphaned_services=<0/1>
    Example: check_for_orphaned_services=1

    This option allows you to enable or disable checks for orphaned service checks. Orphaned service checks are checks which have been executed and have been removed from the event queue, but have not had any results reported in a long time. Since no results have come back in for the service, it is not rescheduled in the event queue. This can cause service checks to stop being executed. Normally it is very rare for this to happen - it might happen if an external user or process killed off the process that was being used to execute a service check. If this option is enabled and Nagios finds that results for a particular service check have not come back, it will log an error message and reschedule the service check. If you start seeing service checks that never seem to get rescheduled, enable this option and see if you notice any log messages about orphaned services.

    • 0 = Don't check for orphaned service checks
    • 1 = Check for orphaned service checks (default)

    Service Freshness Checking Option

    Format: check_service_freshness=<0/1>
    Example: check_service_freshness=0

    This option determines whether or not Nagios will periodically check the "freshness" of service checks. Enabling this option is useful for helping to ensure that passive service checks are received in a timely manner. More information on freshness checking can be found here.

    • 0 = Don't check service freshness
    • 1 = Check service freshness (default)

    Service Freshness Check Interval

    Format: service_freshness_check_interval=<seconds>
    Example: service_freshness_check_interval=60

    This setting determines how often (in seconds) Nagios will periodically check the "freshness" of service check results. If you have disabled service freshness checking (with the check_service_freshness option), this option has no effect. More information on freshness checking can be found here.

    Host Freshness Checking Option

    Format: check_host_freshness=<0/1>
    Example: check_host_freshness=0

    This option determines whether or not Nagios will periodically check the "freshness" of host checks. Enabling this option is useful for helping to ensure that passive host checks are received in a timely manner. More information on freshness checking can be found here.

    • 0 = Don't check host freshness
    • 1 = Check host freshness (default)

    Host Freshness Check Interval

    Format: host_freshness_check_interval=<seconds>
    Example: host_freshness_check_interval=60

    This setting determines how often (in seconds) Nagios will periodically check the "freshness" of host check results. If you have disabled host freshness checking (with the check_host_freshness option), this option has no effect. More information on freshness checking can be found here.

    Date Format

    Format: date_format=<option>
    Example: date_format=us

    This option allows you to specify what kind of date/time format Nagios should use in the web interface and date/time macros. Possible options (along with example output) include:

    OptionOutput FormatSample Output
    usMM/DD/YYYY HH:MM:SS06/30/2002 03:15:00
    euroDD/MM/YYYY HH:MM:SS30/06/2002 03:15:00
    iso8601YYYY-MM-DD HH:MM:SS2002-06-30 03:15:00
    strict-iso8601YYYY-MM-DDTHH:MM:SS2002-06-30T03:15:00

    Illegal Object Name Characters

    Format: illegal_object_name_chars=<chars...>
    Example: illegal_object_name_chars=`~!$%^&*"|'<>?,()=

    This option allows you to specify illegal characters that cannot be used in host names, service descriptions, or names of other object types. Nagios will allow you to use most characters in object definitions, but I recommend not using the characters shown in the example above. Doing may give you problems in the web interface, notification commands, etc.

    Illegal Macro Output Characters

    Format: illegal_macro_output_chars=<chars...>
    Example: illegal_macro_output_chars=`~$^&"|'<>

    This option allows you to specify illegal characters that should be stripped from macros before being used in notifications, event handlers, and other commands. This DOES NOT affect macros used in service or host check commands. You can choose to not strip out the characters shown in the example above, but I recommend you do not do this. Some of these characters are interpreted by the shell (i.e. the backtick) and can lead to security problems. The following macros are stripped of the characters you specify:

    $HOSTOUTPUT$, $HOSTPERFDATA$, $HOSTACKAUTHOR$, $HOSTACKCOMMENT$, $SERVICEOUTPUT$, $SERVICEPERFDATA$, $SERVICEACKAUTHOR$, and $SERVICEACKCOMMENT$

    Regular Expression Matching Option

    Format: use_regexp_matching=<0/1>
    Example: use_regexp_matching=0

    This option determines whether or not various directives in your object definitions will be processed as regular expressions. More information on how this works can be found here.

    • 0 = Don't use regular expression matching (default)
    • 1 = Use regular expression matching

    True Regular Expression Matching Option

    Format: use_true_regexp_matching=<0/1>
    Example: use_true_regexp_matching=0

    If you've enabled regular expression matching of various object directives using the use_regexp_matching option, this option will determine when object directives are treated as regular expressions. If this option is disabled (the default), directives will only be treated as regular expressions if the contain a * or ? wildcard character. If this option is enabled, all appropriate directives will be treated as regular expression - be careful when enabling this! More information on how this works can be found here.

    • 0 = Don't use true regular expression matching (default)
    • 1 = Use true regular expression matching

    Administrator Email Address

    Format: admin_email=<email_address>
    Example: admin_email=root@localhost.localdomain

    This is the email address for the administrator of the local machine (i.e. the one that Nagios is running on). This value can be used in notification commands by using the $ADMINEMAIL$ macro.

    Administrator Pager

    Format: admin_pager=<pager_number_or_pager_email_gateway>
    Example: admin_pager=pageroot@localhost.localdomain

    This is the pager number (or pager email gateway) for the administrator of the local machine (i.e. the one that Nagios is running on). The pager number/address can be used in notification commands by using the $ADMINPAGER$ macro.


    nagios-2.6/html/docs/configobject.html0000664000076500007650000000327607743356403017440 0ustar nagiosnagios Object Definitions

    Object Definitions


    What is Object Data?

    Object data is simply a generic term I use to describe various data definitions you need in order to monitor anything. Types of object definitions include:

    • Services
    • Service Groups
    • Hosts
    • Host Groups
    • Contacts
    • Contact Groups
    • Commands
    • Time Periods
    • Service Escalations
    • Service Dependencies
    • Host Escalations
    • Host Dependencies
    • Extended Host Information
    • Extended Service Information

    Where Is Object Data Defined?

    Object data is defined in one or more configuration files that you specify using the cfg_file and/or cfg_dir directives in the main configuration file. You can include multiple object configuration files and/or directories by using multiple cfg_file and/or cfg_dir directives.

    How Is Object Data Defined?

    Object definitions are defined in a template format. Click here for more information on defining object data using this method.


    nagios-2.6/html/docs/dependencies.html0000664000076500007650000003067210217122245017413 0ustar nagiosnagios Host and Service Dependencies

    Host and Service Dependencies


    Introduction

    Service and host dependencies are an advanced feature that allow you to control the behavior of hosts and services based on the status of one or more other hosts or services. I'll explain how dependencies work, along with the differences between host and service dependencies.

    Service Dependencies Overview

    The image below shows an example logical layout of service dependencies. There are a few things you should notice:

    1. A service can be dependent on one or more other services
    2. A service can be dependent on services which are not associated with the same host
    3. Service dependencies are not inherited (unless specifically configured to)
    4. Service dependencies can be used to cause service execution and service notifications to be suppressed under different circumstances (OK, WARNING, UNKNOWN, and/or CRITICAL states)

    Service Dependencies

    Defining Service Dependencies

    First, the basics. You create service dependencies by adding service dependency definitions in your object config file(s). In each definition you specify the dependent service, the service you are depending on, and the criteria (if any) that cause the execution and notification dependencies to fail (these are described later).

    You can create several dependencies for a given service, but you must add a separate service dependency definition for each dependency you create.

    In the image above, the dependency definitions for Service F on Host C would be defined as follows:

    define servicedependency{
    	host_name			Host B
    	service_description		Service D
    	dependent_host_name		Host C
    	dependent_service_description	Service F
    	execution_failure_criteria	o
    	notification_failure_criteria	w,u
    	}
    
    define servicedependency{
    	host_name			Host B
    	service_description		Service E
    	dependent_host_name		Host C
    	dependent_service_description	Service F
    	execution_failure_criteria	n
    	notification_failure_criteria	w,u,c
    	}
    
    define servicedependency{
    	host_name			Host B
    	service_description		Service C
    	dependent_host_name		Host C
    	dependent_service_description	Service F
    	execution_failure_criteria	w
    	notification_failure_criteria	c
    	}
    

    The other dependency definitions shown in the image above would be defined as follows:

    define servicedependency{
    	host_name			Host A
    	service_description		Service A
    	dependent_host_name		Host B
    	dependent_service_description	Service D
    	execution_failure_criteria	u
    	notification_failure_criteria	n
    	}
    
    define servicedependency{
    	host_name			Host A
    	service_description		Service B
    	dependent_host_name		Host B
    	dependent_service_description	Service E
    	execution_failure_criteria	w,u
    	notification_failure_criteria	c
    	}
    
    define servicedependency{
    	host_name			Host B
    	service_description		Service C
    	dependent_host_name		Host B
    	dependent_service_description	Service E
    	execution_failure_criteria	n
    	notification_failure_criteria	w,u,c
    	}
    

    How Service Dependencies Are Tested

    Before Nagios executes a service check or sends notifications out for a service, it will check to see if the service has any dependencies. If it doesn't have any dependencies, the check is executed or the notification is sent out as it normally would be. If the service does have one or more dependencies, Nagios will check each dependency entry as follows:

    1. Nagios gets the current status* of the service that is being depended upon.
    2. Nagios compares the current status of the service that is being depended upon against either the execution or notification failure options in the dependency definition (whichever one is relevant at the time).
    3. If the current status of the service that is being depended upon matches one of the failure options, the dependency is said to have failed and Nagios will break out of the dependency check loop.
    4. If the current state of the service that is being depended upon does not match any of the failure options for the dependency entry, the dependency is said to have passed and Nagios will go on and check the next dependency entry.

    This cycle continues until either all dependencies for the service have been checked or until one dependency check fails.

    *One important thing to note is that by default, Nagios will use the most current hard state of the service(s) that is/are being depended upon when it does the dependeny checks. If you want Nagios to use the most current state of the services (regardless of whether its a soft or hard state), enable the soft_service_dependencies option.

    Execution Dependencies

    Execution dependencies are used to restrict when active checks of a service can be performed. Passive checks are not restricted by execution dependencies.

    If all of the execution dependency tests for the service passed, Nagios will execute the check of the service as it normally would. If even just one of the execution dependencies for a service fails, Nagios will temporarily prevent the execution of checks for that (dependent) service. At some point in the future the execution dependency tests for the service may all pass. If this happens, Nagios will start checking the service again as it normally would. More information on the check scheduling logic can be found here.

    In the example above, Service E would have failed execution dependencies if Service B is in a WARNING or UNKNOWN state. If this was the case, the service check would not be performed and the check would be scheduled for (potential) execution at a later time.

    Notification Dependencies

    If all of the notification dependency tests for the service passed, Nagios will send notifications out for the service as it normally would. If even just one of the notification dependencies for a service fails, Nagios will temporarily repress notifications for that (dependent) service. At some point in the future the notification dependency tests for the service may all pass. If this happens, Nagios will start sending out notifications again as it normally would for the service. More information on the notification logic can be found here.

    In the example above, Service F would have failed notification dependencies if Service C is in a CRITICAL state, and/or Service D is in a WARNING or UNKNOWN state, and/or if Service E is in a WARNING, UNKNOWN, or CRITICAL state. If this were the case, notifications for the service would not be sent out.

    Dependency Inheritance

    As mentioned before, service dependencies are not inherited by default. In the example above you can see that Service F is dependent on Service E. However, it does not automatically inherit Service E's dependencies on Service B and Service C. In order to make Service F dependent on Service C we had to add another service dependency definition. There is no dependency definition for Service B, so Service F is not dependent on Service B.

    If you do wish to make service dependencies inheritable, you must use the inherits_parent directive in the service dependency definition. When this directive is enabled, it indicates that the dependency inherits dependencies of the service that is being depended upon (also referred to as the master service). In other words, if the master service is dependent upon other services and any one of those dependencies fail, this dependency will also fail.

    In the example above, imagine that you want to add a new dependency for service F to make it dependent on service A. You could create a new dependency definition that specified service F as the dependent service and service A as being the master service (i.e. the service that is being dependend on). You could alternatively modify the dependency definition for services D and F to look like this:

    define servicedependency{
    	host_name			Host B
    	service_description		Service D
    	dependent_host_name		Host C
    	dependent_service_description	Service F
    	execution_failure_criteria	o
    	notification_failure_criteria	n
    	inherits_parent		1
    	}
    
    

    Since the inherits_parent directive is enabled, the dependency between services A and D will be tested when the dependency between services F and D are being tested.

    Dependencies can have multiple levels of inheritence. If the dependency definition between A and D had its inherits_parent directive enable and service A was dependent on some other service (let's call it service G), the service F would be dependent on services D, A, and G (each with potentially different criteria).

    Host Dependencies

    As you'd probably expect, host dependencies work in a similiar fashion to service dependencies. The big difference is that they're for hosts, not services. Another difference is that host dependencies only work for suppressing host notifications, not host checks.

    BEWARE! Do not confuse host dependencies with parent/child host relationships. You should be using parent/child host relationships (defined with the parents directive in host definitions) for most cases, rather than host dependencies.

    The image below shows an example of the logical layout of host dependencies.

    Host Dependencies

    In the image above, the dependency definitions for Host C would be defined as follows:

    define hostdependency{
    	host_name			Host A
    	dependent_host_name		Host C
    	notification_failure_criteria	d
    	}
    
    define hostdependency{
    	host_name			Host B
    	dependent_host_name		Host C
    	notification_failure_criteria	d,u
    	}
    

    As with service dependencies, host dependencies are not inherited. In the example image you can see that Host C does not inherit the host dependencies of Host B. In order for Host C to be dependent on Host A, a new host dependency definition must be defined.

    Host notification dependencies work in a similiar manner to service notification dependencies. If all of the notification dependency tests for the host pass, Nagios will send notifications out for the host as it normally would. If even just one of the notification dependencies for a host fails, Nagios will temporarily repress notifications for that (dependent) host. At some point in the future the notification dependency tests for the host may all pass. If this happens, Nagios will start sending out notifications again as it normally would for the host. More information on the notification logic can be found here.

    NOTE: Host execution dependencies work in a similiar manner to service execution dependencies. However, they only have an affect on regularly scheduled host checks. On-demand host checks are not affected by host execution dependencies.


    nagios-2.6/html/docs/distributed.html0000664000076500007650000004736510431422505017316 0ustar nagiosnagios Distributed Monitoring

    Distributed Monitoring


    Introduction

    Nagios can be configured to support distributed monitoring of network services and resources. I'll try to briefly explan how this can be accomplished...

    Goals

    The goal in the distributed monitoring environment that I will describe is to offload the overhead (CPU usage, etc.) of performing service checks from a "central" server onto one or more "distributed" servers. Most small to medium sized shops will not have a real need for setting up such an environment. However, when you want to start monitoring hundreds or even thousands of hosts (and several times that many services) using Nagios, this becomes quite important.

    Reference Diagram

    The diagram below should help give you a general idea of how distributed monitoring works with Nagios. I'll be referring to the items shown in the diagram as I explain things...

    Central Server vs. Distributed Servers

    When setting up a distributed monitoring environment with Nagios, there are differences in the way the central and distributed servers are configured. I'll show you how to configure both types of servers and explain what effects the changes being made have on the overall monitoring. For starters, lets describe the purpose of the different types of servers...

    The function of a distributed server is to actively perform checks all the services you define for a "cluster" of hosts. I use the term "cluster" loosely - it basically just mean an arbitrary group of hosts on your network. Depending on your network layout, you may have several cluters at one physical location, or each cluster may be separated by a WAN, its own firewall, etc. The important thing to remember to that for each cluster of hosts (however you define that), there is one distributed server that runs Nagios and monitors the services on the hosts in the cluster. A distributed server is usually a bare-bones installation of Nagios. It doesn't have to have the web interface installed, send out notifications, run event handler scripts, or do anything other than execute service checks if you don't want it to. More detailed information on configuring a distributed server comes later...

    The purpose of the central server is to simply listen for service check results from one or more distributed servers. Even though services are occassionally actively checked from the central server, the active checks are only performed in dire circumstances, so lets just say that the central server only accepts passive check for now. Since the central server is obtaining passive service check results from one or more distributed servers, it serves as the focal point for all monitoring logic (i.e. it sends out notifications, runs event handler scripts, determines host states, has the web interface installed, etc).

    Obtaining Service Check Information From Distributed Monitors

    Okay, before we go jumping into configuration detail we need to know how to send the service check results from the distributed servers to the central server. I've already discussed how to submit passive check results to Nagios from same host that Nagios is running on (as described in the documentation on passive checks), but I haven't given any info on how to submit passive check results from other hosts.

    In order to facilitate the submission of passive check results to a remote host, I've written the nsca addon. The addon consists of two pieces. The first is a client program (send_nsca) which is run from a remote host and is used to send the service check results to another server. The second piece is the nsca daemon (nsca) which either runs as a standalone daemon or under inetd and listens for connections from client programs. Upon receiving service check information from a client, the daemon will sumbit the check information to Nagios (on the central server) by inserting a PROCESS_SVC_CHECK_RESULT command into the external command file, along with the check results. The next time Nagios checks for external commands, it will find the passive service check information that was sent from the distributed server and process it. Easy, huh?

    Distributed Server Configuration

    So how exactly is Nagios configured on a distributed server? Basically, its just a bare-bones installation. You don't need to install the web interface or have notifications sent out from the server, as this will all be handled by the central server.

    Key configuration changes:

    • Only those services and hosts which are being monitored directly by the distributed server are defined in the object configuration file.
    • The distributed server has its enable_notifications directive set to 0. This will prevent any notifications from being sent out by the server.
    • The distributed server is configured to obsess over services.
    • The distributed server has an ocsp command defined (as described below).

    In order to make everything come together and work properly, we want the distributed server to report the results of all service checks to Nagios. We could use event handlers to report changes in the state of a service, but that just doesn't cut it. In order to force the distributed server to report all service check results, you must enabled the obsess_over_services option in the main configuration file and provide a ocsp_command to be run after every service check. We will use the ocsp command to send the results of all service checks to the central server, making use of the send_nsca client and nsca daemon (as described above) to handle the tranmission.

    In order to accomplish this, you'll need to define an ocsp command like this:

    ocsp_command=submit_check_result

    The command definition for the submit_check_result command looks something like this:

    define command{
    	command_name	submit_check_result
    	command_line	/usr/local/nagios/libexec/eventhandlers/submit_check_result $HOSTNAME$ '$SERVICEDESC$' $SERVICESTATEID$ '$SERVICEOUTPUT$'
    	}
    

    The submit_check_result shell scripts looks something like this (replace central_server with the IP address of the central server):

    	#!/bin/sh
    
    	# Arguments:
    	#  $1 = host_name (Short name of host that the service is
    	#       associated with)
    	#  $2 = svc_description (Description of the service)
    	#  $3 = state_string (A string representing the status of
    	#       the given service - "OK", "WARNING", "CRITICAL"
    	#       or "UNKNOWN")
    	#  $4 = plugin_output (A text string that should be used
    	#       as the plugin output for the service checks)
    	#
    
    	# Convert the state string to the corresponding return code
    	return_code=-1
    
    	case "$3" in
        	    OK)
            	        return_code=0
                	    ;;
    	        WARNING)
        	            return_code=1
            	        ;;
    	        CRITICAL)
        	            return_code=2
            	        ;;
    	        UNKNOWN)
        	            return_code=-1
            	        ;;
    	esac
    
    	# pipe the service check info into the send_nsca program, which
    	# in turn transmits the data to the nsca daemon on the central
    	# monitoring server
    
    	/bin/printf "%s\t%s\t%s\t%s\n" "$1" "$2" "$return_code" "$4" | /usr/local/nagios/bin/send_nsca central_server -c /usr/local/nagios/etc/send_nsca.cfg
    

    The script above assumes that you have the send_nsca program and it configuration file (send_nsca.cfg) located in the /usr/local/nagios/bin/ and /usr/local/nagios/etc/ directories, respectively.

    That's it! We've sucessfully configured a remote host running Nagios to act as a distributed monitoring server. Let's go over exactly what happens with the distributed server and how it sends service check results to Nagios (the steps outlined below correspond to the numbers in the reference diagram above):

    1. After the distributed server finishes executing a service check, it executes the command you defined by the ocsp_command variable. In our example, this is the /usr/local/nagios/libexec/eventhandlers/submit_check_result script. Note that the definition for the submit_check_result command passed four pieces of information to the script: the name of the host the service is associated with, the service description, the return code from the service check, and the plugin output from the service check.
    2. The submit_check_result script pipes the service check information (host name, description, return code, and output) to the send_nsca client program.
    3. The send_nsca program transmits the service check information to the nsca daemon on the central monitoring server.
    4. The nsca daemon on the central server takes the service check information and writes it to the external command file for later pickup by Nagios.
    5. The Nagios process on the central server reads the external command file and processes the passive service check information that originated from the distributed monitoring server.

    Central Server Configuration

    We've looked at hot distributed monitoring servers should be configured, so let's turn to the central server. For all intensive purposes, the central is configured as you would normally configure a standalone server. It is setup as follows:

    • The central server has the web interface installed (optional, but recommended)
    • The central server has its enable_notifications directive set to 1. This will enable notifications. (optional, but recommended)
    • The central server has active service checks disabled (optional, but recommended - see notes below)
    • The central server has external command checks enabled (required)
    • The central server has passive service checks enabled (required)

    There are three other very important things that you need to keep in mind when configuring the central server:

    • The central server must have service definitions for all services that are being monitored by all the distributed servers. Nagios will ignore passive check results if they do not correspond to a service that has been defined.
    • If you're only using the central server to process services whose results are going to be provided by distributed hosts, you can simply disable all active service checks on a program-wide basis by setting the execute_service_checks directive to 0. If you're using the central server to actively monitor a few services on its own (without the aid of distributed servers), the enable_active_checks option of the defintions for service being monitored by distributed servers should be set to 0. This will prevent Nagios from actively checking those services.

    It is important that you either disable all service checks on a program-wide basis or disable the enable_active_checks option in the definitions for each service that is monitored by a distributed server. This will ensure that active service checks are never executed under normal circumstances. The services will keep getting rescheduled at their normal check intervals (3 minutes, 5 minutes, etc...), but the won't actually be executed. This rescheduling loop will just continue all the while Nagios is running. I'll explain why this is done in a bit...

    That's it! Easy, huh?

    Problems With Passive Checks

    For all intensive purposes we can say that the central server is relying solely on passive checks for monitoring. The main problem with relying completely on passive checks for monitoring is the fact that Nagios must rely on something else to provide the monitoring data. What if the remote host that is sending in passive check results goes down or becomes unreachable? If Nagios isn't actively checking the services on the host, how will it know that there is a problem?

    Fortunately, there is a way we can handle these types of problems...

    Freshness Checking

    Nagios supports a feature that does "freshness" checking on the results of service checks. More information freshness checking can be found here. This features gives some protection against situations where remote hosts may stop sending passive service checks into the central monitoring server. The purpose of "freshness" checking is to ensure that service checks are either being provided passively by distributed servers on a regular basis or performed actively by the central server if the need arises. If the service check results provided by the distributed servers get "stale", Nagios can be configured to force active checks of the service from the central monitoring host.

    So how do you do this? On the central monitoring server you need to configure services that are being monitoring by distributed servers as follows...

    • The check_freshness option in the service definitions should be set to 1. This enables "freshness" checking for the services.
    • The freshness_threshold option in the service definitions should be set to a value (in seconds) which reflects how "fresh" the results for the services (provided by the distributed servers) should be.
    • The check_command option in the service definitions should reflect valid commands that can be used to actively check the service from the central monitoring server.

    Nagios periodically checks the "freshness" of the results for all services that have freshness checking enabled. The freshness_threshold option in each service definition is used to determine how "fresh" the results for each service should be. For example, if you set this value to 300 for one of your services, Nagios will consider the service results to be "stale" if they're older than 5 minutes (300 seconds). If you do not specify a value for the freshness_threshold option, Nagios will automatically calculate a "freshness" threshold by looking at either the normal_check_interval or retry_check_interval options (depending on what type of state the service is in). If the service results are found to be "stale", Nagios will run the service check command specified by the check_command option in the service definition, thereby actively checking the service.

    Remember that you have to specify a check_command option in the service definitions that can be used to actively check the status of the service from the central monitoring server. Under normal circumstances, this check command is never executed (because active checks were disabled on a program-wide basis or for the specific services). When freshness checking is enabled, Nagios will run this command to actively check the status of the service even if active checks are disabled on a program-wide or service-specific basis.

    If you are unable to define commands to actively check a service from the central monitoring host (or if turns out to be a major pain), you could simply define all your services with the check_command option set to run a dummy script that returns a critical status. Here's an example... Let's assume you define a command called 'service-is-stale' and use that command name in the check_command option of your services. Here's what the definition would look like...

    define command{
    	command_name	service-is-stale
    	command_line	/usr/local/nagios/libexec/staleservice.sh
    	}
    

    The staleservice.sh script in your /usr/local/nagios/libexec directory might look something like this:

    #!/bin/sh
    
    /bin/echo "CRITICAL: Service results are stale!"
    
    exit 2
    

    When Nagios detects that the service results are stale and runs the service-is-stale command, the /usr/local/nagios/libexec/staleservice.sh script is executed and the service will go into a critical state. This would likely cause notifications to be sent out, so you'll know that there's a problem.

    Performing Host Checks

    At this point you know how to obtain service check results passivly from distributed servers. This means that the central server is not actively checking services on its own. But what about host checks? You still need to do them, so how?

    Since host checks usually compromise a small part of monitoring activity (they aren't done unless absolutely necessary), I'd recommend that you perform host checks actively from the central server. That means that you define host checks on the central server the same way that you do on the distributed servers (and the same way you would in a normal, non-distributed setup).

    Passive host checks are available (read here), so you could use them in your distributed monitoring setup, but they suffer from a few problems. The biggest problem is that Nagios does not translate passive host check problem states (DOWN and UNREACHABLE) when they are processed. This means that if your monitoring servers have a different parent/child host structure (and they will, if you monitoring servers are in different locations), the central monitoring server will have an inaccurate view of host states.

    If you do want to send passive host checks to a central server in your distributed monitoring setup, make sure:

    The ochp command, which is used for processing host check results, works in a similiar manner to the ocsp command, which is used for processing service check results (see documentation above). In order to make sure passive host check results are up to date, you'll want to enable freshness checking for hosts (similiar to what is described above for services).


    nagios-2.6/html/docs/downtime.html0000664000076500007650000001444607747630366016642 0ustar nagiosnagios Scheduled Downtime

    Scheduled Downtime


    Introduction

    Nagios allows you to schedule periods of planned downtime for hosts and service that you're monitoring. This is useful in the event that you actually know you're going to be taking a server down for an upgrade, etc. When a host a service is in a period of scheduled downtime, notifications for that host or service will be suppressed.

    Downtime File

    Scheduled host and service downtime is stored in the file you specify by the downtime_file directive in your main configuration file.

    Downtime Retention

    Scheduled host and service downtime is automatically preserved across program restarts. When Nagios starts up, it will scan the downtime file, delete any old or invalid entries, and schedule downtime for all valid host and service entries.

    Scheduling Downtime

    You can schedule downtime for hosts and service through the extinfo CGI (either when viewing host or service information). Click in the "Schedule downtime for this host/service" link to actually schedule the downtime.

    Once you schedule downtime for a host or service, Nagios will add a comment to that host/service indicating that it is scheduled for downtime during the period of time you indicated. When that period of downtime passes, Nagios will automatically delete the comment that it added. Nice, huh?

    Fixed vs. Flexible Downtime

    When you schedule downtime for a host or service through the web interface you'll be asked if the downtime is fixed or flexible. Here's an explanation of how "fixed" and "flexible" downtime differs:

    "Fixed" downtime starts and stops at the exact start and end times that you specify when you schedule it. Okay, that was easy enough...

    "Flexible" downtime is intended for times when you know that a host or service is going to be down for X minutes (or hours), but you don't know exactly when that'll start. When you schedule flexible downtime, Nagios will start the scheduled downtime sometime between the start and end times you specified. The downtime will last for as long as the duration you specified when you scheduled the downtime. This assumes that the host or service for which you scheduled flexible downtime either goes down (or becomes unreachable) or goes into a non-OK state sometime between the start and end times you specified. The time at which a host or service transitions to a problem state determines the time at which Nagios actually starts the downtime. The downtime will then last for the duration you specified, even if the host or service recovers before the downtime expires. This is done for a very good reason. As we all know, you can think you've got a problem fixed (and restart a server) ten times before it actually works right. Smart, eh?

    Triggered Downtime

    When scheduling host or service downtime you have the option of making it "triggered" downtime. What is triggered downtime, you ask? With triggered downtime the start of the downtime is triggered by the start of some other scheduled host or service downtime. This is extremely useful if you're scheduling downtime for a large number or hosts or services and the start time of the downtime period depends on the start time of another downtime entry. For instance, if you schedule flexible downtime for a particular host (because its going down for maintenance), you might want to schedule triggered downtime for all of that hosts's "children".

    How Scheduled Downtime Affects Notifications

    When a host or service is in a period of scheduled downtime, Nagios will not allow notifications to be sent out for the host or service. suppression of notifications is accomplished by adding an additional filter to the notification logic. You will not see an icon in the CGIs indicating that notifications for that host/service are disabled. When the scheduled downtime has passed, Nagios will allow notifications to be sent out for the host or service as it normally would.

    Overlapping Scheduled Downtime

    I like to refer to this as the "Oh crap, its not working" syndrome. You know what I'm talking about. You take a server down to perform a "routine" hardware upgrade, only to later realize that the OS drivers aren't working, the RAID array blew up, or the drive imaging failed and left your original disks useless to the world. Moral of the story is that any routine work on a server is quite likely to take three or four times as long as you had originally planned...

    Let's take the following scenario:

    1. You schedule downtime for host A from 7:30pm-9:30pm on a Monday
    2. You bring the server down about 7:45pm Monday evening to start a hard drive upgrade
    3. After wasting an hour and a half battling with SCSI errors and driver incompatabilities, you finally get the machine to boot up
    4. At 9:15 you realize that one of your partitions is either hosed or doesn't seem to exist anywhere on the drive
    5. Knowing you're in for a long night, you go back and schedule additional downtime for host A from 9:20pm Monday evening to 1:30am Tuesday Morning.

    If you schedule overlapping periods of downtime for a host or service (in this case the periods were 7:40pm-9:30pm and 9:20pm-1:30am), Nagios will wait until the last period of scheduled downtime is over before it allows notifications to be sent out for that host or service. In this example notifications would be suppressed for host A until 1:30am Tuesday morning.


    nagios-2.6/html/docs/embeddedperl.html0000664000076500007650000003026410336261307017403 0ustar nagiosnagios Using The Embedded Perl Interpreter

    Using The Embedded Perl Interpreter


    Introduction

    Stephen Davies has contributed code that allows you to compile Nagios with an embedded Perl interpreter. This may be of interest to you if you rely heavily on plugins written in Perl.

    Stanley Hopcroft has worked with the embedded Perl interpreter quite a bit and has commented on the advantages/disadvanges of using it. He has also given several helpful hints on creating Perl plugins that work properly with the embedded interpreter. The majority of this documentation comes from his comments.

    It should be noted that "ePN", as used in this documentation, refers to embedded Perl Nagios, or if you prefer, Nagios compiled with an embedded Perl interpreter.

    Advantages

    Some advantages of ePN (embedded Perl Nagios) include:

    • Nagios will spend much less time running your Perl plugins because it no longer forks to execute the plugin (each time loading the Perl interpreter). Instead, it executes your plugin by making a library call.

    • It greatly reduces the system impact of Perl plugins and/or allows you to run more checks with Perl plugin than you otherwise would be able to. In other words, you have less incentive to write plugins in other languages such as C/C++, or Expect/TCL, that are generally recognised to have development times at least an order of magnitude slower than Perl (although they do run about ten times faster also - TCL being an exception).

    • If you are not a C programmer, then you can still get a huge amount of mileage out of Nagios by letting Perl do all the heavy lifting without having Nagios slow right down. Note however, that the ePN will not speed up your plugin (apart from eliminating the interpreter load time). If you want fast plugins then consider Perl XSUBs (XS), or C after you are sure that your Perl is tuned and that you have a suitable algorithm (Benchmark.pm is invaluable for comparing the performance of Perl language elements).

    • Using the ePN is an excellent opportunity to learn more about Perl.

    Disadvantages

    The disadvantages of ePN (embedded Perl Nagios) are much the same as Apache mod_perl (i.e. Apache with an embedded interpreter) compared to a plain Apache:

    • A Perl program that works fine with plain Nagios may not work with the ePN. You may have to modify your plugins to get them to work.

    • Perl plugins are harder to debug under an ePN than under a plain Nagios.

    • Your ePN will have a larger SIZE (memory footprint) than a plain Nagios.

    • Some Perl constructs cannot be used or may behave differently than what you would expect.

    • You may have to be aware of 'more than one way to do it' and choose a way that seems less attractive or obvious.

    • You will need greater Perl knowledge (but nothing very esoteric or stuff about Perl internals - unless your plugin uses XSUBS).

    Target Audience

    • Average Perl developers; those with an appreciation of the languages powerful features without knowledge of internals or an in depth knowledge of those features.

    • Those with a utilitarian appreciation rather than a great depth of understanding.

    • If you are happy with Perl objects, name management, data structures, and the debugger, that's probably sufficient.

    Things you should do when developing a Perl Plugin (ePN or not)

    • Always always generate some output

    • Use 'use utils' and import the stuff it exports ($TIMEOUT %ERRORS &print_revision &support)

    • Have a look at how the standard Perl plugins do their stuff e.g.

      • Always exit with $ERRORS{CRITICAL}, $ERRORS{OK}, etc.
      • Use getopt to read command line arguments
      • Manage timeouts
      • Call print_usage (supplied by you) when there are no command line arguments
      • Use standard switch names (eg H 'host', V 'version')

    Things you must do to develop a Perl plugin for ePN

    1. <DATA> can not be used; use here documents instead e.g.

      my $data = <<DATA;
      portmapper 100000
      portmap 100000
      sunrpc 100000
      rpcbind 100000
      rstatd 100001
      rstat 100001
      rup 100001
      ..
      DATA
      
      %prognum = map { my($a, $b) = split; ($a, $b) } split(/\n/, $data) ;
      
    2. BEGIN blocks will not work as you expect. May be best to avoid.

    3. Ensure that it is squeaky clean at compile time i.e.

      • use strict
      • use perl -w (other switches [T notably] may not help)
      • use perl -c


    4. Avoid lexical variables (my) with global scope as a means of passing __variable__ data into subroutines. In fact this is __fatal__ if the subroutine is called by the plugin more than once when the check is run. Such subroutines act as 'closures' that lock the global lexicals first value into subsequent calls of the subroutine. If however, your global is read-only (a complicated structure for example) this is not a problem. What Bekman recommends you do instead, is any of the following:

      • make the subroutine anonymous and call it via a code ref e.g.

        turn this                     into  
        
        my $x = 1 ;                   my $x = 1 ;
        sub a { .. Process $x ... }   $a_cr = sub { ... Process $x ... } ;
        .                             .
        .                             .
        a ;                           &$a_cr ;
        $x = 2                        $x = 2 ;
        a ;                           &$a_cr ;
        
        # anon closures __always__ rebind the current lexical value
        
      • put the global lexical and the subroutine using it in their own package (as an object or a module)
      • pass info to subs as references or aliases (\$lex_var or $_[n])
      • replace lexicals with package globals and exclude them from 'use strict' objections with 'use vars qw(global1 global2 ..)'

    5. Be aware of where you can get more information.

      Useful information can be had from the usual suspects (the O'Reilly books, plus Damien Conways "Object Oriented Perl") but for the really useful stuff in the right context start at Stas Bekman's mod_perl guide at http://perl.apache.org/guide/.

      This wonderful book sized document has nothing whatsoever about Nagios, but all about writing Perl programs for the embedded Perl interpreter in Apache (ie Doug MacEacherns mod_perl).

      The perlembed manpage is essential for context and encouragement.

      On the basis that Lincoln Stein and Doug MacEachern know a thing or two about Perl and embedding Perl, their book 'Writing Apache Modules with Perl and C' is almost certainly worth looking at.

    6. Be aware that your plugin may return strange values with an ePN and that this is likely to be caused by the problem in item #4 above

    7. Be prepared to debug via:

      • having a test ePN and
      • adding print statements to your plugin to display variable values to STDERR (can't use STDOUT)
      • adding print statements to p1.pl to display what ePN thinks your plugin is before it tries to run it (vi)
      • running the ePN in foreground mode (probably in conjunction with the former recommendations)
      • use the 'Deparse' module on your plugin to see how the parser has optimised it and what the interpreter will actually get. (see 'Constants in Perl' by Sean M. Burke, The Perl Journal, Fall 2001)

      perl -MO::Deparse <your_program>
    8. Be aware of what ePN is transforming your plugin too, and if all else fails try and debug the transformed version.

      As you can see below p1.pl rewrites your plugin as a subroutine called 'hndlr' in the package named 'Embed::<something_related_to_your_plugin_file_name>'.

      Your plugin may be expecting command line arguments in @ARGV so pl.pl also assigns @_ to @ARGV.

      This in turn gets 'eval' ed and if the eval raises an error (any parse error and run error), the plugin gets chucked out.

      The following output shows how a test ePN transformed the check_rpc plugin before attempting to execute it. Most of the code from the actual plugin is not shown, as we are interested in only the transformations that the ePN has made to the plugin). For clarity, transformations are shown in red:

      
                      package main;
                      use subs 'CORE::GLOBAL::exit';
                      sub CORE::GLOBAL::exit { die "ExitTrap: $_[0] 
      (Embed::check_5frpc)"; }
                      package Embed::check_5frpc; sub hndlr { shift(@_);
      @ARGV=@_;
      #! /usr/bin/perl -w
      #
      # check_rpc plugin for Nagios
      #
      # usage:
      #    check_rpc host service
      #
      # Check if an rpc serice is registered and running
      # using rpcinfo - $proto $host $prognum 2>&1 |";
      #
      # Use these hosts.cfg entries as examples
      #
      # command[check_nfs]=/some/path/libexec/check_rpc $HOSTADDRESS$ nfs
      # service[check_nfs]=NFS;24x7;3;5;5;unix-admin;60;24x7;1;1;1;;check_rpc
      #
      # initial version: 3 May 2000 by Truongchinh Nguyen and Karl DeBisschop
      # current status: $Revision: 1.26 $
      #
      # Copyright Notice: GPL
      #
      ... rest of plugin code goes here (it was removed for brevity) ...
      }
      


    9. Don't use 'use diagnostics' in a plugin run by your production ePN. I think it causes__all__ the Perl plugins to return CRITICAL.

    10. Consider using a mini embedded Perl C program to check your plugin. This is not sufficient to guarantee your plugin will perform Ok with an ePN but if the plugin fails this test it will ceratinly fail with your ePN. [ A sample mini ePN is included in the contrib/ directory of the Nagios distribution for use in testing Perl plugins. Change to the contrib/ directory and type 'make mini_epn' to compile it. It must be executed from the same directory that the p1.pl file resides in (this file is distributed with Nagios). ]

    Compiling Nagios With The Embedded Perl Interpreter

    Okay, you can breathe again now. So do you still want to compile Nagios with the embedded Perl interpreter? ;-)

    If you want to compile Nagios with the embedded Perl interpreter you need to rerun the configure script with the addition of the --enable-embedded-perl option. If you want the embedded interpreter to cache internally compiled scripts, add the --with-perlcache option as well. Example:

    	./configure --enable-embedded-perl --with-perlcache ...other options...
    

    Once you've rerun the configure script with the new options, make sure to recompile Nagios. You can check to make sure that Nagios has been compile with the embedded Perl interpreter by executing it with the -m command-line argument. Output from executing the command will look something like this (notice that the embedded perl interpreter is listed in the options section):

    	[nagios@firestore ]# ./nagios -m
    
    	Nagios 1.0a0
    	Copyright (c) 1999-2001 Ethan Galstad (nagios@nagios.org)
    	Last Modified: 07-03-2001
    	License: GPL
    
    	External Data I/O
    	-----------------
    	Object Data:      DEFAULT
    	Status Data:      DEFAULT
    	Retention Data:   DEFAULT
    	Comment Data:     DEFAULT
    	Downtime Data:    DEFAULT
    	Performance Data: DEFAULT
    
    
    	Options
    	-------
    	* Embedded Perl compiler (With caching)
    
    


    nagios-2.6/html/docs/escalations.html0000664000076500007650000003001207746120016017265 0ustar nagiosnagios Notification Escalations

    Notification Escalations


    Introduction

    Nagios supports optional escalation of contact notifications for hosts and services. I'll explain quickly how they work, although they should be fairly self-explanatory...

    Service Notification Escalations

    Escalation of service notifications is accomplished by defining service escalations in your object configuration file. Service escalation definitions are used to escalate notifications for a particular service.

    Host Notification Escalations

    Escalation of host notifications is accomplished by defining host escalations in your object configuration file. The examples I provide below all use service escalation definitions, but host escalations work the same way (except for the fact that they are used for host notifications and not service notifications).

    When Are Notifications Escalated?

    Notifications are escalated if and only if one or more escalation definitions matches the current notification that is being sent out. If a host or service notification does not have any valid escalation definitions that applies to it, the contact group(s) specified in either the host group or service definition will be used for the notification. Look at the example below:

    define serviceescalation{
    	host_name		webserver
    	service_description	HTTP
    	first_notification	3
    	last_notification	5
    	notification_interval	90
    	contact_groups		nt-admins,managers
    	}
    
    define serviceescalation{
    	host_name		webserver
    	service_description	HTTP
    	first_notification	6
    	last_notification	10
    	notification_interval	60
    	contact_groups		nt-admins,managers,everyone
    	}
    

    Notice that there are "holes" in the notification escalation definitions. In particular, notifications 1 and 2 are not handled by the escalations, nor are any notifications beyond 10. For the first and second notification, as well as all notifications beyond the tenth one, the default contact groups specified in the service definition are used. For all the examples I'll be using, I'll be assuming that the default contact groups for the service definition is called nt-admins.

    Contact Groups

    When defining notification escalations, it is important to keep in mind that any contact groups that were members of "lower" escalations (i.e. those with lower notification number ranges) should also be included in "higher" escalation definitions. This should be done to ensure that anyone who gets notified of a problem continues to get notified as the problem is escalated. Example:

    define serviceescalation{
    	host_name		webserver
    	service_description	HTTP
    	first_notification	3
    	last_notification	5
    	notification_interval	90
    	contact_groups		nt-admins,managers
    	}
    
    define serviceescalation{
    	host_name		webserver
    	service_description	HTTP
    	first_notification	6
    	last_notification	0
    	notification_interval	60
    	contact_groups		nt-admins,managers,everyone
    	}
    

    The first (or "lowest") escalation level includes both the nt-admins and managers contact groups. The last (or "highest") escalation level includes the nt-admins, managers, and everyone contact groups. Notice that the nt-admins contact group is included in both escalation definitions. This is done so that they continue to get paged if there are still problems after the first two service notifications are sent out. The managers contact group first appears in the "lower" escalation definition - they are first notified when the third problem notification gets sent out. We want the managers group to continue to be notified if the problem continues past five notifications, so they are also included in the "higher" escalation definition.

    Overlapping Escalation Ranges

    Notification escalation definitions can have notification ranges that overlap. Take the following example:

    define serviceescalation{
    	host_name		webserver
    	service_description	HTTP
    	first_notification	3
    	last_notification	5
    	notification_interval	20
    	contact_groups		nt-admins,managers
    	}
    
    define serviceescalation{
    	host_name		webserver
    	service_description	HTTP
    	first_notification	4
    	last_notification	0
    	notification_interval	30
    	contact_groups		on-call-support
    	}
    

    In the example above:

    • The nt-admins and managers contact groups get notified on the third notification
    • All three contact groups get notified on the fourth and fifth notifications
    • Only the on-call-support contact group gets notified on the sixth (or higher) notification

    Recovery Notifications

    Recovery notifications are slightly different than problem notifications when it comes to escalations. Take the following example:

    define serviceescalation{
    	host_name		webserver
    	service_description	HTTP
    	first_notification	3
    	last_notification	5
    	notification_interval	20
    	contact_groups		nt-admins,managers
    	}
    
    define serviceescalation{
    	host_name		webserver
    	service_description	HTTP
    	first_notification	4
    	last_notification	0
    	notification_interval	30
    	contact_groups		on-call-support
    	}
    

    If, after three problem notifications, a recovery notification is sent out for the service, who gets notified? The recovery is actually the fourth notification that gets sent out. However, the escalation code is smart enough to realize that only those people who were notified about the problem on the third notification should be notified about the recovery. In this case, the nt-admins and managers contact groups would be notified of the recovery.

    Notification Intervals

    You can change the frequency at which escalated notifications are sent out for a particular host or service by using the notification_interval option of the hostgroup or service escalation definition. Example:

    define serviceescalation{
    	host_name		webserver
    	service_description	HTTP
    	first_notification	3
    	last_notification	5
    	notification_interval	45
    	contact_groups		nt-admins,managers
    	}
    
    define serviceescalation{
    	host_name		webserver
    	service_description	HTTP
    	first_notification	6
    	last_notification	0
    	notification_interval	60
    	contact_groups		nt-admins,managers,everyone
    	}
    

    In this example we see that the default notification interval for the services is 240 minutes (this is the value in the service definition). When the service notification is escalated on the 3rd, 4th, and 5th notifications, an interval of 45 minutes will be used between notifications. On the 6th and subsequent notifications, the notification interval will be 60 minutes, as specified in the second escalation definition.

    Since it is possible to have overlapping escalation definitions for a particular hostgroup or service, and the fact that a host can be a member of multiple hostgroups, Nagios has to make a decision on what to do as far as the notification interval is concerned when escalation definitions overlap. In any case where there are multiple valid escalation definitions for a particular notification, Nagios will choose the smallest notification interval. Take the following example:

    define serviceescalation{
    	host_name		webserver
    	service_description	HTTP
    	first_notification	3
    	last_notification	5
    	notification_interval	45
    	contact_groups		nt-admins,managers
    	}
    
    define serviceescalation{
    	host_name		webserver
    	service_description	HTTP
    	first_notification	4
    	last_notification	0
    	notification_interval	60
    	contact_groups		nt-admins,managers,everyone
    	}
    

    We see that the two escalation definitions overlap on the 4th and 5th notifications. For these notifications, Nagios will use a notification interval of 45 minutes, since it is the smallest interval present in any valid escalation definitions for those notifications.

    One last note about notification intervals deals with intervals of 0. An interval of 0 means that Nagios should only sent a notification out for the first valid notification during that escalation definition. All subsequent notifications for the hostgroup or service will be suppressed. Take this example:

    define serviceescalation{
    	host_name		webserver
    	service_description	HTTP
    	first_notification	3
    	last_notification	5
    	notification_interval	45
    	contact_groups		nt-admins,managers
    	}
    
    define serviceescalation{
    	host_name		webserver
    	service_description	HTTP
    	first_notification	4
    	last_notification	6
    	notification_interval	0
    	contact_groups		nt-admins,managers,everyone
    	}
    	
    define serviceescalation{
    	host_name		webserver
    	service_description	HTTP
    	first_notification	7
    	last_notification	0
    	notification_interval	30
    	contact_groups		nt-admins,managers
    	}
    

    In the example above, the maximum number of problem notifications that could be sent out about the service would be four. This is because the notification interval of 0 in the second escalation definition indicates that only one notification should be sent out (starting with and including the 4th notification) and all subsequent notifications should be repressed. Because of this, the third service escalation definition has no effect whatsoever, as there will never be more than four notifications.

    Time Period Restrictions

    Under normal circumstances, escalations can be used at any time that a notification could normally be sent out for the service. This "notification time window" is determined by the notification_period directive in the service definition.

    You can optionally restrict escalations so that they are only used during specific time periods by using the escalation_period directive in the service escalation definition. If you use the escalation_period directive to specify a timeperiod during which the escalation can be used, the escalation will only be used during that time. If you do not specify any escalation_period directive, the escalation can be used at any time within the "notification time window" for the service.

    Note that the notification is still subject to the normal time restrictions imposed by the notification_period directive in the service escalation, so the timeperiod you specify in the escalation should be a subset of that larger "notification time window".

    State Restrictions

    If you would like to restrict the escalation definition so that it is only used when the service is in a particular state, you can use the escalation_options directive in the service escalation definition. If you do not use the escalation_options directive, the escalation can be used when the service is in any state.


    nagios-2.6/html/docs/eventhandlers.html0000664000076500007650000002256010220364211017617 0ustar nagiosnagios Event Handlers

    Event Handlers


    Introduction

    Event handlers are optional commands that are executed whenever a host or service state change occurs. An obvious use for event handlers (especially with services) is the ability for Nagios to proactively fix problems before anyone is notified. Another potential use for event handlers might be to log service or host events to an external database.

    Event Handler Types

    There are two main types of event handlers than can be defined - service event handlers and host event handlers. Event handler commands are (optionally) defined in each host and service definition. Because these event handlers are only associated with particular services or hosts, I will call these "local" event handlers. If a local event handler has been defined for a service or host, it will be executed when that host or service changes state.

    You may also specify global event handlers that should be run for every host or service state change by using the global_host_event_handler and global_service_event_handler options in your main configuration file. Global event handlers are run immediately prior to running a local service or host event handler.

    When Are Event Handler Commands Executed?

    Service and host event handler commands are executed when a service or host:

    • is in a "soft" error state
    • initially goes into a "hard" error state
    • recovers from a "soft" or "hard" error state

    What are "soft" and "hard" states you ask? They are described here .

    Event Handler Execution Order

    Global event handlers are executed before any local event handlers that you have configured for specific hosts or services.

    Writing Event Handler Commands

    In most cases, event handler commands will be shell or perl scripts. At a minimum, the scripts should take the following macros as arguments:

    Service event handler macros: $SERVICESTATE$, $SERVICESTATETYPE$, $SERVICEATTEMPT$
    Host event handler macros: $HOSTSTATE$, $HOSTSTATETYPE$, $HOSTATTEMPT$

    The scripts should examine the values of the arguments passed in and take any necessary action based upon those values. The best way to understand how event handlers should work is to see and example. Lucky for you, one is provided below. There are also some sample event handler scripts included in the eventhandlers/ subdirectory of the Nagios distribution. Some of these sample scripts demonstrate the use of external commands to implement redundant monitoring hosts.

    Permissions For Event Handler Commands

    Any event handler commands you configure will execute with the same permissions as the user under which Nagios is running on your machine. This presents a problem with scripts that attempt to restart system services, as root privileges are generally required to do these sorts of tasks.

    Ideally you should evaluate the types of event handlers you will be implementing and grant just enough permissions to the Nagios user for executing the necessary system commands. You might want to try using sudo to accomplish this. Implementation of this is your job, so read the docs and decide if its what you need.

    Debugging Event Handler Commands

    When you are debugging event handler commands, I would highly recommend that you enable logging of service retries, host retries, and event handler commands. All of these logging options are configured in the main configuration file. Enabling logging for these options will allow you to see exactly when and why event handler commands are being executed.

    When you're done debugging your event handler commands you'll probably want to disable logging of service and host retries. They can fill up your log file fast, but if you have enabled log rotation you might not care.

    Service Event Handler Example

    The example below assumes that you are monitoring the HTTP server on the local machine and have specified restart-httpd as the event handler command for the HTTP service definition. Also, I will be assuming that you have set the <max_check_attempts> option for the service to be a value of 4 or greater (i.e. the service is checked 4 times before it is considered to have a real problem). An example service definition (w/ only the fields we discuss) might look like this...

    define service{
    	host_name			somehost
    	service_description		HTTP
    	max_check_attempts		4
    	event_handler			restart-httpd
    	...other service variables...
    	}
    

    Once the service has been defined with an event handler, we must define that event handler as a command. Notice the macros in the command line that I am passing to the event handler - these are important!

    define command{
    	command_name	restart-httpd
    	command_line	/usr/local/nagios/libexec/eventhandlers/restart-httpd  $SERVICESTATE$ $SERVICESTATETYPE$ $SERVICEATTEMPT$
    	}
    

    Now, let's actually write the event handler script (this is the /usr/local/nagios/libexec/eventhandlers/restart-httpd file).

    #!/bin/sh
    #
    # Event handler script for restarting the web server on the local machine
    #
    # Note: This script will only restart the web server if the service is
    #       retried 3 times (in a "soft" state) or if the web service somehow
    #       manages to fall into a "hard" error state.
    #
    
    
    # What state is the HTTP service in?
    case "$1" in
    OK)
    	# The service just came back up, so don't do anything...
    	;;
    WARNING)
    	# We don't really care about warning states, since the service is probably still running...
    	;;
    UNKNOWN)
    	# We don't know what might be causing an unknown error, so don't do anything...
    	;;
    CRITICAL)
    	# Aha!  The HTTP service appears to have a problem - perhaps we should restart the server...
    
    	# Is this a "soft" or a "hard" state?
    	case "$2" in
    		
    	# We're in a "soft" state, meaning that Nagios is in the middle of retrying the
    	# check before it turns into a "hard" state and contacts get notified...
    	SOFT)
    			
    		# What check attempt are we on?  We don't want to restart the web server on the first
    		# check, because it may just be a fluke!
    		case "$3" in
    				
    		# Wait until the check has been tried 3 times before restarting the web server.
    		# If the check fails on the 4th time (after we restart the web server), the state
    		# type will turn to "hard" and contacts will be notified of the problem.
    		# Hopefully this will restart the web server successfully, so the 4th check will
    		# result in a "soft" recovery.  If that happens no one gets notified because we
    		# fixed the problem!
    		3)
    			echo -n "Restarting HTTP service (3rd soft critical state)..."
    			# Call the init script to restart the HTTPD server
    			/etc/rc.d/init.d/httpd restart
    			;;
    			esac
    		;;
    				
    	# The HTTP service somehow managed to turn into a hard error without getting fixed.
    	# It should have been restarted by the code above, but for some reason it didn't.
    	# Let's give it one last try, shall we?  
    	# Note: Contacts have already been notified of a problem with the service at this
    	# point (unless you disabled notifications for this service)
    	HARD)
    		echo -n "Restarting HTTP service..."
    		# Call the init script to restart the HTTPD server
    		/etc/rc.d/init.d/httpd restart
    		;;
    	esac
    	;;
    esac
    exit 0
    

    The sample script provided above will attempt to restart the web server on the local machine in two different instances - after the HTTP service is being retried for the 3rd time (in an "soft" error state) and after the service falls into a "hard" state. The "hard" state situation shouldn't really occur, since the script should restart the service when its still in a "soft" state (i.e. the 3rd check retry), but its left as a fallback anyway.

    It should be noted that the service event handler will only be execute the first time that the service falls into a "hard" state. This will prevent Nagios from continuously executing the script to restart the web server when it is in a "hard" state.


    nagios-2.6/html/docs/extcommands.html0000664000076500007650000000661110336261307017310 0ustar nagiosnagios External Commands

    External Commands


    Introduction

    Nagios can process commands from external applications (including CGIs - see the command CGI for an example) and alter various aspects of its monitoring functions based on the commands it receives.

    Enabling External Commands

    By default, Nagios does not check for or process any external commands. If you want to enable external command processing, you'll have to do the following...

    • Enable external command checking with the check_external_commands option
    • Set the frequency of command checks with the command_check_interval option
    • Specify the location of the command file with the command_file option. Its best to put the external command file in its own directory (i.e. /usr/local/nagios/var/rw).
    • Setup proper permissions on the directory containing the external command file. Details on how to do this can be found here.

    When Does Nagios Check For External Commands?

    • At regular intervals specified by the command_check_interval option in the main configuration file
    • Immediately after event handlers are executed. This is in addtion to the regular cycle of external command checks and is done to provide immediate action if an event handler submits commands to Nagios.

    Using External Commands

    External commands can be used to accomplish a variety of things while Nagios is running. Example of what can be done include temporarily disabling notifications for services and hosts, temporarily disabling service checks, forcing immediate service checks, adding comments to hosts and services, etc.

    Command Format

    External commands that are written to the command file have the following format...

    [time] command_id;command_arguments

    ...where time is the time (in time_t format) that the external application or CGI committed the external command to the command file. Some of the commands that are available are described in the table below, along with their command_id and a description of their command_arguments.

    Implemented Commands

    A full listing of external commands that can be used (along with examples of how to use them) can be found online at the following URL:

    http://www.nagios.org/developerinfo/externalcommands/


    nagios-2.6/html/docs/flapping.html0000664000076500007650000002366210510244753016573 0ustar nagiosnagios Detection and Handling of State Flapping

    Detection and Handling of State Flapping


    Introduction

    Nagios supports optional detection of hosts and services that are "flapping". Flapping occurs when a service or host changes state too frequently, resulting in a storm of problem and recovery notifications. Flapping can be indicative of configuration problems (i.e. thresholds set too low) or real network problems.

    Before I go any futher, let me say that flapping detection has been a little difficult to implement. How exactly does one determine what "too frequently" means in regards to state changes for a particular host or service? When I first started looking into flap detection I tried to find some information on how flapping could/should be detected. After I couldn't find any, I decided to settle with what seemed to be a reasonable solution. The methods by which Nagios detects service and host state flapping are described below...

    Service Flap Detection

    Whenever a service check is performed that results in a hard state or a soft recovery state, Nagios checks to see if the services has started or stopped flapping. It does this by storing the results of the last 21 checks of the service in an array. Older check results in the array are overwritten by newer check results.

    The contents of the historical state array are examined (in order from oldest result to newest result) to determine the total percentage of change in state that has occurred during the last 21 service checks. A state change occurs when an archived state is different from the archived state that immediately precedes it in the array. Since we keep the results of the last 21 service checks in the array, there is a possibility of having 20 state changes.

    Image 1 below shows a chronological array of service states. OK states are shown in green, WARNING states in yellow, CRITICAL states in red, and UNKNOWN states in orange. Blue arrows have been placed over periods of time where state changes occur.

    Image 1.
    Service State Transitions

    Services that rarely change between states will have a lower total percentage of change than those that do change between states a lot. Since flapping is associated with frequent state changes, we can use the calculated amount of change in state over a period of time (in this case, the last 21 service checks) to determine whether or not a service is flapping. That's not quite good enough though...

    It stands to reason that newer state changes should carry more weight than older state changes, so we really need to recalculate the total percent change in state for the service on some sort of curve... To make things simple, I've decided to make the relationship between time and weight linear for calculation of percent state change. The flap detection routines are currently designed to make the newest possible state change carry 50% more weight than the oldest possible state change. Image 2 shows how more recent state changes are given more weight than older state changes when calculating the overall or total percent state change for a particular service. If you really want to see exactly how the weighted calculation is done, look at the code in base/flapping.c...

    Image 2.
    Weighted Service State Transitions

    Let's look at a quick example of how flap detection is done. Image 1 above depicts the array of historical service check results for a particular service. The oldest result is on the left and the newest result is on the right. We see that in the example below there were a total of 7 state changes (at t3, t4, t5, t9, t12, t16, and t19). Without any weighting of the state changes over time, this would give us a total state change of 35% (7 state changes out of a possible 20 state changes). When the individual state changes are weighted relative to the time at which they occurred, the resulting total percent state change for the service is less than 35%. This makes sense since most of the state changes occurred earlier rather than later. Let's just say that the weighted percent of state change turned out to be 31%...

    So what significance does the 31% state change have? Well, if the service was previously not flapping and 31% is equal to or greater than the value specified by the high_service_flap_threshold option in the service definition, Nagios considers the service to have just started flapping. If the service was previously flapping and 31% is less than or equal to the value specified by the low_service_flap_threshold value in the service definition, Nagios considers the service to have just stopped flapping. If either of those two conditions are not met, Nagios does nothing else with the service, since it is either not currently flapping or it is still flapping...

    Host Flap Detection

    Host flap detection works in a similiar manner to service flap detection, with one important difference: Nagios will attempt to check to see if a host is flapping whenever the status of the host is checked and whenever a service associated with that host is checked. Why is this done? Well, with services we know that the minimum amount of time between consecutive flap detection routines is going to be equal to the service check interval. With hosts, we don't have a check interval, since hosts are not monitored on a regular basis - they are only checked as necessary. A host will be checked for flapping if its state has changed since the last time the flap detection was performed for that host or if its state has not changed but at least x amount of time has passed since the flap detection was performed. The x amount of time is equal to the average check interval of all services associated with the host. That's the best method I could come up with for determining how often flap detection could be performed on a host...

    Just as with services, Nagios stores the results of the last 21 of these host checks in an array for the flap detection logic. State changes are weighted based on the time at which they occurred, and the total percent change in state is calculated in the same manner that it is in the service flapping logic.

    If a host was previously not flapping and its total computed state change percentage is equal to or greater than the value specified by the high_host_flap_threshold option, Nagios considers the host to have just started flapping. If the host was previously flapping and its total computed state change percentage is less than or equal to the value specified by the low_host_flap_threshold value, Nagios considers the host to have just stopped flapping. If either of those two conditions are not met, Nagios does nothing else with the host, since it is either not currently flapping or it is still flapping...

    Host- and Service-Specific Flap Detection Thresholds

    If you're using the template-based object definition files, you can specify host- and service-specific flap detection thresholds by adding low_flap_threshold and high_flap_threshold directives to individual host and service definitions. If these directives are not present in the host or service definitions, the global host and service flap detection thresholds will be used.

    On a similiar note, you can also enable/disable flap detection for specific hosts and services by using the flap_detection_enabled directive in each object definition. Note that flap detection must be enabled on a program-wide basis (using the enable_flap_detection directive in the main config file) in order for any host or service to have flap detection enabled.

    Flap Handling

    When a service or host is first detected as flapping, Nagios will do three things:

    1. Log a message indicating that the service or host is flapping
    2. Add a non-persistent comment to the host or service indicating that it is flapping
    3. Suppress notifications for the service or host (this is one of the filters in the notification logic)

    When a service or host stops flapping, Nagios will do the following:

    1. Log a message indicating that the service or host has stopped flapping
    2. Delete the comment that was originally added to the service or host when it started flapping
    3. Remove the block on notifications for the service or host (notifications will still be bound to the normal notification logic)


    nagios-2.6/html/docs/freshness.html0000664000076500007650000002021110356775135016771 0ustar nagiosnagios Service and Host Result Freshness Checks

    Service and Host Result Freshness Checks


    Introduction

    Nagios supports a feature that does "freshness" checking on the results of host and service checks. This feature is useful when you want to ensure that passive checks are being received as frequently as you want. Although freshness checking can be used in a number of situations, it is primarily useful when attempting to configure a distributed monitoring environment.

    The purpose of "freshness" checking is to ensure that host and service checks are being provided passively by external applications on a regular basis. If the results of a particular host or service check (for which freshness checking has been enabled) is determined to be "stale", Nagios will force an active check of that host or service.

    Host vs. Service Freshness Checking

    The documentation below discusses service freshness checking. Host freshness checking (which is not documented seperately) works in a similiar way to service freshness checking - except, of course, that its for hosts instead of services. If you need to configure host freshness checking, adjust the directions given below appropriately.

    Configuring Service Freshness Checking

    Before you configure per-service freshness threshold, you must enable freshness checking using the check_service_freshness and service_freshness_check_interval directives in the main config file. If you were configuring host freshness checking, you would use the check_host_freshness and host_freshness_check_interval directives.

    So how do you go about enabling freshness checking for a particular service? You need to configure service definitions as follows.

    • The check_freshness option in the service definition should be set to 1. This enables "freshness" checking for the service.
    • The freshness_threshold option in the service definition should be set to a value (in seconds) which reflects how "fresh" the results for the service should be.
    • The check_command option in the service definition should reflect valid command that should be used to actively check the service when it is detected as being "stale".
    • The normal_check_interval option in the service definition needs to be greater than zero (0) if the freshness_threshold option is setup to zero (0).
    • The check_period option in the service definitions needs to be set to a valid timeperiod. The times allowed by the specified timeperiod determine when freshness checks can be performed for the service.

    How The Freshness Threshold Works

    Nagios periodically checks the "freshness" of the results for all services that have freshness checking enabled. The freshness_threshold option in each service definition is used to determine how "fresh" the results for each service should be. For example, if you set the freshness_threshold option to 60 for one of your services, Nagios will consider that service to be "stale" if its results are older than 60 seconds (1 minute). If you do not specify a value for the freshness_threshold option (or you set it to zero), Nagios will automatically calculate a "freshness" threshold to use by looking at either the normal_check_interval or retry_check_interval options (depending on what type of state the service is currently in).

    What Happens When A Service Check Result Becomes "Stale"

    If the check results of a service are found to be "stale" (as described above), Nagios will force an active check of the service by executing the command specified by the check_command option in the service definition. It is important to note that an active service check which is being forced because the service was detected as being "stale" gets executed even if active service checks are disabled on a program-wide or service-specific basis.

    Working With Passive-Only Checks

    As I mentioned earlier, freshness checking is of most use when you are dealing with services that get their results from passive checks. More often than not (as in the case with distributed monitoring setups), these services may not be getting all of their results from passive checks - no results are obtained from active checks.

    An example of a passive-only service might be one that reports the status of your nightly backup jobs. Perhaps you have a external script that submit the results of the backup job to Nagios once the backup is completed. In this case, all of the checks/results for the service are provided by an external application using passive checks. In order to ensure that the status of the backup job gets reported every day, you may want to enable freshness checking for the service. If the external script doesn't submit the results of the backup job, you can have Nagios fake a critical result by doing something like this...

    Here's what the definition for the service might look like (some required options are omitted)...

    define service{
    	host_name		backup-server
    	service_description	ArcServe Backup Job
    	active_checks_enabled	0			; active checks are NOT enabled
    	passive_checks_enabled	1			; passive checks are enabled (this is how results are reported)
    	check_freshness		1
    	freshness_threshold	93600			; 26 hour threshold, since backups may not always finish at the same time
    	check_command		no-backup-report	; this command is run only if the service results are "stale"
    	...other options...
    	}
    

    Notice that active checks are disabled for the service. This is because the results for the service are only made by an external application using passive checks. Freshness checking is enabled and the freshness threshold has been set to 26 hours. This is a bit longer than 24 hours because backup jobs sometimes run late from day to day (depending on how much data there is to backup, how much network traffic is present, etc.). The no-backup-report command is executed only if the results of the service are determined to be "stale". The definition of the no-backup-report command might look like this...

    define command{
    	command_name	no-backup-report
    	command_line	/usr/local/nagios/libexec/nobackupreport.sh
    	}
    

    The nobackupreport.sh script in your /usr/local/nagios/libexec directory might look something like this:

    #!/bin/sh
    
    /bin/echo "CRITICAL: Results of backup job were not reported!"
    
    exit 2
    

    If Nagios detects that the service results are stale, it will run the no-backup-report command as an active service check (even though active checks are disabled for this specific service - remember that this is a special case). This causes the /usr/local/nagios/libexec/nobackupreport.sh script to be executed, which returns a critical state. The service go into to a critical state (if it isn't already there) and someone will probably get notified of the problem.


    nagios-2.6/html/docs/funstuff.html0000664000076500007650000000151207743356403016633 0ustar nagiosnagios Neat Hacks and Tricks

    Neat Hacks and Tricks


    Other than the standard monitoring stuff, Nagios can be used to do some pretty cool things. Instead of spending your free time playing Quake, why don't you take some time and read about them at http://www.nagios.org/docs/hacks...


    nagios-2.6/html/docs/index.html0000664000076500007650000000404410532717361016077 0ustar nagiosnagios Nagios Documentation

    Nagios

    Nagios® Version 2.x
    Documentation

    Last Updated: 11-27-2006







    Nagios and the Nagios logo are registered trademarks of Ethan Galstad. All other trademarks, servicemarks, registered trademarks, and registered servicemarks mentioned herein may be the property of their respective owner(s). The information contained herein is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.

    nagios-2.6/html/docs/indirectchecks.html0000664000076500007650000001220507743356403017756 0ustar nagiosnagios Indirect Host and Service Checks

    Indirect Host and Service Checks


    Introduction

    Chances are, many of the services that you're going to be monitoring on your network can be checked directly by using a plugin on the host that runs Nagios. Examples of services that can be checked directly include availability of web, email, and FTP servers. These services can be checked directly by a plugin from the Nagios host because they are publicly accessible resources. However, there are a number of things you may be interested in monitoring that are not as publicly accessible as other services. These "private" resources/services include things like disk usage, processor load, etc. on remote machines. Private resources like these cannot be checked without the use of an intermediary agent. Service checks which require an intermediary agent of some kind to actually perform the check are called indirect checks.

    Indirect checks are useful for:

    • Monitoring "local" resources (such as disk usage, processer load, etc.) on remote hosts
    • Monitoring services and hosts behind firewalls
    • Obtaining more realistic results from checks of time-sensitive services between remote hosts (i.e. ping response times between two remote hosts)

    There are several methods for performing indirect active checks (passive checks are not discussed here), but I will only talk about how they can be done by using the nrpe addon.

    Indirect Service Checks

    The diagram below shows how indirect service checks work. Click the image for a larger version...

    Indirect Service Checks

    Multiple Indirected Service Checks

    If you are monitoring servers that lie behind a firewall (and the host running Nagios is outside that firewall), checking services on those machines can prove to be a bit of a pain. Chances are that you are blocking most incoming traffic that would normally be required to perform the monitoring. One solution for performing active checks (passive checks could also be used) on the hosts behind the firewall would be to poke a tiny hold in the firewall filters that allow the Nagios host to make calls to the nrpe daemon on one host inside the firewall. The host inside the firewall could then be used as an intermediary in performing checks on the other servers inside the firewall.

    The diagram below show how multiple indirect service checks work. Notice how the nrpe daemon is running on hosts #1 and #2. The copy that runs on host #2 is used to allow the nrpe agent on host #1 to perform a check of a "private" service on host #2. "Private" services are things like process load, disk usage, etc. that are not directly exposed like SMTP, FTP, and web services. Click on the diagram for a larger image...

    Multiple Indirected Service Checks

    Indirect Host Checks

    Indirect host checks work on the same principle as indirect service checks. Basically, the plugin used in the host check command asks an intermediary agent (i.e. a daemon running on a remote host) to perform the host check for it. Indirect host checks are useful when the remote hosts being monitored are located behind a firewall and you want to restrict inbound monitoring traffic to a particular machine. That machine (remote host #1 in the diagram below) performs will perform the host check and return the results back to the top level check_nrpe plugin (on the central server). It should be noted that with this setup comes potential problems. If remote host #1 goes down, the check_nrpe plugin will not be able to contact the nrpe daemon and Nagios will believe that remote hosts #2, #3, and #4 are down, even though this may not be the case. If host #1 is your firewall machine, then the problem isn't really an issue because Nagios will detect that it is down and mark hosts #2, #3, and #4 as being unreachable.

    The diagram below shows how an indirect host check can be performed by using the nrpe daemon and check_nrpe plugin. Click the image for a larger version.

    Indirect Host Checks


    nagios-2.6/html/docs/installing.html0000664000076500007650000002256310510244753017136 0ustar nagiosnagios Installing Nagios

    Installing Nagios


    Important: Installing and configuring Nagios is rather involved. You can't just compile the binaries, run the program and sit back. There's a lot to setup before you can actually start monitoring anything. Relax, take your time and read all the documentation - you're going to need it. Okay, let's get started...

    Become Root

    You'll need to have root access to install Nagios as described in this documentation, as you'll be creating users and group, modifying your web server config files, etc. Either login as root before you begin or use the su command to change to the root user from another account.

    Getting The Latest Version

    You can download the latest version of Nagios from http://www.nagios.org/download.

    Unpacking The Distribution

    To unpack the Nagios distribution, use the following command:

    tar xzf nagios-version.tar.gz

    When you have finished executing these commands, you should find a nagios-version directory that has been created in your current directory. Inside that directory you will find all the files that comprise the core Nagios distribution.

    Create Nagios User/Group

    You're probably going to want to run Nagios under a normal user account, so add a new user (and group) to your system with the following command (this will vary depending on what OS you're running):

    adduser nagios

    Create Installation Directory

    Create the base directory where you would like to install Nagios as follows...

    mkdir /usr/local/nagios

    Change the owner of the base installtion directory to be the Nagios user and group you added earlier as follows:

    chown nagios.nagios /usr/local/nagios

    Identify Web Server User

    You're probably going to want to issue external commands (like acknowledgements and scheduled downtime) from the web interface. To do so, you need to identify the user your web server runs as (typically apache, although this may differ on your system). This setting is found in your web server configuration file. The following command can be used to quickly determine what user Apache is running as (paths may differ on your system):

    grep "^User" /etc/httpd/conf/httpd.conf

    Add Command File Group

    Next we're going to create a new group whose members include the user your web server is running as and the user Nagios is running as. Let's say we call this new group 'nagcmd' (you can name it differently if you wish). On RedHat Linux you can use the following command to add a new group (other systems may differ):

    /usr/sbin/groupadd nagcmd

    Next, add the users that your web server and Nagios run as to the newly created group with the following commands (I'll assume apache and nagios are the respective users):

    /usr/sbin/usermod -G nagcmd apache
    /usr/sbin/usermod -G nagcmd nagios

    Run the Configure Script

    Run the configure script to initialize variables and create a Makefile as follows...(the last two options: --with-command-xxx are optional, but needed if you want to issue external commands)

    ./configure --prefix=prefix --with-cgiurl=cgiurl --with-htmurl=htmurl --with-nagios-user=someuser --with-nagios-group=somegroup --with-command-group=cmdgroup

    • Replace prefix with the installation directory that you created in the step above (default is /usr/local/nagios)
    • Replace cgiurl with the actual url you will be using to access the CGIs (default is /nagios/cgi-bin). Do NOT append a slash at the end of the url.
    • Replace htmurl with the actual url you will be using to access the HTML for the main interface and documentation (default is /nagios/)
    • Replace someuser with the name of a user on your system that will be used for setting permissions on the installed files (default is nagios)
    • Replace somegroup with the name of a group on your system that will be used for setting permissions on the installed files (default is nagios)
    • Replace cmdgroup with the name of the group running the web server (default is nagios, in the example above it was nagcmd). This will allow group members (i.e. your web server) to be able to submit external commands to Nagios.

    Compile Binaries

    Compile Nagios and the CGIs with the following command:

    make all

    Installing The Binaries And HTML Files

    Install the binaries and HTML files (documentation and main web page) with the following command:

    make install

    Installing An Init Script

    If you wish, you can also install the sample init script to /etc/rc.d/init.d/nagios with the following command:

    make install-init

    You may have to edit the init script to make sense with your particular OS and Nagios installation by editing paths, etc.

    Directory Structure And File Locations

    Change to the root of your Nagios installation directory with the following command...

    cd /usr/local/nagios

    You should see five different subdirectories. A brief description of what each directory contains is given in the table below.

    Sub-Directory Contents
    bin/ Nagios core program
    etc/ Main, resource, object, and CGI configuration files should be put here
    sbin/ CGIs
    share/ HTML files (for web interface and online documentation)
    var/ Empty directory for the log file, status file, retention file, etc.
    var/archives Empty directory for the archived logs
    var/rw Empty directory for the external command file

    Installing The Plugins

    In order for Nagios to be of any use to you, you're going to have to download and install some plugins. Plugins are usually installed in the libexec/ directory of your Nagios installation (i.e. /usr/local/nagios/libexec). Plugins are scripts or binaries which perform all the service and host checks that constitute monitoring. You can grab the latest release of the plugins from the Nagios downloads page or directly from the SourceForge project page.

    Setup The Web Interface

    You're probably going to want to use the web interface, so you'll also have to read the instructions on setting up the web interface and configuring web authentication, etc. next.

    Configuring Nagios

    So now you have things compiled and installed, but you still haven't configured Nagios or defined objects (hosts, services, etc.) that should be monitored. Information on configuring Nagios and defining objects can be found here. There's a lot to configure, but don't let it discourage you - its well worth it.


    nagios-2.6/html/docs/installweb.html0000664000076500007650000001012310342163030017112 0ustar nagiosnagios Setting Up The Web Interface

    Setting Up The Web Interface


    Notes

    In these instructions I will assume that you are running the Apache web server on your machine. If you are using some other web server, you'll have to make changes where appropriate. I am also assuming that you used the /usr/local/nagios as the installation prefix.

    Sample Configuration

    A sample Apache config file snippet is created when you run the configure script - you can find the sample config file (named httpd.conf) in the sample-config/ subdirectory of the Nagios distribution. You will need to add the contents of this file to your Apache configuration files before you can access the Nagios web interface. The instructions found below detail how to manually add the appropriate configuration entries to Apache.

    Configure Aliases and Directory Options For The Web Interface

    First you'll need to create appropriate entries for the Nagios web interface (HTML and CGIs) in your web server config file. Add the following snippet to your web server configuration file (i.e. httpd.conf), changing it to match any directory differences on your system.

    ScriptAlias /nagios/cgi-bin /usr/local/nagios/sbin
    
    <Directory "/usr/local/nagios/sbin">
        Options ExecCGI
        AllowOverride None
        Order allow,deny
        Allow from all
        AuthName "Nagios Access"
        AuthType Basic
        AuthUserFile /usr/local/nagios/etc/htpasswd.users
        Require valid-user
    </Directory>
    
    Alias /nagios /usr/local/nagios/share
    
    <Directory "/usr/local/nagios/share">
        Options None
        AllowOverride None
        Order allow,deny
        Allow from all
        AuthName "Nagios Access"
        AuthType Basic
        AuthUserFile /usr/local/nagios/etc/htpasswd.users
        Require valid-user
    </Directory>
    

    Note: The default Nagios installation expects to find the HTML files and CGIs at http://yourmachine/nagios/ and http://yourmachine/nagios/cgi-bin/, respectively. These locations can be changed using the --with-htmurl and --with-cgiurl options in the configure script.

    Important! If you are installing Nagios on a multi-user system, you may want use CGIWrap to provide additional security between the CGIs and the external command file. If you decide to use CGIWrap, the ScriptAlias you'll end up using will most likely be different from that mentioned above. More information on doing this can be found here.

    Restart The Web Server

    Once you've finished editing the Apache configuration file, you'll need to restart the web server with a command like this...

    /etc/rc.d/init.d/httpd restart

    Configure Web Authentication

    Once you have installed the web interface properly, you'll need to specify who can access the Nagios web interface. Follow these instructions to do this.

    Verify Your Changes

    Don't forget to check and see if the changes you made to Apache work. You should be able to point your web browser at http://yourmachine/nagios/ and get the web interface for Nagios. The CGIs may not display any information, but this will be remedied once you configure everything and start Nagios.


    nagios-2.6/html/docs/int-snmptrap.html0000664000076500007650000002225310141023044017406 0ustar nagiosnagios UCD-SNMP (NET-SNMP) Integration

    UCD-SNMP (NET-SNMP) Integration


    Note: Nagios is not designed to be a replacement for a full-blown SNMP management application like HP OpenView or OpenNMS. However, you can set things up so that SNMP traps received by a host on your network can generate alerts in Nagios. Here's how...

    Introduction

    This example explains how to easily generate alerts in Nagios for SNMP traps that are received by the UCD-SNMP snmptrapd daemon. These directions assume that the host which is receiving SNMP traps is not the same host on which Nagios is running. If your monitoring box is the same box that is receiving SNMP traps you will need to make a few modifications to the examples I provide. Also, I am assuming that you having installed the nsca daemon on your monitoring server and the nsca client (send_nsca) on the machine that is receiving SNMP traps.

    For the purposes of this example, I will be describing how I setup Nagios to generate alerts from SNMP traps received by the ArcServe backup jobs running on my Novell servers. I wanted to get notified when backups failed, so this worked very nicely for me. You'll have to tweak the examples in order to make it suit your needs.

    Additional Software

    Translating SNMP traps into Nagios events can be a bit tedious. If you'd like to make it easier, you might want to check out Alex Burger's SNMP Trap Translator project located at http://www.snmptt.org which, combined with Net-SNMP, provides a more enhanced trap handling system. The snmptt documentation includes integration details for Nagios.

    Defining The Service

    First off you're going to have to define a service in your object configuration file for the SNMP traps (in this example, I am defining a service for ArcServe backup jobs). Assuming that the host that the alerts are originating from is called novellserver, a sample service definition might look something like this:

    define service{
    	host_name                       novellserver
    	service_description             ArcServe Backup
    	is_volatile                     1
    	active_checks_enabled		0
    	passive_checks_enabled		1
    	max_check_attempts              1
    	contact_groups                  novell-backup-admins
    	notification_interval           120
    	notification_period             24x7
    	notification_options            w,u,c,r
    	check_command                   check_none
    	}
    

    Important things to note are the fact that this service has the volatile option enabled. We want this option enabled because we want a notification to be generated for every alert that comes in. Also of note is the fact that active checks are disabled for the service, while passive checks are enabled. This means that the service will never be actively checked - all alert information will have to be sent in passively by the nsca client on the SNMP management host (in my example, it will be called firestorm).

    ArcServe and Novell SNMP Configuration

    In order to get ArcServe (and my Novell server) to send SNMP traps to my management host, I had to do the following:

    1. Modify the ArcServe autopilot job to send SNMP traps on job failures, successes, etc.
    2. Edit SYS:\ETC\TRAPTARG.CFG and add the IP address of my management host (the one receiving the SNMP traps)
    3. Load SNMP.NLM
    4. Load ALERT.NLM to facilitate the actual sending of the SNMP traps

    SNMP Management Host Configuration

    On my Linux SNMP management host (firestorm), I installed the UCD-SNMP (NET-SNMP) software. Once the software was installed I had to do the following:

    1. Install the ArcServe MIBs (included on the ArcServe installation CD)
    2. Edit the snmptrapd configuration file (/etc/snmp/snmptrapd.conf) to define a trap handler for ArcServe alerts. This is detailed below.
    3. Start the snmptrapd daemon to listen for incoming SNMP traps

    In order to have the snmptrapd daemon route ArcServe SNMP traps to our Nagios host, we've got to define a traphandler in the /etc/snmp/snmptrapd.conf file. In my setup, the config file looked something like this:

    #############################
    # ArcServe SNMP Traps
    #############################
    
    # Tape format failures
    traphandle ARCserve-Alarm-MIB::arcServetrap9 /usr/local/nagios/libexec/eventhandlers/handle-arcserve-trap 9
    
    # Failure to read tape header
    traphandle ARCserve-Alarm-MIB::arcServetrap10 /usr/local/nagios/libexec/eventhandlers/handle-arcserve-trap 10
    
    # Failure to position tape
    traphandle ARCserve-Alarm-MIB::arcServetrap11 /usr/local/nagios/libexec/eventhandlers/handle-arcserve-trap 11
    
    # Cancelled jobs
    traphandle ARCserve-Alarm-MIB::arcServetrap12 /usr/local/nagios/libexec/eventhandlers/handle-arcserve-trap 12
    
    # Successful jobs
    traphandle ARCserve-Alarm-MIB::arcServetrap13 /usr/local/nagios/libexec/eventhandlers/handle-arcserve-trap 13
    
    # Imcomplete jobs
    traphandle ARCserve-Alarm-MIB::arcServetrap14 /usr/local/nagios/libexec/eventhandlers/handle-arcserve-trap 14
    
    # Job failures
    traphandle ARCserve-Alarm-MIB::arcServetrap15 /usr/local/nagios/libexec/eventhandlers/handle-arcserve-trap 15
    

    This example assumes that you have a /usr/local/nagios/libexec/eventhandlers/ directory on your SNMP mangement host and that the handle-arcserve-trap script exists there. You can modify these to fit your setup. Anyway, the handle-arcserve-trap script on my management host looked something like this:

    #!/bin/sh
    
    # Arguments:
    #  $1 = trap type
    
    	# First line passed from snmptrapd is FQDN of host that sent the trap
         read host
    
        # Given a FQDN, get the short name of the host as it is setup in Nagios
        hostname="unknown"
        case $host in
            novellserver.mylocaldomain.com)
                hostname="novellserver"
                ;;
            nt.mylocaldomain.com)
                hostname="ntserver"
                ;;
    	esac
    	
        # Get severity level (OK, WARNING, UNKNOWN, or CRITICAL) and plugin output based on trape type
        state=-1
        output="No output"
        case "$1" in
    
            # failed to format tape - critical
            11)
                output="Critical: Failed to format tape"
                state=2
                ;;
    
            # failed to read tape header - critical
            10)
                output="Critical: Failed to read tape header"
                state=2
                ;;
    
            # failed to position tape - critical
            11)
                output="Critical: Failed to position tape"
                state=2
                ;;
    
            # backup cancelled - warning
            12)
                output="Warning: ArcServe backup operation cancelled"
                state=1
                ;;
    
            # backup success - ok
            13)
                output="Ok: ArcServe backup operation successful"
                state=0
                ;;
    
            # backup incomplete - warning
            14)
                output="Warning: ArcServe backup operation incomplete"
                state=1
                ;;
    
            # backup failure - critical
            15)
                output="Critical: ArcServe backup operation failed"
                state=2
                ;;
        esac
    
    
        # Submit passive check result to monitoring host
        /usr/local/nagios/libexec/eventhandlers/submit_check_result $hostname "ArcServe Backup" $state "$output"
    
    exit 0
    

    Notice that the handle-arcserve-trap script calls the submit_check_result script to actually send the alert back to the monitoring host. Assuming your monitoring host is called monitor, the submit check_result script might look like this (you'll have to modify this to specify the proper location of the send_nsca program on your management host):

    #!/bin/sh
    
    # Arguments
    #	$1 = name of host in service definition
    #	$2 = name/description of service in service definition
    #	$3 = return code
    #	$4 = output
    
    /bin/echo -e "$1\t$2\t$3\t$4\n" | /usr/local/nagios/bin/send_nsca monitor -c /usr/local/nagios/etc/send_nsca.cfg
    

    Finishing Up

    You've now configured everything you need to, so all you have to do is restart the Nagios on your monitoring server. That's it! You should be getting alerts in Nagios whenever ArcServe jobs fail, succeed, etc.


    nagios-2.6/html/docs/int-tcpwrappers.html0000664000076500007650000001153007743356403020136 0ustar nagiosnagios TCP Wrapper Integration

    TCP Wrapper Integration


    Introduction

    This example explains how to easily generate alerts in Nagios for connection attempts that are rejected by TCP wrappers. These directions assume that the host which you are generating alerts for (i.e. the host you are using TCP wrappers on) is not the same host on which Nagios is running. If you want to generate alerts on the same host that Nagios is running you will need to make a few modifications to the examples I provide. Also, I am assuming that you having installed the nsca daemon on your monitoring server and the nsca client (send_nsca) on the machine that you are generating TCP wrapper alerts from.

    Defining The Service

    First off you're going to have to define a service in your object configuration file for the TCP wrapper alerts. Assuming that the host that the alerts are originating from is called firestorm, a sample service definition might look something like this:

    define service{
    	host_name                       firestorm
    	service_description             TCP Wrappers
    	is_volatile                     1
    	active_checks_enabled		0
    	passive_checks_enabled		1
    	max_check_attempts              1
    	contact_groups                  security-admins
    	notification_interval           120
    	notification_period             24x7
    	notification_options            w,u,c,r
    	check_command                   check_none
    	}
    

    Important things to note are the fact that this service has the volatile option enabled. We want this option enabled because we want a notification to be generated for every alert that comes in. Also of note is the fact that active checks of the service as disabled, while passive checks are enabled. This means that the service will never be actively checked - all alert information will have to be sent in passively by the nsca client on the firestorm host.

    Configuring TCP Wrappers

    Now you're going to have to modify the /etc/hosts.deny file on the host called firestorm. In order to have the TCP wrappers send an alert to the monitoring host whenever a connection attempt is denied, you'll have to add a line similiar to the following:

    ALL: ALL: RFC931: twist (/usr/local/nagios/libexec/eventhandlers/handle_tcp_wrapper %h %d) &
    

    This line assumes that there is a script called handle_tcp_wrapper in the /usr/local/nagios/libexec/eventhandlers/ directory on firestorm. The directory and script name can be changed to whatever you want.

    Writing The Script

    The last thing you need to do is write the handle_tcp_wrapper script on firestorm that will send the alert back to the monitoring host. It might look something like this:

    #!/bin/sh
    
    /usr/local/nagios/libexec/eventhandlers/submit_check_result firestorm "TCP Wrappers" 2 "Denied $2-$1" > /dev/null 2> /dev/null
    

    Notice that the handle_tcp_wrapper script calls the submit_check_result script to actually send the alert back to the monitoring host. Assuming your monitoring host is called monitor, the submit check_result script might look like this (you'll have to modify this to specify the proper location of the send_nsca program on firestorm):

    #!/bin/sh
    
    # Arguments
    #	$1 = name of host in service definition
    #	$2 = name/description of service in service definition
    #	$3 = return code
    #	$4 = output
    
    /bin/echo -e "$1\t$2\t$3\t$4\n" | /usr/local/nagios/bin/send_nsca monitor -c /usr/local/nagios/etc/send_nsca.cfg
    

    Finishing Up

    You've now configured everything you need to, so all you have to do is restart the inetd process on firestorm and restart Nagios on your monitoring server. That's it! When the TCP wrappers on firestorm deny a connection attempt, you should be getting alerts in Nagios. The plugin output for the alert will look something like the following:

    Denied sshd2-sdn-ar-002mnminnP321.dialsprint.net 
    


    nagios-2.6/html/docs/macros.html0000664000076500007650000021631510326736064016264 0ustar nagiosnagios Using Macros In Commands

    Using Macros In Commands


    Macros

    One of the features available in Nagios is the ability to use macros in command defintions. Immediately prior to the execution of a command, Nagios will replace all macros in the command with their corresponding values. This allows you to define a few generic commands to handle all your needs.

    Macro Substitution

    Before any commands (host and service checks, notifications, event handlers, etc.) are executed, Nagios will replace any macros it finds in the command definition with their corresponding values.

    When you use host and service macros in command definitions, they refer to values for the host or service for which the command is being run. Let's try an example. Assuming we are using a host definition and a check_ping command defined like this:

    define host{
    	host_name		linuxbox
    	address		192.168.1.2
    	check_command	check_ping
    	...
    	}
    	
    define command{
    	command_name    check_ping
    	command_line    /usr/local/nagios/libexec/check_ping -H $HOSTADDRESS$ -w 100.0,90% -c 200.0,60%
    	}
    

    the expanded/final command line to be executed for the host's check command would look like this:

    	/usr/local/nagios/libexec/check_ping -H 192.168.1.2 -w 100.0,90% -c 200.0,60%
    

    You can pass arguments to commands as well, which is quite handy if you'd like to keep your command definitions rather generic. Arguments are specified in the object (i.e. host or service) definition, by seperating them from the command name with exclamation points (!) like so:

    define service{
    	host_name		linuxbox
    	service_description	PING
    	...
    	check_command	check_ping!200.0,80%!400.0,40%
    	...
    	}
    

    In the example above, the service check command has two arguments (which can be referenced with $ARGn$ macros). The $ARG1$ macro will be "200.0,80%" and $ARG2$ will be "400.0,40%" (both without quotes). Assuming we are using the host definition given earlier and a check_ping command defined like this:

    define command{
    	command_name    check_ping
    	command_line    /usr/local/nagios/libexec/check_ping -H $HOSTADDRESS$ -w $ARG1$ -c $ARG2$
    	}
    

    the expanded/final command line to be executed for the service's check command would look like this:

    	/usr/local/nagios/libexec/check_ping -H 192.168.1.2 -w 200.0,80% -c 400.0,40%
    

    On-Demand Macros

    Normally when you use host and service macros in command definitions, they refer to values for the host or service for which the command is being run. For instance, if a host check command is being executed for a host named "linuxbox", all the host macros listed in the table below will refer to values for that host ("linuxbox").

    If you would like to reference values for another host or service in a command (for which the command is not being run), you can use what are called "on-demand" macros. On-demand macros look like normal macros, except for the fact that they contain an identifier for the host or service from which they should get their value. Here's the basic format for on-demand macros:

    • $HOSTMACRO:host_name$
    • $SERVICEMACRO:host_name:service_description$

    Note that the macro name is seperated from the host or service identifier by a colon (:). For on-demand service macros, the service identifier consists of both a host name and a service description - these are seperated by a colon (:) as well.

    Examples of on-demand host and service macros follow:

    $HOSTDOWNTIME:myhost$
    $SERVICESTATEID:novellserver:DS Database$
    

    Macro Cleansing

    Some macros are stripped of potentially dangerous shell metacharacters before being substituted into commands to be executed. Which characters are stripped from the macros depends on the setting of the illegal_macro_output_chars directive. The following macros are stripped of potentially dangerous characters:

    1. $HOSTOUTPUT$
    2. $HOSTPERFDATA$
    3. $HOSTACKAUTHOR$
    4. $HOSTACKCOMMENT$
    5. $SERVICEOUTPUT$
    6. $SERVICEPERFDATA$
    7. $SERVICEACKAUTHOR$
    8. $SERVICEACKCOMMENT$

    Macros as Environment Variables

    Starting with Nagios 2.0, most macros have been made available as environment variables. This means that scripts that are run from Nagios (i.e. service and host check commands, notification commands, etc.) can reference these macros directly as standard environment variables. For purposes of security and sanity, $USERn$ and "on-demand" host and service macros are not made available as environment variables. Environment variables that contain macros are named the same as their corresponding macro names (listed below), with "NAGIOS_" prepended to their names. For example, the $HOSTNAME$ macro would be available as an environment variable named "NAGIOS_HOSTNAME".

    Macro Validity

    Although macros can be used in all commands you define, not all macros may be "valid" in a particular type of command. For example, some macros may only be valid during service notification commands, whereas other may only be valid during host check commands. There are ten types of commands that Nagios recognizes and treats differently. They are as follows:

    1. Service checks
    2. Service notifications
    3. Host checks
    4. Host notifications
    5. Service event handlers and/or a global service event handler
    6. Host event handlers and/or a global host event handler
    7. OCSP command
    8. OCHP command
    9. Service performance data commands
    10. Host performance data commands

    The tables below list all macros currently available in Nagios, along with a brief description of each and the types of commands in which they are valid. If a macro is used in a command in which it is invalid, it is replaced with an empty string. It should be noted that macros consist of all uppercase characters and are enclosed in $ characters.

    Macro Availability Chart

    Legend:
    NoThe macro is not available
    YesThe macro is available

    Macro Name Service Checks Service Notifications Host Checks Host Notifications Service Event Handlers, Global Service Event Handler, OCSP Command Host Event Handlers, Global Host Event Handler, OCHP Command Service Performance Data Commands Host Performance Data Commands
    Host Macros: 3
    $HOSTNAME$ YesYesYesYesYesYesYesYes
    $HOSTALIAS$ YesYesYesYesYesYesYesYes
    $HOSTADDRESS$ YesYesYesYesYesYesYesYes
    $HOSTSTATE$ YesYesYes 1YesYesYesYesYes
    $HOSTSTATEID$ YesYesYes 1YesYesYesYesYes
    $HOSTSTATETYPE$ YesYesYes 1YesYesYesYesYes
    $HOSTATTEMPT$ YesYesYesYesYesYesYesYes
    $HOSTLATENCY$ YesYesYesYesYesYesYesYes
    $HOSTEXECUTIONTIME$ YesYesYes 1YesYesYesYesYes
    $HOSTDURATION$ YesYesYesYesYesYesYesYes
    $HOSTDURATIONSEC$ YesYesYesYesYesYesYesYes
    $HOSTDOWNTIME$ YesYesYesYesYesYesYesYes
    $HOSTPERCENTCHANGE$ YesYesYesYesYesYesYesYes
    $HOSTGROUPNAME$ YesYesYesYesYesYesYesYes
    $HOSTGROUPALIAS$ YesYesYesYesYesYesYesYes
    $LASTHOSTCHECK$ YesYesYesYesYesYesYesYes
    $LASTHOSTSTATECHANGE$ YesYesYesYesYesYesYesYes
    $LASTHOSTUP$ YesYesYesYesYesYesYesYes
    $LASTHOSTDOWN$ YesYesYesYesYesYesYesYes
    $LASTHOSTUNREACHABLE$ YesYesYesYesYesYesYesYes
    $HOSTOUTPUT$ YesYesYes 1YesYesYesYesYes
    $HOSTPERFDATA$ YesYesYes 1YesYesYesYesYes
    $HOSTCHECKCOMMAND$ YesYesYesYesYesYesYesYes
    $HOSTACKAUTHOR$ NoNoNoYesNoNoNoNo
    $HOSTACKCOMMENT$ NoNoNoYesNoNoNoNo
    $HOSTACTIONURL$ YesYesYesYesYesYesYesYes
    $HOSTNOTESURL$ YesYesYesYesYesYesYesYes
    $HOSTNOTES$ YesYesYesYesYesYesYesYes
    Service Macros:
    $SERVICEDESC$ YesYesNoNoYesNoYesNo
    $SERVICESTATE$ Yes 2YesNoNoYesNoYesNo
    $SERVICESTATEID$ Yes 2YesNoNoYesNoYesNo
    $SERVICESTATETYPE$ YesYesNoNoYesNoYesNo
    $SERVICEATTEMPT$ YesYesNoNoYesNoYesNo
    $SERVICELATENCY$ YesYesNoNoYesNoYesNo
    $SERVICEEXECUTIONTIME$ Yes 2YesNoNoYesNoYesNo
    $SERVICEDURATION$ YesYesNoNoYesNoYesNo
    $SERVICEDURATIONSEC$ YesYesNoNoYesNoYesNo
    $SERVICEDOWNTIME$ YesYesNoNoYesNoYesNo
    $SERVICEPERCENTCHANGE$ YesYesNoNoYesNoYesNo
    $SERVICEGROUPNAME$ YesYesNoNoYesNoYesNo
    $SERVICEGROUPALIAS$ YesYesNoNoYesNoYesNo
    $LASTSERVICECHECK$ YesYesNoNoYesNoYesNo
    $LASTSERVICESTATECHANGE$ YesYesNoNoYesNoYesNo
    $LASTSERVICEOK$ YesYesNoNoYesNoYesNo
    $LASTSERVICEWARNING$ YesYesNoNoYesNoYesNo
    $LASTSERVICEUNKNOWN$ YesYesNoNoYesNoYesNo
    $LASTSERVICECRITICAL$ YesYesNoNoYesNoYesNo
    $SERVICEOUTPUT$ Yes 2YesNoNoYesNoYesNo
    $SERVICEPERFDATA$ Yes 2YesNoNoYesNoYesNo
    $SERVICECHECKCOMMAND$ YesYesNoNoYesNoYesNo
    $SERVICEACKAUTHOR$ NoYesNoNoNoNoNoNo
    $SERVICEACKCOMMENT$ NoYesNoNoNoNoNoNo
    $SERVICEACTIONURL$ YesYesNoNoYesNoYesNo
    $SERVICENOTESURL$ YesYesNoNoYesNoYesNo
    $SERVICENOTES$ YesYesNoNoYesNoYesNo
    Summary Macros:
    $TOTALHOSTSUP$ YesYes 4YesYes 4YesYesYesYes
    $TOTALHOSTSDOWN$ YesYes 4YesYes 4YesYesYesYes
    $TOTALHOSTSUNREACHABLE$ YesYes 4YesYes 4YesYesYesYes
    $TOTALHOSTSDOWNUNHANDLED$ YesYes 4YesYes 4YesYesYesYes
    $TOTALHOSTSUNREACHABLEUNHANDLED$ YesYes 4YesYes 4YesYesYesYes
    $TOTALHOSTPROBLEMS$ YesYes 4YesYes 4YesYesYesYes
    $TOTALHOSTPROBLEMSUNHANDLED$ YesYes 4YesYes 4YesYesYesYes
    $TOTALSERVICESOK$ YesYes 4YesYes 4YesYesYesYes
    $TOTALSERVICESWARNING$ YesYes 4YesYes 4YesYesYesYes
    $TOTALSERVICESCRITICAL$ YesYes 4YesYes 4YesYesYesYes
    $TOTALSERVICESUNKNOWN$ YesYes 4YesYes 4YesYesYesYes
    $TOTALSERVICESWARNINGUNHANDLED$ YesYes 4YesYes 4YesYesYesYes
    $TOTALSERVICESCRITICALUNHANDLED$ YesYes 4YesYes 4YesYesYesYes
    $TOTALSERVICESUNKNOWNUNHANDLED$ YesYes 4YesYes 4YesYesYesYes
    $TOTALSERVICEPROBLEMS$ YesYes 4YesYes 4YesYesYesYes
    $TOTALSERVICEPROBLEMSUNHANDLED$ YesYes 4YesYes 4YesYesYesYes
    Notification Macros:
    $NOTIFICATIONTYPE$ NoYesNoYesNoNoNoNo
    $NOTIFICATIONNUMBER$ NoYesNoYesNoNoNoNo
    Contact Macros:
    $CONTACTNAME$ NoYesNoYesNoNoNoNo
    $CONTACTALIAS$ NoYesNoYesNoNoNoNo
    $CONTACTEMAIL$ NoYesNoYesNoNoNoNo
    $CONTACTPAGER$ NoYesNoYesNoNoNoNo
    $CONTACTADDRESSn$ NoYesNoYesNoNoNoNo
    Date Macros:
    $LONGDATETIME$ YesYesYesYesYesYesYesYes
    $SHORTDATETIME$ YesYesYesYesYesYesYesYes
    $DATE$ YesYesYesYesYesYesYesYes
    $TIME$ YesYesYesYesYesYesYesYes
    $TIMET$ YesYesYesYesYesYesYesYes
    File Macros:
    $MAINCONFIGFILE$ YesYesYesYesYesYesYesYes
    $STATUSDATAFILE$ YesYesYesYesYesYesYesYes
    $COMMENTDATAFILE$ YesYesYesYesYesYesYesYes
    $DOWNTIMEDATAFILE$ YesYesYesYesYesYesYesYes
    $RETENTIONDATAFILE$ YesYesYesYesYesYesYesYes
    $OBJECTCACHEFILE$ YesYesYesYesYesYesYesYes
    $TEMPFILE$ YesYesYesYesYesYesYesYes
    $LOGFILE$ YesYesYesYesYesYesYesYes
    $RESOURCEFILE$ YesYesYesYesYesYesYesYes
    $COMMANDFILE$ YesYesYesYesYesYesYesYes
    $HOSTPERFDATAFILE$ YesYesYesYesYesYesYesYes
    $SERVICEPERFDATAFILE$ YesYesYesYesYesYesYesYes
    Misc Macros:
    $PROCESSSTARTTIME$ YesYesYesYesYesYesYesYes
    $ADMINEMAIL$ YesYesYesYesYesYesYesYes
    $ADMINPAGER$ YesYesYesYesYesYesYesYes
    $ARGn$ YesYesYesYesYesYesYesYes
    $USERn$ YesYesYesYesYesYesYesYes

    Macro Descriptions

    Host Macros: 3
    $HOSTNAME$ Short name for the host (i.e. "biglinuxbox"). This value is taken from the host_name directive in the host definition.
    $HOSTALIAS$ Long name/description for the host. This value is taken from the alias directive in the host definition.
    $HOSTADDRESS$ Address of the host. This value is taken from the address directive in the host definition.
    $HOSTSTATE$ A string indicating the current state of the host ("UP", "DOWN", or "UNREACHABLE").
    $HOSTSTATEID$ A number that corresponds to the current state of the host: 0=UP, 1=DOWN, 2=UNREACHABLE.
    $HOSTSTATETYPE$ A string indicating the state type for the current host check ("HARD" or "SOFT"). Soft states occur when host checks return a non-OK (non-UP) state and are in the process of being retried. Hard states result when host checks have been checked a specified maximum number of times.
    $HOSTATTEMPT$ The number of the current host check retry. For instance, if this is the second time that the host is being rechecked, this will be the number two. Current attempt number is really only useful when writing host event handlers for "soft" states that take a specific action based on the host retry number.
    $HOSTLATENCY$ A (floating point) number indicating the number of seconds that a scheduled host check lagged behind its scheduled check time. For instance, if a check was scheduled for 03:14:15 and it didn't get executed until 03:14:17, there would be a check latency of 2.0 seconds. On-demand host checks have a latency of zero seconds.
    $HOSTEXECUTIONTIME$ A (floating point) number indicating the number of seconds that the host check took to execute (i.e. the amount of time the check was executing).
    $HOSTDURATION$ A string indicating the amount of time that the host has spent in its current state. Format is "XXh YYm ZZs", indicating hours, minutes and seconds.
    $HOSTDURATIONSEC$ A number indicating the number of seconds that the host has spent in its current state.
    $HOSTDOWNTIME$ A number indicating the current "downtime depth" for the host. If this host is currently in a period of scheduled downtime, the value will be greater than zero. If the host is not currently in a period of downtime, this value will be zero.
    $HOSTPERCENTCHANGE$ A (floating point) number indicating the percent state change the host has undergone. Percent state change is used by the flap detection algorithm.
    $HOSTGROUPNAME$ The short name of the hostgroup that this host belongs to. This value is taken from the hostgroup_name directive in the hostgroup definition. If the host belongs to more than one hostgroup this macro will contain the name of just one of them.
    $HOSTGROUPALIAS$ The longer name/alias of the hostgroup that this host belongs to. This value is taken from the alias directive in the hostgroup definition. If the host belongs to more than one hostgroup, this macro contains the alias of just one of them.
    $LASTHOSTCHECK$ This is a timestamp in time_t format (seconds since the UNIX epoch) indicating the time at which a check of the host was last performed.
    $LASTHOSTSTATECHANGE$ This is a timestamp in time_t format (seconds since the UNIX epoch) indicating the time the host last changed state.
    $LASTHOSTUP$ This is a timestamp in time_t format (seconds since the UNIX epoch) indicating the time at which the host was last detected as being in an UP state.
    $LASTHOSTDOWN$ This is a timestamp in time_t format (seconds since the UNIX epoch) indicating the time at which the host was last detected as being in a DOWN state.
    $LASTHOSTUNREACHABLE$ This is a timestamp in time_t format (seconds since the UNIX epoch) indicating the time at which the host was last detected as being in an UNREACHABLE state.
    $HOSTOUTPUT$ The text output from the last host check (i.e. "Ping OK").
    $HOSTPERFDATA$ This macro contains any performance data that may have been returned by the last host check.
    $HOSTCHECKCOMMAND$ This macro contains the name of the command (along with any arguments passed to it) used to perform the host check.
    $HOSTACKAUTHOR$ A string containing the name of the user who acknowledged the host problem. This macro is only valid in notifications where the $NOTIFICATIONTYPE$ macro is set to "ACKNOWLEDGEMENT".
    $HOSTACKCOMMENT$ A string containing the acknowledgement comment that was entered by the user who acknowledged the host problem. This macro is only valid in notifications where the $NOTIFICATIONTYPE$ macro is set to "ACKNOWLEDGEMENT".
    $HOSTACTIONURL$ Action URL for the host. This value is taken from the action_url directive in the extended host information definition.
    $HOSTNOTESURL$ Notes URL for the host. This value is taken from the notes_url directive in the extended host information definition.
    $HOSTNOTES$ Notes for the host. This value is taken from the notes directive in the extended host information definition.
    Service Macros:
    $SERVICEDESC$ The long name/description of the service (i.e. "Main Website"). This value is taken from the description directive of the service definition.
    $SERVICESTATE$ A string indicating the current state of the service ("OK", "WARNING", "UNKNOWN", or "CRITICAL").
    $SERVICESTATEID$ A number that corresponds to the current state of the service: 0=OK, 1=WARNING, 2=CRITICAL, 3=UNKNOWN.
    $SERVICESTATETYPE$ A string indicating the state type for the current service check ("HARD" or "SOFT"). Soft states occur when service checks return a non-OK state and are in the process of being retried. Hard states result when service checks have been checked a specified maximum number of times.
    $SERVICEATTEMPT$ The number of the current service check retry. For instance, if this is the second time that the service is being rechecked, this will be the number two. Current attempt number is really only useful when writing service event handlers for "soft" states that take a specific action based on the service retry number.
    $SERVICELATENCY$ A (floating point) number indicating the number of seconds that a scheduled service check lagged behind its scheduled check time. For instance, if a check was scheduled for 03:14:15 and it didn't get executed until 03:14:17, there would be a check latency of 2.0 seconds.
    $SERVICEEXECUTIONTIME$ A (floating point) number indicating the number of seconds that the service check took to execute (i.e. the amount of time the check was executing).
    $SERVICEDURATION$ A string indicating the amount of time that the service has spent in its current state. Format is "XXh YYm ZZs", indicating hours, minutes and seconds.
    $SERVICEDURATIONSEC$ A number indicating the number of seconds that the service has spent in its current state.
    $SERVICEDOWNTIME$ A number indicating the current "downtime depth" for the service. If this service is currently in a period of scheduled downtime, the value will be greater than zero. If the service is not currently in a period of downtime, this value will be zero.
    $SERVICEPERCENTCHANGE$ A (floating point) number indicating the percent state change the service has undergone. Percent state change is used by the flap detection algorithm.
    $SERVICEGROUPNAME$ The short name of the servicegroup that this service belongs to. This value is taken from the servicegroup_name directive in the servicegroup definition. If the service belongs to more than one servicegroup this macro will contain the name of just one of them.
    $SERVICEGROUPALIAS$ The long name/alias of the servicegroup that this service belongs to. This value is taken from the alias directive in the servicegroup definition. If the service belongs to more than one servicegroup this macro will contain the name of just one of them.
    $LASTSERVICECHECK$ This is a timestamp in time_t format (seconds since the UNIX epoch) indicating the time at which a check of the service was last performed.
    $LASTSERVICESTATECHANGE$ This is a timestamp in time_t format (seconds since the UNIX epoch) indicating the time the service last changed state.
    $LASTSERVICEOK$ This is a timestamp in time_t format (seconds since the UNIX epoch) indicating the time at which the service was last detected as being in an OK state.
    $LASTSERVICEWARNING$ This is a timestamp in time_t format (seconds since the UNIX epoch) indicating the time at which the service was last detected as being in a WARNING state.
    $LASTSERVICEUNKNOWN$ This is a timestamp in time_t format (seconds since the UNIX epoch) indicating the time at which the service was last detected as being in an UNKNOWN state.
    $LASTSERVICECRITICAL$ This is a timestamp in time_t format (seconds since the UNIX epoch) indicating the time at which the service was last detected as being in a CRITICAL state.
    $SERVICEOUTPUT$ The text output from the last service check (i.e. "Ping OK").
    $SERVICEPERFDATA$ This macro contains any performance data that may have been returned by the last service check.
    $SERVICECHECKCOMMAND$ This macro contains the name of the command (along with any arguments passed to it) used to perform the service check.
    $SERVICEACKAUTHOR$ A string containing the name of the user who acknowledged the service problem. This macro is only valid in notifications where the $NOTIFICATIONTYPE$ macro is set to "ACKNOWLEDGEMENT".
    $SERVICEACKCOMMENT$ A string containing the acknowledgement comment that was entered by the user who acknowledged the service problem. This macro is only valid in notifications where the $NOTIFICATIONTYPE$ macro is set to "ACKNOWLEDGEMENT".
    $SERVICEACTIONURL$ Action URL for the service. This value is taken from the action_url directive in the extended service information definition.
    $SERVICENOTESURL$ Notes URL for the service. This value is taken from the notes_url directive in the extended service information definition.
    $SERVICENOTES$ Notes for the service. This value is taken from the notes directive in the extended service information definition.
    Notification Macros:
    $NOTIFICATIONTYPE$ A string identifying the type of notification that is being sent ("PROBLEM", "RECOVERY", "ACKNOWLEDGEMENT", "FLAPPINGSTART" or "FLAPPINGSTOP").
    $NOTIFICATIONNUMBER$ The current notification number for the service or host. The notification number increases by one (1) each time a new notification is sent out for a host or service (except for acknowledgements). The notification number is reset to 0 when the host or service recovers (after the recovery notification has gone out). Acknowledgements do not cause the notification number to increase.
    SUMMARY Macros:
    $TOTALHOSTSUP$ This macro reflects the total number of hosts that are currently in an UP state.
    $TOTALHOSTSDOWN$ This macro reflects the total number of hosts that are currently in a DOWN state.
    $TOTALHOSTSUNREACHABLE$ This macro reflects the total number of hosts that are currently in an UNREACHABLE state.
    $TOTALHOSTSDOWNUNHANDLED$ This macro reflects the total number of hosts that are currently in a DOWN state that are not currently being "handled". Unhandled host problems are those that are not acknowledged, are not currently in scheduled downtime, and for which checks are currently enabled.
    $TOTALHOSTSUNREACHABLEUNHANDLED$ This macro reflects the total number of hosts that are currently in an UNREACHABLE state that are not currently being "handled". Unhandled host problems are those that are not acknowledged, are not currently in scheduled downtime, and for which checks are currently enabled.
    $TOTALHOSTPROBLEMS$ This macro reflects the total number of hosts that are currently either in a DOWN or an UNREACHABLE state.
    $TOTALHOSTPROBLEMSUNHANDLED$ This macro reflects the total number of hosts that are currently either in a DOWN or an UNREACHABLE state that are not currently being "handled". Unhandled host problems are those that are not acknowledged, are not currently in scheduled downtime, and for which checks are currently enabled.
    $TOTALSERVICESOK$ This macro reflects the total number of services that are currently in an OK state.
    $TOTALSERVICESWARNING$ This macro reflects the total number of services that are currently in a WARNING state.
    $TOTALSERVICESCRITICAL$ This macro reflects the total number of services that are currently in a CRITICAL state.
    $TOTALSERVICESUNKNOWN$ This macro reflects the total number of services that are currently in an UNKNOWN state.
    $TOTALSERVICESWARNINGUNHANDLED$ This macro reflects the total number of services that are currently in a WARNING state that are not currently being "handled". Unhandled services problems are those that are not acknowledged, are not currently in scheduled downtime, and for which checks are currently enabled.
    $TOTALSERVICESCRITICALUNHANDLED$ This macro reflects the total number of services that are currently in a CRITICAL state that are not currently being "handled". Unhandled services problems are those that are not acknowledged, are not currently in scheduled downtime, and for which checks are currently enabled.
    $TOTALSERVICESUNKNOWNUNHANDLED$ This macro reflects the total number of services that are currently in an UNKNOWN state that are not currently being "handled". Unhandled services problems are those that are not acknowledged, are not currently in scheduled downtime, and for which checks are currently enabled.
    $TOTALSERVICEPROBLEMS$ This macro reflects the total number of services that are currently either in a WARNING, CRITICAL, or UNKNOWN state.
    $TOTALSERVICEPROBLEMSUNHANDLED$ This macro reflects the total number of services that are currently either in a WARNING, CRITICAL, or UNKNOWN state that are not currently being "handled". Unhandled services problems are those that are not acknowledged, are not currently in scheduled downtime, and for which checks are currently enabled.
    Contact Macros:
    $CONTACTNAME$ Short name for the contact (i.e. "jdoe") that is being notified of a host or service problem. This value is taken from the contact_name directive in the contact definition.
    $CONTACTALIAS$ Long name/description for the contact (i.e. "John Doe") being notified. This value is taken from the alias directive in the contact definition.
    $CONTACTEMAIL$ Email address of the contact being notified. This value is taken from the email directive in the contact definition.
    $CONTACTPAGER$ Pager number/address of the contact being notified. This value is taken from the pager directive in the contact definition.
    $CONTACTADDRESSn$ Address of the contact being notified. Each contact can have six different addresses (in addition to email address and pager number). The macros for these addresses are $CONTACTADDRESS1$ - $CONTACTADDRESS6$. This value is taken from the addressx directive in the contact definition.
    Date Macros:
    $LONGDATETIME$ Current date/time stamp (i.e. Fri Oct 13 00:30:28 CDT 2000). Format of date is determined by date_format directive.
    $SHORTDATETIME$ Current date/time stamp (i.e. 10-13-2000 00:30:28). Format of date is determined by date_format directive.
    $DATE$ Date stamp (i.e. 10-13-2000). Format of date is determined by date_format directive.
    $TIME$ Current time stamp (i.e. 00:30:28).
    $TIMET$ Current time stamp in time_t format (seconds since the UNIX epoch).
    File Macros:
    $MAINCONFIGFILE$ The location of the main config file.
    $STATUSDATAFILE$ The location of the status data file.
    $COMMENTDATAFILE$ The location of the comment data file.
    $DOWNTIMEDATAFILE$ The location of the downtime data file.
    $RETENTIONDATAFILE$ The location of the retention data file.
    $OBJECTCACHEFILE$ The location of the object cache file.
    $TEMPFILE$ The location of the temp file.
    $LOGFILE$ The location of the log file.
    $RESOURCEFILE$ The location of the resource file.
    $COMMANDFILE$ The location of the command file.
    $HOSTPERFDATAFILE$ The location of the host performance data file (if defined).
    $SERVICEPERFDATAFILE$ The location of the service performance data file (if defined).
    Misc Macros:
    $PROCESSSTARTTIME$ Time stamp in time_t format (seconds since the UNIX epoch) indicating when the Nagios process was last (re)started. You can determine the number of seconds that Nagios has been running (since it was last restarted) by subtracting $PROCESSSTARTTIME$ from $TIMET$.
    $ADMINEMAIL$ Global administrative email address. This value is taken from the admin_email directive.
    $ADMINPAGER$ Global administrative pager number/address. This value is taken from the admin_pager directive.
    $ARGn$ The nth argument passed to the command (notification, event handler, service check, etc.). Nagios supports up to 32 argument macros ($ARG1$ through $ARG32$).
    $USERn$ The nth user-definable macro. User macros can be defined in one or more resource files. Nagios supports up to 32 user macros ($USER1$ through $USER32$).

    Notes

    1 These macros are not valid for the host they are associated with when that host is being checked (i.e. they make no sense, as they haven't been determined yet).

    2 These macros are not valid for the service they are associated with when that service is being checked (i.e. they make no sense, as they haven't been determined yet).

    3 When host macros are used in service-related commands (i.e. service notifications, event handlers, etc) they refer to they host that they service is associated with.

    4 When host and service summary macros are used in notification commands, the totals are filtered to reflect only those hosts and services for which the contact is authorized (i.e. hosts and services they are configured to receive notifications for).


    nagios-2.6/html/docs/nagiostats.html0000664000076500007650000001667207760226761017166 0ustar nagiosnagios Using The Nagiostats Utility

    Using The Nagiostats Utility


    Introduction

    A utility called nagiostats is included in the Nagios distribution. It is compiled and installed along with the main Nagios daemon.

    The nagiostats utility allows you to obtain various information about a running Nagios process. You can obtain information either in human-readable or MRTG-compatible format.

    Usage Information

    You can run the nagiostats utility with the --help option to get usage information:

    [nagios@lanman ~]# /usr/local/nagios/bin/nagiostats --help
    
    Nagios Stats 2.0a1
    Copyright (c) 2003 Ethan Galstad (nagios@nagios.org)
    Last Modified: 11-18-2003
    License: GPL
    
    Usage: /usr/local/nagios/bin/nagiostats [options]
    
    Startup:
     -V, --version      display program version information and exit.
     -L, --license      display license information and exit.
     -h, --help         display usage information and exit.
    
    Input file:
     -c, --config=FILE  specifies location of main Nagios config file.
    
    Output:
     -m, --mrtg         display output in MRTG compatible format.
     -d, --data=VARS    comma-seperated list of variables to output in MRTG
                        (or compatible) format.  See possible values below.
                        Percentages are rounded, times are in milliseconds.
    
    MRTG DATA VARIABLES (-d option):
     NUMSERVICES        total number of services.
     NUMHOSTS           total number of services.
     NUMSVCOK           number of services OK.
     NUMSVCWARN         number of services WARNING.
     NUMSVCUNKN         number of services UNKNOWN.
     NUMSVCCRIT         number of services CRITICAL.
     NUMSVCPROB         number of service problems (WARNING, UNKNOWN or CRITIAL).
     NUMHSTUP           number of hosts UP.
     NUMHSTDOWN         number of hosts DOWN.
     NUMHSTUNR          number of hosts UNREACHABLE.
     NUMHSTPROB         number of host problems (DOWN or UNREACHABLE).
     xxxACTSVCLAT       MIN/MAX/AVG active service check latency (ms).
     xxxACTSVCEXT       MIN/MAX/AVG active service check execution time (ms).
     xxxACTSVCPSC       MIN/MAX/AVG active service check % state change.
     xxxPSVSVCPSC       MIN/MAX/AVG passive service check % state change.
     xxxSVCPSC          MIN/MAX/AVG service check % state change.
     xxxACTHSTLAT       MIN/MAX/AVG active host check latency (ms).
     xxxACTHSTEXT       MIN/MAX/AVG active host check execution time (ms).
     xxxACTHSTPSC       MIN/MAX/AVG active host check % state change.
     xxxPSVHSTPSC       MIN/MAX/AVG passive host check % state change.
     xxxHSTPSC          MIN/MAX/AVG host check % state change.
     NUMACTHSTCHKxM    number of active host checks in last 1/5/15/60 minutes.
     NUMPSVHSTCHKxM    number of passive host checks in last 1/5/15/60 minutes.
     NUMACTSVCCHKxM    number of active service checks in last 1/5/15/60 minutes.
     NUMPSVSVCCHKxM    number of passive service checks in last 1/5/15/60 minutes.
    
     Note: Replace x's in MRTG variable names with 'MIN', 'MAX', 'AVG', or the
           the appropriate number (i.e. '1', '5', '15', or '60').
    
    [nagios@lanman ~]# 
    

    Human-Readable Output

    For normal operation, run the nagiostats utility, specifying only the config file location as an argument, as follows:

    [nagios@lanman ~]# /usr/local/nagios/bin/nagiostats -c /usr/local/nagios/etc/nagios.cfg
    
    Nagios Stats 2.0a1
    Copyright (c) 2003 Ethan Galstad (nagios@nagios.org)
    Last Modified: 11-18-2003
    License: GPL
    
    CURRENT STATUS DATA
    ----------------------------------------------------
    Status File:                          /usr/local/nagios/var/status.dat
    Status File Age:                      0d 0h 0m 13s
    Status File Version:                  2.0-very-pre-alpha
    
    Program Running Time:                 14d 17h 19m 13s
    
    Total Services:                       32
    Services Checked:                     32
    Services Scheduled:                   29
    Active Service Checks:                29
    Passive Service Checks:               3
    Total Service State Change:           0.000 / 65.530 / 2.930 %
    Active Service Latency:               0.048 / 14.837 / 1.035 %
    Active Service Execution Time:        0.076 / 60.006 / 4.301 sec
    Active Service State Change:          0.000 / 10.530 / 0.762 %
    Active Services Last 1/5/15/60 min:   1 / 13 / 29 / 29
    Passive Service State Change:         0.000 / 65.530 / 23.883 %
    Passive Services Last 1/5/15/60 min:  0 / 0 / 0 / 0
    Services Ok/Warn/Unk/Crit:            23 / 5 / 1 / 3
    Services Flapping:                    1
    Services In Downtime:                 0
    
    Total Hosts:                          9
    Hosts Checked:                        9
    Hosts Scheduled:                      9
    Active Host Checks:                   9
    Passive Host Checks:                  0
    Total Host State Change:              0.000 / 28.420 / 4.034 %
    Active Host Latency:                  0.000 / 15.741 / 5.443 %
    Active Host Execution Time:           1.022 / 10.032 / 3.047 sec
    Active Host State Change:             0.000 / 28.420 / 4.034 %
    Active Hosts Last 1/5/15/60 min:      0 / 8 / 9 / 9
    Passive Host State Change:            0.000 / 0.000 / 0.000 %
    Passive Hosts Last 1/5/15/60 min:     0 / 0 / 0 / 0
    Hosts Up/Down/Unreach:                7 / 1 / 1
    Hosts Flapping:                       0
    Hosts In Downtime:                    0
    
    
    [nagios@lanman ~]# 
    

    As you can see, the utility displays a number of different metrics pertaining to the Nagios process. Metrics which have multiple values are (unless otherwise specified) min, max and average values for that partciular metric.

    MRTG Integration

    You can use the nagiostats utility to display various Nagios metrics using MRTG (or other compatible program). To do so, run the nagiostats utility using the --mrtg and --data arguments. The --data argument is used to specify what statistics should be graphed. Possible values for the --data argument can be found by running the nagiostats utility with the --help option.

    Here's an MRTG config file snippet for using the nagiostats utility for graphing average service latency and execution time.

    # Service Latency and Execution Time
    Target[nagios-a]: `/usr/local/nagios/bin/nagiostats --mrtg --data=AVGACTSVCLAT,AVGACTSVCEXT`
    MaxBytes[nagios-a]: 100000
    Title[nagios-a]: Average Service Check Latency and Execution Time
    PageTop[nagios-a]: <H1>Average Service Check Latency and Execution Time</H1>
    Options[nagios-a]: growright,gauge,nopercent
    YLegend[nagios-a]: Milliseconds
    ShortLegend[nagios-a]: &nbsp;
    LegendI[nagios-a]: &nbsp;Latency:
    LegendO[nagios-a]: &nbsp;Execution Time:
    Legend1[nagios-a]: Latency
    Legend2[nagios-a]: Execution Time
    Legend3[nagios-a]: Maximal 5 Minute Latency
    Legend4[nagios-a]: Maximal 5 Minute Execution Time
    

    The MRTG graphs generated from the above config snippet look like this:

    MRTG Stats


    nagios-2.6/html/docs/networkoutages.html0000664000076500007650000001230307743356403020054 0ustar nagiosnagios Network Outages

    Network Outages


    Introduction

    The outages CGI is designed to help pinpoint the cause of network outages. For small networks this CGI may not be particularly useful, but for larger ones it will be. Pinpointing the cause of outages will help admins to more quickly find and resolve problems which are causing the biggest impact on the network.

    It should be noted that the outages CGI will not attempt to find the exact cause of the problem, but will rather locate the hosts on your network which seem to be causing the most problems. Delving into the problem at a deeper level is left to the user, as there are any number of things which might actually be the cause of the problem.

    Diagrams

    The diagrams below help to show how the outages CGI goes about determining the cause of network outages. You can click on either image for a larger version...

    Diagram 1
    This diagram will serve as the basis for our example. All hosts shows in red are either down or unreachable (from the view of Nagios). All other hosts are up.
    Hosts That Are Down Or Unreachable
    Diagram 2
    This diagram pinpoints the causes of the network outages (from the view of Nagios), and shows various groups of hosts which are affected by the outages.
    Hosts That Are Causing Outages

    Determining The Cause Of Network Outages

    So how does the outages CGI determine which hosts are the source of problems? "Problem" hosts must be either in a DOWN or UNREACHABLE state and at least one of their immediate parent hosts must be UP. Hosts which fit this criteria are flagged as being potential problem hosts.

    In order to determine whether these flagged hosts are causing network outages, we must performs some other tests...

    If all of the immediate child hosts of one of these flagged hosts is DOWN or UNREACHABLE and has no immediate parent host that is up, the flagged host is the cause of a network outage. If even one of the immediate children of a flagged host does not pass this test, then the flagged host is not the cause of a network outage.

    Determining The Effects Of Network Outages

    Along with telling you what hosts are causing problem on your network, the outages CGI will also tell you how many hosts and services are affected by a particular problem host. How is this determined? Take a look at diagram 2 above...

    From the diagram it is clear that host 1 is blocking two child hosts (in domain A). Host 2 is solely responsbile for blocking only itself (domain B) and host 3 is solely responsibly for blocking 7 hosts (domain C). The outage effects of the two hosts in domain D are "shared" between hosts 2 and 3, since it is unclear as to which host is actually the cause of the outage. If either host 2 or 3 was UP, the these hosts might not be blocked.

    The numbers of affected hosts for each problem host are as follows (the problem host is also included in these figures):

    • Host 1: 3 affected hosts
    • Host 2: 3 affected hosts
    • Host 3: 10 affected hosts

    Ranking Problems Based On Severity Level

    The outages CGI will display all problem hosts, whether they are causing network outages or not. However, the CGI will tell you how many of the problem hosts (if any) are causing network outages.

    In order to display the problem hosts in a somewhat useful manner, they are sorted by the severity of the effect they are having on the network. The severity level is determined by two things: The number of hosts which are affected by problem host and the number of services which are affected. Hosts hold a higher weight than services when it comes to calculating severity. The current code sets this weight ratio at 4:1 (i.e. hosts are 4 times more important than individual services).

    Assuming that all hosts in diagram 2 have an equal number of services associated with them, host 3 would be ranked as the most severe problem, while hosts 1 and 2 would have the same severity level.


    nagios-2.6/html/docs/networkreachability.html0000664000076500007650000001305410200220453021022 0ustar nagiosnagios Determining Status and Reachability of Network Hosts

    Determining Status and Reachability of Network Hosts


    Monitoring Services on Down or Unreachable Hosts

    The main purpose of Nagios is to monitor services that run on or are provided by physical hosts or devices on your network. It should be obvious that if a host or device on your network goes down, all services that it offers will also go down with it. Similarly, if a host becomes unreachable, Nagios will not be able to monitor the services associated with that host.

    Nagios recognizes this fact and attempts to check for such a scenario when there are problems with a service. Whenever a service check results in a non-OK status level, Nagios will attempt to check and see if the host that the service is running on is "alive". Typically this is done by pinging the host and seeing if any response is received. If the host check commmand returns a non-OK state, Nagios assumes that there is a problem with the host. In this situation Nagios will "silence" all potential alerts for services running on the host and just notify the appropriate contacts that the host is down or unreachable. If the host check command returns an OK state, Nagios will recognize that the host is alive and will send out an alert for the service that is misbehaving.

    Local Hosts

    "Local" hosts are hosts that reside on the same network segment as the host running Nagios - no routers or firewalls lay between them. Figure 1 shows an example network layout. Host A is running Nagios and monitoring all other hosts and routers depicted in the diagram. Hosts B, C, D, E and F are all considered to be "local" hosts in relation to host A.

    The <parents> option in the host definition for a "local" host should be left blank, as local hosts have no depencies or "parents" - that's why they're local.

    Monitoring Local Hosts

    Checking hosts that are on your local network is fairly simple. Short of someone accidentally (or intentially) unplugging the network cable from one of your hosts, there isn't too much that can go wrong as far as checking network connectivity is concerned. There are no routers or external networks between the host doing the monitoring and the other hosts on the local network.

    If Nagios needs to check to see if a local host is "alive" it will simply run the host check command for that host. If the command returns an OK state, Nagios assumes the host is up. If the command returns any other status level, Nagios will assume the host is down.

    Figure 1.

    Remote Hosts

    "Remote" hosts are hosts that reside on a different network segment than the host running Nagios. In the figure above, hosts G, H, I, J, K, L and M are all considered to be "remote" hosts in relation to host A.

    Notice that some hosts are "farther away" than others. Hosts H, I and J are one hop further away from host A than host G (the router) is. From this observation we can construct a host dependency tree as show below in Figure 2. This tree diagram will help us in deciding how to configure each host in Nagios.

    The <parents> option in the host definition for a "remote" host should be the short name(s) of the host(s) directly above it in the tree diagram (as show below). For example, the parent host for host H would be host G. The parent host for host G is host F. Host F has no parent host, since it is on the network segment as host A - it is a "local" host.

    Figure 2.

    Monitoring Remote Hosts

    Checking the status of remote hosts is a bit more complicated that for local hosts. If Nagios cannot monitor services on a remote host, it needs to determine whether the remote host is down or whether it is unreachable. Luckily, the <parents> option allows Nagios to do this.

    If a host check command for a remote host returns a non-OK state, Nagios will "walk" the depency tree (as shown in the figure above) until it reaches the top (or until a parent host check results in an OK state). By doing this, Nagios is able to determine if a service problem is the result of a down host, an down network link, or just a plain old service failure.

    DOWN vs. UNREACHABLE Notification Types

    I get lots of email from people asking why Nagios is sending notifications out about hosts that are unreachable. The answer is because you configured it to do that. If you want to disable UNREACHABLE notifications for hosts, modify the notification_options argument of your host definitions to not include the u (unreachable) option. More information can be found in this FAQ.


    nagios-2.6/html/docs/notifications.html0000664000076500007650000003432010426153505017635 0ustar nagiosnagios Notifications

    Notifications


    Introduction

    I've had a lot of questions as to exactly how notifications work. This will attempt to explain exactly when and how host and service notifications are sent out, as well as who receives them.

    When Do Notifications Occur?

    The decision to send out notifications is made in the service check and host check logic. Host and service notifications occur in the following instances...

    • When a hard state change occurs. More information on state types and hard state changes can be found here.
    • When a host or service remains in a hard non-OK state and the time specified by the <notification_interval> option in the host or service definition has passed since the last notification was sent out (for that specified host or service). If you don't like the idea of recurring notifications, set the <notification_interval> value to 0 - this prevents notifications from getting sent out more than once for any given problem.

    Who Gets Notified?

    Each service definition has a <contact_groups> option that specifies what contact groups receive notifications for that particular service. Each contact group can contain one or more individual contacts. When Nagios sends out a service notification, it will notify each contact that is a member of any contact groups specified in the <contactgroups> option of the service definition. Nagios realizes that any given contact may be a member of more than one contact group, so it removes duplicate contact notifications before it does anything.

    Each host definition has a <contact_groups> option that specifies what contact groups receive notifications for that particular host. When Nagios sends out a host notification, it will notify contacts that are members of all the contact groups that that should be notified for that host. Nagios removes any duplicate contacts from the notification list before it does anything.

    What Filters Must Be Passed In Order For Notifications To Be Sent?

    Just because there is a need to send out a host or service notification doesn't mean that any contacts are going to get notified. There are several filters that potential notifications must pass before they are deemed worthy enough to be sent out. Even then, specific contacts may not be notified if their notification filters do not allow for the notification to be sent to them. Let's go into the filters that have to be passed in more detail...

    Program-Wide Filter:

    The first filter that notifications must pass is a test of whether or not notifications are enabled on a program-wide basis. This is initially determined by the enable_notifications directive in the main config file, but may be changed during runtime from the web interface. If notifications are disabled on a program-wide basis, no host or service notifications can be sent out - period. If they are enabled on a program-wide basis, there are still other tests that must be passed...

    Service and Host Filters:

    The first filter for host or service notifications is a check to see if the host or service is in a period of scheduled downtime. It it is in a scheduled downtime, no one gets notified. If it isn't in a period of downtime, it gets passed on to the next filter. As a side note, notifications for services are suppressed if the host they're associated with is in a period of scheduled downtime.

    The second filter for host or service notification is a check to see if the host or service is flapping (if you enabled flap detection). If the service or host is currently flapping, no one gets notified. Otherwise it gets passed to the next filter.

    The third host or service filter that must be passed is the host- or service-specific notification options. Each service definition contains options that determine whether or not notifications can be sent out for warning states, critical states, and recoveries. Similiarly, each host definition contains options that determine whether or not notifications can be sent out when the host goes down, becomes unreachable, or recovers. If the host or service notification does not pass these options, no one gets notified. If it does pass these options, the notification gets passed to the next filter... Note: Notifications about host or service recoveries are only sent out if a notification was sent out for the original problem. It doesn't make sense to get a recovery notification for something you never knew was a problem.

    The fourth host or service filter that must be passed is the time period test. Each host and service definition has a <notification_period> option that specifies which time period contains valid notification times for the host or service. If the time that the notification is being made does not fall within a valid time range in the specified time period, no one gets contacted. If it falls within a valid time range, the notification gets passed to the next filter... Note: If the time period filter is not passed, Nagios will reschedule the next notification for the host or service (if its in a non-OK state) for the next valid time present in the time period. This helps ensure that contacts are notified of problems as soon as possible when the next valid time in time period arrives.

    The last set of host or service filters is conditional upon two things: (1) a notification was already sent out about a problem with the host or service at some point in the past and (2) the host or service has remained in the same non-OK state that it was when the last notification went out. If these two criteria are met, then Nagios will check and make sure the time that has passed since the last notification went out either meets or exceeds the value specified by the <notification_interval> option in the host or service definition. If not enough time has passed since the last notification, no one gets contacted. If either enough time has passed since the last notification or the two criteria for this filter were not met, the notification will be sent out! Whether or not it actually is sent to individual contacts is up to another set of filters...

    Contact Filters:

    At this point the notification has passed the program mode filter and all host or service filters and Nagios starts to notify all the people it should. Does this mean that each contact is going to receive the notification? No! Each contact has their own set of filters that the notification must pass before they receive it. Note: Contact filters are specific to each contact and do not affect whether or not other contacts receive notifications.

    The first filter that must be passed for each contact are the notification options. Each contact definition contains options that determine whether or not service notifications can be sent out for warning states, critical states, and recoveries. Each contact definition also contains options that determine whether or not host notifications can be sent out when the host goes down, becomes unreachable, or recovers. If the host or service notification does not pass these options, the contact will not be notified. If it does pass these options, the notification gets passed to the next filter... Note: Notifications about host or service recoveries are only sent out if a notification was sent out for the original problem. It doesn't make sense to get a recovery notification for something you never knew was a problem...

    The last filter that must be passed for each contact is the time period test. Each contact definition has a <notification_period> option that specifies which time period contains valid notification times for the contact. If the time that the notification is being made does not fall within a valid time range in the specified time period, the contact will not be notified. If it falls within a valid time range, the contact gets notified!

    What Aren't Any Notification Methods Incorporated Directly Into Nagios?

    I've gotten several questions about why notification methods (paging, etc.) are not directly incorporated into the Nagios code. The answer is simple - it just doesn't make much sense. The "core" of Nagios is not designed to be an all-in-one application. If service checks were embedded in Nagios' core it would be very difficult for users to add new check methods, modify existing checks, etc. Notifications work in a similiar manner. There are a thousand different ways to do notifications and there are already a lot of packages out there that handle the dirty work, so why re-invent the wheel and limit yourself to a bike tire? Its much easier to let an external entity (i.e. a simple script or a full-blown messaging system) do the messy stuff. Some messaging packages that can handle notifications for pagers and cellphones are listed below in the resource section.

    Notification Type Macro

    When crafting your notification commands, you need to take into account what type of notification is occurring. The $NOTIFICATIONTYPE$ macro contains a string that identifies exactly that. The table below lists the possible values for the macro and their respective descriptions:

    ValueDescription
    PROBLEMA service or host has just entered (or is still in) a problem state. If this is a service notification, it means the service is either in a WARNING, UNKNOWN or CRITICAL state. If this is a host notification, it means the host is in a DOWN or UNREACHABLE state.
    RECOVERYA service or host recovery has occurred. If this is a service notification, it means the service has just returned to an OK state. If it is a host notification, it means the host has just returned to an UP state.
    ACKNOWLEDGEMENTThis notification is an acknowledgement notification for a host or service problem. Acknowledgement notifications are initiated via the web interface by contacts for the particular host or service.
    FLAPPINGSTARTThe host or service has just started flapping.
    FLAPPINGSTOPThe host or service has just stopped flapping.

    Helpful Resources

    There are many ways you could configure Nagios to send notifications out. Its up to you to decide which method(s) you want to use. Once you do that you'll have to install any necessary software and configure notification commands in your config files before you can use them. Here are just a few possible notification methods:

    • Email
    • Pager
    • Phone (SMS)
    • WinPopup message
    • Yahoo, ICQ, or MSN instant message
    • Audio alerts
    • etc...

    Basically anything you can do from a command line can be tailored for use as a notification command.

    If you're interested in sending an alphanumeric notification to your pager or cellphone via email, you may be find the following information useful. Here are a few links to various messaging service providers' websites that contain information on how to send alphanumeric messages to pagers and phones...

    If you're looking for an alternative to using email for sending messages to your pager or cellphone, check out these packages. They could be used in conjuction with Nagios to send out a notification via a modem when a problem arises. That way you don't have to rely on email to send notifications out (remember, email may *not* work if there are network problems). I haven't actually tried these packages myself, but others have reported success using them...

    • Gnokii (SMS software for contacting Nokia phones via GSM network)
    • QuickPage (alphanumeric pager software)
    • Sendpage (paging software)
    • SMS Client (command line utility for sending messages to pagers and mobile phones)

    If you want to try out a non-traditional method of notification, you might want to mess around with audio alerts. If you want to have audio alerts played on the monitoring server (with synthesized speech), check out Festival. If you'd rather leave the monitoring box alone and have audio alerts played on another box, check out the Network Audio System (NAS) and rplay projects.

    Lastly, there in an area in the contrib downloads section on the Nagios homepage for notification scripts that have been contributed by users. You might find these scripts useful, as they take care of a lot of the dirty work needed to send out alphanumeric notifications...


    nagios-2.6/html/docs/parallelization.html0000664000076500007650000002104610326736064020165 0ustar nagiosnagios Service Check Parallelization

    Service Check Parallelization


    Introduction

    One of the features of Nagios is its ability to execute service checks in parallel. This documentation will attempt to explain in detail what that means and how it affects services that you have defined.

    How The Parallelization Works

    Before I can explain how the service check parallelization works, you first have to understand a bit about how Nagios schedules events. All internal events in Nagios (i.e. log file rotations, external command checks, service checks, etc.) are placed in an event queue. Each item in the event queue has a time at which it is scheduled to be executed. Nagios does its best to ensure that all events get executed when they should, although events may fall behind schedule if Nagios is busy doing other things.

    Service checks are one type of event that get scheduled in Nagios' event queue. When it comes time for a service check to be executed, Nagios will kick off another process (using a call to fork()) to go out and run the service check (i.e. a plugin of some sort). Nagios does not, however, wait for the service check to finish! Instead, Nagios will immediately go back to servicing other events that reside in the event queue...

    So what happens when the service check finishes executing? Well, the process that was started by Nagios to run the service check sends a message back to Nagios containing the results of the service check. It is then up to Nagios to check for and process the results of that service check when it gets a chance.

    In order for Nagios to actually do any monitoring, it must process the results of service checks that have finished executing. This is done via a service check "reaper" process. Service "reapers" are another type of event that get scheduled in Nagios' event queue. The frequency of these "reaper" events is determined by the service_reaper_frequency option in the main configuration file. When a "reaper" event is executed, it will check for any messages that contain the result of service checks that have finished executing. These service check results are then handled by the core service monitoring logic. From there Nagios determines whether or not hosts should be checked, notifications should be sent out, etc. When the service check results have been processed, Nagios will reschedule the next check of the service and place it in the event queue for later execution. That completes the service check/monitoring cycle!

    For those of you who really want to know, but haven't looked at the code, Nagios uses message queues to handle communication between Nagios and the process that actually runs the service check...

    Potential Gotchas...

    You should realize that there are potential drawbacks to having service checks parallelized. Since more than one service check may be running at the same time, they have may interfere with one another. You'll have to evaluate what types of service checks you're running and take appropriate steps to guard against any unfriendly outcomes. This is particularly important if you have more than one service check that accesses any hardware (like a modem). Also, if two or more service checks connect to daemon on a remote host to check some information, make sure that daemon can handle multiple simultaneous connections.

    Fortunately, there are some things you can do to protect against problems with having some types of service checks "collide"...

    1. The easiest thing you can do to prevent service check collisions to to use the service_interleave_factor variable. Interleaving services will help to reduce the load imposed upon remote hosts by service checks. Set the variable to use "smart" interleave factor calculation and then adjust it manually if you find it necessary to do so.
    2. The second thing you can do is to set the max_check_attempts argument in each service definition to something greater than one. If the service check does happen to collide with another running check, Nagios will retry the service check max_check_attempts-1 times before notifying anyone of a problem.
    3. You could try is to implement some kind of "back-off and retry" logic in the actual service check code, although you may find it difficult or too time-consuming
    4. If all else fails you can effectively prevent service checks from being parallelized by setting the max_concurrent_checks option to 1. This will allow only one service to be checked at a time, so it isn't a spectacular solution. If there is enough demand, I will add an option to the service definitions which will allow you to specify on a per-service basis whether or not a service check can be parallelized. If there isn't enough demand, I won't...

    One other thing to note is the effect that parallelization of service checks can have on system resources on the machine that runs Nagios. Running a lot of service checks in parallel can be taxing on the CPU and memory. The inter_check_delay_method will attempt to minimize the load imposed on your machine by spreading the checks out evenly over time (if you use the "smart" method), but it isn't a surefire solution. In order to have some control over how many service checks can be run at any given time, use the max_concurrent_checks variable. You'll have to tweak this value based on the total number of services you check, the system resources you have available (CPU speed, memory, etc.), and other processes which are running on your machine. For more information on how to tweak the max_concurrent_checks variable for your setup, read the documentation on check scheduling.

    What Isn't Parallelized

    It is important to remember that only the execution of service checks has been parallelized. There is good reason for this - other things cannot be parallelized in a very safe or sane manner. In particular, event handlers, contact notifications, processing of service checks, and host checks are not parallelized. Here's why...

    Event handlers are not parallelized because of what they are designed to do. Much of the power of event handlers comes from the ability to do proactive problem resultion. An example of this is restarting the web server when the HTTP service on the local machine is detected as being down. In order to prevent more than one event handler from trying to "fix" problems in parallel (without any knowledge of what each other is doing), I have decided to not parallelize them.

    Contact notifications are not parallelized because of potential notification methods you may be using. If, for example, a contact notification uses a modem to dial out and send a message to your pager, it requires exclusive access to the modem while the notification is in progress. If two or more such notifications were being executed in parallel, all but one would fail because the others could not get access to the modem. There are ways to get around this, like providing some kind of "back-off and retry" method in the notification script, but I've decided not to rely on users having implemented this type of feature in their scripts. One quick note - if you have service checks which use a modem, make sure that any notification scripts that dial out have some method of retrying access to the modem. This is necessary because a service check may be running at the same time a notification is!

    Processing of service check results has not been parallelized. This has been done to prevent situations where multiple notifications about host problems or recoveries may be sent out if a host goes down, becomes unreachable, or recovers.


    nagios-2.6/html/docs/passivechecks.html0000664000076500007650000002651410154447045017630 0ustar nagiosnagios Passive Host and Service Checks

    Passive Host and Service Checks


    Introduction

    On of the features of Nagios is that is can process host and service check results that are submitted by external applications. Host and service checks which are performed and submitted to Nagios by external apps are called passive checks. Passive checks can be contrasted with active checks, which are host or service checks that have been initiated by Nagios.

    Why The Need For Passive Checks?

    Passive checks are useful for monitoring services that are:

    • located behind a firewall, and can therefore not be checked actively from the host running Nagios
    • asynchronous in nature and can therefore not be actively checked in a reliable manner (e.g. SNMP traps, security alerts, etc.)

    Passive host and service checks are also useful when configured a distributed monitoring setup.

    Passive Service Checks vs. Passive Host Checks

    Passive host and service checks function in a similiar manner, but there are some important limitations in regards to passive host checks. Read below for more information about the limitations with passive host checks.

    How Do Passive Service Checks Work?

    The only real difference between active and passive checks is that active checks are initiated by Nagios, while passive checks are performed by external applications. Once an external application has performed a service check (either actively or by having received an synchronous event like an SNMP trap or security alert), it submits the results of the service "check" to Nagios through the external command file.

    The next time Nagios processes the contents of the external command file, it will place the results of all passive service checks into a queue for later processing. The same queue that is used for storing results from active checks is also used to store the results from passive checks.

    Nagios will periodically execute a service reaper event and scan the service check result queue. Each service check result, regardless of whether the check was active or passive, is processed in the same manner. The service check logic is exactly the same for both types of checks. This provides a seamless method for handling both active and passive service check results.

    How Do External Apps Submit Service Check Results?

    External applications can submit service check results to Nagios by writing a PROCESS_SERVICE_CHECK_RESULT external command to the external command file.

    The format of the command is as follows:

    [<timestamp>] PROCESS_SERVICE_CHECK_RESULT;<host_name>;<description>;<return_code>;<plugin_output>

    where...

    • timestamp is the time in time_t format (seconds since the UNIX epoch) that the service check was perfomed (or submitted). Please note the single space after the right bracket.
    • host_name is the short name of the host associated with the service in the service definition
    • description is the description of the service as specified in the service definition
    • return_code is the return code of the check (0=OK, 1=WARNING, 2=CRITICAL, 3=UNKNOWN)
    • plugin_output is the text output of the service check (i.e. the plugin output)

    Note that in order to submit service checks to Nagios, a service must have already been defined in the object configuration file! Nagios will ignore all check results for services that had not been configured before it was last (re)started.

    If you only want passive results to be provided for a specific service (i.e. active checks should not be performed), simply set the active_checks_enabled member of the service definition to 0. This will prevent Nagios from ever actively performing a check of the service. Make sure that the passive_checks_enabled member of the service definition is set to 1. If it isn't, Nagios won't process passive checks for the service!

    An example shell script of how to submit passive service check results to Nagios can be found in the documentation on volatile services.

    Submitting Passive Service Check Results From Remote Hosts

    If an application that resides on the same host as Nagios is sending passive service check results, it can simply write the results directly to the external command file as outlined above. However, applications on remote hosts can't do this so easily. In order to allow remote hosts to send passive service check results to the host that runs Nagios, I've developed the nsca addon. The addon consists of a daemon that runs on the Nagios hosts and a client that is executed from remote hosts. The daemon will listen for connections from remote clients, perform some basic validation on the results being submitted, and then write the check results directly into the external command file (as described above). More information on the nsca addon can be found here...

    Using Both Active And Passive Service Checks

    Unless you're implementing a distributed monitoring environment with the central server accepting only passive service checks (and not performing any active checks), you'll probably be using both types of checks in your setup. As mentioned before, active checks are more suited for services that lend themselves to periodic checks (availability of an FTP or web server, etc), whereas passive checks are better off at handling asynchronous events that occur at variable intervals (security alerts, etc.).

    The image below gives a visual representation of how active and passive service checks can both be used to monitor network resources (click on the image for a larger version).

    The orange bubbles on the right side of the image are third-party applications that submit passive check results to Nagios' external command file. One of the applications resides on the same host as Nagios, so it can write directly to the command file. The other application resides on a remote host and makes used of the nsca client program and daemon to transfer the passive check results to Nagios.

    The items on the left side of the image represent active service checks that Nagios is performing. I've shown how the checks can be made for local resources (disk usage, etc.), "exposed" resources on remote hosts (web server, FTP server, etc.), and "private" resources on remote hosts (remote host disk usage, processor load, etc.). In this example, the private resources on the remote hosts are actually checked by making use of the nrpe addon, which facilitates the execution of plugins on remote hosts.

    How Do Passive Host Checks Work?

    Passive host checks work in a similiar manner to passive service checks. Once an external application has performed a host check, it submits the results of that host "check" to Nagios through the external command file. The next time Nagios processes the contents of the external command file, it will process the host check result that was submitted.

    WARNING! Passive host checks have some limitations. Unlike active host checks, Nagios does not attempt to determine whether or host is DOWN or UNREACHABLE with passive checks. Rather, Nagios takes the passive check result to be the actual state the host is in and doesn't try to determine the actual state. In contrast, Nagios attempts to determine the proper status (DOWN or UNREACHABLE) for hosts that are not UP when the host check is active (initiated by Nagios). This can cause problems if you are submitting passive checks from a remote host or you have a distributed monitoring setup where the parent/child host relationships are different. See the documentation on host reachability for more information on how DOWN and UNREACHABLE states are determined for active host checks.

    How Do External Apps Submit Host Check Results?

    External applications can submit host check results to Nagios by writing a PROCESS_HOST_CHECK_RESULT external command to the external command file.

    The format of the command is as follows:

    [<timestamp>] PROCESS_HOST_CHECK_RESULT;<host_name>;<host_status>;<plugin_output>

    where...

    • timestamp is the time in time_t format (seconds since the UNIX epoch) that the host check was perfomed (or submitted). Please note the single space after the right bracket.
    • host_name is the short name of the host (as defined in the host definition)
    • host_status is the status of the host (0=UP, 1=DOWN, 2=UNREACHABLE)
    • plugin_output is the text output of the host check

    Note that in order to submit host checks to Nagios, a host must have already been defined in the object configuration file! Nagios will ignore all check results for hosts that had not been configured before it was last (re)started.

    Submitting Passive Host Check Results From Remote Hosts

    If an application that resides on the same host as Nagios is sending passive service check results, it can simply write the results directly to the external command file as outlined above. However, applications on remote hosts can't do this so easily. In order to allow remote hosts to send passive host check results to the host that runs Nagios, you can use the nsca addon. The addon consists of a daemon that runs on the Nagios hosts and a client that is executed from remote hosts. The daemon will listen for connections from remote clients, perform some basic validation on the results being submitted, and then write the check results directly into the external command file (as described above). More information on the nsca addon can be found here.


    nagios-2.6/html/docs/perfdata.html0000664000076500007650000001666110220364211016550 0ustar nagiosnagios Performance Data

    Performance Data


    Introduction

    Nagios is designed to allow plugins to return optional performance data in addition to normal status data, as well as allow you to pass that performance data to external applications for processing. A description of the different types of performance data, as well as information on how to go about processing that data is described below...

    Types of Performance Data

    There are two basic categories of performance data that can be obtained from Nagios:

    1. Check performance data
    2. Plugin performance data

    Check performance data is internal data that relates to the actual execution of a host or service check. This might include things like service check latency (i.e. how "late" was the service check from its scheduled execution time) and the number of seconds a host or service check took to execute. This type of performance data is available for all checks that are performed. The $HOSTEXECUTIONTIME$ and $SERVICEEXECUTIONTIME$ macros can be used to determine the number of seconds a host or service check was running and the $HOSTLATENCY$ and $SERVICELATENCY$ macros can be used to determine how "late" a regularly-scheduled host or service check was.

    Plugin performance data is external data specific to the plugin used to perform the host or service check. Plugin-specific data can include things like percent packet loss, free disk space, processor load, number of current users, etc. - basically any type of metric that the plugin is measuring when it executes. Plugin-specific performance data is optional and may not be supported by all plugins. As of this writing, no plugins return performance data, although they mostly likely will in the near future. Plugin-specific performance data (if available) can be obtained by using the $HOSTPERFDATA$ and $SERVICEPERFDATA$ macros. See below for more information on how plugins can return performance data to Nagios for inclusion in the $HOSTPERFDATA$ and $SERVICEPERFDATA$ macros.

    Performance Data Support For Plugins

    Normally plugins return a single line of text that indicates the status of some type of measurable data. For example, the check_ping plugin might return a line of text like the following:

    PING ok - Packet loss = 0%, RTA = 0.80 ms

    With this type of output, the entire line of text is available in the $HOSTOUTPUT$ or $SERVICEOUTPUT$ macros (depending on whether this plugin was used as a host check or service check).

    In order to facilitate the passing of plugin-specific performance data to Nagios, the plugin specification has been expanded. If a plugin wishes to pass performance data back to Nagios, it does so by sending the normal text string that it usually would, followed by a pipe character (|), and then a string containing one or more performance data metrics. Let's take the check_ping plugin as an example and assume that it has been enhanced to return percent packet loss and average round trip time as performance data metrics. A sample plugin output might look like this:

    PING ok - Packet loss = 0%, RTA = 0.80 ms | percent_packet_loss=0, rta=0.80

    When Nagios seems this format of plugin output it will split the output into two parts: everything before the pipe character is considered to be the "normal" plugin output and everything after the pipe character is considered to be the plugin-specific performance data. The "normal" output gets stored in the $HOSTOUTPUT$ or $SERVICEOUTPUT$ macro, while the optional performance data gets stored in the $HOSTPERFDATA$ or $SERVICEPERFDATA$ macro. In the example above, the $HOSTOUTPUT$ or $SERVICEOUTPUT$ macro would contain "PING ok - Packet loss = 0%, RTA = 0.80 ms" (without quotes) and the $HOSTPERFDATA$ or $SERVICEPERFDATA$ macro would contain "percent_packet_loss=0, rta=0.80" (without quotes).

    Format of Performance Data Output

    The Nagios daemon doesn't directly process performance data, so it doesn't really care what the performance data looks like. There aren't really any inherent limitations on the format or content of the performance data. However, if you are using an external addon to process the performance data (i.e. PerfParse), the addon may be expecting that the plugin returns performance data in a specific format. Check the documentation that comes with the addon for more information. Also, make sure to check the plugin developer guidelines at SourceForge (http://nagiosplug.sourceforge.net/) for information on writing plugins.

    Enabling Performance Data Processing

    If you want to process the performance data that is available from Nagios and the plugins, you'll need to do the following:

    1. Enable the process_performance_data option.

    2. Configure Nagios so that performance data is written to files and/or processed by executing commands.

    Writing Performance Data To Files

    You can have Nagios write all host and service performance data to files using the host_perfdata_file and service_perfdata_file options. You can control how the data is written to those files using the host_perfdata_file_template and service_perfdata_file_template options. Additionally, you can have Nagios periodically execute commands to process the performance data files using the host_perfdata_file_processing_command and service_perfdata_file_processing_command options.

    Processing Performance Data Using Commands

    You can have Nagios process host and service performance data by executing commands by using the host_perfdata_command or service_perfdata_command options. An example command definition that simply writes service performance data to a file is shown below:

    define command{
    	command_name	process-service-perfdata
    	command_line	/bin/echo -e "$LASTSERVICECHECK$\t$HOSTNAME$\t$SERVICEDESC$\t$SERVICESTATE$\t$SERVICEATTEMPT$\t$SERVICESTATETYPE$\t$SERVICEEXECUTIONTIME$\t$SERVICELATENCY$\t$SERVICEOUTPUT$\t$SERVICEPERFDATA$" >> /usr/local/nagios/var/service-perfdata.dat
    	}
    


    nagios-2.6/html/docs/plugins.html0000664000076500007650000000570207743356403016461 0ustar nagiosnagios Nagios Plugins

    Nagios Plugins


    What Are Plugins?

    Plugins are compiled executables or scripts (Perl, shell, etc.) that can be run from a command line to check the status or a host or service. Nagios uses the results from plugins to determine the current status or hosts and services on your network. No, you can't get away without using plugins - Nagios is useless without them.

    Obtaining Plugins

    Plugin development for Nagios is being done at SourceForge. The Nagios plugin development project page (where the latest version of by plugins can always be found) is located at http://sourceforge.net/projects/nagiosplug/.

    How Do I Use Plugin X?

    Documentation on how to use individual plugins is not supplied with the core Nagios distribution. You should refer to the latest plugin distribution for information on using plugins. Karl DeBisschop, lead plugin developer/maintainer points out the following:

    All plugins that comply with minimal development guideline for this project include internal documentation. The documentation can be read executing plugin with the '-h' option ('--help' if long options are enabled). If the '-h' option does not work, that is a bug.

    For example, if you want to know how the check_http plugin works or what options it accepts, you should try executing one of the following commands:

    ./check_http --help

    or

    ./check_http -h

    Command Definition Examples For Services

    It is important to note that command definitions found in sample config files in the core Nagios distribution are probably not accurate as to command line parameters, etc when it comes to the plugins. They are simply provided as examples of how to define commands.

    Creating Custom Plugins

    Creating your own plugins to perform custom host or service checks is easy. You can find information on how to write plugins at http://sourceforge.net/projects/nagiosplug/. The developer guidelines can be found at http://nagiosplug.sourceforge.net/developer-guidelines.html.


    nagios-2.6/html/docs/plugintheory.html0000664000076500007650000001172110377720771017527 0ustar nagiosnagios Plugin Theory

    Plugin Theory


    Introduction

    Unlike many other monitoring tools, Nagios does not include any internal mechanisms for checking the status of services, hosts, etc. Instead, Nagios relies on external programs (called plugins) to do the all the dirty work. Nagios will execute a plugin whenever there is a need to check a service or host that is being monitored. The plugin does something (notice the very general term) to perform the check and then simply returns the results to Nagios. Nagios will process the results that it receives from the plugin and take any necessary actions (running event handlers, sending out notifications, etc).

    The image below show how plugins are separated fromt the core program logic in Nagios. Nagios executes the plugins which then check local or remote resources or services of some type. When the plugins have finished checking the resource or service, they simply pass the results of the check back to Nagios for processing. A more complex diagram on how plugins work can be found in the documentation on passive service checks.

    The Upside

    The good thing about the plugin architecture is that you can monitor just about anything you can think of. If you can automate the process of checking something, you can monitor it with Nagios. There are already a lot of plugins that have been created in order to monitor basic resources such as processor load, disk usage, ping rates, etc. If you want to monitor something else, take a look at the documentation on writing plugins and roll your own. Its simple!

    The Downside

    The only real downside to the plugin architecture is the fact that Nagios has absolutely no idea what it is that you're monitoring. You could be monitoring network traffic statistics, data error rates, room temperate, CPU voltage, fan speed, processor load, disk space, or the ability of your super-fantastic toaster to properly brown your bread in the morning... As such, Nagios cannot produce graphs of changes to the exact values of resources you're monitoring over time. It can only track changes in the state of those resources. Only the plugins themselves know exactly what they're monitoring and how to perform checks. However, plugins can return optional performance data along with status information. This performance data can then be passed on to external applications which could produce graphs of service-specific information (i.e. disk space usage, processor load, etc.). More information on performance data can be found here.

    Using Plugins For Service Checks

    The correlation between plugins and service checks should be fairly obvious. When Nagios needs to check the status of a particular service that you have defined, it will execute the plugin you specified in the <check_command> argument of the service definition. The plugin will check the status of the service or resource you specify and return the results to Nagios.

    Using Plugins For Host Checks

    Using plugins to check the status of hosts may be a bit more difficult to understand. In each host definition you use the <host_check_command> argument to specify a plugin that should be executed to check the status of the host. Host checks are not performed on a regular basis - they are executed only as needed, usually when there are problems with one or more services that are associated with the host.

    Host checks can use the same plugins as service checks. The only real difference between the two types of checks is in the interpretation of the plugin results. If a plugin that is used for a host check results in a non-OK status, Nagios will believe that the host is down.

    In most situations, you'll want to use a plugin which checks to see if the host can be pinged, as this is the most common method of telling whether or not a host is up. However, if you were monitoring some kind of super-fantastic toaster, you might want to use a plugin that would check to see if the heating elements turned on when the handle was pushed down. That would give a decent indication as to whether or not the toaster was "alive".


    nagios-2.6/html/docs/redundancy.html0000664000076500007650000004261610220364213017117 0ustar nagiosnagios Redundant and Failover Network Monitoring

    Redundant and Failover Network Monitoring


    Introduction

    This section describes a few scenarios for implementing redundant monitoring hosts an various types of network layouts. With redundant hosts, you can maintain the ability to monitor your network when the primary host that runs Nagios fails or when portions of your network become unreachable.

    Note: If you are just learning how to use Nagios, I would suggest not trying to implement redudancy until you have becoming familiar with the prerequisites I've laid out. Redundancy is a relatively complicated issue to understand, and even more difficult to implement properly.

    Index

    Prerequisites
    Sample scripts
    Scenario 1 - Redundant monitoring
    Scenario 2 - Failover monitoring

    Prerequisites

    Before you can even think about implementing redundancy with Nagios, you need to be familiar with the following...

    Sample Scripts

    All of the sample scripts that I use in this documentation can be found in the eventhandlers/ subdirectory of the Nagios distribution. You'll probably need to modify them to work on your system...

    Scenario 1 - Redundant Monitoring

    Introduction

    This is an easy (and naive) method of implementing redundant monitoring hosts on your network and it will only protect against a limited number of failures. More complex setups are necessary in order to provide smarter redundancy, better redundancy across different network segments, etc.

    Goals

    The goal of this type of redundancy implementation is simple. Both the "master" and "slave" hosts monitor the same hosts and service on the network. Under normal circumstances only the "master" host will be sending out notifications to contacts about problems. We want the "slave" host running Nagios to take over the job of notifying contacts about problems if:

    1. The "master" host that runs Nagios is down or..
    2. The Nagios process on the "master" host stops running for some reason

    Network Layout Diagram

    The diagram below shows a very simple network setup. For this scenario I will be assuming that hosts A and E are both running Nagios and are monitoring all the hosts shown. Host A will be considered the "master" host and host E will be considered the "slave" host.

    Initial Program Settings

    The slave host (host E) has its initial enable_notifications directive disabled, thereby preventing it from sending out any host or service notifications. You also want to make sure that the slave host has its check_external_commands directive enabled. That was easy enough...

    Initial Configuration

    Next we need to consider the differences between the object configuration file(s) on the master and slave hosts...

    I will assume that you have the master host (host A) setup to monitor services on all hosts shown in the diagram above. The slave host (host E) should be setup to monitor the same services and hosts, with the following additions in the configuration file...

    • The host definition for host A (in the host E configuration file) should have a host event handler defined. Lets say the name of the host event handler is handle-master-host-event.
    • The configuration file on host E should have a service defined to check the status of the Nagios process on host A. Lets assume that you define this service check to run the check_nagios plugin on host A. This can be done by using one of the methods described in this FAQ.
    • The service definition for the Nagios process check on host A should have an event handler defined. Lets say the name of the service event handler is handle-master-proc-event.

    It is important to note that host A (the master host) has no knowledge of host E (the slave host). In this scenario it simply doesn't need to. Of course you may be monitoring services on host E from host A, but that has nothing to do with the implementation of redundancy...

    Event Handler Command Definitions

    We need to stop for a minute and describe what the command definitions for the event handlers on the slave host look like. Here is an example...

    define command{
    	command_name	handle-master-host-event
    	command_line	/usr/local/nagios/libexec/eventhandlers/handle-master-host-event $HOSTSTATE$ $HOSTSTATETYPE$
    	}
    	
    define command{
    	command_name	handle-master-proc-event
    	command_line	/usr/local/nagios/libexec/eventhandlers/handle-master-proc-event $SERVICESTATE$ $SERVICESTATETYPE$
    	}
    

    This assumes that you have placed the event handler scripts in the /usr/local/nagios/libexec/eventhandlers directory. You may place them anywhere you wish, but you'll need to modify the examples I've given here.

    Event Handler Scripts

    Okay, now lets take a look at what the event handler scripts look like...

    Host Event Handler (handle-master-host-event):

    #!/bin/sh
    
    # Only take action on hard host states...
    case "$2" in
    HARD)
    	case "$1" in
    	DOWN)
    		# The master host has gone down!
    		# We should now become the master host and take
    		# over the responsibilities of monitoring the 
    		# network, so enable notifications...
    		/usr/local/nagios/libexec/eventhandlers/enable_notifications
    		;;
    	UP)
    		# The master host has recovered!
    		# We should go back to being the slave host and
    		# let the master host do the monitoring, so 
    		# disable notifications...
    		/usr/local/nagios/libexec/eventhandlers/disable_notifications
    		;;
    	esac
    	;;
    esac
    exit 0
    

    Service Event Handler (handle-master-proc-event):

    #!/bin/sh
    
    # Only take action on hard service states...
    case "$2" in
    HARD)
    	case "$1" in
    	CRITICAL)
    		# The master Nagios process is not running!
    		# We should now become the master host and
    		# take over the responsibility of monitoring
    		# the network, so enable notifications...
    		/usr/local/nagios/libexec/eventhandlers/enable_notifications
    		;;
    	WARNING)
    	UNKNOWN)
    		# The master Nagios process may or may not
    		# be running.. We won't do anything here, but
    		# to be on the safe side you may decide you 
    		# want the slave host to become the master in
    		# these situations...
    		;;
    	OK)
    		# The master Nagios process running again!
    		# We should go back to being the slave host, 
    		# so disable notifications...
    		/usr/local/nagios/libexec/eventhandlers/disable_notifications
    		;;
    	esac
    	;;
    esac
    exit 0
    

    What This Does For Us

    The slave host (host E) initially has notifications disabled, so it won't send out any host or service notifications while the Nagios process on the master host (host A) is still running.

    The Nagios process on the slave host (host E) becomes the master host when...

    • The master host (host A) goes down and the handle-master-host-event host event handler is executed.
    • The Nagios process on the master host (host A) stops running and the handle-master-proc-event service event handler is executed.

    When the Nagios process on the slave host (host E) has notifications enabled, it will be able to send out notifications about any service or host problems or recoveries. At this point host E has effectively taken over the responsibility of notifying contacts of host and service problems!

    The Nagios process on host E returns to being the slave host when...

    • Host A recovers and the handle-master-host-event host event handler is executed.
    • The Nagios process on host A recovers and the handle-master-proc-event service event handler is executed.

    When the Nagios process on host E has notifications disabled, it will not send out notifications about any service or host problems or recoveries. At this point host E has handed over the responsibilities of notifying contacts of problems to the Nagios process on host A. Everything is now as it was when we first started!

    Time Lags

    Redundancy in Nagios is by no means perfect. One of the more obvious problems is the lag time between the master host failing and the slave host taking over. This is affected by the following...

    • The time between a failure of the master host and the first time the slave host detects a problem
    • The time needed to verify that the master host really does have a problem (using service or host check retries on the slave host)
    • The time between the execution of the event handler and the next time that Nagios checks for external commands

    You can minimize this lag by...

    • Ensuring that the Nagios process on host E (re)checks one or more services at a high frequency. This is done by using the check_interval and retry_interval arguments in each service definition.
    • Ensuring that the number of host rechecks for host A (on host E) allow for fast detection of host problems. This is done by using the max_check_attempts argument in the host definition.
    • Increase the frequency of external command checks on host E. This is done by modifying the command_check_interval option in the main configuration file.

    When Nagios recovers on the host A, there is also some lag time before host E returns to being a slave host. This is affected by the following...

    • The time between a recovery of host A and the time the Nagios process on host E detects the recovery
    • The time between the execution of the event handler on host B and the next time the Nagios process on host E checks for external commands

    The exact lag times between the transfer of monitoring responsibilities will vary depending on how many services you have defined, the interval at which services are checked, and a lot of pure chance. At any rate, its definitely better than nothing.

    Special Cases

    Here is one thing you should be aware of... If host A goes down, host E will have notifications enabled and take over the responsibilities of notifying contacts of problems. When host A recovers, host E will have notifications disabled. If - when host A recovers - the Nagios process on host A does not start up properly, there will be a period of time when neither host is notifying contacts of problems! Fortunately, the service check logic in Nagios accounts for this. The next time the Nagios process on host E checks the status of the Nagios process on host A, it will find that it is not running. Host E will then have notifications enabled again and take over all responsibilities of notifying contacts of problems.

    The exact amount of time that neither host is monitoring the network is hard to determine. Obviously, this period can be minimized by increasing the frequency of service checks (on host E) of the Nagios process on host A. The rest is up to pure chance, but the total "blackout" time shouldn't be too bad.

    Scenario 2 - Failover Monitoring

    Introduction

    Failover monitoring is similiar to, but slightly different than redundant monitoring (as discussed above in scenario 1).

    Goals

    The basic goal of failover monitoring is to have the Nagios process on the slave host sit idle while the Nagios process on the master host is running. If the process on the master host stops running (or if the host goes down), the Nagios process on the slave host starts monitoring everything.

    While the method described in scenario 1 will allow you to continue receive notifications if the master monitoring hosts goes down, it does have some pitfalls. The biggest problem is that the slave host is monitoring the same hosts and servers as the master at the same time as the master! This can cause problems with excessive traffic and load on the machines being monitored if you have a lot of services defined. Here's how you can get around that problem...

    Initial Program Settings

    Disable active service checks and notifications on the slave host using the execute_service_checks and enable_notifications directives. This will prevent the slave host from monitoring hosts and services and sending out notifications while the Nagios process on the master host is still up and running. Make sure you also have the check_external_commands directive enabled on the slave host.

    Master Process Check

    Set up a cron job on the slave host that periodically (say every minute) runs a script that checks the staus of the Nagios process on the master host (using the check_nrpe plugin on the slave host and the nrpe daemon and check_nagios plugin on the master host). The script should check the return code of the check_nrpe plugin . If it returns a non-OK state, the script should send the appropriate commands to the external command file to enable both notifications and active service checks. If the plugin returns an OK state, the script should send commands to the external command file to disable both notifications and active checks.

    By doing this you end up with only one process monitoring hosts and services at a time, which is much more efficient that monitoring everything twice.

    Also of note, you don't need to define host and service handlers as mentioned in scenario 1 because things are handled differently.

    Additional Issues

    At this point, you have implemented a very basic failover monitoring setup. However, there is one more thing you should consider doing to make things work smoother.

    The big problem with the way things have been setup thus far is the fact that the slave host doesn't have the current status of any services or hosts at the time it takes over the job of monitoring. One way to solve this problem is to enable the ocsp command on the master host and have it send all service check results to the slave host using the nsca addon. The slave host will then have up-to-date status information for all services at the time it takes over the job of monitoring things. Since active service checks are not enabled on the slave host, it will not actively run any service checks. However, it will execute host checks if necessary. This means that both the master and slave hosts will be executing host checks as needed, which is not really a big deal since the majority of monitoring deals with service checks.

    That's pretty much it as far as setup goes.


    nagios-2.6/html/docs/robots.txt0000664000076500007650000000003207436604435016152 0ustar nagiosnagiosUser-agent: * Disallow: / nagios-2.6/html/docs/security.html0000664000076500007650000001351210214170564016632 0ustar nagiosnagios Securing Nagios

    Securing Nagios


    Introduction

    This is intended to be a brief overview of some things you should keep in mind when installing Nagios, so as to not set it up in an insecure manner. This document is new, so if anyone has additional notes or comments on securing Nagios, please drop me a note at nagios@nagios.org

    Do Not Run Nagios As Root!

    Nagios doesn't need to run as root, so don't do it. Even if you start Nagios at boot time with an init script, you can force it to drop privileges after startup and run as another user/group by using the nagios_user and nagios_group directives in the main config file.

    If you need to execute event handlers or plugins which require root access, you might want to try using sudo.

    Enable External Commands Only If Necessary

    By default, external commands are disabled. This is done to prevent an admin from setting up Nagios and unknowingly leaving its command interface open for use by "others".. If you are planning on using event handlers or issuing commands from the web interface, you will have to enable external commands. If you aren't planning on using event handlers or the web interface to issue commands, I would recommend leaving external commands disabled.

    Set Proper Permissions On The External Command File

    If you enable external commands, make sure you set proper permissions on the /usr/local/nagios/var/rw directory. You only want the Nagios user (usually nagios) and the web server user (usually nobody) to have permissions to write to the command file. If you've installed Nagios on a machine that is dedicated to monitoring and admin tasks and is not used for public accounts, that should be fine.

    If you've installed it on a public or multi-user machine, allowing the web server user to have write access to the command file can be a security problem. After all, you don't want just any user on your system controlling Nagios through the external command file. In this case, I would suggest only granting write access on the command file to the nagios user and using something like CGIWrap to run the CGIs as the nagios user instead of nobody.

    Instructions on setting up permissions for the external command file can be found here.

    Require Authentication In The CGIs

    I would strongly suggest requiring authentication for accessing the CGIs. Once you do that, read the documentation on the default rights that authenticated contacts have, and only authorize specific contacts for additional rights as necessary. Instructions on setting up authentication and configuring authorization rights can be found here. If you disable the CGI authentication features using the use_authentication directive in the CGI config file, the command CGI will refuse to write any commands to the external command file. After all, you don't want the world to be able to control Nagios do you?

    Use Full Paths In Command Definitions

    When you define commands, make sure you specify the full path to any scripts or binaries you're executing.

    Hide Sensitive Information With $USERn$ Macros

    The CGIs read the main config file and object config file(s), so you don't want to keep any sensitive information (usernames, passwords, etc) in there. If you need to specify a username and/or password in a command definition use a $USERn$ macro to hide it. $USERn$ macros are defined in one or more resource files. The CGIs will not attempt to read the contents of resource files, so you can set more restrictive permissions (600 or 660) on them. See the sample resource.cfg file in the base of the Nagios distribution for an example of how to define $USERn$ macros.

    Strip Dangerous Characters From Macros

    Use the illegal_macro_output_chars directive to strip dangerous characters from the $HOSTOUTPUT$, $SERVICEOUTPUT$, $HOSTPERFDATA$, and $SERVICEPERFDATA$ macros before they're used in notifications, etc. Dangerous characters can be anything that might be interpreted by the shell, thereby opening a security hole. An example of this is the presence of backtick (`) characters in the $HOSTOUTPUT$, $SERVICEOUTPUT$, $HOSTPERFDATA$, and/or $SERVICEPERFDATA$ macros, which could allow an attacker to execute an arbitrary command as the nagios user (one good reason not to run Nagios as the root user).


    nagios-2.6/html/docs/stalking.html0000664000076500007650000001311707743356403016613 0ustar nagiosnagios State Stalking

    State Stalking


    Introduction

    State "stalking" is a feature which is probably not going to used by most users. When enabled, it allows you to log changes in service and host checks even if the state of the host or service does not change. When stalking is enabled for a particular host or service, Nagios will watch that service very carefully and log any changes it sees. As you'll see, it can be very helpful to you in later analysis of the log files.

    How Does It Work?

    Under normal circumstances, the result of a host or service check is only logged if the host or service has changed state since it was last checked. There are a few exceptions to this, but for the most part, that's the rule.

    If you enable stalking for one or more states of a particular host or service, Nagios will log the results of the host or service check if the output from the check differs from the output from the previous check. Take the following example of eight consecutive checks of a service:

    Service Check #:Service State:Service Check Output:
    xOKRAID array optimal
    x+1OKRAID array optimal
    x+2WARNINGRAID array degraded (1 drive bad, 1 hot spare rebuilding)
    x+3CRITICALRAID array degraded (2 drives bad, 1 host spare online, 1 hot spare rebuilding)
    x+4CRIICALRAID array degraded (3 drives bad, 2 hot spares online)
    x+5CRITICALRAID array failed
    x+6CRITICALRAID array failed
    x+7CRITICALRAID array failed

    Given this sequence of checks, you would normally only see two log entries for this catastrophe. The first one would occur at service check x+2 when the service changed from an OK state to a WARNING state. The second log entry would occur at service check x+3 when the service changed from a WARNING state to a CRITICAL state.

    For whatever reason, you may like to have the complete history of this catasrophe in your log files. Perhaps to help explain to your manager how quickly the situation got out of control, perhaps just to laugh at over a couple of drinks at the local pub, whatever...

    Well, if you had enabled stalking of this service for CRITICAL states, you would have events at x+4 and x+5 logged in addition to the events at x+2 and x+3. Why is this? With state stalking enabled, Nagios would have examined the output from each service check to see if it differed from the output of the previous check. If the output differed and the state of the service didn't change between the two checks, the result of the newer service check would get logged.

    A similiar example of stalking might be on a service that checks your web server. If the check_http plugin first returns a WARNING state because of a 404 error and on subsequent checks returns a WARNING state because of a particular pattern not being found, you might want to know that. If you didn't enable state stalking for WARNING states of the service, only the first WARNING state event (the 404 error) would be logged and you wouldn't have any idea (looking back in the archived logs) that future problems were not due to a 404, but rather a missing pattern in the returned web page.

    Should I Enable Stalking?

    First, you must decide if you have a real need to analyze archived log data to find the exact cause of a problem. You may decide you need this feature for some hosts or services, but not for all. You may also find that you only have a need to enable stalking for some host or service states, rather than all of them. For example, you may decide to enable stalking for WARNING and CRITICAL states of a service, but not for OK and UNKNOWN states.

    The decision to to enable state stalking for a particular host or service will also depend on the plugin that you use to check that host or service. If the plugin always returns the same text output for a particular state, there is no reason to enable stalking for that state.

    How Do I Enable Stalking?

    You can enable state stalking for hosts and services by using the stalking_options directive in host and service definitions.

    Caveats

    You should be aware that there are some potential pitfalls with enabling stalking. These all relate to the reporting functions found in various CGIs (histogram, alert summary, etc.). Because state stalking will cause additional alert entries to be logged, the data produced by the reports will show evidence of inflated numbers of alerts.

    As a general rule, I would suggest that you not enable stalking for hosts and services without thinking things through. Still, its there if you need and want it.


    nagios-2.6/html/docs/starting.html0000664000076500007650000001025207743356403016627 0ustar nagiosnagios Starting Nagios

    Starting Nagios


    IMPORTANT: Before you actually start Nagios, you'll have to make sure that you have configured it properly and verified the config data!

    Methods For Starting Nagios

    There are basically four different ways you can start Nagios:

    1. Manually, as a foreground process (useful for initial testing and debugging)
    2. Manually, as a background process
    3. Manually, as a daemon
    4. Automatically at system boot

    Let's examine each method briefly...

    Running Nagios Manually as a Foreground Process

    If you enabled the debugging options when running the configure script (and recompiled Nagios), this would be your first choice for testing and debugging. Running Nagios as a foreground process at a shell prompt will allow you to more easily view what's going on in the monitoring and notification processes. To run Nagios as a foreground process for testing, invoke Nagios like this...

    /usr/local/nagios/bin/nagios <main_config_file>

    Note that you must specify the path/filename of the main configuration file (i.e. /usr/local/nagios/etc/nagios.cfg) on the command line.

    To stop Nagios at any time, just press CTRL-C. If you've enabled the debugging options you'll probably want to redirect the output to a file for easier review later.

    Running Nagios Manually as a Background Process

    To run Nagios as a background process, invoke it with an ampersand as follows...

    /usr/local/nagios/bin/nagios <main_config_file> &

    Note that you must specify the path/filename of the main configuration file (i.e. /usr/local/nagios/etc/nagios.cfg) on the command line.

    Running Nagios Manually as a Daemon

    In order to run Nagios in daemon mode you must supply the -d switch on the command line as follows...

    /usr/local/nagios/bin/nagios -d <main_config_file>

    Note that you must specify the path/filename of the main configuration file (i.e. /usr/local/nagios/etc/nagios.cfg) on the command line.

    Running Nagios Automatically at System Boot

    When you have tested Nagios and are reasonably sure that it is not going to crash, you will probably want to have it start automatically at boot time. To do this (in Linux) you will have to create a startup script in your /etc/rc.d/init.d/ directory. You will also have to create a link to the script in the runlevel(s) that you wish to have Nagios to start in. I'll assume that you know what I'm talking about and are able to do this.

    A sample init script (named daemon-init) is created in the base directory of the Nagios distribution when you run the configure script. You can install the sample script to your /etc/rc.d/init.d directory using the 'make install-init' command, as outlined in the installation instructions.

    The sample init scripts are designed to work under Linux, so if you want to use them under FreeBSD, Solaris, etc. you may have to do a little hacking...

    Stopping and Restarting Nagios

    Directions on how to stop and restart Nagios can be found here.


    nagios-2.6/html/docs/statetypes.html0000664000076500007650000001560510220364213017166 0ustar nagiosnagios State Types

    State Types


    Introduction

    The current state of services and hosts is determined by two components: the status of the service or host (i.e. OK, WARNING, UP, DOWN, etc.) and the type of state it is in. There are two state types in Nagios - "soft" states and "hard" states. State types are a crucial part of Nagios' monitoring logic. They are used to determine when event handlers are executed and when notifications are sent out.

    Service and Host Check Retries

    In order to prevent false alarms, Nagios allows you to define how many times a service or host check will be retried before the service or host is considered to have a real problem. The maximum number of retries before a service or host check is considered to have a real problem is controlled by the <max_check)attempts> option in the service and host definitions, respectively. Depending on what attempt a service or host check is currently on determines what type of state it is is. There are a few exceptions to this in the service monitoring logic, but we'll ignore those for now. Let's take a look at the different service state types...

    Soft States

    Soft states occur for services and hosts in the following situations...

    • When a service or host check results in a non-OK state and it has not yet been (re)checked the number of times specified by the <max_check_attempts> option in the service or host definition. Let's call this a soft error state...
    • When a service or host recovers from a soft error state. This is considered to be a soft recovery.

    Soft State Events

    What happens when a service or host is in a soft error state or experiences a soft recovery?

    • The soft error or recovery is logged if you enabled the log_service_retries or log_host_retries options in the main configuration file.
    • Event handlers are executed (if you defined any) to handle the soft error or recovery for the service or host. (Before any event handler is executed, the $HOSTSTATETYPE$ or $SERVICESTATETYPE$ macro is set to "SOFT").
    • Nagios does not send out notifications to any contacts because there is (or was) no "real" problem with the service or host.

    As can be seen, the only important thing that really happens during a soft state is the execution of event handlers. Using event handlers can be particularly useful if you want to try and proactively fix a problem before it turns into a hard state. More information on event handlers can be found here.

    Hard States

    Hard states occur for services in the following situations (hard host states are discussed later)...

    • When a service check results in a non-OK state and it has been (re)checked the number of times specified by the <max_check_attempts> option in the service definition. This is a hard error state.
    • When a service recovers from a hard error state. This is considered to be a hard recovery.
    • When a service check results in a non-OK state and its corresponding host is either DOWN or UNREACHABLE. This is an exception to the general monitoring logic, but makes perfect sense. If the host isn't up why should we try and recheck the service?

    Hard states occur for hosts in the following situations...

    • When a host check results in a non-OK state and it has been (re)checked the number of times specified by the <max_check_attempts> option in the host definition. This is a hard error state.
    • When a host recovers from a hard error state. This is considered to be a hard recovery.

    Hard State Changes

    Before I discuss what happens when a host or service is in a hard state, you need to know about hard state changes. Hard state changes occur when a service or host...

    • changes from a hard OK state to a hard non-OK state
    • changes from a hard non-OK state to a hard OK-state
    • changes from a hard non-OK state of some kind to a hard non-OK state of another kind (i.e. from a hard WARNING state to a hard UNKNOWN state)

    Hard State Events

    What happens when a service or host is in a hard error state or experiences a hard recovery? Well, that depends on whether or not a hard state change (as described above) has occurred.

    If a hard state change has occurred and the service or host is in a non-OK state the following things will occur..

    • The hard service or host problem is logged.
    • Event handlers are executed (if you defined any) to handle the hard problem for the service or host. (Before any event handler is executed, the $HOSTSTATETYPE$ or $SERVICESTATETYPE$ macro is set to "HARD").
    • Contacts will be notified of the service or host problem (if the notification logic allows it).

    If a hard state change has occurred and the service or host is in an OK state the following things will occur..

    • The hard service or host recovery is logged.
    • Event handlers are executed (if you defined any) to handle the hard recovery for the service or host. (Before any event handler is executed, the $HOSTSTATETYPE$ or $SERVICESTATETYPE$ macro is set to "HARD").
    • Contacts will be notified of the service or host recovery (if the notification logic allows it).

    If a hard state change has NOT occurred and the service or host is in a non-OK state the following things will occur..

    • Contacts will be re-notified of the service or host problem (if the notification logic allows it).

    If a hard state change has NOT occurred and the service or host is in an OK state nothing happens. This is because the service or host is in an OK state and was the last time it was checked as well.


    nagios-2.6/html/docs/stoprestart.html0000664000076500007650000001145407743356403017373 0ustar nagiosnagios Stopping and Restarting Nagios

    Stopping And Restarting Nagios


    Once you have Nagios up and running, you may need to stop the process or reload the configuration data "on the fly". This section describes how to do just that.

    IMPORTANT: Before you restart Nagios, make sure that you have verified the configuration data using the -v command line switch, especially if you have made any changes to your config files. If Nagios encounters problem with one of the config files when it restarts, it will log an error and terminate.

    Stopping And Restarting With The Init Script

    If you have installed the sample init script to your /etc/rc.d/init.d directory you can stop and restart Nagios easily. If you haven't, skip this section and read how to do it manually below. I'll assume that you named the init script Nagios in the examples below...

    Desired Action Command Description
    Stop Nagios /etc/rc.d/init.d/nagios stop This kills the Nagios process
    Restart Nagios /etc/rc.d/init.d/nagios restart This kills the current Nagios process and then starts Nagios up again
    Reload Configuration Data /etc/rc.d/init.d/nagios reload Sends a SIGHUP to the Nagios process, causing it to flush its current configuration data, reread the configuration files, and start monitoring again

    Stopping, restarting, and reloading Nagios are fairly simple with an init script and I would highly recommend you use one if at all possible.

    Stopping and Restarting Nagios Manually

    If you aren't using an init script to start Nagios, you'll have to do things manually. First you'll have to find the process ID that Nagios is running under and then you'll have to use the kill command to terminate the application or make it reload the configuration data by sending it the proper signal. Directions for doing this are outlined below...

    Finding The Nagios Process ID

    First off, you will need to know the process id that Nagios is running as. To do that, just type the following command at a shell prompt:

    ps axu | grep nagios

    The output should look something like this:

    nagios  6808  0.0  0.7   840   352  p3 S    13:44   0:00 grep nagios
    nagios 11149  0.2  1.0   868   488  ?  S   Feb 27   6:33 /usr/local/nagios/bin/nagios nagios.cfg
    
    From the program output, you will notice that Nagios was started by user nagios and is running as process id 11149.

    Manually Stopping Nagios

    In order to stop Nagios, use the kill command as follows...

    kill 11149

    You should replace 11149 with the actual process id that Nagios is running as on your machine.

    Manually Restarting Nagios

    If you have modified the configuration data, you will want to restart Nagios and have it re-read the new configuration. If you have changed the source code and recompiled the main Nagios executable you should not use this method. Instead, stop Nagios by killing it (as outlined above) and restart it manually. Restarting Nagios using the method below does not actually reload Nagios - it just causes Nagios to flush its current configuration, re-read the new configuration, and start monitoring all over again. To restart Nagios, you need to send the SIGHUP signal to Nagios. Assuming that the process id for Nagios is 11149 (taken from the example above), use the following command:

    kill -HUP 11149

    Remember, you will need to replace 11149 with the actual process id that Nagios is running as on your machine.


    nagios-2.6/html/docs/templaterecursion.html0000664000076500007650000002111207743356403020536 0ustar nagiosnagios Object Inheritance

    Object Inheritance


    Introduction

    This documentation attempts to explain object inheritance and how it can be used in template-based object definitions.

    One of my primary motivations for adding support for template-based object data was its ability to easily allow object definitions to inherit various properties from other object definitions. Object property inheritance is accomplished through recursion when Nagios processes your configuration files.

    If you are still confused about how recursion and inheritance work after reading this, take a look at the sample object config files provided in the distribution. If that still doesn't help, drop an email message with a detailed description of your problem to the nagios-users mailing list.

    Basics

    There are three variables affecting recursion and inheritance that are present in all object definitions. They are indicated in red as follows...

    	define someobjecttype{
    		object-specific variables ...
    		name		template_name
    		use		name_of_template_to_use
    		register	[0/1]
    		}
    

    The first variable is name. Its just a "template" name that can be referenced in other object definitions so they can inherit the objects properties/variables. Template names must be unique amongst objects of the same type, so you can't have two or more host definitions that have "hosttemplate" as their template name.

    The second variable is use. This is where you specify the name of the template object that you want to inherit properties/variables from. The name you specify for this variable must be defined as another object's template named (using the name variable).

    The third variable is register. This variable is used to indicate whether or not the object definition should be "registered" with Nagios. By default, all object definitions are registered. If you are using a partial object definition as a template, you would want to prevent it from being registered (an example of this is provided later). Values are as follows: 0 = do NOT register object definition, 1 = register object definition (this is the default). This variable is NOT inherited; every (partial) object definition used as a template must explicitly set the register directive to be 0. This prevents the need to override an inherited register directive with a value of 1 for every object that should be registered.

    Local Variables vs. Inherited Variables

    One important thing to understand with inheritance is that "local" object variables always take precedence over variables defined in the template object. Take a look at the following example of two host definitions (not all required variables have been supplied):

    	define host{
    		host_name		bighost1
    		check_command		check-host-alive
    		notification_options	d,u,r
    		max_check_attempts	5
    		name			hosttemplate1
    		}
    
    	define host{
    		host_name		bighost2
    		max_check_attempts	3
    		use			hosttemplate1
    		}
    

    You'll note that the definition for host bighost1 has been defined as having hosttemplate1 as its template name. The definition for host bighost2 is using the definition of bighost1 as its template object. Once Nagios processes this data, the resulting definition of host bighost2 would be equivalent to this definition:

    	define host{
    		host_name		bighost2
    		check_command		check-host-alive
    		notification_options	d,u,r
    		max_check_attempts	3
    		}
    

    You can see that the check_command and notification_options variables were inherited from the template object (where host bighost1 was defined). However, the host_name and max_check_attempts variables were not inherited from the template object because they were defined locally. Remember, locally defined variables override variables that would normally be inherited from a template object. That should be a fairly easy concept to understand.

    inheritance Chaining

    Objects can inherit properties/variables from multiple levels of template objects. Take the following example:

    	define host{
    		host_name		bighost1
    		check_command		check-host-alive
    		notification_options	d,u,r
    		max_check_attempts	5
    		name			hosttemplate1
    		}
    
    	define host{
    		host_name		bighost2
    		max_check_attempts	3
    		use			hosttemplate1
    		name			hosttemplate2
    		}
    
    	define host{
    		host_name		bighost3
    		use			hosttemplate2
    		}
    

    You'll notice that the definition of host bighost3 inherits variables from the definition of host bighost2, which in turn inherits variables from the definition of host bighost1. Once Nagios processes this configuration data, the resulting host definitions are equivalent to the following:

    	define host{
    		host_name		bighost1
    		check_command		check-host-alive
    		notification_options	d,u,r
    		max_check_attempts	5
    		}
    
    	define host{
    		host_name		bighost2
    		check_command		check-host-alive
    		notification_options	d,u,r
    		max_check_attempts	3
    		}
    
    	define host{
    		host_name		bighost3
    		check_command		check-host-alive
    		notification_options	d,u,r
    		max_check_attempts	3
    		}
    

    There is no inherent limit on how "deep" inheritance can go, but you'll probably want to limit yourself to at most a few levels in order to maintain sanity.

    Using Incomplete Object Definitions as Templates

    It is possible to use imcomplete object definitions as templates for use by other object definitions. By "incomplete" definition, I mean that all required variables in the object have not been supplied in the object definition. It may sound odd to use incomplete definitions as templates, but it is in fact recommended that you use them. Why? Well, they can serve as a set of defaults for use in all other object definitions. Take the following example:

    	define host{
    		check_command		check-host-alive
    		notification_options	d,u,r
    		max_check_attempts	5
    		name			generichosttemplate
    		register			0
    		}
    
    	define host{
    		host_name		bighost1
    		address			192.168.1.3
    		use			generichosthosttemplate
    		}
    
    	define host{
    		host_name		bighost2
    		address			192.168.1.4
    		use			generichosthosttemplate
    		}
    

    Notice that the first host definition is incomplete because it is missing the required host_name variable. We don't need to supply a host name because we just want to use this definition as a generic host template. In order to prevent this definition from being registered with Nagios as a normal host, we set the register variable to 0.

    The definitions of hosts bighost1 and bighost2 inherit their values from the generic host definition. The only variable we've chosed to override is the address variable. This means that both hosts will have the exact same properties, except for their host_name and address variables. Once Nagios processes the config data in the example, the resulting host definitions would be equivalent to specifying the following:

    	define host{
    		host_name		bighost1
    		address			192.168.1.3
    		check_command		check-host-alive
    		notification_options	d,u,r
    		max_check_attempts	5
    		}
    
    	define host{
    		host_name		bighost2
    		address			192.168.1.4
    		check_command		check-host-alive
    		notification_options	d,u,r
    		max_check_attempts	5
    		}
    

    At the very least, using a template definition for default variables will save you a lot of typing. It'll also save you a lot of headaches later if you want to change the default values of variables for a large number of hosts.


    nagios-2.6/html/docs/templatetricks.html0000664000076500007650000004527507756053047020046 0ustar nagiosnagios Time-Saving Tricks For Object Definitions

    Time-Saving Tricks For Object Definitions

    or...
    "How To Preserve Your Sanity"


    Introduction

    This documentation attempts to explain how you can exploit the (somewhat) hidden features of template-based object definitions to save your sanity. How so, you ask? Several types of objects allow you to specify multiple host names and/or hostgroup names in definitions, allowing you to "copy" the object defintion to multiple hosts or services. I'll cover each type of object that supports these features seperately. For starters, the object types which support this time-saving feature are as follows:

    Object types that are not listed above (i.e. timeperiods, commands, etc.) do not support the features I'm about to describe.

    Regular Expression Matching

    The examples I give below use "standard" matching of object names. If you wish, you can enable regular expression matching for object names by using the use_regexp_matching config option. By default, regular expression matching will only be used in object names that contain the * and ? wildcard characters. If you want regular expression matching to be used on all object names (regardless of whether or not they contain the * and ? wildcard characters), enable the use_true_regexp_matching config option.

    Regular expressions can be used in any of the fields used in the examples below (host names, hostgroup names, service names, and servicegroup names).

    NOTE: Be careful when enabling regular expression matching - you may have to change your config file, since some directives that you might not want to be interpreted as a regular expression just might be! Any problems should become evident once you verify your configuration.

    Service Definitions

    Multiple Hosts: If you want to create identical services that are assigned to multiple hosts, you can specify multiple hosts in the host_name directive as follows:

    	define service{
    		host_name		HOST1,HOST2,HOST3,...,HOSTN
    		service_description	SOMESERVICE
    		other service directives ...
    		}
    

    The definition above would create a service called SOMESERVICE on hosts HOST1 through HOSTN. All the instances of the SOMESERVICE service would be identical (i.e. have the same check command, max check attempts, notification period, etc.).

    All Hosts In Multiple Hostgroups: If you want to create identical services that are assigned to all hosts in one or more hostgroups, you can do so by creating a single service definition. How? The hostgroup_name directive allows you to specify the name of one or more hostgroups that the service should be created for:

    	define service{
    		hostgroup_name		HOSTGROUP1,HOSTGROUP2,...,HOSTGROUPN
    		service_description	SOMESERVICE
    		other service directives ...
    		}
    

    The definition above would create a service called SOMESERVICE on all hosts that are members of hostgroups HOSTGROUP1 through HOSTGROUPN. All the instances of the SOMESERVICE service would be identical (i.e. have the same check command, max check attempts, notification period, etc.).

    All Hosts: If you want to create identical services that are assigned to all hosts that are defined in your configuration files, you can use a wildcard in the host_name directive as follows:

    	define service{
    		host_name		*
    		service_description	SOMESERVICE
    		other service directives ...
    		}
    

    The definition above would create a service called SOMESERVICE on all hosts that are defined in your configuration files. All the instances of the SOMESERVICE service would be identical (i.e. have the same check command, max check attempts, notification period, etc.).

    Service Escalation Definitions

    Multiple Hosts: If you want to create service escalations for services of the same name/description that are assigned to multiple hosts, you can specify multiple hosts in the host_name directive as follows:

    	define serviceescalation{
    		host_name		HOST1,HOST2,HOST3,...,HOSTN
    		service_description	SOMESERVICE
    		other escalation directives ...
    		}
    

    The definition above would create a service escalation for services called SOMESERVICE on hosts HOST1 through HOSTN. All the instances of the service escalation would be identical (i.e. have the same contact groups, notification interval, etc.).

    All Hosts In Multiple Hostgroups: If you want to create service escalations for services of the same name/description that are assigned to all hosts in in one or more hostgroups, you can do use the hostgroup_name directive as follows:

    	define serviceescalation{
    		hostgroup_name		HOSTGROUP1,HOSTGROUP2,...,HOSTGROUPN
    		service_description	SOMESERVICE
    		other escalation directives ...
    		}
    

    The definition above would create a service escalation for services called SOMESERVICE on all hosts that are members of hostgroups HOSTGROUP1 through HOSTGROUPN. All the instances of the service escalation would be identical (i.e. have the same contact groups, notification interval, etc.).

    All Hosts: If you want to create identical service escalations for services of the same name/description that are assigned to all hosts that are defined in your configuration files, you can use a wildcard in the host_name directive as follows:

    	define serviceescalation{
    		host_name		*
    		service_description	SOMESERVICE
    		other escalation directives ...
    		}
    

    The definition above would create a service escalation for all services called SOMESERVICE on all hosts that are defined in your configuration files. All the instances of the service escalation would be identical (i.e. have the same contact groups, notification interval, etc.).

    All Services On Same Host: If you want to create service escalations for all services assigned to a particular host, you can use a wildcard in the service_description directive as follows:

    	define serviceescalation{
    		host_name		HOST1
    		service_description	*
    		other escalation directives ...
    		}
    

    The definition above would create a service escalation for all services on host HOST1. All the instances of the service escalation would be identical (i.e. have the same contact groups, notification interval, etc.).

    If you feel like being particularly adventurous, you can specify a wildcard in both the host_name and service_description directives. Doing so would create a service escalation for all services that you've defined in your configuration files.

    Multiple Services On Same Host: If you want to create service escalations for all multiple services assigned to a particular host, you can use a specify more than one service description in the service_description directive as follows:

    	define serviceescalation{
    		host_name		HOST1
    		service_description	SERVICE1,SERVICE2,...,SERVICEN
    		other escalation directives ...
    		}
    

    The definition above would create a service escalation for services SERVICE1 through SERVICEN on host HOST1. All the instances of the service escalation would be identical (i.e. have the same contact groups, notification interval, etc.).

    All Services In Multiple Servicegroups: If you want to create service escalations for all services that belong in one or more servicegroups, you can do use the servicegroup_name directive as follows:

    	define serviceescalation{
    		servicegroup_name		SERVICEGROUP1,SERVICEGROUP2,...,SERVICEGROUPN
    		other escalation directives ...
    		}
    

    The definition above would create service escalations for all services that are members of servicegroups SERVICEGROUP1 through SERVICEGROUPN. All the instances of the service escalation would be identical (i.e. have the same contact groups, notification interval, etc.).

    Service Dependency Definitions

    Multiple Hosts: If you want to create service dependencies for services of the same name/description that are assigned to multiple hosts, you can specify multiple hosts in the host_name and or dependent_host_name directives as follows:

    	define servicedependency{
    		host_name			HOST1,HOST2
    		service_description		SERVICE1
    		dependent_host_name		HOST3,HOST4
    		dependent_service_description	SERVICE2
    		other dependency directives ...
    		}
    

    In the example above, service SERVICE2 on hosts HOST3 and HOST4 would be dependent on service SERVICE1 on hosts HOST1 and HOST2. All the instances of the service dependencies would be identical except for the host names (i.e. have the same notification failure criteria, etc.).

    All Hosts In Multiple Hostgroups: If you want to create service dependencies for services of the same name/description that are assigned to all hosts in in one or more hostgroups, you can do use the hostgroup_name and/or dependent_hostgroup_name directives as follows:

    	define servicedependency{
    		hostgroup_name			HOSTGROUP1,HOSTGROUP2
    		service_description		SERVICE1
    		dependent_hostgroup_name	HOSTGROUP3,HOSTGROUP4
    		dependent_service_description	SERVICE2
    		other dependency directives ...
    		}
    

    In the example above, service SERVICE2 on all hosts in hostgroups HOSTGROUP3 and HOSTGROUP4 would be dependent on service SERVICE1 on all hosts in hostgroups HOSTGROUP1 and HOSTGROUP2. Assuming there were five hosts in each of the hostgroups, this definition would be equivalent to creating 100 single service dependency definitions! All the instances of the service dependency would be identical except for the host names (i.e. have the same notification failure criteria, etc.).

    All Services On Same Host: If you want to create service dependencies for all services assigned to a particular host, you can use a wildcard in the service_description and/or dependent_service_description directives as follows:

    	define servicedependency{
    		host_name			HOST1
    		service_description		*
    		dependent_host_name		HOST2
    		dependent_service_description	*
    		other dependency directives ...
    		}
    

    In the example above, all services on host HOST2 would be dependent on all services on host HOST1. All the instances of the service dependencies would be identical (i.e. have the same notification failure criteria, etc.).

    Multiple Services On Same Host: If you want to create service dependencies for multiple services assigned to a particular host, you can specify more than one service description in the service_description and/or dependent_service_description directives as follows:

    	define servicedependency{
    		host_name			HOST1
    		service_description		SERVICE1,SERVICE2,...,SERVICEN
    		dependent_host_name		HOST2
    		dependent_service_description	SERVICE1,SERVICE2,...,SERVICEN
    		other dependency directives ...
    		}
    

    All Services In Multiple Servicegroups: If you want to create service dependencies for all services that belong in one or more servicegroups, you can do use the servicegroup_name and/or dependent_servicegroup_name directive as follows:

    	define servicedependency{
    		servicegroup_name		SERVICEGROUP1,SERVICEGROUP2,...,SERVICEGROUPN
    		dependent_servicegroup_name	SERVICEGROUP3,SERVICEGROUP4,...SERVICEGROUPN
    		other escalation directives ...
    		}
    

    Host Escalation Definitions

    Multiple Hosts: If you want to create host escalations for multiple hosts, you can specify multiple hosts in the host_name directive as follows:

    	define hostescalation{
    		host_name		HOST1,HOST2,HOST3,...,HOSTN
    		other escalation directives ...
    		}
    

    The definition above would create a host escalation for hosts HOST1 through HOSTN. All the instances of the host escalation would be identical (i.e. have the same contact groups, notification interval, etc.).

    All Hosts In Multiple Hostgroups: If you want to create host escalations for all hosts in in one or more hostgroups, you can do use the hostgroup_name directive as follows:

    	define hostescalation{
    		hostgroup_name		HOSTGROUP1,HOSTGROUP2,...,HOSTGROUPN
    		other escalation directives ...
    		}
    

    The definition above would create a host escalation on all hosts that are members of hostgroups HOSTGROUP1 through HOSTGROUPN. All the instances of the host escalation would be identical (i.e. have the same contact groups, notification interval, etc.).

    All Hosts: If you want to create identical host escalations for all hosts that are defined in your configuration files, you can use a wildcard in the host_name directive as follows:

    	define hostescalation{
    		host_name		*
    		other escalation directives ...
    		}
    

    The definition above would create a hosts escalation for all hosts that are defined in your configuration files. All the instances of the host escalation would be identical (i.e. have the same contact groups, notification interval, etc.).

    Host Dependency Definitions

    Multiple Hosts: If you want to create host dependencies for multiple hosts, you can specify multiple hosts in the host_name and/or dependent_host_name directives as follows:

    	define hostdependency{
    		host_name		HOST1,HOST2
    		dependent_host_name	HOST3,HOST4,HOST5
    		other dependency directives ...
    		}
    

    The definition above would be equivalent to creating six seperate host dependencies. In the example above, hosts HOST3, HOST4 and HOST5 would be dependent upon both HOST1 and HOST2. All the instances of the host dependencies would be identical except for the host names (i.e. have the same notification failure criteria, etc.).

    All Hosts In Multiple Hostgroups: If you want to create host escalations for all hosts in in one or more hostgroups, you can do use the hostgroup_name and /or dependent_hostgroup_name directives as follows:

    	define hostdependency{
    		hostgroup_name			HOSTGROUP1,HOSTGROUP2
    		dependent_hostgroup_name	HOSTGROUP3,HOSTGROUP4
    		other dependency directives ...
    		}
    

    In the example above, all hosts in hostgroups HOSTGROUP3 and HOSTGROUP4 would be dependent on all hosts in hostgroups HOSTGROUP1 and HOSTGROUP2. All the instances of the host dependencies would be identical except for host names (i.e. have the same notification failure criteria, etc.).

    Hostgroups

    All Hosts: If you want to create a hostgroup that has all hosts that are defined in your configuration files as members, you can use a wildcard in the members directive as follows:

    	define hostgroup{
    		hostgroup_name		HOSTGROUP1
    		members			*
    		other hostgroup directives ...
    		}
    

    The definition above would create a hostgroup called HOSTGROUP1 that has all all hosts that are defined in your configuration files as members.


    nagios-2.6/html/docs/timeperiods.html0000664000076500007650000001654107743356403017327 0ustar nagiosnagios Time Periods

    Time Periods


    or...
    "Is This a Good Time?"


    Introduction

    Time periods allow you to have greater control over when service checks may be run, when host and service notifications may be sent out, and when contacts may receive notifications. With this newly added power come some potential problems, as I will describe later. I was initially very hesitant to introduce time periods because of these snafus. I'll leave it up to you to decide what it right for your particular situation...

    How Time Periods Work With Service Checks

    Without the implementation of time periods, Nagios would monitor all services that you had defined 24 hours a day, 7 days a week. While this is fine for most services that need monitoring, it doesn't work out so well for others. For instance, do you really need to monitor printers all the time when they're really only used during normal business hours? Perhaps you have development servers which you would prefer to have up, but aren't "mission critical" and therefore don't have to be monitored for problems over the weekend. Time period definitions now allow you to have more control over when such services may be checked...

    The <check_period> argument of each service definition allows you to specify a time period that tells Nagios when the service can be checked. When Nagios attempts to reschedule a service check, it will make sure that the next check falls within a valid time range within the defined time period. If it doesn't, Nagios will adjust the next service check time to coincide with the next "valid" time in the specified time period. This means that the service may not get checked again for another hour, day, or week, etc.

    Potential Problems With Service Checks

    If you use time periods which do not cover a 24x7 range, you will run into problems, especially if a service (or its corresponding host) is down when the check is delayed until the next valid time in the time period. Here are some of those problems...

    1. Contacts will not get re-notified of problems with a service until the next service check can be run.
    2. If a service recovers during a time that has been excluded from the check period, contacts will not be notified of the recovery.
    3. The status of the service will appear unchanged (in the status log and CGI) until it can be checked next.
    4. If all services associated with a particular host are on the same check time period, host problems or recoveries will not be recognized until one of the services can be checked (and therefore notifications may be delayed or not get sent out at all).

    Limiting the service check period to anything other than a 24 hour a day, 7 days a week basis can cause a lot of problems. Well, not really problems so much as annoyances and inaccuracies... Unless you have good reason to do so, I would strongly suggest that you set the <check_period> argument of each service definition to a "24x7" type of time period.

    How Time Periods Work With Contact Notifications

    Probably the best use of time periods is to control when notifications can be sent out to contacts. By using the <service_notification_period> and <host_notification_period> arguments in contact definitions, you're able to essentially define an "on call" period for each contact. Note that you can specify different time periods for host and service notifications. This is helpful if you want host notifications to go out to the contact any day of the week, but only have service notifications get sent to the contact on weekdays. It should be noted that these two notification periods should cover any time that the contact can be notified. You can control notification times for specific services and hosts on a one-by-one basis as follows...

    By setting the <notification_period> argument of the host definition, you can control when Nagios is allowed to send notifications out regarding problems or recoveries for that host. When a host notification is about to get sent out, Nagios will make sure that the current time is within a valid range in the <notification_period> time period. If it is a valid time, then Nagios will attempt to notify each contact of the host problem. Some contacts may not receive the host notification if their <host_notification_period> does not allow for host notifications at that time. If the time is not valid within the <notification_period> defined for the host, Nagios will not send the notification out to any contacts.

    You can control notification times for services in a similiar manner to host notification times. By setting the <notification_period> argument of the service definition, you can control when Nagios is allowed to send notifications out regarding problems or recoveries for that service. When a service notification is about to get sent out, Nagios will make sure that the current time is within a valid range in the <notification_period> time period. If it is a valid time, then Nagios will attempt to notify each contact of the service problem. Some contacts may not receive the service notification if their <svc_notification_period> does not allow for service notifications at that time. If the time is not valid within the <notification_period> defined for the service, Nagios will not send the notification out to any contacts.

    Potential Problems With Contact Notifications

    There aren't really any major problems that you'll run into with using time periods to create custom contact notification times. You do, however, need to be aware that contacts may not always be notified of a service or host problem or recovery. If the time isn't right for both the host or service notification period and the contact notification period, the notification won't go through. Once you weigh the potential problems of time-restricted notifications against your needs, you should be able to come up with a configuration that works well for your situation.

    Conclusion

    Time periods allow you to have greater control of how Nagios performs its monitoring and notification functions, but can lead to problems. If you are unsure of what type of time periods to implement, or if you are having problems with your current implementation, I would suggest using "24x7" time periods (where all times are valid for each day of the week). Feel free to contact me if you have questions or are running into problems.


    nagios-2.6/html/docs/toc.html0000664000076500007650000001405710127142120015543 0ustar nagiosnagios Table Of Contents

    Nagios

    Version 2.0 Documentation

    Table of Contents


    About

    Release Notes Support Getting Started Installing Nagios Configuring Nagios Running Nagios Nagios Plugins Nagios Addons
      NRPE - Daemon and plugin for executing plugins on remote hosts
      NSCA - Daemon and client program for sending passive check results across the network
    Theory Of Operation Advanced Topics Integration With Other Software Miscellaneous


    nagios-2.6/html/docs/tuning.html0000664000076500007650000002107607753357050016306 0ustar nagiosnagios Tuning Nagios For Maximum Performance

    Tuning Nagios For Maximum Performance


    Introduction

    So you've finally got Nagios up and running and you want to know how you can tweak it a bit... Here are a few things to look at for optimizing Nagios. Let me know if you think of any others...

    Optimization Tips:

    1. Use aggregated status updates. Enabling aggregated status updates (with the aggregate_status_updates option) will greatly reduce the load on your monitoring host because it won't be constantly trying to update the status log. This is especially recommended if you are monitoring a large number of services. The main trade-off with using aggregated status updates is that changes in the states of hosts and services will not be reflected immediately in the status file. This may or may not be a big concern for you.

    2. Use a ramdisk for holding status data. If you're using the standard status log and you're not using aggregated status updates, consider putting the directory where the status log is stored on a ramdisk. This will speed things up quite a bit (in both the core program and the CGIs) because it saves a lot of interrupts and disk thrashing.

    3. Check service latencies to determine best value for maximum concurrent checks. Nagios can restrict the number of maximum concurrently executing service checks to the value you specify with the max_concurrent_checks option. This is good because it gives you some control over how much load Nagios will impose on your monitoring host, but it can also slow things down. If you are seeing high latency values (> 10 or 15 seconds) for the majority of your service checks (via the extinfo CGI), you are probably starving Nagios of the checks it needs. That's not Nagios's fault - its yours. Under ideal conditions, all service checks would have a latency of 0, meaning they were executed at the exact time that they were scheduled to be executed. However, it is normal for some checks to have small latency values. I would recommend taking the minimum number of maximum concurrent checks reported when running Nagios with the -s command line argument and doubling it. Keep increasing it until the average check latency for your services is fairly low. More information on service check scheduling can be found here.

    4. Use passive checks when possible. The overhead needed to process the results of passive service checks is much lower than that of "normal" active checks, so make use of that piece of info if you're monitoring a slew of services. It should be noted that passive service checks are only really useful if you have some external application doing some type of monitoring or reporting, so if you're having Nagios do all the work, this won't help things.

    5. Avoid using interpreted plugins. One thing that will significantly reduce the load on your monitoring host is the use of compiled (C/C++, etc.) plugins rather than interpreted script (Perl, etc) plugins. While Perl scripts and such are easy to write and work well, the fact that they are compiled/interpreted at every execution instance can significantly increase the load on your monitoring host if you have a lot of service checks. If you want to use Perl plugins, consider compiling them into true executables using perlcc(1) (a utility which is part of the standard Perl distribution) or compiling Nagios with an embedded Perl interpreter (see below).

    6. Use the embedded Perl interpreter. If you're using a lot of Perl scripts for service checks, etc., you will probably find that compiling an embedded Perl interpreter into the Nagios binary will speed things up. In order to compile in the embedded Perl interpreter, you'll need to supply the --enable-embedded-perl option to the configure script before you compile Nagios. Also, if you use the --with-perlcache option, the compiled version of all Perl scripts processed by the embedded interpreter will be cached for later reuse.

    7. Optimize host check commands. If you're checking host states using the check_ping plugin you'll find that host checks will be performed much faster if you break up the checks. Instead of specifying a max_attempts value of 1 in the host definition and having the check_ping plugin send 10 ICMP packets to the host, it would be much faster to set the max_attempts value to 10 and only send out 1 ICMP packet each time. This is due to the fact that Nagios can often determine the status of a host after executing the plugin once, so you want to make the first check as fast as possible. This method does have its pitfalls in some situations (i.e. hosts that are slow to respond may be assumed to be down), but I you'll see faster host checks if you use it. Another option would be to use a faster plugin (i.e. check_fping) as the host_check_command instead of check_ping.

    8. Don't schedule regular host checks. Do NOT schedule regular checks of hosts unless absolutely necessary. There are not many reasons to do this, as host checks are performed on-demand as needed. To disable regular checks of a host, set the check_interval directive in the host definition to 0. If you do need to have regularly scheduled host checks, try to use a longer check interval and make sure your host checks are optimized (see above).

    9. Don't use agressive host checking. Unless you're having problems with Nagios recognizing host recoveries, I would recommend not enabling the use_aggressive_host_checking option. With this option turned off host checks will execute much faster, resulting in speedier processing of service check results. However, host recoveries can be missed under certain circumstances when this it turned off. For example, if a host recovers and all of the services associated with that host stay in non-OK states (and don't "wobble" between different non-OK states), Nagios may miss the fact that the host has recovered. A few people may need to enable this option, but the majority don't and I would recommend not using it unless you find it necessary...

    10. Increase external command check interval. If you're processing a lot of external commands (i.e. passive checks in a distributed setup, you'll probably want to set the command_check_interval variable to -1. This will cause Nagios to check for external commands as often as possible. This is important because most systems have small pipe buffer sizes (i.e. 4KB). If Nagios doesn't read the data from the pipe fast enough, applications that write to the external command file (i.e. the NSCA daemon) will block and wait until there is enough free space in the pipe to write their data.

    11. Optimize hardware for maximum performance. Your system configuration and your hardware setup are going to directly affect how your operating system performs, so they'll affect how Nagios performs. The most common hardware optimization you can make is with your hard drives. CPU and memory speed are obviously factors that affect performance, but disk access is going to be your biggest bottlenck. Don't store plugins, the status log, etc on slow drives (i.e. old IDE drives or NFS mounts). If you've got them, use UltraSCSI drives or fast IDE drives. An important note for IDE/Linux users is that many Linux installations do not attempt to optimize disk access. If you don't change the disk access parameters (by using a utility like hdparam), you'll loose out on a lot of the speedy features of the new IDE drives.


    nagios-2.6/html/docs/verifyconfig.html0000664000076500007650000000752207743356403017474 0ustar nagiosnagios Verifying Your Nagios Configuration

    Verifying Your Nagios Configuration


    Verifying The Configuration From The Command Line

    Once you've entered all the necessary data into the configuration files, its time to do a sanity check. Everyone make mistakes from time to time, so its best to verify what you've entered. Nagios automatically runs a "pre-flight check" before before it starts monitoring, but you also have the option of running this check manually before attempting to start Nagios. In order to do this, you must start Nagios with the -v command line argument as follows...

    /usr/local/nagios/bin/nagios -v <main_config_file>

    Note that you should be entering the path/filename of your main configuration file (i.e. /usr/local/nagios/etc/nagios.cfg) as the second argument. Nagios will read your main configuration file and all object configuration files and verify that they contain valid data.

    Relationships Verified During The Pre-Flight Check

    During the "pre-flight check", Nagios verifies that you have defined the data relationships necessary for monitoring. Objects are all related and need to be setup properly in order for things to run. This is a list of the basic things that Nagios attempts to check before it will start monitoring...

    1. Verify that all contacts are a member of at least one contact group.
    2. Verify that all contacts specified in each contact group are valid.
    3. Verify that all hosts are a member of at least one host group.
    4. Verify that all hosts specified in each host group are valid.
    5. Verify that all hosts have at least one service associated with them.
    6. Verify that all commands used in service and host checks are valid.
    7. Verify that all commands used in service and host event handlers are valid.
    8. Verify that all commands used in contact service and host notifications are valid.
    9. Verify that all notification time periods specified for services, hosts, and contact are valid.
    10. Verify that all service check time periods specified for services are valid.

    Fixing Configuration Errors

    If you've forgotten to enter some critical data or just plain screwed things up, Nagios will spit out a warning or error message that should point you to the location of the problem. Error messages generally print out the line in the configuration file that seems to be the source of the problem. On errors, Nagios will often exit the pre-flight check and return to the command prompt after printing only the first error that it has encountered. This is done so that one error does not cascade into multiple errors as the remainder of the configuration data is verified. If you get any error messages you'll need to go and edit your configuration files to remedy the problem. Warning messages can generally be safely ignored, since they are only recommendations and not requirements.

    Where To Go From Here

    Once you've verified your configuration files and fixed any errors, you can be reasonably sure that Nagios will start monitoring the services you've specified. On to starting Nagios!


    nagios-2.6/html/docs/volatileservices.html0000664000076500007650000001327410350046567020361 0ustar nagiosnagios Volatile Services

    Volatile Services


    Introduction

    Nagios has the ability to distinguish between "normal" services and "volatile" services. The is_volatile option in each service definition allows you to specify whether a specific service is volatile or not. For most people, the majority of all monitored services will be non-volatile (i.e. "normal"). However, volatile services can be very useful when used properly...

    What Are They Useful For?

    Volatile services are useful for monitoring...

    • things that automatically reset themselves to an "OK" state each time they are checked
    • events such as security alerts which require attention every time there is a problem (and not just the first time)

    What's So Special About Volatile Services?

    Volatile services differ from "normal" services in three important ways. Each time they are checked when they are in a hard non-OK state, and the check returns a non-OK state (i.e. no state change has occurred)...

    • the non-OK service state is logged
    • contacts are notified about the problem (if that's what should be done)
    • the event handler for the service is run (if one has been defined)

    These events normally only occur for services when they are in a non-OK state and a hard state change has just occurred. In other words, they only happen the first time that a service goes into a non-OK state. If future checks of the service result in the same non-OK state, no hard state change occurs and none of the events mentioned take place again.

    The Power Of Two

    If you combine the features of volatile services and passive service checks, you can do some very useful things. Examples of this include handling SNMP traps, security alerts, etc.

    How about an example... Let's say you're running PortSentry to detect port scans on your machine and automatically firewall potential intruders. If you want to let Nagios know about port scans, you could do the following..

    In Nagios:

    • Configure a service called Port Scans and associate it with the host that PortSentry is running on.
    • Set the max_check_attempts option in the service definition to 1. This will tell Nagios to immediate force the service into a hard state when a non-OK state is reported.
    • Either set the active_checks_enabled option to 0 or set the check_time option in the service definition to a timeperiod that contains no valid time ranges. Doing either of these will prevent Nagios from ever actively checking the service. Even though the service check will get scheduled, it will never actually be checked.

    In PortSentry:

    • Edit your PortSentry configuration file (portsentry.conf), define a command for the KILL_RUN_CMD directive as follows:

      KILL_RUN_CMD="/usr/local/Nagios/libexec/eventhandlers/submit_check_result <host_name> 'Port Scans' 2 'Port scan from host $TARGET$ on port $PORT$. Host has been firewalled.'"

      Make sure to replace <host_name> with the short name of the host that the service is associated with.

    Create a shell script in the /usr/local/nagios/libexec/eventhandlers directory named submit_check_result. The contents of the shell script should be something similiar to the following...

    	#!/bin/sh
     
    	# Write a command to the Nagios command file to cause
    	# it to process a service check result
     
    	echocmd="/bin/echo"
     
    	CommandFile="/usr/local/nagios/var/rw/nagios.cmd"
     
    	# get the current date/time in seconds since UNIX epoch
    	datetime=`date +%s`
     
    	# create the command line to add to the command file
    	cmdline="[$datetime] PROCESS_SERVICE_CHECK_RESULT;$1;$2;$3;$4"
     
    	# append the command to the end of the command file
    	`$echocmd $cmdline >> $CommandFile`
    

    Note that if you are running PortSentry as root, you will have to make additions to the script to reset file ownership and permissions so that Nagios and the CGIs can read/modify the command file. Details on permissions/ownership of the command file can be found here.

    So what happens when PortSentry detects a port scan on the machine?

    • It blocks the host (this is a function of the PortSentry software)
    • It executes the submit_check_result shell script to send the security alert info to Nagios
    • Nagios reads the command file, recognized the port scan entry as a passive service check
    • Nagios processes the results of the service by logging the CRITICAL state, sending notifications to contacts (if configured to do so), and executes the event handler for the Port Scans service (if one is defined)


    nagios-2.6/html/docs/whatsnew.html0000664000076500007650000003565710356775135016655 0ustar nagiosnagios What's New

    What's New in Version 2.0


    Important: Make sure you read through the documentation (especially the FAQs) before sending a question to the mailing lists.

    Change Log

    The change log for Nagios can be found online at http://www.nagios.org/changelog.php or in the Changelog file in the root directory of the source code distribution.

    Known Issues

    There is a known issue that can affect Nagios 2.0 on FreeBSD systems. Hopefully this problem can be fixed in a 2.x release...

    1. FreeBSD and threads. On FreeBSD there's a native user-level implementation of threads called 'pthread' and there's also an optional ports collection 'linuxthreads' that uses kernel hooks. Some folks from Yahoo! have reported that using the pthread library causes Nagios to pause under heavy I/O load, causing some service check results to be lost. Switching to linuxthreads seems to help this problem, but not fix it. The lock happens in liblthread's __pthread_acquire() - it can't ever acquire the spinlock. It happens when the main thread forks to execute an active check. On the second fork to create the grandchild, the grandchild is created by fork, but never returns from liblthread's fork wrapper, because it's stuck in __pthread_acquire(). Maybe some FreeBSD users can help out with this problem.

    Changes and New Features

    1. Macro Changes - Macros have undergone a major overhaul. You will have to update most of your command definitions to match the new macros. Most macros are now available as environment variables. Also, "on-demand" host and service macros have been added. See the documentation on macros for more information.

    2. Hostgroup Changes
      • Hostgroup escalations removed - Hostgroup escalations have been removed. Their functionality can be duplicated by using the hostgroup_name directive in hostgroup definitions.
      • Member directive changes - Hostgroup definitions can now contain multiple members directives, which should make editing the config files easier when you have a lot of member hosts. Alternatively, you may use the hostgroups directive in host definitions to specify what hostgroup(s) a particular host is a member of.
      • Contact group changes - The contact_groups directive has been moved from hostgroup definitions to host definitions. This was done in order to maintain consistency with the way service contacts are specified. Make sure to update your config files!
      • Authorization changes - Authorization for access to hostgroups in the CGIs has been changed. You must now be authorized for all hosts that are members of the hostgroup in order to be authorized for the hostgroup.

    3. Host Changes
      • Host freshness checking - Freshness checking has been added for host checks. This is controlled by the check_host_freshness option, along with the check_freshness directive in host definitions.
      • OCHP Command - Host checks can now be obsessed over, just as services can be. The OCHP command is run for all hosts that have the obsess_over_host directive enabled in their host definition.

    4. Host Check Changes
      • Regularly scheduled checks - You can now schedule regular checks of hosts by using the check_interval directive in host definitions. NOTE: Listen up! You should use regularly scheduled host checks rather sparingly. They are not necessary for normal operation (on-demand checks are already performed when necessary) and can negatively affect performance if used improperly. You've been warned.
      • Passive host checks - Passive host checks are now supported if you've enabled them with the accept_passive_host_checks option in the main config file and the accept_passive_host_checks directive in the host definition. Passive host checks can make setting up redundant or distributed monitoring environments easier. NOTE: There are some problems with passive host checks that you should be aware of - read more about them here.

    5. Retention Changes
      • Retention of scheduling information - Host and service check scheduling information (next check times) can now be retained across program restarts using the use_retained_scheduling_info directive.
      • Smarter retention - Values of various host and service directives that can be retained across program restarts are now only retained if they are changed during runtime by an external command. This should make things less confusing to people when they try and modify host and service directive values and then restart Nagios, expecting to see some changes.
      • More stuff retained - More information is now retained across program restarts, including flap detection history. Hoorah!

    6. Extended Info Changes
      • New location - Extended host info and service info definitions are now stored in object config files along with host definitions, etc. As a result, extended info definitions are now parsed and validated by the Nagios daemon before startup.
      • New directives - Extended host info and service info definitions now have two new directives: notes and action_url.

    7. Embedded Perl Changes
      • p1.pl location - You can now specify the location of the embedded Perl "helper" file (p1.pl) using the p1_file directive.

    8. Notification Changes
      • Flapping notifications - Notifications are now sent out when flapping starts and stops for hosts and services. This feature can be controlled using the f option in the notification_options for contacts, hosts and services.
      • Better logic - Notification logic has been improved a bit. This should prevent recovery notifications getting sent out when no problem notification was sent out to begin with.
      • Service notifications - Before service notifications are sent out, notification dependencies for the host are now checked. If host notifications are not deemed to be viable, notifications for the service will not be sent out either.
      • Escalation options - Time period and state options have been added to host and service escalations. This gives you more control in determining when escalations can be used. More information on escalations can be found here.

    9. Service Groups Added - Service groups have now been added. They allow you to group services together for display purposes in the CGIs and can be referenced in service dependency and service escalation definitions to make configuration a bit easier.

    10. Triggered Downtime Added - Support for what's called "triggered" downtime has been added for host and service downtime. Triggered downtime allows you to define downtime that should start at the same time another downtime starts (very useful for scheduling downtime for child hosts when the parent host is scheduled for flexible downtime). More information on triggered downtime can be found here.

    11. New Stats Utility - A new utility called 'nagiostats' is now included in the Nagios distribution. Its a command-line utility that allows you to view current statistics for a running Nagios process. It can also produce data compatible with MRTG, so you can graph statistical information. More information on how to use the utility can be found here.

    12. Adaptive Monitoring - You can now change certain attributes relating to host and service checks (check command, check interval, max check attempts etc.) during runtime by submitting the appropriate external commands. This kind of adaptive monitoring will probably not be of much use to the majority of users out there, but it does provide a way for doing some neat stuff. More information on adaptive monitoring can be found here.

    13. Performance Data Changes - The methods for processing performance data have changed slightly. You can now process performance data by executing external commands and/or writing to files without recompiling Nagios. Read the documentation on performance data for more information.

    14. Native DB Support Dropped - Native support for storing various types of data (status, retention, comment, downtime, etc.) in MySQL and PostgreSQL has been dropped. Stop whining. I expect someone will develop an alternative using the new event broker sometime in the near future. Besides, DB support was not well implemented and dropping native DB support will make things easier for newbies to understand (one less thing to figure out).

    15. Event Broker API - An API has been created to allow individual developers to create addons that integrate with the core Nagios daemon. Documentation on the event broker API will be created as the 2.x code matures and will be available on the Nagios website.

    16. Misc Changes
      • All commands can contain arguments - All command types (host checks, notifications, performance data processors, event handlers, etc.) can contain arguments (seperated from the command name by ! characters). Arguments are substituted in the command line using $ARGx macros.
      • Config directory recursion - Nagios now recursively processes all config files found in subdirectories of the directories specified by the cfg_dir directive.
      • Old config file support dropped - Support for older (non-template) style object and extended info config files has been dropped.
      • Faster searches - Objects are now stored in a chained hash in order to speed searches. This should greatly improve the performance of the CGIs.
      • Worker threads - A few worker threads have been added in order to artificially buffer data for the external command file and the internal pipe used to process service check results. This should substantially increase performance in larger setups.
      • Logging changes - Initial host and service states are now logged a bit differently. Also, the initial states of all hosts and services are logged immediately after all log rotations. This should help with all those "undetermined time" problems in the availability and trends CGIs.
      • Cached object config file - An object cache file is now created by Nagios at startup. It should help speed up the CGIs a bit and allow you to edit you object config files while Nagios is running without affecting the CGI output.
      • Initial check limits - You can now specify timeframes in which the initial checks of all hosts and services should be performed after Nagios start. These timeframes are controlled by the max_host_check_spread and max_service_check_spread variables.
      • "Sticky" acknowledgements - You can now designate host and service acknowledgements as being "sticky" or not. Sticky acknowledgements suppress notifications until a host or service fully recovers to an UP or OK state. Non-sticky acknowledgements only suppress notifications until a host or service changes state.
      • Changed in checking clusters - The way you monitor service and host "clusters" has now changed and is more reliable than before. This is due to the incorporation of on-demand macros and a new plugin (check_cluster2). Read more about checking clusters here.
      • Regular expression matching - Regular expression matching of various object directives can be enabled using the use_regexp_matching and use_true_regexp_matching variables. Information on how and where regular expression matching can be used can be found in the template tips and tricks documentation.
      • Service pseudo-states - Support for some redundant service pseudo-states have been removed from the status CGI. This will affect any hardcoded URLs which use the servicestatustypes=X parameter for the CGI. Check include/statusdata.h for the new list of service states that you can use.
      • Freshness check changes - The freshness check logic has been changed slightly. Freshness checks will not occur if the current time is not valid for the host or service check_timeperiod. Also, freshness checks will no longer occur if both the host or service check_interval and freshness_threshold variables are set to zero (0).


    nagios-2.6/html/docs/xodtemplate.html0000664000076500007650000027425210532717361017330 0ustar nagiosnagios Template-Based Object Configuration

    Template-Based Object Configuration


    Notes

    When creating and/or editing configuration files, keep the following in mind:

    1. Lines that start with a '#' character are taken to be comments and are not processed
    2. Directive names are case-sensitive

    Introduction

    One of the benefits of using the template-based config file format is that you can create object definitions that have some of their properties inherited from other object definitions. The notion of object inheritence, along with documentation on how to do it, is described here. I strongly suggest that you familiarize yourself with object inheritence once you read over the documentation presented below, as inheritence will make the job of creating and maintaining object definitions much easier than it otherwise would be.

    Time-Saving Tricks

    There are several things you can do with template-based object definitions that allow you to create large numbers of objects using just a small number of definitions in your config file(s). One example of such a trick is the ability to define a single service object that creates a service for multiple hosts and/or hostgroups. These tricks are described here.

    Retention Notes

    It is important to point out that several directives in host and service definitions may not be picked up by Nagios when you change them. Host and service directives that can exhibit this behavior are marked with an asterisk (*). The reason for this behavior is due to the fact that Nagios chooses to honor values stored in the state retention file over values found in the config files, assuming you have state retention enabled on a program-wide basis and the value of the directive is changed during runtime (by submitting an external command).

    One way to get around this problem is to disable the retention of non-status information using the retain_nonstatus_information directive in the host and service definitions. Disabling this directive will cause Nagios to take the initial values for these directives from your config files, rather than from the state retention file when it (re)starts. Using this option is not recommended, as it may result in some unexpected (from your point of view) results.

    Alternatively, you can issue the appropriate external command or change the value of the host or service directive via the web interface, so that it matches what you've changed it to in the config files. This is usually done by using the extended information CGI. This option takes a bit more work, but is preferable to disabling the retention of non-status information (mentioned above).

    Sample Configuration

    A few sample object configuration files are created when you run the configure script - you can find them in the sample-config/template-object/ subdirectory of the Nagios distribution.

    Object Types

    Host definitions
    Host group definitions
    Service definitions
    Service group definitions
    Contact definitions
    Contact group definitions
    Time period definitions
    Command definitions
    Service dependency definitions
    Service escalation definitions
    Host dependency definitions
    Host escalation definitions
    Extended host information definitions
    Extended service information definitions

    Host Definition

    Description:

    A host definition is used to define a physical server, workstation, device, etc. that resides on your network.

    Definition Format:

    Note: Directives in red are required, while those in black are optional.

    define host{
    host_namehost_name
    aliasalias
    addressaddress
    parentshost_names
    hostgroupshostgroup_names
    check_commandcommand_name
    max_check_attempts#
    check_interval#
    active_checks_enabled[0/1]
    passive_checks_enabled[0/1]
    check_periodtimeperiod_name
    obsess_over_host[0/1]
    check_freshness[0/1]
    freshness_threshold#
    event_handlercommand_name
    event_handler_enabled[0/1]
    low_flap_threshold#
    high_flap_threshold#
    flap_detection_enabled[0/1]
    process_perf_data[0/1]
    retain_status_information[0/1]
    retain_nonstatus_information[0/1]
    contact_groupscontact_groups
    notification_interval#
    notification_periodtimeperiod_name
    notification_options[d,u,r,f]
    notifications_enabled[0/1]
    stalking_options[o,d,u]
       }

    Example Definition:

    define host{
    	host_name			bogus-router
    	alias				Bogus Router #1
    	address				192.168.1.254
    	parents				server-backbone
    	check_command			check-host-alive
    	max_check_attempts		5
    	check_period			24x7
    	process_perf_data		0
    	retain_nonstatus_information	0
    	contact_groups			router-admins
    	notification_interval		30
    	notification_period		24x7
    	notification_options		d,u,r
    	}
    

    Directive Descriptions:

    host_name: This directive is used to define a short name used to identify the host. It is used in host group and service definitions to reference this particular host. Hosts can have multiple services (which are monitored) associated with them. When used properly, the $HOSTNAME$ macro will contain this short name.
    alias: This directive is used to define a longer name or description used to identify the host. It is provided in order to allow you to more easily identify a particular host. When used properly, the $HOSTALIAS$ macro will contain this alias/description.
    address: This directive is used to define the address of the host. Normally, this is an IP address, although it could really be anything you want (so long as it can be used to check the status of the host). You can use a FQDN to identify the host instead of an IP address, but if DNS services are not availble this could cause problems. When used properly, the $HOSTADDRESS$ macro will contain this address. Note: If you do not specify an address directive in a host definition, the name of the host will be used as its address. A word of caution about doing this, however - if DNS fails, most of your service checks will fail because the plugins will be unable to resolve the host name.
    parents: This directive is used to define a comma-delimited list of short names of the "parent" hosts for this particular host. Parent hosts are typically routers, switches, firewalls, etc. that lie between the monitoring host and a remote hosts. A router, switch, etc. which is closest to the remote host is considered to be that host's "parent". Read the "Determining Status and Reachability of Network Hosts" document located here for more information. If this host is on the same network segment as the host doing the monitoring (without any intermediate routers, etc.) the host is considered to be on the local network and will not have a parent host. Leave this value blank if the host does not have a parent host (i.e. it is on the same segment as the Nagios host). The order in which you specify parent hosts has no effect on how things are monitored.
    hostgroups: This directive is used to identify the short name(s) of the hostgroup(s) that the host belongs to. Multiple hostgroups should are seperated by commas. This directive may be used as an alternative to (or in addition to) using the members directive in hostgroup definitions.
    check_command: This directive is used to specify the short name of the command that should be used to check if the host is up or down. Typically, this command would try and ping the host to see if it is "alive". The command must return a status of OK (0) or Nagios will assume the host is down. If you leave this argument blank, the host will not be checked - Nagios will always assume the host is up. This is useful if you are monitoring printers or other devices that are frequently turned off. The maximum amount of time that the notification command can run is controlled by the host_check_timeout option.
    max_check_attempts: This directive is used to define the number of times that Nagios will retry the host check command if it returns any state other than an OK state. Setting this value to 1 will cause Nagios to generate an alert without retrying the host check again. Note: If you do not want to check the status of the host, you must still set this to a minimum value of 1. To bypass the host check, just leave the check_command option blank.
    check_interval: NOTE: Do NOT enable regularly scheduled checks of a host unless you absolutely need to! Host checks are already performed on-demand when necessary, so there are few times when regularly scheduled checks would be needed. Regularly scheduled host checks can negatively impact performance - see the performance tuning tips for more information. This directive is used to define the number of "time units" between regularly scheduled checks of the host. Unless you've changed the interval_length directive from the default value of 60, this number will mean minutes. More information on this value can be found in the check scheduling documentation.
    active_checks_enabled *: This directive is used to determine whether or not active checks (either regularly scheduled or on-demand) of this host are enabled. Values: 0 = disable active host checks, 1 = enable active host checks.
    passive_checks_enabled *: This directive is used to determine whether or not passive checks are enabled for this host. Values: 0 = disable passive host checks, 1 = enable passive host checks.
    check_period: This directive is used to specify the short name of the time period during which active checks of this host can be made.
    obsess_over_host *: This directive determines whether or not checks for the host will be "obsessed" over using the ochp_command.
    check_freshness *: This directive is used to determine whether or not freshness checks are enabled for this host. Values: 0 = disable freshness checks, 1 = enable freshness checks.
    freshness_threshold: This directive is used to specify the freshness threshold (in seconds) for this host. If you set this directive to a value of 0, Nagios will determine a freshness threshold to use automatically.
    event_handler: This directive is used to specify the short name of the command that should be run whenever a change in the state of the host is detected (i.e. whenever it goes down or recovers). Read the documentation on event handlers for a more detailed explanation of how to write scripts for handling events. The maximum amount of time that the event handler command can run is controlled by the event_handler_timeout option.
    event_handler_enabled *: This directive is used to determine whether or not the event handler for this host is enabled. Values: 0 = disable host event handler, 1 = enable host event handler.
    low_flap_threshold: This directive is used to specify the low state change threshold used in flap detection for this host. More information on flap detection can be found here. If you set this directive to a value of 0, the program-wide value specified by the low_host_flap_threshold directive will be used.
    high_flap_threshold: This directive is used to specify the high state change threshold used in flap detection for this host. More information on flap detection can be found here. If you set this directive to a value of 0, the program-wide value specified by the high_host_flap_threshold directive will be used.
    flap_detection_enabled *: This directive is used to determine whether or not flap detection is enabled for this host. More information on flap detection can be found here. Values: 0 = disable host flap detection, 1 = enable host flap detection.
    process_perf_data *: This directive is used to determine whether or not the processing of performance data is enabled for this host. Values: 0 = disable performance data processing, 1 = enable performance data processing.
    retain_status_information: This directive is used to determine whether or not status-related information about the host is retained across program restarts. This is only useful if you have enabled state retention using the retain_state_information directive. Value: 0 = disable status information retention, 1 = enable status information retention.
    retain_nonstatus_information: This directive is used to determine whether or not non-status information about the host is retained across program restarts. This is only useful if you have enabled state retention using the retain_state_information directive. Value: 0 = disable non-status information retention, 1 = enable non-status information retention.
    contact_groups: This is a list of the short names of the contact groups that should be notified whenever there are problems (or recoveries) with this host. Multiple contact groups should be separated by commas.
    notification_interval: This directive is used to define the number of "time units" to wait before re-notifying a contact that this server is still down or unreachable. Unless you've changed the interval_length directive from the default value of 60, this number will mean minutes. If you set this value to 0, Nagios will not re-notify contacts about problems for this host - only one problem notification will be sent out.
    notification_period: This directive is used to specify the short name of the time period during which notifications of events for this host can be sent out to contacts. If a host goes down, becomes unreachable, or recoveries during a time which is not covered by the time period, no notifications will be sent out.
    notification_options: This directive is used to determine when notifications for the host should be sent out. Valid options are a combination of one or more of the following: d = send notifications on a DOWN state, u = send notifications on an UNREACHABLE state, r = send notifications on recoveries (OK state), and f = send notifications when the host starts and stops flapping. If you specify n (none) as an option, no host notifications will be sent out. Example: If you specify d,r in this field, notifications will only be sent out when the host goes DOWN and when it recovers from a DOWN state.
    notifications_enabled *: This directive is used to determine whether or not notifications for this host are enabled. Values: 0 = disable host notifications, 1 = enable host notifications.
    stalking_options: This directive determines which host states "stalking" is enabled for. Valid options are a combination of one or more of the following: o = stalk on UP states, d = stalk on DOWN states, and u = stalk on UNREACHABLE states. More information on state stalking can be found here.

    Host Group Definition

    Description:

    A host group definition is used to group one or more hosts together for display purposes in the CGIs.

    Definition Format:

    Note: Directives in red are required, while those in black are optional.

    define hostgroup{
    hostgroup_namehostgroup_name
    aliasalias
    membersmembers
       }

    Example Definition:

    define hostgroup{
    	hostgroup_name		novell-servers
    	alias			Novell Servers
    	members			netware1,netware2,netware3,netware4
    	}
    

    Directive Descriptions:

    hostgroup_name: This directive is used to define a short name used to identify the host group.
    alias: This directive is used to define is a longer name or description used to identify the host group. It is provided in order to allow you to more easily identify a particular host group.
    members: This is a list of the short names of hosts that should be included in this group. Multiple host names should be separated by commas. This directive may be used as an alternative to (or in addition to) the hostgroups directive in host definitions.

    Service Definition

    Description:

    A service definition is used to identify a "service" that runs on a host. The term "service" is used very loosely. It can mean an actual service that runs on the host (POP, SMTP, HTTP, etc.) or some other type of metric associated with the host (response to a ping, number of logged in users, free disk space, etc.). The different arguments to a service definition are outlined below.

    Definition Format:

    Note: Directives in red are required, while those in black are optional.

    define service{
    host_namehost_name
    service_descriptionservice_description
    servicegroupsservicegroup_names
    is_volatile[0/1]
    check_commandcommand_name
    max_check_attempts#
    normal_check_interval#
    retry_check_interval#
    active_checks_enabled[0/1]
    passive_checks_enabled[0/1]
    check_periodtimeperiod_name
    parallelize_check[0/1]
    obsess_over_service[0/1]
    check_freshness[0/1]
    freshness_threshold#
    event_handlercommand_name
    event_handler_enabled[0/1]
    low_flap_threshold#
    high_flap_threshold#
    flap_detection_enabled[0/1]
    process_perf_data[0/1]
    retain_status_information[0/1]
    retain_nonstatus_information[0/1]
    notification_interval#
    notification_periodtimeperiod_name
    notification_options[w,u,c,r,f]
    notifications_enabled[0/1]
    contact_groupscontact_groups
    stalking_options[o,w,u,c]
       }

    Example Definition:

    define service{
    	host_name		linux-server
    	service_description	check-disk-sda1
    	check_command		check-disk!/dev/sda1
    	max_check_attempts	5
    	normal_check_interval	5
    	retry_check_interval	3
    	check_period		24x7
    	notification_interval	30
    	notification_period	24x7
    	notification_options	w,c,r
    	contact_groups		linux-admins
    	}
    

    Directive Descriptions:

    host_name: This directive is used to specify the short name of the host that the service "runs" on or is associated with.
    service_description;: This directive is used to define the description of the service, which may contain spaces, dashes, and colons (semicolons, apostrophes, and quotation marks should be avoided). No two services associated with the same host can have the same description. Services are uniquely identified with their host_name and service_description directives.
    servicegroups: This directive is used to identify the short name(s) of the servicegroup(s) that the service belongs to. Multiple servicegroups should are seperated by commas. This directive may be used as an alternative to using the members directive in servicegroup definitions.
    is_volatile: This directive is used to denote whether the service is "volatile". Services are normally not volatile. More information on volatile service and how they differ from normal services can be found here. Value: 0 = service is not volatile, 1 = service is volatile.
    check_command:

    This directive is used to specify the short name of the command that Nagios will run in order to check the status of the service. The maximum amount of time that the service check command can run is controlled by the service_check_timeout option.

    max_check_attempts: This directive is used to define the number of times that Nagios will retry the service check command if it returns any state other than an OK state. Setting this value to 1 will cause Nagios to generate an alert without retrying the service check again.
    normal_check_interval: This directive is used to define the number of "time units" to wait before scheduling the next "regular" check of the service. "Regular" checks are those that occur when the service is in an OK state or when the service is in a non-OK state, but has already been rechecked max_attempts number of times. Unless you've changed the interval_length directive from the default value of 60, this number will mean minutes. More information on this value can be found in the check scheduling documentation.
    retry_check_interval: This directive is used to define the number of "time units" to wait before scheduling a re-check of the service. Services are rescheduled at the retry interval when the have changed to a non-OK state. Once the service has been retried max_attempts times without a change in its status, it will revert to being scheduled at its "normal" rate as defined by the check_interval value. Unless you've changed the interval_length directive from the default value of 60, this number will mean minutes. More information on this value can be found in the check scheduling documentation.
    active_checks_enabled *: This directive is used to determine whether or not active checks of this service are enabled. Values: 0 = disable active service checks, 1 = enable active service checks.
    passive_checks_enabled *: This directive is used to determine whether or not passive checks of this service are enabled. Values: 0 = disable passive service checks, 1 = enable passive service checks.
    check_period: This directive is used to specify the short name of the time period during which active checks of this service can be made.
    parallelize_check: This directive is used to determine whether or not the service check can be parallelized. By default, all service checks are parallelized. Disabling parallel checks of services can result in serious performance problems. More information on service check parallelization can be found here. Values: 0 = service check cannot be parallelized (use with caution!), 1 = service check can be parallelized.
    obsess_over_service *: This directive determines whether or not checks for the service will be "obsessed" over using the ocsp_command.
    check_freshness *: This directive is used to determine whether or not freshness checks are enabled for this service. Values: 0 = disable freshness checks, 1 = enable freshness checks.
    freshness_threshold: This directive is used to specify the freshness threshold (in seconds) for this service. If you set this directive to a value of 0, Nagios will determine a freshness threshold to use automatically.
    event_handler_enabled: This directive is used to determine whether or not the event handler for this service is enabled. Values: 0 = disable service event handler, 1 = enable service event handler.
    low_flap_threshold: This directive is used to specify the low state change threshold used in flap detection for this service. More information on flap detection can be found here. If you set this directive to a value of 0, the program-wide value specified by the low_service_flap_threshold directive will be used.
    high_flap_threshold: This directive is used to specify the high state change threshold used in flap detection for this service. More information on flap detection can be found here. If you set this directive to a value of 0, the program-wide value specified by the high_service_flap_threshold directive will be used.
    flap_detection_enabled *: This directive is used to determine whether or not flap detection is enabled for this service. More information on flap detection can be found here. Values: 0 = disable service flap detection, 1 = enable service flap detection.
    process_perf_data *: This directive is used to determine whether or not the processing of performance data is enabled for this service. Values: 0 = disable performance data processing, 1 = enable performance data processing.
    retain_status_information: This directive is used to determine whether or not status-related information about the service is retained across program restarts. This is only useful if you have enabled state retention using the retain_state_information directive. Value: 0 = disable status information retention, 1 = enable status information retention.
    retain_nonstatus_information: This directive is used to determine whether or not non-status information about the service is retained across program restarts. This is only useful if you have enabled state retention using the retain_state_information directive. Value: 0 = disable non-status information retention, 1 = enable non-status information retention.
    notification_interval: This directive is used to define the number of "time units" to wait before re-notifying a contact that this service is still in a non-OK state. Unless you've changed the interval_length directive from the default value of 60, this number will mean minutes. If you set this value to 0, Nagios will not re-notify contacts about problems for this service - only one problem notification will be sent out.
    notification_period: This directive is used to specify the short name of the time period during which notifications of events for this service can be sent out to contacts. No service notifications will be sent out during times which is not covered by the time period.
    notification_options: This directive is used to determine when notifications for the service should be sent out. Valid options are a combination of one or more of the following: w = send notifications on a WARNING state, u = send notifications on an UNKNOWN state, c = send notifications on a CRITICAL state, r = send notifications on recoveries (OK state), and f = send notifications when the service starts and stops flapping. If you specify n (none) as an option, no service notifications will be sent out. Example: If you specify w,r in this field, notifications will only be sent out when the service goes into a WARNING state and when it recovers from a WARNING state.
    notifications_enabled *: This directive is used to determine whether or not notifications for this service are enabled. Values: 0 = disable service notifications, 1 = enable service notifications.
    contact_groups: This is a list of the short names of the contact groups that should be notified whenever there are problems (or recoveries) with this service. Multiple contact groups should be separated by commas.
    stalking_options: This directive determines which service states "stalking" is enabled for. Valid options are a combination of one or more of the following: o = stalk on OK states, w = stalk on WARNING states, u = stalk on UNKNOWN states, and c = stalk on CRITICAL states. More information on state stalking can be found here.

    Service Group Definition

    Description:

    A service group definition is used to group one or more services together for display purposes in the CGIs.

    Definition Format:

    Note: Directives in red are required, while those in black are optional.

    define servicegroup{
    servicegroup_nameservicegroup_name
    aliasalias
    membersmembers
       }

    Example Definition:

    define servicegroup{
    	servicegroup_name	dbservices
    	alias			Database Services
    	members			ms1,SQL Server,ms1,SQL Server Agent,ms1,SQL DTC
    	}
    

    Directive Descriptions:

    servicegroup_name: This directive is used to define a short name used to identify the service group.
    alias: This directive is used to define is a longer name or description used to identify the service group. It is provided in order to allow you to more easily identify a particular service group.
    members:

    This is a list of the descriptions of services (and the names of their corresponding hosts) that should be included in this group. Host and service names should be separated by commas. This directive may be used as an alternative to the servicegroups directive in service definitions. The format of the member directive is as follows (note that a host name must precede a service name/description):

    members=<host1>,<service1>,<host2>,<service2>,...,<hostn>,<servicen>

    Contact Definition

    Description:

    A contact definition is used to identify someone who should be contacted in the event of a problem on your network. The different arguments to a contact definition are described below.

    Definition Format:

    Note: Directives in red are required, while those in black are optional.

    define contact{
    contact_namecontact_name
    aliasalias
    contactgroupscontactgroup_names
    host_notification_periodtimeperiod_name
    service_notification_periodtimeperiod_name
    host_notification_options[d,u,r,f,n]
    service_notification_options[w,u,c,r,f,n]
    host_notification_commandscommand_name
    service_notification_commandscommand_name
    emailemail_address
    pagerpager_number or pager_email_gateway
    addressxadditional_contact_address
       }

    Example Definition:

    define contact{
    	contact_name                    jdoe
    	alias                           John Doe
    	service_notification_period     24x7
    	host_notification_period        24x7
    	service_notification_options    w,u,c,r
    	host_notification_options       d,u,r
    	service_notification_commands   notify-by-email
    	host_notification_commands      host-notify-by-email
    	email				jdoe@localhost.localdomain
    	pager				555-5555@pagergateway.localhost.localdomain
    	address1			xxxxx.xyyy@icq.com
    	address2			555-555-5555
    	}
    

    Directive Descriptions:

    contact_name: This directive is used to define a short name used to identify the contact. It is referenced in contact group definitions. Under the right circumstances, the $CONTACTNAME$ macro will contain this value.
    alias: This directive is used to define a longer name or description for the contact. Under the rights circumstances, the $CONTACTALIAS$ macro will contain this value.
    contactgroups: This directive is used to identify the short name(s) of the contactgroup(s) that the contact belongs to. Multiple contactgroups should are seperated by commas. This directive may be used as an alternative to (or in addition to) using the members directive in contactgroup definitions.
    host_notification_period: This directive is used to specify the short name of the time period during which the contact can be notified about host problems or recoveries. You can think of this as an "on call" time for host notifications for the contact. Read the documentation on time periods for more information on how this works and potential problems that may result from improper use.
    service_notification_period: This directive is used to specify the short name of the time period during which the contact can be notified about service problems or recoveries. You can think of this as an "on call" time for service notifications for the contact. Read the documentation on time periods for more information on how this works and potential problems that may result from improper use.
    host_notification_commands: This directive is used to define a list of the short names of the commands used to notify the contact of a host problem or recovery. Multiple notification commands should be separated by commas. All notification commands are executed when the contact needs to be notified. The maximum amount of time that a notification command can run is controlled by the notification_timeout option.
    host_notification_options: This directive is used to define the host states for which notifications can be sent out to this contact. Valid options are a combination of one or more of the following: d = notify on DOWN host states, u = notify on UNREACHABLE host states, r = notify on host recoveries (UP states), and f = notify when the host starts and stops flapping. If you specify n (none) as an option, the contact will not receive any type of host notifications.
    service_notification_options: This directive is used to define the service states for which notifications can be sent out to this contact. Valid options are a combination of one or more of the following: w = notify on WARNING service states, u = notify on UNKNOWN service states, c = notify on CRITICAL service states, r = notify on service recoveries (OK states), and f = notify when the servuce starts and stops flapping. If you specify n (none) as an option, the contact will not receive any type of service notifications.
    service_notification_commands: This directive is used to define a list of the short names of the commands used to notify the contact of a service problem or recovery. Multiple notification commands should be separated by commas. All notification commands are executed when the contact needs to be notified. The maximum amount of time that a notification command can run is controlled by the notification_timeout option.
    email: This directive is used to define an email address for the contact. Depending on how you configure your notification commands, it can be used to send out an alert email to the contact. Under the right circumstances, the $CONTACTEMAIL$ macro will contain this value.
    pager: This directive is used to define a pager number for the contact. It can also be an email address to a pager gateway (i.e. pagejoe@pagenet.com). Depending on how you configure your notification commands, it can be used to send out an alert page to the contact. Under the right circumstances, the $CONTACTPAGER$ macro will contain this value.
    addressx: Address directives are used to define additional "addresses" for the contact. These addresses can be anything - cell phone numbers, instant messaging addresses, etc. Depending on how you configure your notification commands, they can be used to send out an alert o the contact. Up to six addresses can be defined using these directives (address1 through address6). The $CONTACTADDRESSx$ macro will contain this value.

    Contact Group Definition

    Description:

    A contact group definition is used to group one or more contacts together for the purpose of sending out alert/recovery notifications. When a host or service has a problem or recovers, Nagios will find the appropriate contact groups to send notifications to, and notify all contacts in those contact groups. This may sound complex, but for most people it doesn't have to be. It does, however, allow for flexibility in determining who gets notified for particular events. The different arguments to a contact group definition are outlined below.

    Definition Format:

    Note: Directives in red are required, while those in black are optional.

    define contactgroup{
    contactgroup_namecontactgroup_name
    aliasalias
    membersmembers
       }

    Example Definition:

    define contactgroup{
    	contactgroup_name		novell-admins
    	alias			Novell Administrators
    	members			jdoe,rtobert,tzach
    	}
    

    Directive Descriptions:

    contactgroup_name: This directive is a short name used to identify the contact group.
    alias: This directive is used to define a longer name or description used to identify the contact group.
    members: This directive is used to define a list of the short names of contacts that should be included in this group. Multiple contact names should be separated by commas. This directive may be used as an alternative to (or in addition to) using the contactgroups directive in contact definitions.

    Time Period Definition

    Description:

    A time period is a list of times during various days that are considered to be "valid" times for notifications and service checks. It consists one or more time periods for each day of the week that "rotate" once the week has come to an end. Exceptions to the normal weekly time range rotations are not suported.

    Definition Format:

    Note: Directives in red are required, while those in black are optional.

    define timeperiod{
    timeperiod_nametimeperiod_name
    aliasalias
    sundaytimeranges
    mondaytimeranges
    tuesdaytimeranges
    wednesdaytimeranges
    thursdaytimeranges
    fridaytimeranges
    saturdaytimeranges
       }

    Example Definition:

    define timeperiod{
    	timeperiod_name		nonworkhours
    	alias			Non-Work Hours
    	sunday			00:00-24:00
    	monday			00:00-09:00,17:00-24:00
    	tuesday			00:00-09:00,17:00-24:00
    	wednesday		00:00-09:00,17:00-24:00
    	thursday		00:00-09:00,17:00-24:00
    	friday			00:00-09:00,17:00-24:00
    	saturday		00:00-24:00
    	}
    

    Directive Descriptions:

    timeperiod_name: This directives is the short name used to identify the time period.
    alias: This directive is a longer name or description used to identify the time period.
    someday: The sunday through saturday directives are comma-delimited lists of time ranges that are "valid" times for a particular day of the week. Notice that there are seven different days for which you can define time ranges (Sunday through Saturday). Each time range is in the form of HH:MM-HH:MM, where hours are specified on a 24 hour clock. For example, 00:15-24:00 means 12:15am in the morning for this day until 12:20am midnight (a 23 hour, 45 minute total time range). If you wish to exclude an entire day from the timeperiod, simply do not include it in the timeperiod definition.

    Command Definition

    Description:

    A command definition is just that. It defines a command. Commands that can be defined include service checks, service notifications, service event handlers, host checks, host notifications, and host event handlers. Command definitions can contain macros, but you must make sure that you include only those macros that are "valid" for the circumstances when the command will be used. More information on what macros are available and when they are "valid" can be found here. The different arguments to a command definition are outlined below.

    Definition Format:

    Note: Directives in red are required, while those in black are optional.

    define command{
    command_namecommand_name
    command_linecommand_line
       }

    Example Definition:

    define command{
    	command_name	check_pop
    	command_line	/usr/local/nagios/libexec/check_pop -H $HOSTADDRESS$	
    	}
    

    Directive Descriptions:

    command_name: This directive is the short name used to identify the command. It is referenced in contact, host, and service definitions (in notification, check, and event handler directives), among other places.
    command_line:

    This directive is used to define what is actually executed by Nagios when the command is used for service or host checks, notifications, or event handlers. Before the command line is executed, all valid macros are replaced with their respective values. See the documentation on macros for determining when you can use different macros. Note that the command line is not surrounded in quotes. Also, if you want to pass a dollar sign ($) on the command line, you have to escape it with another dollar sign.

    NOTE: You may not include a semicolon (;) in the command_line directive, because everything after it will be ignored as a config file comment. You can work around this limitation by setting one of the $USER$ macros in your resource file to a semicolon and then referencing the appropriate $USER$ macro in the command_line directive in place of the semicolon.

    If you want to pass arguments to commands during runtime, you can use $ARGn$ macros in the command_line directive of the command definition and then seperate individual arguments from the command name (and from each other) using bang (!) characters in the object definition directive (host check command, service event handler command, etc) that references the command. More information on how arguments in command definitions are processed during runtime can be found in the documentation on macros.

    Service Dependency Definition

    Description:

    Service dependencies are an advanced feature of Nagios that allow you to suppress notifications and active checks of services based on the status of one or more other services. Service dependencies are optional and are mainly targeted at advanced users who have complicated monitoring setups. More information on how service dependencies work (read this!) can be found here.

    Definition Format:

    Note: Directives in red are required, while those in black are optional. However, you must supply at least one type of criteria for the definition to be of much use.

    define servicedependency{
    dependent_host_namehost_name
    dependent_service_descriptionservice_description
    host_namehost_name
    service_descriptionservice_description
    inherits_parent[0/1]
    execution_failure_criteria[o,w,u,c,p,n]
    notification_failure_criteria[o,w,u,c,p,n]
       }

    Example Definition:

    define servicedependency{
    	host_name			WWW1
    	service_description		Apache Web Server
    	dependent_host_name		WWW1
    	dependent_service_description	Main Web Site
    	execution_failure_criteria	n
    	notification_failure_criteria	w,u,c
    	}
    

    Directive Descriptions:

    dependent_host: This directive is used to identify the short name of the host that the dependent service "runs" on or is associated with.
    dependent_service_description: This directive is used to identify the description of the dependent service.
    host_name: This directive is used to identify the short name of the host that the service that is being depended upon (also referred to as the master service) "runs" on or is associated with.
    service_description: This directive is used to identify the description of the service that is being depended upon (also referred to as the master service).
    inherits_parent: This directive indicates whether or not the dependency inherits dependencies of the service that is being depended upon (also referred to as the master service). In other words, if the master service is dependent upon other services and any one of those dependencies fail, this dependency will also fail.
    execution_failure_criteria: This directive is used to specify the criteria that determine when the dependent service should not be actively checked. If the master service is in one of the failure states we specify, the dependent service will not be actively checked. Valid options are a combination of one or more of the following (multiple options are seperated with commas): o = fail on an OK state, w = fail on a WARNING state, u = fail on an UNKNOWN state, c = fail on a CRITICAL state, and p = fail on a pending state (e.g. the service has not yet been checked). If you specify n (none) as an option, the execution dependency will never fail and checks of the dependent service will always be actively checked (if other conditions allow for it to be). Example: If you specify o,c,u in this field, the dependent service will not be actively checked if the master service is in either an OK, a CRITICAL, or an UNKNOWN state.
    notification_failure_criteria: This directive is used to define the criteria that determine when notifications for the dependent service should not be sent out. If the master service is in one of the failure states we specify, notifications for the dependent service will not be sent to contacts. Valid options are a combination of one or more of the following: o = fail on an OK state, w = fail on a WARNING state, u = fail on an UNKNOWN state, c = fail on a CRITICAL state, and p = fail on a pending state (e.g. the service has not yet been checked). If you specify n (none) as an option, the notification dependency will never fail and notifications for the dependent service will always be sent out. Example: If you specify w in this field, the notifications for the dependent service will not be sent out if the master service is in a WARNING state.

    Service Escalation Definition

    Description:

    Service escalations are completely optional and are used to escalate notifications for a particular service. More information on how notification escalations work can be found here.

    Definition Format:

    Note: Directives in red are required, while those in black are optional.

    define serviceescalation{
    host_namehost_name
    service_descriptionservice_description
    contact_groupscontactgroup_name
    first_notification#
    last_notification#
    notification_interval#
    escalation_periodtimeperiod_name
    escalation_options[w,u,c,r]
       }

    Example Definition:

    define serviceescalation{
    	host_name		nt-3
    	service_description	Processor Load
    	first_notification	4
    	last_notification	0
    	notification_interval	30
    	contact_groups		all-nt-admins,themanagers
    	}
    

    Directive Descriptions:

    host_name: This directive is used to identify the short name of the host that the service the escalation should apply to is associated with.
    service_description: This directive is used to identify the description of the service the escalation should apply to.
    first_notification: This directive is a number that identifies the first notification for which this escalation is effective. For instance, if you set this value to 3, this escalation will only be used if the service is in a non-OK state long enough for a third notification to go out.
    last_notification: This directive is a number that identifies the last notification for which this escalation is effective. For instance, if you set this value to 5, this escalation will not be used if more than five notifications are sent out for the service. Setting this value to 0 means to keep using this escalation entry forever (no matter how many notifications go out).
    contact_groups: This directive is used to identify the short name of the contact group that should be notified when the service notification is escalated. Multiple contact groups should be separated by commas.
    notification_interval: This directive is used to determine the interval at which notifications should be made while this escalation is valid. If you specify a value of 0 for the interval, Nagios will send the first notification when this escalation definition is valid, but will then prevent any more problem notifications from being sent out for the host. Notifications are sent out again until the host recovers. This is useful if you want to stop having notifications sent out after a certain amount of time. Note: If multiple escalation entries for a host overlap for one or more notification ranges, the smallest notification interval from all escalation entries is used.
    escalation_period: This directive is used to specify the short name of the time period during which this escalation is valid. If this directive is not specified, the escalation is considered to be valid during all times.
    escalation_options: This directive is used to define the criteria that determine when this service escalation is used. The escalation is used only if the service is in one of the states specified in this directive. If this directive is not specified in a service escalation, the escalation is considered to be valid during all service states. Valid options are a combination of one or more of the following: r = escalate on an OK (recovery) state, w = escalate on a WARNING state, u = escalate on an UNKNOWN state, and c = escalate on a CRITICAL state. Example: If you specify w in this field, the escalation will only be used if the service is in a WARNING state.

    Host Dependency Definition

    Description:

    Host dependencies are an advanced feature of Nagios that allow you to suppress notifications for hosts based on the status of one or more other hosts. Host dependencies are optional and are mainly targeted at advanced users who have complicated monitoring setups. More information on how host dependencies work (read this!) can be found here.

    Definition Format:

    Note: Directives in red are required, while those in black are optional.

    define hostdependency{
    dependent_host_namehost_name
    host_namehost_name
    inherits_parent[0/1]
    execution_failure_criteria[o,d,u,p,n]
    notification_failure_criteria[o,d,u,p,n]
       }

    Example Definition:

    define hostdependency{
    	host_name			WWW1
    	dependent_host_name		DBASE1
    	notification_failure_criteria	d,u
    	}
    

    Directive Descriptions:

    dependent_host: This directive is used to identify the short name of the dependent host.
    host_name: This directive is used to identify the short name of the host that is being depended upon (also referred to as the master host).
    inherits_parent: This directive indicates whether or not the dependency inherits dependencies of the host that is being depended upon (also referred to as the master host). In other words, if the master host is dependent upon other hosts and any one of those dependencies fail, this dependency will also fail.
    execution_failure_criteria: This directive is used to specify the criteria that determine when the dependent host should not be actively checked. If the master host is in one of the failure states we specify, the dependent host will not be actively checked. Valid options are a combination of one or more of the following (multiple options are seperated with commas): o = fail on an UP state, d = fail on a DOWN state, u = fail on an UNREACHABLE state, and p = fail on a pending state (e.g. the host has not yet been checked). If you specify n (none) as an option, the execution dependency will never fail and the dependent host will always be actively checked (if other conditions allow for it to be). Example: If you specify u,d in this field, the dependent host will not be actively checked if the master host is in either an UNREACHABLE or DOWN state.
    notification_failure_criteria: This directive is used to define the criteria that determine when notifications for the dependent host should not be sent out. If the master host is in one of the failure states we specify, notifications for the dependent host will not be sent to contacts. Valid options are a combination of one or more of the following: o = fail on an UP state, d = fail on a DOWN state, u = fail on an UNREACHABLE state, and p = fail on a pending state (e.g. the host has not yet been checked). If you specify n (none) as an option, the notification dependency will never fail and notifications for the dependent host will always be sent out. Example: If you specify d in this field, the notifications for the dependent host will not be sent out if the master host is in a DOWN state.

    Host Escalation Definition

    Description:

    Host escalations are completely optional and are used to escalate notifications for a particular host. More information on how notification escalations work can be found here.

    Definition Format:

    Note: Directives in red are required, while those in black are optional.

    define hostescalation{
    host_namehost_name
    hostgroup_namehostgroup_name
    contact_groupscontactgroup_name
    first_notification#
    last_notification#
    notification_interval#
    escalation_periodtimeperiod_name
    escalation_options[d,u,r]
       }

    Example Definition:

    define hostescalation{
    	host_name		router-34
    	first_notification	5
    	last_notification	8
    	notification_interval	60
    	contact_groups		all-router-admins
    	}
    

    Directive Descriptions:

    host_name: This directive is used to identify the short name of the host that the escalation should apply to.
    hostgroup_name: This directive is used to identify the short name(s) of the hostgroup(s) that the escalation should apply to. Multiple hostgroups should are seperated by commas. If this is used, the escalation will apply to all hosts that are members of the specified hostgroup(s).
    first_notification: This directive is a number that identifies the first notification for which this escalation is effective. For instance, if you set this value to 3, this escalation will only be used if the host is down or unreachable long enough for a third notification to go out.
    last_notification: This directive is a number that identifies the last notification for which this escalation is effective. For instance, if you set this value to 5, this escalation will not be used if more than five notifications are sent out for the host. Setting this value to 0 means to keep using this escalation entry forever (no matter how many notifications go out).
    contact_groups: This directive is used to identify the short name of the contact group that should be notified when the host notification is escalated. Multiple contact groups should be separated by commas.
    notification_interval: This directive is used to determine the interval at which notifications should be made while this escalation is valid. If you specify a value of 0 for the interval, Nagios will send the first notification when this escalation definition is valid, but will then prevent any more problem notifications from being sent out for the host. Notifications are sent out again until the host recovers. This is useful if you want to stop having notifications sent out after a certain amount of time. Note: If multiple escalation entries for a host overlap for one or more notification ranges, the smallest notification interval from all escalation entries is used.
    escalation_period: This directive is used to specify the short name of the time period during which this escalation is valid. If this directive is not specified, the escalation is considered to be valid during all times.
    escalation_options: This directive is used to define the criteria that determine when this host escalation is used. The escalation is used only if the host is in one of the states specified in this directive. If this directive is not specified in a host escalation, the escalation is considered to be valid during all host states. Valid options are a combination of one or more of the following: r = escalate on an UP (recovery) state, d = escalate on a DOWN state, and u = escalate on an UNREACHABLE state. Example: If you specify d in this field, the escalation will only be used if the host is in a DOWN state.

    Extended Host Information Definition

    Description:

    Extended host information entries are basically used to make the output from the status, statusmap, statuswrl, and extinfo CGIs look pretty. They have no effect on monitoring and are completely optional.

    Definition Format:

    Note: Variables in red are required, while those in black are optional. However, you need to supply at least one optional variable in each definition for it to be of much use.

    define hostextinfo{
    host_namehost_name
    notesnote_string
    notes_urlurl
    action_urlurl
    icon_imageimage_file
    icon_image_altalt_string
    vrml_imageimage_file
    statusmap_imageimage_file
    2d_coordsx_coord,y_coord
    3d_coordsx_coord,y_coord,z_coord
       }

    Example Definition:

    define hostextinfo{
    	host_name	netware1
    	notes		This is the primary Netware file server
    	notes_url	http://webserver.localhost.localdomain/hostinfo.pl?host=netware1
    	icon_image	novell40.png 
    	icon_image_alt	IntranetWare 4.11
    	vrml_image	novell40.png
    	statusmap_image	novell40.gd2
    	2d_coords	100,250
    	3d_coords	100.0,50.0,75.0
    	}
    

    Variable Descriptions:

    host_name: This variable is used to identify the short name of the host which the data is associated with.
    notes: This directive is used to define an optional string of notes pertaining to the host. If you specify a note here, you will see the it in the extended information CGI (when you are viewing information about the specified host).
    notes_url: This variable is used to define an optional URL that can be used to provide more information about the host. If you specify an URL, you will see a link that says "Extra Host Notes" in the extended information CGI (when you are viewing information about the specified host). Any valid URL can be used. If you plan on using relative paths, the base path will the the same as what is used to access the CGIs (i.e. /cgi-bin/nagios/). This can be very useful if you want to make detailed information on the host, emergency contact methods, etc. available to other support staff.
    action_url: This directive is used to define an optional URL that can be used to provide more actions to be performed on the host. If you specify an URL, you will see a link that says "Extra Host Actions" in the extended information CGI (when you are viewing information about the specified host). Any valid URL can be used. If you plan on using relative paths, the base path will the the same as what is used to access the CGIs (i.e. /cgi-bin/nagios/).
    icon_image: This variable is used to define the name of a GIF, PNG, or JPG image that should be associated with this host. This image will be displayed in the status and extended information CGIs. The image will look best if it is 40x40 pixels in size. Images for hosts are assumed to be in the logos/ subdirectory in your HTML images directory (i.e. /usr/local/nagios/share/images/logos).
    icon_image_alt: This variable is used to define an optional string that is used in the ALT tag of the image specified by the <icon_image> argument. The ALT tag is used in the status, extended information and statusmap CGIs.
    vrml_image: This variable is used to define the name of a GIF, PNG, or JPG image that should be associated with this host. This image will be used as the texture map for the specified host in the statuswrl CGI. Unlike the image you use for the <icon_image> variable, this one should probably not have any transparency. If it does, the host object will look a bit wierd. Images for hosts are assumed to be in the logos/ subdirectory in your HTML images directory (i.e. /usr/local/nagios/share/images/logos).
    statusmap_image: This variable is used to define the name of an image that should be associated with this host in the statusmap CGI. You can specify a JPEG, PNG, and GIF image if you want, although I would strongly suggest using a GD2 format image, as other image formats will result in a lot of wasted CPU time when the statusmap image is generated. GD2 images can be created from PNG images by using the pngtogd2 utility supplied with Thomas Boutell's gd library. The GD2 images should be created in uncompressed format in order to minimize CPU load when the statusmap CGI is generating the network map image. The image will look best if it is 40x40 pixels in size. You can leave these option blank if you are not using the statusmap CGI. Images for hosts are assumed to be in the logos/ subdirectory in your HTML images directory (i.e. /usr/local/nagios/share/images/logos).
    2d_coords: This variable is used to define coordinates to use when drawing the host in the statusmap CGI. Coordinates should be given in positive integers, as the correspond to physical pixels in the generated image. The origin for drawing (0,0) is in the upper left hand corner of the image and extends in the positive x direction (to the right) along the top of the image and in the positive y direction (down) along the left hand side of the image. For reference, the size of the icons drawn is usually about 40x40 pixels (text takes a little extra space). The coordinates you specify here are for the upper left hand corner of the host icon that is drawn. Note: Don't worry about what the maximum x and y coordinates that you can use are. The CGI will automatically calculate the maximum dimensions of the image it creates based on the largest x and y coordinates you specify.
    3d_coords: This variable is used to define coordinates to use when drawing the host in the statuswrl CGI. Coordinates can be positive or negative real numbers. The origin for drawing is (0.0,0.0,0.0). For reference, the size of the host cubes drawn is 0.5 units on each side (text takes a little more space). The coordinates you specify here are used as the center of the host cube.

    Extended Service Information Definition

    Description:

    Extended service information entries are basically used to make the output from the status and extinfo CGIs look pretty. They have no effect on monitoring and are completely optional.

    Definition Format:

    Note: Variables in red are required, while those in black are optional. However, you need to supply at least one optional variable in each definition for it to be of much use.

    define serviceextinfo{
    host_namehost_name
    service_descriptionservice_description
    notesnote_string
    notes_urlurl
    action_urlurl
    icon_imageimage_file
    icon_image_altalt_string
       }

    Example Definition:

    define serviceextinfo{
    	host_name		linux2
    	service_description	Log Anomalies
    	notes			Security-related log anomalies on secondary Linux server
    	notes_url		http://webserver.localhost.localdomain/serviceinfo.pl?host=linux2&service=Log+Anomalies
    	icon_image		security.png 
    	icon_image_alt		Security-Related Alerts
    	}
    

    Variable Descriptions:

    host_name: This directive is used to identify the short name of the host that the service is associated with.
    service_description: This directive is description of the service which the data is associated with.
    notes: This directive is used to define an optional string of notes pertaining to the service. If you specify a note here, you will see the it in the extended information CGI (when you are viewing information about the specified service).
    notes_url: This directive is used to define an optional URL that can be used to provide more information about the service. If you specify an URL, you will see a link that says "Extra Service Notes" in the extended information CGI (when you are viewing information about the specified service). Any valid URL can be used. If you plan on using relative paths, the base path will the the same as what is used to access the CGIs (i.e. /cgi-bin/nagios/). This can be very useful if you want to make detailed information on the service, emergency contact methods, etc. available to other support staff.
    action_url: This directive is used to define an optional URL that can be used to provide more actions to be performed on the service. If you specify an URL, you will see a link that says "Extra Service Actions" in the extended information CGI (when you are viewing information about the specified service). Any valid URL can be used. If you plan on using relative paths, the base path will the the same as what is used to access the CGIs (i.e. /cgi-bin/nagios/).
    icon_image: This variable is used to define the name of a GIF, PNG, or JPG image that should be associated with this host. This image will be displayed in the status and extended information CGIs. The image will look best if it is 40x40 pixels in size. Images for hosts are assumed to be in the logos/ subdirectory in your HTML images directory (i.e. /usr/local/nagios/share/images/logos).
    icon_image_alt: This variable is used to define an optional string that is used in the ALT tag of the image specified by the <icon_image> argument. The ALT tag is used in the status, extended information and statusmap CGIs.


    nagios-2.6/html/images/0000775000076500007650000000000010532717606014417 5ustar nagiosnagiosnagios-2.6/html/images/action.gif0000664000076500007650000000253607673733055016401 0ustar nagiosnagiosGIF89a((÷ÆÆÎ!!Î))Î11Î99ÎBBÖBBÖJJÖRRÖZZÖccÞccÞkkÞssÞ{{Þ„„ç„„çŒŒç””çœœç¥¥ï¥¥ï­­ïµµï½½ïÆÆ÷ÆÆ÷ÎÎ÷ÖÖ÷ÞÞ÷ççÿççÿïïÿ÷÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ!ù#,((þGH° Áƒ*ÄB¡Ã‡'L€HÑa† +j,èAA† Šp !dH:TÁä %!ŠhÁä„ <œ   z†¬PáB…YÁÁ‚&GÀÌà çU~x Á‡t ôð Ä–šfäР„ 5È9"„ ¼>ÈûA…$ÄùB _x hÞVh¤‡&(0@´¢ ¤¥° ²Á*dð°tçÏ©;ð¹Â Ù0€@A®4tø š‚ñãÈÿ…øa² 8h°`‚³kŸ !V¬ þˆMØ‚oè‚Ó«_¯Bõ¯C`hà‚ýûøóN€¡5EÔD¦Ÿ~@à_E!<€€4èàƒ.Àð!H |§á††§P=”½U·@(¦¨âŠ)*°`…a [$À¢Š Ð@h$& Àf P0ÞB˜hä‘´Âd@Á~ðü˜@?fébo›…xi_"@bŽIfWBÀ›ƒm$‚uP•$VIb„ ¨»PAO@'\#t@HP@~Žà@ „€t`n à€ià'’6Õj= Ä* ˜$™•ÔAk @€I<ðéA˜ÿ ‹PäÕCÐÒ³…@@¬ÔBÔU¶ÿ)Q@;nagios-2.6/html/images/ack.gif0000664000076500007650000000157307436604464015660 0ustar nagiosnagiosGIF89a÷ææúÍ…?¾¾¾/OOÿÿÿÿÿÿ×p€!ù,X8€A&dX™AC†²O?x0«AiÕ«BšØAƒ†´hHàal€ ï7³?9ïÏ[¾öŸ¾'šSÅžÍúŒó¡ïûîõ±dæÞá7Ý‹öŸŸ÷+üåÅ£(Êþ³ýûFŸçE slYÍæJaÎuò½÷姆wÂÿÁgBÛYRôšëÊ=žø[wÀÑZXÀ±tn8;Z¦®¹pî ^xï^ Ã÷Äû¡[ .ž»åU–ü¼#tuº+{mR7{YÃ÷Ç)\,K„~ìËû ? ÎG„ŽÞš4Å~RTfuÚ É1Ú³ãØ%Ͼi{â½qüÜêßÝ-|ù^£Ñ(¬ZwWoö—6ç?,Šçúv Ébø²*{{{ûûû›Û[µZ- Ãîîî¾¾¾ÑÑÑìJŸ‘A«¾¯wvvpA¼S*•ŠÅ"^à²'Q ä{ƒS·ººº½»sxx¸··ƒÙÞ¯âý®JG§ »¿¿  ï‘þßÄY%¡ûÒþÁþîöH„Q©Tj‡ÕƒƒPËâââÊÊ –°Õ±`SÀäädOOÏ{Ð.¸¶¶¶¾¾¾¹¹‰â^]]]`ÌØ¸&è|`ÀöÄ÷…ã\oÞ¼™æ^mlllîlcÂëõ:>´c·‡F¯]»662259åý¡áûã|’paqayyyuä¶‚e(—Ëa½Â©ÌÍͽ~ýzww7ö#á•+×îÝ»÷ñÇcñ@0^F5ÅÌ8í.[[[oß¾}òäÉãÇq#Ð^‡wŽ]¸p’t844ä~h;ã\pÓ…Ù~ôèÑ_|ñàá·à};û{…Bzþbí@¦À?þðCüsPå¡Íóˆ3aœÒͳgϾùêËùùyÐ4Ìzµ¿ÛÛÛ`£‰µ†H••0Œ‡‡GñÈ&{5·|'™|`Æ ç?|ùÅÿþïÿbP¸ˆ/ `¯_½v÷îÝ›7oâûÃÃÃé•mgœNç§{úô)‰¯«:O BUvð+WVÊ•âÄøøôôôàW)ýS`¬Ça{|/Œ#ˆ;Û—À>ùò%¬5|5DQíqV~!À?ëõÔB‘555ÑâÞä‹c'·€°ÅM°' Aöx“6!3 N˜…333s³"uqSHHG„¹,XVŸÿ9n&ü¥J)Ì{¬u±TÂsaz‹ <×ÄÄÄÒÒøì„?:®  Dô"ÈÕ”$I3A€/€ãSpnèÀ°a`CzùI!?ƒ\ð~p{+… §šýEƒXì0 t %YV¬iIecö©ó~‚ï((‚±Q ŒCô–t1Â0rï@tACqýúë¯aT@X&GF‡&'/œþT <@g@ͦ’:=ÁÂA¶`á[Û[}ýy/ÍϘI¬)”y¨ô[ë˜|¼_ÃJ¥Œ¥¤Õ=22ó_ÀëìrüÑ™÷<½'®_¿À‹Ï?ÿáI_{6ã šå+êŠ/É òä·…XEG„&Çx°¶´´ˆ÷A0 A‡7nÜüÒ… ÃÞ ³Êß ë É߇äSÂV:÷åŸ^ì+3C߬×é’õþT­”ïJ¥ÃÒÀÒöƒxs ¶C Có ‚ <äwíÚµK—.MNNvvvþ‘'ù羦ý×ýë_ÿúþýûT$ÅY%!ÔQæá¯Ê:q–0… ²+ÕjŠ .qîð5Xüx¹»»¿µµƒ5)²ƒ:96>Ôr}ç/­+\ñi›÷åk‡¸8n„oÖ U#Âó‚3 Ä2}òÉ'ÝÝÝ×o\k|uyà¹õbPÞºu T:>>Þ××—÷¨fø§ú'Pà¿ÿû¿Ÿò³Æ Eo‘$Q_‡_2{)ýÄ¢ú—<ô7A±XªEuˆ)áþÞáÁ~_€JÓÛÛ],û›9ÝÍ”ÔXLή'„-ê\¿G Cî 5ÂJÁþÀO£V·}ÂÏ3D%%í åÑ ¦ò»SÏÏ8“Ǿs 9i{P}K.Ñ*U\]ËÕ«—¡gŽ]¿¹t Ëþþ!V <Žª)4U3M]˜˜ÒIûaܽïMÜýL6Næ%öŽQÅhæÊ-b{ûLsû.`Þ~ùË_þ¿ÿ÷ÿNùΙˆ"«R.—a§Aò”J% YogÖ^‡*)qOä!$$ •••'Ož`±»»;»z:@„îút½èE„û:׫@ñ¿FYreùCÉü!®W -õSÞÙ¶u,ªupÒ§Ùw ƒß™þš¡(ùs½µÌmË‹cçÿŒK“ؼd Íß½Ëw;¡ÅÌ»¤ëÿ”ÌÑînqè…Nœ³?‚Ó}²ÕŒ§T±‘PO»ˆÐZi¨iâê/…þD[kºŽ\0ÓÓyJËëÿú¯ÿjÿ4‹sHBê~T>#…z)ÂSQÖœÇ@MGÇt¨¾µ½,x===ÓÓÃ#}½Ýà¯îâY@ÿ§+â³R#uKêèÁé¨í"%ùçÑi§¼M?‘˜ÇîÎN­z©—BsÄ[Ÿ}{{›L”ßßßÏ}ÓNöGà¿“#´¬4XŒ±(ÜŽÏ¥±åRüÛR×Ò’˜pn_—?öÞÉÝGFG·w¶ÇÇ'ðM訽½½Œ2!Ùm-%“1d~{ìÎv8ZeÊçõX±è.žþ6¤†¥CÎä;7gvþOü(%¾µ³³G?¼*uÐàDŸ |½±'<F_dI·ç·¬oë"žÎ&NùÚ9$!É »o( Ýn TL>Š£tŽýR Æ›§Q‡:øéà`ßÈèÐðð ææ÷-¢—KáÉ!r½“ª¿S¯¬{“DÛ² ÍqòÉ=?q屮…º…íukowW<·{`1•J¥[» %ÝÜ"Aø>u3|¤Â<ÁàààIÂí¤ô ìb¸g_W`ßã^ø‹±ñ›œ Ãèèh—ÔØ²(xßʳì`j*~ÕQîħ]• ãZvg–»ÓǦú—d îìmãÓõÕ L/.²¹¹ ®„…ëêèìëï?F2œ¼aZÈ€¹tôôtñÍý½½êa+ N³££ŒgÄóf÷ëIƒ?vb½v.œÙ÷›UQ¶Ax.ÜZ²»ª5±}D»jøžŒ°”˜#ɤåR¥Ü×Ó‹µîèêäØÚsìú¶æØ©;³c&!3¦ZK´@6¹w¤ˆÞ÷šÔ¨’JtËF£¾¶¶úâÅ‹±ñ‘±±°X¡—²Iò<¨»xxš `Q—è莑;º$Gyáéý[§ä™S.ˆ)^_[ǼcC¬®®.//ãÅÚÚÚæÖ–R&kO_/ý–*767Ô3lн½=!i–Òðð0hclll||Œ÷I97ïÙ*'Û—À0@B‹‹‹¯^½Âkì{Œ÷†àí轄®ˆ;ŽC}À™©‡‹,---+4‹hWÔø0ÄV£cÃx.l ù>å´Da8`––Væææ0%x^æ3U°³Ò…ë àÖC#ÃX2ç!K&ö8KɽÃ{©On r>lÔ˜*Ýó16pÀí½]¬FŽíŽëCwuw”K )ÈŠX`üd° E)ͪÙTÒÆ©,mÎÿìk‰*/,,`Â×V7Ä[±‡GߦO¡Ö”³Ë¥ÊÅ f «££«§§³KX3&Ј.7&S•¸Àk V³¢…϶¬þ{!€å¡+Ò)K|ß©CG;ÁÈÈ?Š·SžMŸ/,Î÷Ý·##CØÁò`##[+ÀtcÞ•èdaœ¤‘Ë ã…b!q‰;^ãL¦#ö4ƒn^¾|‰mñæÍ›·K’‡}ˆW­â¾Ogw—p„¸™úÒ kF}K"Åuù¥K—nß¾}ùòe,Ø >Oµ©8%¿)¸Qð°-ž?>33óôéSìTJBæ*8;·ÃÚã—|ðÄÐF6;; KûÁƒóóó°¦Å³¬Ö2~‘råê%PéÇ~„Û iæ`;€þ‰1|ó̓¯¾újvVR‚k‡ufêâ: BÆÅ‹Swîܹ}÷¾Oi Cl›CãYÀ @Þx@Œ¤Q¯òqd&=SÊj5Ð!yH126Œ/¨cüX$hû~|Tv?Ø_ve˜mßåÙÇ\YYÁÝ¿ýö;¦ÈbH[›2ɇ"A„š‚Rwªr© b Cn¹Sä! ÐÞÄÄäää­[·À;nß¾ÛÂZ^«"[Íþ›ì™6­‚«@‘èÅ#F¶%Á=ºÍÎ](ô0éØ:=ºxñ" «‚uu^¨E¥ÂRA‚žÜ«QoOhžžlq£‡ ÿäPÉÃÇÞªæÐ=}ürøùó§Xû¥•eî€z‚»(+QM¸£¤Qò~ü8-ÐU„íw˜ÍL-e Kòfîí'Ÿ~üÑGuvVTWÉÒáiAmЈçñãÇ_ý5È;KKË“ª/„!ù¦3† Œ;âAn)ðågÏžýæ7¿yøð!üáa³¯›¿*ξ",1—hzRSÖ¦)aMA!_|ñÅïÿû×ó¯÷ ž5À ¹¸]ZÓ .n%¡XÊêc'i¥®3 †Š…Æ>{òØežG‡hÚàA¥xjJþΩïìÃ-_v&–\­ôðë›×oà‘§¦¦˜*|ì†NÿÙôŸi6Þö«ÙYÌóþ÷ <)f7Å ‹wà A„˜dÕïê$ºîU3|T*‹Mˆ˜=HBlZL)ø X3"Š×& O¹%a».N§%5Ò¬èhÃK=(Ù1Ø—^ˆÿ\ æâóÏ?‡<Á;Y_ˆP¸¦ædÃN¿…hu.?ºïøâ”f|uyåå‹|÷Í7ß`V°ê›;Û0dÇ7BL{$UYýAÁíÄU†+²“€Qášø»±¾EE Ë|x ‚®JB‡N??Ö[ñõå—_‚~ðC­l{B(›çb°ª0ÇšÅÓ 9ܤòBî®]„AŠz…:äl0M¨£ ¤>ÈÆTmnÚ-++kÃwß}‡y»¸XoT ‘}MÓNQú ãb¹;Jenñ†‚ê6O¹Søo¥S<ð‡ÝYUk ~WÀcÞ»w¤J)žâJÍŽêÆÓgϾýöÛ/>ÿRd rºxw¢WEiŠr2íbƉt•DåÃD%ÁøWVWÝüïïâÓ«W¯bZ¾gxé¬ê()žŒ9µò×Ù‡¤Í­{IÄoj|ÏO\)äÙHvÛþÁþâòÖþÊ•+°4†'ÆO©ÓrýÔê<‰!š~*cˆbÇ´Nb"‹oÀ‰¿ýúëGß=œy 6¶·» Ñè1Zè}å:^Ó[ŽOUø*A&ªEÕ'õÆQaÖK‡XOÐ¥m&pbz.……„2Œ}¦QÒÂrêüŽÎ›Ü'[ìT Zì$ü ‹²¾º¶²$–­xù|5µºõü°Qb»@ÞÞ¸qãæÍ뤊›+|‹ºÀÂÂÒÂÛ%\×Ç33‰ê¦·Þ¨ã" Œ™R ×9¥c·{#à' ¨ƒ*ÞEÎì‡;n*0OCÕg)œÚ‡‘ºÐ<_”x.Ì8)øžÈe‰ÐGuŒÏ6Õñ&Y_|ùÕcÁS0húøy¢_DåºID”›ÿH˜¯dƒ„QHË"4ÉzµVçqèʸ$ó)ËýNâ:«:ê©“€ž:°U,žü85ÞZîšý¡ZV¾&¸øÜIòBvR)•ÿð‡?ÀÃlötuSÇÀ5é“ðÒèVÊ ¾£:§ý¶HB7,t­ÿýýï_<{Žmƒ6jÔ*Õ)§jnà!~¨ÞüR¹¤‰;^WW81“4†và¾N-,ÌξöµD¿® öè)†§& x3Ɔה Ž0( ½Œ3Œ_àÄâî ²q·D1ƒÁŒP|ìJnq°¿_é(ýƒÔoݺ].;E¸0®#~ÑF½éáâN¥¤òåkUÊ^ßͬ{»ÿ 7…hÅ3â/KÒhácÒ‚Ô º_’ƒ¥÷-$z ‘†¡¡Š`÷²¡„pIåѤ—˜úÙ"ö-T.ü'¿ <Ì.™ » 2~²w’Ùû¡Ûè|MO^¦L4®ØI†L'aä^êóTQ‰ÐŠb:6X«†yd-éøÌ݉îÎ.²“Äa}œ×‡Ê¥"ñ­­M[6ÄÚÊê›×sX lìBÜN$éS,©©â‚N š +#ŒCi¬R颇Ò¦««ÏN-T}™ëbͧÛôà`¿Z=\\¬@õš¼0ÁXÂÐÐ1åçœìfúB)X˜“ÀUw|'˃²‚+™™8ÞÛÙ[ÞÚØÄ¥›A­¦Ê‚m?ÇÑù—SI%SÊ•4³Týrß`£ÃnéQˆ‘ ….U5É‘QmAô¥ im¶ÈÃ:¤×{;2Â$blM^ùØÎÅB±&›O(¼³³› =௃ýCì(¥^Ð1,® UŠ €5¦÷’Œg@ƒÒ324<:&~üc‰¼ O=77j„Vãæ-û.3Á)áâ!(•h>•ÔN£³š?çÆjq½ê<7¨èzj×¹,ßìÒªM %{Á‹ÒŒyõs‚×¢®îW¦Ô·ì ¾×ݦ·/g_=|ø6? >9ónin666U©£‚ˆ{¬ZÝÝÝK­VÉ+â%Iw†}O=™þ*ü½}ûv;ÿgÌ«W ?ö  ¢Q¯‹4æD½]éG6114<€«•JXßâÑ]]Ã΄L uˆÄá‘í-7bîŠ$ÙføæE„^F¾ÑG„Én\Ž*¸CŸÑ9jÖ:¥º¥’¡Oº‚å°÷úÕì·}ýÃv»tiº^—½U•‡«‹C$V‡L—Êå(5eU¸‘X.^¨ùœ­SàÜEÔ¦öj 1q"MR4¢4Яš›l‹ ¹¾K—.ONNB=Æx4͵ö <²^wÇFYYYÚÙÚ”ð}]h¿d³×ðþ£'Ç.ŒBEBKiɘÁ_–ÏB80næÈ »›Ÿä; ©Ik¹¾~émW«AµÃéÉh¡»*›•‚=SZÞƒ|gÁZ„C â.VŠjORË€@b°M$ª&ÝóûÎ@pÉq`L`.ósoðh³¯_Bß~òè)ìU·'†Ÿ† =Š]I½µ‰¿q| ³]ª”±à²ïWWY¢-Á÷Ò T’ÌÄùÄヶA½x.V`aÕR,ƒÊÊÊììKꤺŒnˆ1Xó +þË_~v÷öÉ© jÉÇô¾]\xôèì¼Æ„‹vÖµîÔ|‰B¡}åÊ•ééi–wý1ˆÐEchðôè¦$‡Èú0½”…3ã_ÆSA^;Öžê-Ét`OcGB¶@ ãy@ÆÎ/ÊÚE.¹¯ÿßB¶qâvרӑ°½Rß\—½+=â¨B¡k–gÅØCý˜Ó;wîÜ¿/$ Ø×Ïùj0ØÝÛÃb`Lj]ÅBBí¨*_±ÞóóóP°ïܾuãÆ5¯MP±G±Ûð—qˆñå¥Iü·Ã>ÃbOMH~ÿúõk\KWÓ!ôa‹”Y™TàR-~¼Xì¢"sðµÒRE¶¬/5 è$Ì8Ç<7rèí°ð¿ûö8QÖ$`qaYLAýLi†R«A®âûlK{ajòúõë˜ðÎî.05¨]˜@ºØE¢~àŠÈAœ¸&h ·Æ°AE˜—ÿÈŒ+ü–ÁííÍÃê~Ää*p·rG"9”&ûúznܸþÉ'Ÿ|öɧ&Æ::’¼h¬ÑâòÒÅ‹Ÿ\¼„yÆlƒ«‡’ÑÞ×ßí ¤xùòå{÷îA޲ÖK„nÙÔI=|ñâå‘‘§•:Ì8NðÂo4¸`¹¯Fá%[‚ÕIn[¨r¢ÅÁØmaT ëØ‘˜}<Þö~?w§´W‡{(rÓ­Q¡ ‚f.‚_ä¿6ÿ·ÎèØVèæÍ›R) «ÞÙçXA¹»xâê’ÀÑÕÓ}óæwïßÿå¯>^»|EÜ⥠§bvjRÜÝÕÑÛÓÕQ)¥¦Q¬±PM'XkñîÞöÆæ“¡Ú'!ì0˜ÚK¢9'YŸ0•y¼ òÃx°MïÞ½{qjÔ‚+c¢`åBÓ›yþýä/þâ/®^½Šõ tuuïlnb$x:¡Xà‘HWµB…ü 6'z;Û1b„ŒôàŽxÀl»w¦0¿B=2¬•)¨«B¬ø@>ÝÙÚÆ] ¾Jn†Ry‘AæRúÖ­ø´!ÙÕžê&P½r¬oö‡$Âc¯ :ĬadÐÖV7õ¨Z«bzBØof§¢RHòß„ êííß߇Ìô –2F¯Þ]l„5iNGàjÐ^Ài0 ´”ö˜Ô‹ÿ*岨Cà¤Ë )O”š\zì,ðáÑðÌÆLù£=ã¶´Ùû•Ì>vü•K—z{zý#ÓkUé ¿kAµd(Pµ-•Æ8tйŠê²…}O*+”8§ÃÓÙË áT>}GB$0w°_üâ,¨uÃÁ÷1`ˆÚX›ìnïÔêµ®Î.¥j?IN’Ž?˜£°T¬ €ÙO ¸zÜŒ»Õ#Áw”Åʇ6Vð‚P"œª¦h¼"áÊB—*ìJå£ mæù³·oæ@°ä£BPò¼Nî& ‹ð»Éé©»÷ïÝÿø#ü–ÀÎB ÎÞÁ±‡ëÝýÝM ôÉîoH½¶$ µÉ2óÄÌÁ¦ÚÜÜ]±©ØëóCîá~žª}Û/¸†(‰}èUk‡ÛÛ[>ÂtMMO¨"6ÐÓ%yùcã£Âï Já¿‘Q:–% ÜÙ‘•{'åi—&Ï×cº HëöíÛ’&²%îÆ&h¥ábÙÊ<4 °(ì*êUñ”BæïlocA±Ü¸dÚèØ°$åIùò…1Š;:éeÏyÚÆº=IµÉ´Ï/ÏG„¸7„¤?Vÿõì°@I¯5HΕÂUÇ\`ëãMfñ²®7qU´Y‹HŠ"zA ³ Ìá©9ÈWz ßQ{ÚrJzj´tïhñIrÐñãÞÇê&ñ(½f¹,¾r('Û;›Ú“jº6©k¿­ìë5Ãn[_Ûd©Q:˜X=I¦5èyxx´»»·}^êg§ŸÙy;\rŒZƒ„§§¦`“Œ »uu {ój„œÇ¶ÞÞÛÐG -H`¤H2Ašç”NOÒÀ ‰Š+‡á’i)H¾“>ö4uE –5»Ïè°Å|n®oAg‹Ã¸¤TZÔÀ†D`é¿ñ •bEü™’=508ÜÓÛŸ):Öñxù…螘šžºtypäÉÂò, (&.÷ˆ;*¢™¹²¥`Þ,¯G×`gwþëèêû<ÒL½¡ÌÁcŒ™è´x®Á¡~ü…Ú"„ŽÜÕÕáb’r ÇððÔÅéS2Wß[/=R°\ºt ätùòK(! .h¤îSçßcEö=6%ÞÁ:1ÆMË0K.ʇé`&~È´)I\Òmhõ°ï'¶ T6)ÁÉö#=¡vÖ¹pZÞW§‹z)<:!¢å9cãÅÌ3,ÉúúÚúú†:W4Š­Uxd ËK«°(…w¨$¥4IòŒº»KzÎĈ¢e î¯cΓÍPó5|ŒíÎxÉHÆÔiöˆ=®§CO¤Ak½êeŠZš+ŽQS3õaûi†`j¿I!eÖW$Ùê.\ |Èn ¬sè$ ^ül¢O,Ù”,ÜrG¥OÍ\‡RëØh3L1|‡:¹!Wñœ M“$Iò¤·3€»OLŒ+ψÀÅp}m0¾´´"[.帟CÝô„°m‰'‡êê’Vt°>FÜÅ¥Bœ²ˆ" ðîXXÜ_ËŽ¿Ý;øc¡—†È%­³Ndšx3 . Œ’­²8 “E«®‹¡£X—µë?ÅâÒHŽ_Löe,¥™1ÇôÕ7ÑDûDdÉÏÅpÈä2¬/öL|,å7À·_AâáðHÍeñ%Ù 4cPÌHèÈŒ2«*©Æ`ZË%¨««gdDV¨eƲ,À™…‰w*SzB±ƒtˆy£ïûm‚]j~F&¦¦‡‡`¨TÕCév b‰¹Kr³á}©— E2¤¨ið ÿ²wSšÅ/˜®r©o ÷êéëÍözR:Ž«‡0ME%–£‚J*J‹­ýÄg„-ÞÓÓ742Ê(Wû¾Òxüš_O”‰.ЭrQ{YüBKš«¢M£V5¬)ë¡Ù À“b«‰‰©k×®½|ùrqqy_ ½Ô\âl«/C˜VÕÁÓ5O“L ÀÃÎÄ~ý§™ôÔoåL‡¥•Õùù\ùÊ•+X~—’‘e²Y²ü±ˆgE0ÜÌ f&.º:CòTª@t6€'Akgœû›-ô½4*gÒß}° NÀ›¹êŒeã^ð zå‚Ûè¢ D*5¥A槣·<Ñ‘µS“² _ý1 þ’Ø}”†Ä$fkwFìC,k­Öp—ÅÁ–VÞ*ÍR¸(íu†$Kùf)C™IžæÇíyÍt¢P#F%ñÉmm>þüƒ>€­~çÎÈFÈé©Évr;—×ô|D­Ccë¿ùæ+Œ¯éh!aÉâ„YÐ5 †‡ñh†š­¿€'ÁCBìH‹çd./-e`¼20ò#ÍcL]äÂ\=†øCBRùŠ>]L›Ì>sV¿‚!7777«5‚ÉõkÔUõÞKõüùS¨Öúé2Ï<‘ÈVìÕ´Lª ¼°Ì=„Œð½]’mã‹OTóZ‹øŒü×>u íLbMÚ$ËÆVàª[ˆ0f°D' Òªsi‚祿F4/õ¤Å2~hÒIætì ;š…81ò¡øAsƒ ×ÙÙQ­FêóeËÆ.NÈðŒ¦é$gÙg2"*åNɹXoht‡Ú9Ø@ ,! ‹iÈ.W>z„/$Ë«Tô–äAâF³GNšš.Á£3§4“>&wÇúâ‰îß¿¿½´í"›-Ä”èÕŽa´vѨÐùšÅÁd¬Ý­ú+±±÷ØÊ€i± s¨x oˆÆ–xžwÍùˆ8¿ýíoŸ) .ܽõ…OáǨ 4&jødtt6̇~(–È‚ž™ÒòQé !{vsêW³Fþ6"ѧm›ÔdK°"ªRǘ9„*†ýâÅ "Þñ”Sj‚NIñ =ñ,¬¯«®*0»°ÐÓ#¢¹ãæû{‡¢©Aèebh²M÷«[›;Ê}aÙîööv·, ¶I]»¾—Ê%ÚÀ)^ªÏûPœ1þ¤é‹±æÃzNR¸Ç<ƒäeØÑmgÏ|-aë‘aÈ(¶öñ2š|˜­3ÛN| Û[ýÚìœÏ޵ê  Wmìy‰Ò«bKÛ]ñŠ|´Ô Íp–v•[š°Œ0ÓÀ¡Å¸uŠ@ß^ËM\˜PÏBL‹Û`aþ­æÄIø´”¤Ý‚ÉÌ„Ú)‰ÅbaÉÎ â# KL_&{øíÛ· (PàÝXîÃÃ}loçÿaBÇ^HrêÞ¾Ånþâ‹/p{º:Ó,ŠHËXƒ´ž jAÎ.P…—ºq㚆©«ØôkzXžîE:W°câ@À =ËÉH4¹9ÉVS‹!N\5¸(ÏåÁcÇ·D…™‚¡÷?ÿó?6Æ,,Ô± ¢åØ´¢#RC߃l¤™Jø s¾p‹ñQÉŰAÃ+ñšF¨4Ôîbω²$[jey•ARËBªJ¤tÑHÌB/³u¸H’=«hYWKéIÝÁÎîþAUb9Ú+.íørëHŽ<ÃÖ lbü® <¹&µú(¦O¿ÒYI<ŸY‡8õ4R£/Q*žjõì,Óýàâ æÃ½}ð+Ü+$¦¾«³Ñ¾• ¨fò£ö}¶`Æ¢ÆÉ¢ %† ™-åb¬ìQ1Ÿùè|/^®”:X ÅíÉ£Çà#¸0ÆÙY‘g#/ÆÌлÃ6B Û¤c+N\÷ÉP“Þ‚ø37hˆâs˜ôšzç€ï Bg®dy'ÏÄÆnž™™¡ßÂK¡iµ-1Ï9]Ђ€qxÿ~Có¢ÿþïÿ†«»*•rI [ ÷m8NÌÆÍ¼Óô®œ•„lìÝÂG@„”Û¿ûÝïX÷"äey©ÞDú>€` å÷öök¾«¯¹&]zHƒt”èíîÃØ^¿~¥±2)ÏÛÚÙ(òXКyRëÖʇÙÀS0q’“@_GÐ=.E&á~sE²O·±!I܃‘NÅR#¬C`k“6³‹¤£ÏÂÛ@]ºr¹e‰Ý«r¹HßkÌ})5¨13‰ G5,)üÍ\KpåÊè´x} ¹uä.ä… !ñD­–×vh9ÅnM‹¼œS­ÅfVÖ%Éøéí…^íeLåÙX>qõõ^¾|ùúÕk:]uù~wŸtHëž1“óŠ7oÞ‚JÉj8]ÀE “tKßÇû ¿ëׯxücëªÞ“³‹äè;Æ87£QÄÊ0E®=†ŽÕÒZœ;ÒK¨^ÿÍo~ÑZ« 6€¯±šVó4„Åt‰KH ƒÀwq-6GP7¦çµ pˆ%(!=× ÇraLVñáo¹,5 ˜Á?þøîÝûXQÚc Òˆ¡£Œ)îëéÇ7gfžƒõÀ`‹G‰ª{½À&fàÜà(›ÛÚ©B[§´H¬=ìdn4„ÊΓjy^Ð/wvw—WVÖ6Öy×Ú] wÀÔaKmníÀPóåSf©sÞ´ZNÔ*XŒÖy#ÚVÚá,âÖx€nÑ[t¼C…KòvÃI0Ÿ˜èÀœCä‰Ôct"½&#{‘ÞŠÙ©Ù"—N¥BF2ÿa@Kª½vùò+4b–6¿•RÒüÎéM±‘ŽpHãG\»ru}u ‘rx‰;”qÑ]…tâ˜yöøñc< AÛ‚l'¾¥FÃkÚ®¡îÌic ŸÔ.óÃÇ ÝDã/ÈÏuÅäîoaQÎ!v¬‚î‡Õ¢ë!y†i»ÛÄGê{™\Jí7ÁÈïuÔ cŠ »G¶0Oë迦9ä’lx#gQ`%À,a¬þÍßüÍÍ›`y˜‰ÇnøÂÐàÐîοå©ÝБÀ>÷vb—ð©ÛwÜßǦ? NëµÙ< @,¸òüÜqÌîl»Vqnªy´#ØÇìì,¦«/ i:£äIæÂ‚ƒz-é\̧+JÄ(.¨ ]¯‹w4Í|¨´ÊLfF«+/Ô3-øÕ0—#æ–µC{#°åTÃݽ=ÞÓÐ(‡ÚW kU´mnlõ2¡¼•ö%ZŒ6äß2…ãY—8þBþ³K"‹Î²_k\Ÿ»°5¾ u˜ÝÜ~alBk WØÓŒõÊw²žiuµ>TYᆛ›ï”ðïC„-ÎF_»€ÄšŠáÀ, f0gKr²Ÿj¿ ÑkפttNÍãµõ6°}k¥RY K„b0'­{ªu5jPZD<ïí wЖmÍuÂܱr‡º{Ë©6ã?˜ÃÃØ@7oÞ„<ÄrË>4luMmÞâæöÎüÂ"66ŒçJì"Hè¤M í“l€Ä] 4<55uûöíÍu±Ó`€‰B<~¹„‹…§Ïg^L>x åKúÈаc…oß.>xðàÑÇ oßbÇzZS¯9Ò¾8ü”¥uúIpŒiqqÚý8;QØgtºH‘8bâ<ÒïÇ-(Kø±;©·stwwõƒQiúNP*үƼ\/UÈÙ#cuuª1ø—Tâ é9ñ2C‚‘»½±½¾²º¹¶Þ¨6 Êúš<.‡Ç”€j¦¦¯¯'«¸ey[ß󰃽ÝÝ¢ö¡ÛÛÞëîécÑr¯B[HL^˜¸zùšzù†Í`!â7†Ùäxe'lxf®—ɾ8¯oæ¬ÞQnq··Ò}42¥´lÊÇÃÈõaB€lîÞ½ T¤Z¥ÔþйÀÈÎu¤É1žçùq›t¥¯?á—™Öàî^®S¨—±%¼L€‹†%ø"8 Ô•lD;ò¥sIŒT&]ýØÓ™ÌëïäÕ¼£Š=¨é°VŰÁyÄiyx Æj”DDÇä`ù?ÿüs)@ÙÚ¼xñâ`ÿY*3 Â'O$W†=Ñ2íí”aKneÁÛÆgÄÑ%s¶?¸®Éà44ˆ¥î™­Ó³5VqšY¸P»»]”®N?Œ¡Á,|.}:15ÙÙ}L­­<ø³gÏèù“pQRFÈ ‹@ç-f[Û½JSK‚„ŒF°1܃¤dë醑Ñ%¶·?É=J‘ñˆœ·¾¾Ê%xøð! ãûpáhövq¦—žæ6üãm³É8Ñ4U'8¥hvdh9."ëòÆlbî®^½|ãÆ <êæÖzü‹¼ T÷qÓßÇNðµ§wDe­¯¨ûµÄ¾ÝÖÉV夳“¼&Ù€¿ôôJÊÈIÓÅdK$иã³ç3oæðÚ¦üB }YüðCÌ8^€cù¦nƒbACX^¬ 5mvÆMÁ¨<¬ú‘Cd¹u˜&•#—õ–Œ¼yfffèË/±uvvö° P`4ÅäPº†½®é>~óæÍêzÒ·"5R«‰©ŒE¿¨G9Àã¡dÆñX‹ $ûsEàæÍ›_ýõðð0îk .ËG’^u^âß ÷x:Âînç=Æì»“ÚIiø4Icˆµ¼´ÈFÚØIoß.j`yϹò³ƒaJšŸiåì|­Y3s–Ï­ÖòPXh<Åe¨w/JsW £1ˆ•4ªLcëx¼´!Døú5䌪î짺¥=š–ÓÖ†I.C3»HõŠkÜ Ìc9XãÙU…M@ž=y*F FqØÞ&Ô›nk>óÞ‰ñÁ71rIY¨TªÕ© Õs>0TfY9.àÄ} Ø3 »ýˆêhö–i“˜æéÙŽ é¶a•‰ÃÊ.•ß–6Å^=ÐÍ(a¸M†ò*T·žŸ8õº×Œ0}¼¥¤PvŒ'®eØŒ`ºÂ„º–õZ]2DÞ.=|ð¨zP{ùâ#xØ(Ú™zJÚüüB x&=“*xÈA­·‹É1 ¼††ÕÃÝ݃ÝZ£º_=èî8r»“Éxìl5ˆBìÚׯf™¨à„UC‹Ó/M‘t5K˜ärG‰áuõXjbG¨ý]õ!â_ ´d}E›õo©‹Âóº³kAÆ~V|¨8ͧw¹.DÕ½¥Ã¿@Í$ÁÊ ‘?óó‘:cZ\¬xí£ÖØØ?[åŒGÉæ 1‰¯T.1³‚ú¯¥}ØðØ6wîÜÁìAulÙTšŒ%Å«sóók«xIEg¨œ=i©glU© Õ!„çabõ!ä±»»ÛìéöâÅ‹§OŸ/-­p Y7¤§M@±‚ @¨Ä,Îjßá?<2­É¹^²î`'^@"qQÃêX#ÇÊ“† ÙGü©[Gƒ~ê¬Sf¸ÒfKÜ´a UJå­Mlèñ‘QìžMågQÆCSÔEL·º¿V¡aE±-´aî¡‹nhé€ÝÝH=dRz!d T®BIf²îÕ Ô­®¯ÀðЖ•¬‘Ùtšëk¬ßøÒâ½{÷@éPŠ–V–›1:çÑ: Ý7I¯-]…ÊäôÈ;ecmmS«Ãð¼x­X>"1{q Õk"a¤ìvc;¥.?;¥Øvb´‚Ò0Ffó6CP\ú¬‡9%®\¹BSMrŒz{AZØÖž•Ôæyi#6b‚ɤÚÜfÉ™?àqèµÐÏtÂe±ÝÁµïß¿ÿÉ'Ÿà¦<%.;$Ö²rJnšèåÉ.¢ #µQ~¡¡Ájpê­mºdÁJ@WžDÿöé4Ö:©M×¼8ë.fcèééi°6ËqÜÍ;g”â|D襺A6Í׎‹»z6õ±nˆ=\. ÕÆ—Øþ7ï_ââ‹´-,ÄGµ–=Å!qÆD1+ûº{z:;Öâ¨vxP.>Ö>úø¡\GˆÊS;^8$ž"ê° •÷WÕ"/±Q.œ´iÒbŠ„‡‘ÖYÙ^õ`kׂ޷]oËPñS—ˆ{|è0ÐH娆•&yÖB øjfWÙ7$9~UÚªw||BBšCCK+‹Ïž†{Õ}(ÀÒyÑ+èêpØ}ï{É‘2.æžu’f°‰!O&&ÆçççÖ×S>¹3ÅÁD¨u4ËU¡"â›LÝ•¡is«­êVi&røI*fÀdWUœ—!Ð[•:iÚwRî|íÚµ?þˆÙÆþn÷ãûvš›œº°¹µ^_]­Vé÷ÒóÏšýæ,”°Û¹ù7à- bŒ/ÜR+¦ÈBÌÃË-=f½6áC„ÎI…€Á°Ðù$],¶¸--A„¯¬@9qéI×ôÔ8¼{÷.K¤I½Ü1lDKçuœž×§ ùØ3³GÊJÙ@%¡‡ŸH?_¬†‘ôV“ ´ÆÆ×ìœÔi"Qì€:;‹ª&í9éÚ´SNÉ–Îbk«aõP<ÿé IA„~Y+±U«ªS½ZÖoÖò'ƒÄ?ûì3² è?صìŨݜ$@ZbAG¹stttú’ vóæÓ°Î?.CÚ$>š7j†‹"¶š×–vÙ w»S"ÄnÆfÂ¥pg¦¹ìÇdyço‹ŽÓí€}©íq *YP. šbY%óûèáYG¨QabWȨ"능¤€C½#5:˜`"Äÿ)[<¾öJÃ7ñDì (®ïÍ-•½U/M”o¨içR曄Dȳ.\‚Žt>8W ׿"ØnQ³ñ©wNxn"ä2`f!a¿AysI¤Ž˜¶C?K6¡ìX¸áb61Ñi8¯6Ž®üB@ƒ0E"p~䑱Q)÷V:Ì^¯:µÁÝï¿]z+­4UWü¬ÕÓà ÝÄ‘ª©^Z#J rúZÅSZG0Ýà—OŸ?Û…ªr¸/Ãã|ikY*–;*V½Ý}>é¬t¨ƒ‘)­Gª³«4ÿ—ù—Òhhtô«¯¾â1[òìe©Ï*–¥äØÈ(ÆpçÞm˜¦&±#·wvæ—æ‹•2ÏWÇòÄ ©ÆuaõEawGÒ60qß9áƒ3†‹c¢ İ“’x½S¹ÓFì9ÏQºå¶ˆVü«I«»£Åõ>|ˆ=‘˜ŽpmÊm­6êÀŒV$ÎÑ –Ö QE’Q´¾)ýÔðæôô$´÷>úèúÕkׯ_÷2Jl ³­V«RÁÝÙÕõfnÛiw×WíÌç)}lxÉ0•ü2R·pÌ.ò±€à†Œð˜tüÅD  _Wàuv*~D› æô¿øëÓA0m– dG‚™tnÛï|óæÍ›M=1:n·³-y3Ì0wUŽYÞD>‚‘³Ã/73Ùv.Ž¿˜v}ø‡”„ít"’gd÷f…5†EWŠ3ßå°ÕNÑš°]0Y,ÖöŽš Ùá¶Ü WÆx5‹&¹˜¨NCÑe-â.œàà‹.¼ÓL‹QhWoïÕÞ^éf[, ŽH2Ô‹‰ ­oÔ£fè +!¾ÁRqxhT<º#Ãd~ÊóÆÔ p J£?ºPéìêîë]\^H —*ÅR¥R×n|J£C£·o}pù⥱á±fƒÊ¶E Ž2ï>óÝ0 ìp#¦õÞ>XE ÏèÒäÎÑÓ)aâ¤Kˆœ÷P”Pjâ²f~¨%Ð<2p)Ùùµ}”7²TŒ„y¤Ž`0á/NAPu £§l·mØi2Ð~9l˜ "d^„óQ{âI†;;[ø2¸Ã’°á<¦cgKZ˜tÐÑLãl‰¶ª»°ÓTÁÅüŽ^‡© '“;ÆÒ®®¯¹æ¿ƒ#ÂÕ&§.Ò_ÏÜ+†¤˜ŠÅ+3mRQØArú·œ—Xxšd¡«ÒQ–RîJºÀk}dü……#GÛ-ËòC‰•-2$þIÒm*þdw[Š? {ÍrB¶Ò*†{€èªîW¥Î@~uq.…ê½T¡'äÚ(E†Q½Õ½àø^`±žzËpžŽ5æ,`®"¦;S‘]ÓSô.Gix1ªÀ~àòùi²¡§Ãú]̇|újFâ»ãÃ㼎&‹gìO¯éa~’|ö´Wp…n­.¯hZ)àìÇ~ î,F¼ñ·¥Fç½Í¿saË,goF)5?`ÀÇ™°.þË<æ3Ž û0xA-Žç¾u…~×8=ˆ± wÈÉ;w†¤ˆML`B÷öÁDä$=ãùE¥H¿=Ÿ°=ø›½2{l§ƒ±÷Û‘¾ùš2Ælô8+ù˜ÒDøõì£Gx†;;Þ¼.YìlÝ•·ž¤AuËQ¡ÅX;nÁÀѦ/;¬vó#âÎ}²2Š›‡ÕU-æ@6¨kdÎ9{¥»ÙÆT;¾pÆý×ô¨¥ßi7L²?_[[QeŠ®Ë¬Òh75Ïbtµ%H&  wo®®®ÓDdv;vceß,˜gTK'Ýè=ðÇL»šçÞ?6IçﴤΜ]qiqÙMp¸+ë‹À¹$aðy<Æ@Ï Q ÃJ<{4ËÂ}äM×sŠGç©“=põ©®1aT¡±ãÆwß>À€ª‰[ÏϽ$k˜žžvV+E³1µ¥RÒݪé Ô’Ÿ………%(WZêæ5êž®nmt¦Êž„DË…"®9Ø?Ð×Ó[)•[f©åuœ‡rÛáKÏ–ÜòsÊ=¯é5pŽ–£íØÎ°Ý³K¯oÙgIWOÔ ºXVFsl)i6¦Òò~‹6þ}ð"<‰uµÜ>NÊÆŽŽî,o£¯ÅyÉü´è!{tÉé:OËJ·/Æ1søÝræDBÞ’êí†[;žvñXúsÅ'ü6¹m@ùa“ž/¿üòéã'Xûr‡4)Z|»"„%Uª©”ö—ŠLÎÒþ%×Õ¶l^viiméíÒÌÌÌì«9éZØ–Œu•š©“È7ðxÊvjVóâÉÉDQ]T’ñdÚ娶FÀ®“±_.–ú¥Ú½{÷._¾ÜRjpìNÊæsµÏÞYlïS¾pÊ;ÇÒ̱‚è×lyÿ¤«¹OO¹K‹˜=]&œÉ&dvõòò2Oç©<åNQ–6Ó³ŸVa7[º¤;žz¥¹ »l=Ô¬O×§âo™G±ÀØ€S®(Z™Ç@µ t9|ó, ºìë¶ã×32× NúÊ©› ù&ƒ¿ý½}0ÞXµäk¬! £ýê ÝýJ±T×&Ó•Jicmsiqj*ËÕð“=²ïíŠD w?òcé˜(ÄÌø„Ö@IîDgw§zØoÃÚ¼råJ{|¯]‹óý÷¬ˆûž8vsSž4Ú÷¾…w*79ãG?,ÎdBdAš=Q€yÞzéò™ÞÕÉ0š£À¬†Éð1³æy0DYÓbãR¿•S¬ pŠ_Ã_ÜgtÀŽÁ^ÂcÎZ;§ÿ©óJàQÇ zj’-Z€ru5KáãþÁa¬§ͽ™å<È T¥4 JII'5­H˜W¬‡œ$§&ÆrÍñqIoúó?ÿóÏ>û,›ÁûêR†ïÓ‚õü˼êW¯^=z´¢piæî4_S„áe›8’"Žfzx'5Á.MÖ)oGNíâIiz'6–Tp -ñŒŸ ܾ‡@›žž¾zõ*ì^=]óï7ê’Æª½89bC{ÅBÀ>ŸåbP;ÐÙ8ª×B!m6="Å×¼Ú Ñy+ô„ŒØ+—Êcc£×®]»­h/ìÌ{> GpZ°žåhoi³÷–Gd‚&ydŠË91«þ›'±¸|<:iÜûNôQzG‹™íÁÚûh8ÓY ÁÂÞìÇ6ùüéÀ ibb‚GyA«Ä3¾zõš.bQ³ÓîuÚM<`éˆöð9áž¶ˆ×Yˆ]Ϙ ð]qhtÈŽo|ðÁ§Ÿ~úñÇß¼y3›áñœÃiê¨+d¤¯…ùuÔýÜG.ÀÍŠŠ3=/¼´-œ×,¥-²ž)úH™¤7RPfºÁpƒ:"dSZæžÔàô§ Ä;wªÚe¬¾¶¹¹U×úÆ8 ƒ$"…RÕ!uÃ<*ˆóŸœæËñ]Õz#­íJrúØœ##Ã7nÜøÅ'AÍVÙduÃO §¡³è`“hÂÉ$ Ï©‚²ª…~s6&h÷nQ_uÒ‘Ø+l)Oµ“ÔųÜq¢«¥G^9Bå75-ÙñL§bK‚ìMóžÕcà4|Ø®—/_f(Á‹ÅžŸËîæøZ©PôVHG~C²•:““baRöèé7<¡zkGr;ÙöF¯#éÅÓÓ’{ù!ðÑ=PàØØˆ›àh0ÆðÓÁ»½£ØëXrì¬=ˆgrrÒKÆØ ;ð’)—\£Ál„ËhÃE˜,Ë —ìæ dïzþÕ3«›ÍUý´ï³rÁòoݺå²~²;¬%ÖÄ.z¬l˜˜òøÙÒÒ’6ùÓÈ>3r’ÎH½ÒÈttL8ÎÐÈh˜ekâdf7Ô(”Î/^Ä„|ôÑG·>¸õšœl­4ýÉÎÏŸ8ŽIÌiÇšbyy™ç³î$ÄFÔÌÁ¥øŠÒå²]VwMºNhžÈæ4ø¶݃ÌÕf(Òu\%:Âæ1  =lÍaEÞ3ù´ jäÄÉ'Ïç% m‘|9I))Cýxº ò˜CÚjßÁr@bε `¹zXÇ7¯]»vùÊEvþòN »~:8‘[ÖŒu(î\¦™ÓVä1®®Q †¦‹;7&`* »!2(IËñ/IÉ-'ÚÆéY.tÃ2‹J).ul}ÍÏ<Æ[˜Üêõym PWåAêwxöØÀ@ š´ƒFÀÆ-<ì RÍÀéøøø… cy?“á|8“$ôNÞÜÙ÷ÙÂÏT²yi*̃xÇrnæ»eÛ7ëeOýáÏÛÛ»±öbjÔ#:9“ƒ ¢Øµ™hfßøÙßn«)‘XJ?Ãϧa»-qRúß) ¯gÇ÷¡œŸÕ½ÇàfT¾;ÉËð3Âi>ëöd¢ó2ÅöÒì?[:ƶàXÚnùá)Ìâg½ùZ"¥Ù‡my“ßÌžÿ‘áŸõ$ü‰ã¬ê(qv¶ýN‘x–ÈÞYn÷LœîÉ<åaÛU’ÿc3óç#BƒÁðƒÃR( †œaDh0ä #Bƒ!g 9ÈÐ`ÈF„CÎ0"4r†¡Á3Œ †œaDh0ä #Bƒ!g 9ÈÐ`ÈF„CÎ0"4r†¡Á3Œ †œaDh0ä #Bƒ!g 9ÈÐ`ÈF„CÎ0"4r†¡Á3Œ †œaDh0ä #Bƒ!g 9ÈÐ`ÈF„CÎ0"4r†¡Á3Œ †œaDh0ä #Bƒ!g 9ÈÐ`ÈF„CÎ0"4r†¡Á3Œ †œaDh0ä #Bƒ!g 9ÈÐ`ÈF„CÎ0"4r†¡Á3Œ †œaDh0ä #Bƒ!g 9ÈÐ`ÈF„CÎ0"4r†¡Á3Œ †œaDh0ä #Bƒ!g 9ÈÐ`ÈF„CÎ0"4r†¡Á3Œ †œaDh0ä #Bƒ!g 9ÈÐ`ÈF„CÎ0"4r†¡Á3Œ †œaDh0ä #Bƒ!g 9ÈÐ`ÈF„CÎ0"4r†¡Á3Œ †œaDh0ä #Bƒ!g 9ÈÐ`ÈF„CÎ0"4r†¡Á3Œ †œaDh0ä #Bƒ!g 9ÈÐ`ÈF„CÎ0"4r†¡Á3Œ †œaDh0ä #Bƒ!g 9ÈÐ`ÈF„CÎ0"4r†¡Á3Œ †œaDh0ä #Bƒ!g 9ÈÐ`ÈF„CÎøÿ¼_oGÃTøIEND®B`‚nagios-2.6/html/images/logos/unknown.gd20000664000076500007650000000452507436604467017656 0ustar nagiosnagiosgd2((!!!)))111999BBBJJJRRRZZZccckkksss{{{„„„ŒŒŒ”””œœœ¥¥¥­­­µµµ½½½ÆÆÆÎÎÎÖÖÖÞÞÞçççïïï÷÷÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ                 nagios-2.6/html/images/logos/unknown.gif0000664000076500007650000000240007436604467017735 0ustar nagiosnagiosGIF89a((÷!!!)))111999BBBJJJRRRZZZccckkksss{{{„„„ŒŒŒ”””œœœ¥¥¥­­­µµµ½½½ÆÆÆÎÎÎÖÖÖÞÞÞçççïïï÷÷÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ!ù,((þ?H° Áƒ*\Ȱ¡Ã‡#JœH±`‡2dÐpÑCŃ$$ 0@€€’$¸àñ£À @³&M™<èü˜a¦ÍŸ4@è ³¥Äž@“¨À¡£Ñ‡H8YÒgÍ 66Ý ±g€,\¨€Uš*\ȰèS† ,ÈÀ!ƒ ø9  ھeH#†  èýYà„¿t‰Fô`˜BÎHÐÀ 8^Hy¼öÚ Ð€Aƒ*ÐåêrÝ hFКƒ0l…è!$’?xÐÛspÁ½&Ç*9ߟ…KîªY ˆ­Þ¿Ž ›m‡QoRÈpÁ²ƒ‡6Ts…»¼w»BàíÜ­6Áù9` §y£-`Àeúñ÷˜ ‘Œe>à`6—n2É4À~YÀÖp¥w“"ú'˜‰ É(ÕŽAcE:~ÍwÞDF(áÀ‰£CqÀᇎÅÙ“µU–ŸcÀý‡eC¥F!‘ÏiXQiT@`~ÉKè$¥‡€ç$œÙ¦Aô©•™éÔl`(¡ná9PQ5Z”¢u$¤;nagios-2.6/html/images/command.png0000664000076500007650000000224307436604466016554 0ustar nagiosnagios‰PNG  IHDRºWí?,tEXtCreation TimeMon 31 Dec 2001 12:39:41 -0600Õ/CtIMEÑ (‡t2 pHYs  ÒÝ~ügAMA± üaPLTE!!!)))111999BBBJJJRRRZZZccckkksss{{{„„„ŒŒŒ”””œœœ¥¥¥­­­µµµ½½½ÆÆÆÎÎÎÖÖÖÞÞÞçççïïï÷÷÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿf³)u tRNSÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ\\íÂIDATxÚËŽÃ Ei›Ð€ &€ÿÿ/Ë$šª‹nfîòÈÖ}þ"ñwX¶˜c!•΢Rޱ΀‘@c8ÍVº Öÿ¼]]µM½.*µ¡dNhˆ¹ÚÂNj;”ÞwõðRåÖ†uÊ”ï€èõóŒbʆZU™–iÿ€ÌmÝÀx¿ö7ÜE‘2í‚·mÖÚ ï;¬›.7™“™-ξž—Á,ÏQ·ŽÞ¥kÞ7©1Öÿîù©÷¨#œìûóèIEND®B`‚nagios-2.6/html/images/comment.gif0000664000076500007650000000160407436604464016557 0ustar nagiosnagiosGIF89a÷Æÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ!ù,aH° ÁƒX¸0aÁ…" àp ‰j|£Ç‰vüø1d€‹$IšD™ÒcÓ-U†dSâÊš6gâ´iq'C‚[š4Èräă#5þäXt(Ѥ/*uŠ0 ;nagios-2.6/html/images/contexthelp1.gif0000664000076500007650000000270407436604467017540 0ustar nagiosnagiosGIF89a÷!!!!)))!)!)!)!))))!1!1)1)1)!11)9)9)91!91)911991B)B91B99BB1BB9J1JB1JB9JBBJJ9JJBR9RJ9RJBRJJRRBRRJZ9ZRBZRJZRRZZJZZRcBcZJcZRccRccZkBkcRkcZkcckkZkkcsJskZskcskksscssk{R{sk{{k{{s{{{„R„{s„„s„„{ŒZŒ„{ŒŒ{ŒŒ„”Œ„””Œœcœkœ”Œœ””œœ”¥k¥œ”¥œœ¥¥œ­s­¥œ­¥¥­­¥µ­­µµ­µµµ½{½µµ½½µÆ„ƽ½ÆÆ½ÆÆÆÎ„ÎŒÎÎÆÎÎÎÖŒÖÖÎÖÖÖÞ”ÞÖÖÞÞÖÞÞÞçœçÞÞççÞçççïœïççïïçïïï÷œ÷¥÷ïï÷÷÷ÿ¥ÿ­ÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ!ù‡,þ HðРA{îȹ³çÏ ‚#²ƒfL—*Qœ4y˘;Cöyƒ† .U¦hT’„å2~B4çÍ›5gÄpÁ2¥I$@ƒNyóPâ9säÔò :€ R¤j$cB*³gš%5f´HA6ÅŒ=¦‚DÄ=jŽÊéäEŠ 6ÔñB† -íd:CFŠ$®|Éà÷À‘Ô„ þ(hÎÂ…‹$÷P™"ÅÈ Æ,hÐ`CnZð@ž‹„É¡Q:Ì` s/°00ÐqÜŒÀ‚])”7Ç!hüT2çÂØÀGji|'¤à &T¨Æ!g 1ÄË9‡ ŒHH ,0‚ )&Øb k"‡Œ=à`£s,,™nÀÁ#TøB )˜` v²‡C$i#y  À™pPe 3èÐC ?Ö@Ø Q„©$s/˜Wæ™°A -ÔTŽ`Ä@\؉§y,À”n`Y=¡„ €0BÁ1wæ¹¢W€·_ 8ñdÚÂ…£âE’4ÈÀh£BIÂ/è #xÐjíá4İ¢(ଳ¼ ä DQ½Ñà ¶úÇ (˜ ‚¦d€èžGD²öPë²áŽ©``/º#t’!p<ÁíŠYŽ0.½ìoÈ4 cüÀœË›é ^¦0Awˆ±* ,”Uƒ]ÌqÐÅý1GcŒñÆLòË;nagios-2.6/html/images/contexthelp2.gif0000664000076500007650000000257607436604467017550 0ustar nagiosnagiosGIF89a÷!!!!!!!!!)))!)!)!)!)!!))))!)))1!1)1)1)!1))11!11)1119)9)91)91199)991B)B91B99BB1BB9BBBJ1JB1JB9JBBJJ9JJBR9RJ9RJBRJJRRBRRJRRRZ9ZRBZRJZRRZZJZZRcBcZJcZRcZZccRccZkBkcRkcZkkZkkcsJskcsscssk{R{sk{ss{{k{{s„R„{s„„{ŒZŒ„{ŒŒ„”Œ„”ŒŒ””Œœcœkœ”Œœœ”¥k¥œ”¥œœ¥¥œ­s­¥œ­­¥µ­¥µµ­µ÷Z½{½½µÆ„ƽ½ÆÆ½ÆÆÆÎ„ÎŒÎÆÆÎÎÆÎÎÎÖŒÖÖÖÞ”ÞÖÖÞÞÖçœçççïœ÷œ÷¥ÿ¥ÿ­ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ!ùk,þ×H° Áƒ :#F†„ú¸¢EK–+V¬DYÒãaD‚-ȨA3¦‹–ŒV¨L™%G‚ ¸ÄÓ 0'£èܹñÄoôà¡Ó& •%>fÌÈÑ#I“&N æHFOQÓ¦M96ЈÜ4ö#âC¦=0ÔrM#9f pñÅŒ,@i 3làð)0Á–0a®øÝÈJT0'ò6bþ$‡1ƒ–-]žøÂ¾G,(ìȳúˆ6`ÀP:ðÄ•ÿF°×^ÁáGcn @ âÁÀ 6馮 TDáëµ×C"ˆ 8ð` È=8•EJ ‘á=äÐÀ\s̱ -ƒ‰ôÀSI¸èž{2 À‘œ ^—9è ANéÃ=à@‘H’°ÔI$Á—)DAA%TQã.tKDaD +°€â@*(„0iƒ_·C@!Å,œB ÔC™ªY£ ±b&œpÂY0Ä?ð€Ã©6TÀÀª«žPh]$ÄJB'J© ¸Ö  uÆÛ§ ÄÚ¨A0Àˆƒ 2ìªß )x ³ÏJ˜6ô€«²ÌžP ЂúÑ ¨*ËB³ž’ÐãGÀ‚R38ج´èä€8ï½ñ;nagios-2.6/html/images/critical.png0000664000076500007650000000255107436604466016732 0ustar nagiosnagios‰PNG  IHDRºWí?,tEXtCreation TimeMon 31 Dec 2001 11:56:53 -0600*n¯6tIMEÑ )ÙÐ pHYs  ÒÝ~ügAMA± üaPLTE9JRZcksss{{{{!)„„„!!„))ŒŒŒ11Œ9BŒBBŒJJ””!”99”RZ”ZZ”kkœœ11œRRœkkœssœ{{œ„„œŒŒœ””œœ”œœœ¥¥¥¥­­)1­JJ­œœ­­­µµ!µJRµµµ½½11½„„ÆÆ!Æ)1Î!Î9BÎBJÎÎÎÖ!Ö)1Ö­­ÖÖÖÞ!ÞœœÞÖÞç!çck焌眥çççï!ïJRïZcï{„ï„ŒïŒ”ïœœïµ½ï½½ïÆÆïÖÖïïï÷!÷!1÷)1÷9B÷Zc÷s{÷¥­÷ÖÖ÷÷÷ÿ!ÿ)ÿ!)ÿ)1ÿBJÿJRÿksÿs{ÿ„„ÿ¥­ÿµµÿ½½ÿÎÎÿÖÖÿÞÞÿÞçÿççÿïïÿ÷÷ÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿn®ûutRNSÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ›°Þê3IDATxÚUýK1Ç-|ÃäˆiÙ¢Lñ´—³ÎbW]â,ÊÐaiÇNÄ,ì¸ÿŸ¶; úü0¶{žgû‚/ñæãQ÷áqüœ|Ë÷hÈ(¥¦qÝ^¬äìƒsî0j™i¾„r6ä®ër‡RË ¤Þ—òë•»“éĤvnûðóƸ;ýœþIõÒ‡ùý¿‰÷ï`L©ôŒD–rçž,Ê9=•Óõ*VáÞ/dŒÑõ5áHMEJÚ†iQI,f4ˆ®a´qÏ a%¦pb6VRGÐ#ÄÅUŒ™,š$@ׄK'·+à÷êz õš¨EéøfñBü½UÓ$UK—*Tl!½Ö1– ¤$’™½ò ̳‚„QñÔV±ÜY†ì{7»¹l6—/”ÎìUò’ΕàvìB5iû>}—ËIEND®B`‚nagios-2.6/html/images/delay.gif0000664000076500007650000000170607436604466016220 0ustar nagiosnagiosGIF89a÷œœÿÿÿÎÎÎÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ!ù,£ H° A *ˆ€€ #&$ˆ°€TlX ÀD„,z|Øð@E8pqÄ0ÀDr¥M”.eÆœ À"ËŸ-uîäéó&Æž¢è´©ˆ:ß,h4ˆ@—MA ‰“M<î¼sÁ” ä`´¨†%/ šds“ŸŠÖí4!ÍWIRmUV ˜S 6Aê*ñÒ-5Xm"$h ’ºŸBuäÔñÊW›`”©èD›L pÕ ÁJKd¼ÉHW8\‘ÝI”$;4ndª4 Î9”)¹óç®;nagios-2.6/html/images/flapping.gif0000664000076500007650000000110207436604466016710 0ustar nagiosnagiosGIF89a¢­­­ÆÆÆçççÿÿÿÿÿÿÿÿÿ!ÿ NETSCAPE2.0!ù ,HºÜþ0ÊI«½8ëÍ»ÿ`(N@ižè—!ù ,ºÜ !ù ,  8ÜÞb¨GYœõE»ÿ–AÒ2’`úlë¾jL$!ù , $8ÜÞb¨GYœõE»ÿ–AÒ2’â¹l—Ž—yñl m®³ !ù ,#H°ÜN0ʇ8ë,†Ý ÖQ¤ô…[w¢œw±m)Ïtmßøœ!ù , H°ÜN0Ê)m4ëÍ»ÿà—!ù ,HºÜ !ù ,ºÜ !ù , HºÜ 0Êéj"èÍ·X'jŸe†c÷¡©f­›!ù ,%HºÜþ0º!‚½øŠA³·[÷e›ôˆ£ÆU©Š¶¥Ù¼iȶƒC!ù , "HºÜþ0ÊIß!ë­Å¸\˜y ÈySšÝ‡±mÊtmßD!ù ,  HºÜþ0ÊI+8ëmÛþ‘;nagios-2.6/html/images/greendot.gif0000664000076500007650000000051107436604466016722 0ustar nagiosnagiosGIF89a Õÿ  @@]11Goo jj™ee’\\…XXDDb++>""1$ÀÀÀqq¢ooŸjj˜ii—hh•ccŽPPsGGfEEcCC`00E!jj—aaŠNNo!!/ ÿüùôïîÚ×Ïͳ±†|{mL<'  !ù, @f@‡Ð¡ Ãa"Ps¡T1\æ!œxh¥‘vÔu’à0q¡£Áf6PeHÑ̶ÚOÞT0l¸0>  `9/&Z,5 B0p#'7B6+[$2I !7;bª«`A;nagios-2.6/html/images/histogram.png0000664000076500007650000004301607507661353017133 0ustar nagiosnagios‰PNG  IHDR„@kÊ%ç+tEXtCreation TimeWed 3 May 2000 15:22:45 -0600E°@tIMEÒ.FÐ$H pHYs ð ðB¬4˜gAMA± üaEfIDATxÚìÝwtõ‡ñB A=!$ÐB異€ (‚Š¨Ø " Š…«¢^Á‚ÒDP)Ò;⥅z/¡§z„ò~ïþ^ǹ»Ih±<ŸÃÉ™ÌN <;m³\ºtÉ8!«Ó+€®ÌˆÑ,YœÞ ü%]wŒz”¨ý¥†Í? -×£ Mû%§¦;í?¹ é»Ö5‡<½KÔŒñ.Q‘À‹Ïµ¼É#C-f¤÷¯8J €´\}Œz—¨^fpÔ“@:®þ4}zqItà*ñœQ8†€c2)F9G€«Ç‘Q8戈°^ÆÅÅ…„„x·ëÖ­›Ó뀿°?bô×_mذ¡÷Ë¢E‹îÞ½;Í7=ÚéõÀ_ØåcôÑGýî»ï40xðà[n¹¥@æe–,Y³¸Ÿ0úôÓO„……Íš5˼½ÿþšXSêíãÆ;räH£F>ÿüóú裯¾úJ¿ÒHÕ­YŠJ× ¨YÍ€5=þ®®4FóäɳxñâvíÚ1bРA.wq/^\EŠ™6mÚñãÇ_zé%¥ªÆ+VLc8ðÎ;Tzšƒ Ò»wï÷Þ{ÏßßÒ¤IæØê¢E‹¬õŽ`üm™óòÖ…¡/­…c‰%\îÐüùçŸ;¦U/êWsçÎÕ°âR•iÞ® ô²I“&úiÆäÏŸ?11Ñ «Y]î3ø9sæLoq뀿¥,—2ûË“bbbJ—.Ý¿uêŒ3œîmüIùdúûõëW¿~ýÄÄĆ 2Äé ÀŸWæ®ßMÇ£p 1 Ç£p 1 Ç£p 1 Ç£p 1 Ç£p 1 Ç£p 1 Ç£p 1 Ç£p 1 Ç£p 1 Ç£p 1 Ç£p 1 Ç£p 1 Ç£p 1 Ç£p 1 Ç£p 1 Ç£p 1 Ç£p 1 Ç£p 1 Ç£p 1 Ç£p 1 Ç£p 1 Ç£p 1 Ç£p 1 Ç£p 1 Ç£p 1 Ç£p 1 Ç£p 1 Ç£p 1 Ç£p 1 Ç£p 1 Ç£p 1 Ç£p 1 Ç£p 1 Ç£p 1 Ç£p 1 Ç£p 1 Ç£p 1 Ç£p 1 Ç£p 1 Ç£p 1 Ç£p 1 Ç£p 1 Ç£p 1 Ç£p 1 Ç£p 1 Ç£p 1 Ç£p 1 Ç£p 1 Ç£p 1 Ç£p 1 Ç£p 1 Ç£p 1 Ç£p 1 Ç£p 1 Ç£p 1 Ç£p 1 Ç£p 1 Ç£p 1 Ç£p 1 Ç£p 1 Ç£p 1 Ç£p 1 Ç£p 1 Ç£p 1 Ç£p 1 Ç£p 1 Ç£p 1 Ç£p 1 Ç£p 1 Ç£p 1 Ç£p 1 Ç£p 1 Ç£p 1 Ç£p 1 Ç£p 1 Ç£p 1 Ç£p 1 Ç£p 1 Ç£p 1 Ç£p 1 Ç£p 1 Ç£p 1 Ç£p 1 Ç£p 1 Ç£p 1 Ç£p 1 Ç£p 1 Ç£p 1 Ç£p 1 Ç£p 1 Ç£p 1 Ç£p 1 Ç£p 1 Ç£p 1 Ç£p 1 Ç£p 1 Ç£p 1 Ç£p 1 Ç£p 1 Ç£pŒÓ+ðWrèÐ!3pêÔ©7ž?>½)“““>œ-[¶ æ–+W.3ìëë›ñÄY³f ×dLbMpË-·8½·.øƒi͸¸¸;v¤¦¦FGGŸt[¿~ý… Nœ8qüøq3åÅ‹5A³ºtéÒµ­C–,YÒûUŽ9Tœ¼±páÂVŒ-Z4þü+VôññѰÆh|ræÌéúsÔj–kÞM]ŠÎíÛ·8pÀ俦M›Ž9röìÙ„„ÕÑùó畞®ëÊA­©5+v Ô£P•*C³eËVªT)Õm¡B…Ì€~™ßÞ¼úSíb€LðàÁ;v¬]»vëÖ­ëׯ?zôèñãÇSSS/^¼x -äëë«°³^j8_¾|°ô …*|íç÷5|îÜ9g÷’J7gΜÊPs588¸bÅŠ P¡j8$$äF-—3ªÏ-[¶¬X±"::ZªMII¹páÂfO¶lÙüüüÌpîܹóäÉfZÓßß¿xñâ… ÖxkúìÙ³+F38·îA«¡µŸâWk%wîÜ©õt¹kuß¾}¦˜ÍgÏž½¶¢Zy¥dÞ¼yº]í M¡*O *T¶lÙ*Uªèg„[fý±ˆQðw³råÊyóæ­^½ZawæÌ™ËÆ–J+ @Y©´2q© Ukr3ÓZ÷‰zQ±h†=²ÒD¤:/ÍÅ)gµVæê¥Ö~„U+c­–rúôécÇŽ™—qnªU³QjÊÝ»wëç•4¥¤…jCÂÃõu‘‘‘EŠIJJº¶jW(m5+UiõêÕ•§E‹½žã¦Ä(ø«R€ª>çÌ™£ß̉us>]åT¾|ù}êÔ©J"å‘wÀ˜ =Í9wSŸ*!åZ```zé§´Õ¿Úû‡¬;Ó sßõÒzˆ’«…Z/5|òäIëå™3g28¦›&¨ÊO[§mT˜šK ‚&µ­<=}ú´¶îèÑ£—MÉ,Y²è]šUm7ÍÐ<ûÉÎ:zª½·zõjmÔÞ½{õ·Hó`°vˆb´V­Z Såiט£àOJñôË/¿Ìœ93&&F—æÑ8%TÊ–-«„Rƒ¹Yõ©rR3][zª5ƒƒƒÕvêN³ó´Nó[ÜôˆQïG#ÙëÓ#Fí©ª*]·nݦM›Ì­§V^_6Ø´É&Oµ&O‹ºiM¬65)©*]¶lÙöíÛ>œæq߬Y³ªàË”)S³fÍzõê¥wÚ]ë¦yêÔ)­ðªU«ôÇÒKï«=V°`Á¨¨(U©þF•*Uò8\JŒ€?uØìÙ³¿üòKUNrr²÷æjˈˆˆºuëšäÊ›7¯¹õÇ’ÂHɵaÆô É›š)W®\õë×/]º´bNª+R¤ˆ)¹›ÿpxS«Zóýû÷oÙ²Åìõô’%K´QªjýJ!˜AÈiÍͲ Á%JDFF* säÈárßw¥ùïÚµK³23ÚÏÏ/ àôéÓöo6r¹Oî«´xàÛn»­\¹rNo·36nÜ£½§žf˜j·‡‡‡W­ZÕÜJoU©væîÝ»7oÞüÛo¿mÙ²E»×þ.ehdddË–-›5k–ñ¹{‹÷ ‰QpS}ñÅýû÷ß·oŸ=B¡¡¡ÕªU»õÖ[K–,i‹Ï¸AÍ—s*Cããã>l@’¯¯¯æsûí··nÝZõ78ŸY¬0ݳgÏâÅ‹ÍÃü-éU©öüöíÛ5½þªI{ñgÉ’¥`Á‚ÊýæÍ›_a’ÚgHŒ€›áÀüñ¸qãâââìùaNÇ««W¯®asS¼ZgË–-&}¼4o޼ŊS*)}Ö¬Y£)ímô:´{çÍ›7sæÌM›6©æí¿²ª´^½zQQQöCÔëÖ­›?þÚµk9bý)Íå¤5jß¾}®|ˆQpc™ ýî»ï¬oZw¹Û¥hÑ¢wÜq‡ÔãtüŠ+TH111ö“Âæ~ðÈÈÈÚµk+^÷ïß?}úô7Zª 4þñÇWýcOÇ_3íÉénÞ'ñ+W®¬O 5jÔ°”^¸pAñª={¶ý¯ 9sælÖ¬Ù•')1 n”434[¶laaa-Z´P5ZŠW6ØïsJ3I/^¼¸~ýúÑ£Gë#„†ÍH}¢¨[·®’Ôû›î‰Q9¾ýöÛ×_Ý—… nÓ¦M³fÍìßí® Ô4 ÖØØX«C”5ŠË† Z7n+g-Z4jÔ¨]»v™i”;µk×~ñÅÛµkçô¶þCmܸqÊ”) ÍM›6ÙÿvJÒÖ­[ëÏmM©ú¡ú8aÌ;÷O<ѼysûÇb\¯Ý»w?÷Üs3gÎ´Ž„YÇÌŠ+fM–’’¢¾üá‡Ô—V¨`êÕ«çqtM£ÉæÌ™c]€ªEtîÜùïzm¨¹ªÁ¾»œšÉe8pàÇ2dˆ’Ô©…š§ßÛ?xh}<.ÃP†Ö¨Q㥗^²‘£àºL˜0á©§žJHH0/ýýý›6mzß}÷ÙãR £FRŒZgðU-j—6mÚ¨Kì'y—/_þÍ7ßXDsäÈѱcÇ^xáÚؤ².v,X°`fµlšÙg-KÉ~å³êõë××€öÏ5§¤÷Lnжú}õÕWúÌ`¸×VW¬Xñ¡‡ªV­šuìÓ\<~üxûG û!Rb\»nݺ 8ÐzP¡B…:wîܤI빡.w_.\¸pذaûöí3côÛ:uê(X=.$MNNž4i’úƺBTôîÝû¸¶Õ3}o^FFFNœ8±L™2×¹Õi¶£}YjëêÕ«+¾µÄ+™áºuë4½V®\©ž»¶µò˜‰Ç¶ëOóæ›ovíÚõ:·ÝÃÒ¥Kû÷ï?eÊëÿ€>c<øàƒ­Zµ2Wýú2wîÜ#FÄÅÅ™1æ髯¾ê“¹+þ!:Ô¦M›èèhs`ËܨԥKÔKJJúé§Ÿ~ùå…¦£zS†6mÚÔßßß>¥tèС“'O6çú}}}zè!•èö\šNœ8¡S åÊ•+%%eëÖ­ª•“ùí–-[”Pæaz55~FEE¹Ü¹©™i¤f« _±b…ë÷ã£Ö²4†—,YÒ«W¯>úȼE?ÍdöºÜQR£kÅ47%ìÁƒµh븦™yBB‚ö¶vˆõ.ûš{ÏÄcÛsçÎ}áÂ…ýû÷¿÷Þ{úåË—ÏÌß<ϵT©R×sr_*~þùço¾ùæóÏ?7gíõw2dÈöíÛ;uêdýíôñã®»îÒ"ô™ÄÜØ$úÏÓ½{÷ÿ;¸*‹/.Y²¤U$9räèСƒ"ïW›  0 råÊV©>ï¾ûî1cÆüêE#k×®m%Í“'âæú×síÚµÊ Ÿ3f|ðÁZ“3¾AƒZýV…¤¥‡††úþNë¼fÍÕd­Zµüüü4Y“&M-Z¤in¹å–"EŠ*THóÔÜôS#UuöeÍš5«gÏžú­J±páÂæ-2~üxû •€jYÅœy—™›úÒÌPBÝ´n%J”Ð4zWãÆµ¯ìk>þ|™h@kb_Ÿ¾}û¶lÙÒäfΜ9UŸJ[mŽªTòÛo¿™™­¸f;wîìÚµ«ýh¨¶ýµ×^›3gŽý­ÿ$ú¯bŸŒ#£àê,\¸°uëÖG5/úté¢B²ŸpOIIQÿ5*))ÉŒQštêÔÉã ¾qðàÁ~ýú­^½Ú¼T-}úé§Í›7ÏÄu>|øðþó5“¹oæå—_ÖV˜_) •kæ ¢"éüùó111Ÿ|òÉòåË·nÝtæÌ™¹sçæÊ•ËL£™¨,9âr?±Hqé±,e™æ ÉÔµÊ>ó–ÈÈÈ=zìڵ˚áÛo¿­M^¿~}7í(¥¤ùiŽÑš3쯼òŠöÞ¥Ž<}úô›o¾© ±Ö\ó<{öì† ì3±¯Ì… úôésñâEo×®9f©(ÔL´ Ên½Ë,ÈþÑk  QìØ±ã±Ç³êSiþøã듌uÙ׌€«`/QõMÕªUŸ}öY3éJ¢#F(FͽJŠT¥ªý¤­ÝÚµk ´yóf3ÃÛo¿]!X¡B…LY[s¥ú2 àܹsšÿ×_ݸqãJ•*:uÊTFæÎ[§b7nœBJe¬fÕ6êsæÌ™5kÖ‡~ªhÓ4?þø£†o½õV½}̘15jÔ0'¸­e©¶µ,Ÿ^½zéæ-uëÖõ˜aBB‚bQ¿ nذ¡µ>+W®Ô€æfuÚìÙ³õrïÞ½uêÔ±¯¹"UknŸ‰ë÷kF­õÑÖiÔšÚ· ;v¬4ÎmôèÑša›6m\îÑ2å6|u¿â~èСæÂ ó×â‰'ì~r¹ï0`€rœ#£àJÙKT‘ѲeËÎ;[_ìiZP•*UÖ[¼g¨…úùùU«VíøñãÖÛµVfq†Þ¥Ž¿å–[45×€BÓ{&­ä?ü°ÿþ®]»®_¿^Æ£_)R¤yóæJÕQ£F¹2ïPúó}ñÅÚö>}úÄÆÆjõ,X u{å•Wì=ª-zã7´>Y¯cYàÄ^¢*ËöíÛ?õÔSÞ%ª¸\µj•)Ñ2eʼõÖ[š2Íݵk×§Ÿ~jJT¥Õ£Gÿûß7¢Dd £üùóïØ±£[·n 8Õ§"©aÆÏ?ÿ|hh¨"Ïå¾ëÿ·ß~›6mš†U“JÀ”””Aƒ©Þ\îªöžíöíÛíßzjF:tÒ¤I>ú¨ýºm ÷ ”3|øðœ?ÞL©ÿüç?cÆŒ±‹jš‘#G®Y³FIç½æiÎÄîðáÃÚ(ÓÜ5kÖ¬Q£F·.]º¨DµþÍÜ<6ä:ió¿ûî»Zµj™—úÔñî»ï®]»Ö>ö€þ qš\žG‰>ùä“wß}·=¶\ÿ{é§~¥¾éܹs¡B…Òœ¡}b…ÚG}ôôÓOgújÛŸvß¡C‡#GŽôíÛwóæÍÊ;—û ãÙ³gµEçÎSÉ©S•wæh¢Úî×_5—`êç³Ï>«Ž4³*X° f{àÀMY¸pa%l±bżÏä1¦Q£FööîÝ{îܹK–,Q#jÑæ0gPPPbbb`` 9Ç­_iþ&5^¥JÓ²fÍ5¥º9&&Æš‰ì§éSSSµ{O:¥¿H¯^½T„Ú.¹Fê3Cš«‰bccõ1@»Úä¾¶å•W^©Zµª}NÓ€Ë8tèP§N¬³ó;v¼l‰ÞsÏ=÷VÛ©´¾ýö[3±zîõ×_¿%*¹rå*_¾¼Pi3F¶mÛ¶?þ822R-¨t V&>óÌ3 ÄJ•*iJmÝý÷ß_¿~ýþýûGGGk|K·E‹™Yé-3fÌøôÓOwïÞ]¼xq¡Ç²¼—®Ÿ \û {ôèÑ¥K—ýë_»víRYîÛ·Ïßß_#G¥Ê4»]c>ùä“áÇkåc‹-ÌÃY­5ì±ÇÂÂÂ>üðCûLÌâÌÒòæÍ›/_>}–xþùç]î‹tU¨ziÎË{¯v&*Z´èçŸ0xð`õ¨þ“|õÕWÊS­³5 GFÀeÔ©SgÙ²e®ô+3..î£>ºÂ½xñâ!CÆŽ«•è“O>©–²‡äÍwC:ëäÉ“ö}»qãÆzõꥤ¤,\¸Ð:‡~Ö¡gÏž¦Gõ²jÕª¯½öšuÈœkF@Fºuëm†kÖ¬iL¡²1bÄ–¨Ìš5kÒ¤IæÉöÍš5{ï½÷œ-Q×ïGåFt–Ǿ=qâ„ù–¬›V¢fôyCŸ:ôÙÃå¾~Tÿa¬¯åÈ(H×Â… ï¼óNÓ aaa}úôñx<“BBe9pà@s—÷eKtóæÍï¼óŽùNÈR¥JýüóÏ™õ'\!c¥7s¹ÖñÑìÙ³?óÌ3­ZµÊ’% GF@ºž~úiS¢þþþ]ºtñ~Pè¦M›Fež'Ú AƒŒK4))I-bJ4Ož<Ÿ~ú)%zó9uZË}ï½÷š5kær?iKÿmÌׇrH[ß¾}Í©KÓ¦Mëׯï1ÁÉ“'GŒa¾c©L™2O<ñD%*óæÍ3÷É–-Û«¯¾š¹ß±t ¬ï£7²fÍjnåIsë+ãoÎúÜ Åé“À'Ÿ|b¾bÀåþ«½üòËé=ñ ÓéÈ—_~yäÈ‘èèhóÍo½õ1 Ò°{÷î?þØ\Χ*zðÁ½¿ÆsÖ¬Y«V­Ò@```—.]<¾bÇCbb¢yÚ¥†[µjõì³Ï:»*?åµõ¥¦Æã?þù矧9BjÑ¢E7®GoÂâ´ˆ¯¿þúÑG>|øñãÇsçÎݹsgµéG}tƒ6Ê›ùZÔ‡~899Yÿy¦NJŒ€4¼üòËæ»ˆ²dÉÒ¢E ïÐT\ª$Ì}H7®\¹rÆ3\°`All¬Ë}ÌïùçŸwü¦¥'N¨üÌã< méèÑ£»víZ®\¹4'¸Îoo¿ÚõÉôÅé3ÃæÍ›£¢¢Ö­[7lذ„„„#FXGIošûî»oöìÙß|óþóüôÓO\3 <­ZµjÆŒf¸lÙ²·ß~»Ç—.]š0a‚‰ËôŽ›ÚÙ‹Þu×] 4pzÓ Õ;{öì'Ÿ|âôŠÜ( 0ús¨'Nœxë­·:²&/¾ø¢¹þ8))‰ž `ž»®Ä¼ï¾û¼¿ S:{ölÕ[zÇM=,_¾Ü:,zƒžoŸ)NŸ>­D[²dÉÍ_´öLéÒ¥Í÷Ú맆oÜs¦rçÎ}÷Ýw¯[·Î©Õ'œçž{Î|§é€§ ˜råÊy?R :mÚ´ÄÄD—û /{˜355uñâÅæ°h£Fþœ‡E-gΜyûí·çÌ™sÙ):”`†³fÍ’/_¾ô&>r䈦7W5øúúªò¾æWæ^%5j”¹4B‚‚‚¼/ݽ{÷É“']îcœZ\zË:qâÄÞ½{Ͳ<&.S¦Ì–-[Z·n]µjÕaÆ}üñÇãÈ~~à†ºqãFbüíÛ·+›\îk(ï¸ãó]—vIIIÖ±ÃÊ•+['Ó£„Z·n™á=÷Üãôö]FJJÊÒ¥KçÎ[°`Á4'P€¾úê«Ë—/?wÒ|«~*1###Û¶mÛ¥Kû±+W®|ùå—µW•¹~~~fJsóF×ï÷*¹Ü_æ Lû÷ï8pà„ >¬ê5ß\¥eµoßþ¡‡ ¶–¥ ýᇾþúk½Åeå Aƒ¬3é̉òn¹råRä%%%:uÊ\knÉ¿÷Þ{ßzë­ãÇ[ièï–'OÔ4Ö5£øì³ÏˆÖ—·kqz©•Ôâ\ ÐiÓ¦Õ®];&&Æ:°j”3gÎ#GŽhY&F­ÙÚ¯"Hoø&È—/_É’%92 þ B²N@‡……yO ²1ßçérÇèeÏÑ«¬–*UÊéíK—âò•W^Q½Y«­àK3FUŸåË—oРÁ!C.\8eÊ DFFæÎÛL XܰaömÛ”‰ÖÁH??¿"EŠôë×oÙ²eßÿ½Õ—Ð~›7ož5eh£F,X0yòä‚ ZŸΟ??qâD5«¬÷jþZÜ‹/¾8|øp•qÆ õǺq·ç_³ºuërdüaíÚµæ‚QµNšßyÜÍå®·+ùÉ#n.÷±º¢E‹:½}iҤɯ¿þºxñbsÐQ˜fj+VlöìÙÊÐ &¼ýöÛÊwí1ekjjª5BÖºRÖèÛ·oÛ¶m]îG\Éú$%%Ywë»Ü}Ù»woó@þ‡~øÃ?4ãÕ 7nÔß˾¶Z%|ýõ׳fͪÂnß¾ýã?~£¿ÎôDDDpdüÁ:Ïëããcêó˜ÀLãççw%1ª*2Gì²gÏž?~§·/#깞={ZWŽ*þ¼/¾t¹ïz饗}ôÑñãÇïÚµkß¾}ñññ nÓîjSkVfnU«V½ªõÑ •’ÖKýE¬Kx••ziýJÙªÀ½í¶ÛTüÖHý™Nœ8qìØ±|ýõ×Í›7ß±c‡ÓûØS©R¥ˆQp©ÕÌiz•èe帆 6nÜØ:YŸ¦Î;O˜0A‘§ÚSqªÚÃÃýße?Vêqèô ÙkXÃéÍA¿Ê’%K×®]‹/®¤°ÿÖÜê´ÿþo¿ýÖéì)88˜7¿¿¿9¼wöìYï[Âÿ„Þzë­ bt÷îÝ ,0çñ]îÃÃ÷ÝwßüùóGå}Õ>æüùó{÷î5ÃéÝå!oÞ¼æY¡Ö»¬9lÛ¶Íš‰24,,,..î™gžQ‰öèÑ£E‹!!!ÿ}pÒïÇVÏ;7vìX§÷®'ý—àšQpÒ<‹í¡P¡B*¶äää“nN¯òå•/_¾yóæãÇ7—ÆzÐ&ØO›cZgbü¡`Á‚Š­ .˜»æ‹/î1APPPîܹÕ7gΜٷoŸyÜzÌóÌô±±±+Vtz/ï7Þ˜7oÞ‰'¼“Ñ×××>255U]8vìXõ¨ÇÃDÍ¥Zß  Ÿ»víêÓ§æ ‰¯ä ±"¾}ûöï¿ÿ¾™ƒöáþýû{÷î­аudÔÇǧC‡.÷-eæÊ3fÌ;×ßß_éioÖš5kþ©JÔå>ÄËizðÅ¥ªÅå>)œ””ä=A@@€9‹­$2ßÔ±Ün.÷yê+™þÏ 22²sçÎi>)**ªFöÇ*9rdçÎÚWGF³dÉÒ£GÀÀ@ëT»JñСC*rÌ5_þ”æš<ñÄú<`þ"fz»ýøzcëÖ­5jd½Es>vìXBB‚>*hÀÜ=¦EhMÞ|óM§w­§Í›7£à!!!ÖMôÛ·o÷ž@1j=Ôú*¦ ØïÊ_³fÓÛw¥TyòäIóÑNï¾ûnÞ¼yýýý­ßj@/í×wµk×îß¿¡B…T“fb3eŽ9ì7Úk—¦÷°§àààI“&Õ¯__oQwZWhYš§r¹M›6_ýµËýôSM¬ÙjnV¼jz½Ô¯ÂÃà P½zu§÷«§åË—sšü%Ë´iÓ\îS¨ÉÉÉÊ ûo•S%J”˜?¾™àðáá¡¡ÌM U´hÑÕ«WkxÕªUžk•h¥K—Öúh‹.]º¤µ² ÕFuïÞý‹/¾0/íÔ©SG8xðà;w&&&êíªÀ5jLŸ>]»Ëcn 6œè¶lÙ2¥¡~•/_¾½{÷®[·ÎZVþüùs¹¥¹>%K–ÔÞž;wîŒ3ô®ÔÔÔ‹/êWÕªU»çž{ôÓ̤X±b‹/6ßbo ¥*URßu×]-[¶ü>ÊàСC»wïÎr%×Ï€Ž1cÆtìØÑôPÿþý½¿6)&&¦gÏž)))æLtóæÍ3žáœ9súöí«*ŒUWû¸Íʺ§*ÍD¶ßqu% í1·={öÔ¯__;ªlÙ²ªÒºuë*^7oÞ}Za´råJï-^¼xxxø¶mÛÔ—K—.mÖ¬™÷j;¥Xâãã=:oÞ¼?UŒfÜ|W[„ÓŸ8qB›œœœ½nݺQ£F={öÌ™3§N².oЮ{ì±Ç®y‰i¿üò‹JkFÀÿ ±¾7röìÙ‰‰‰(˜š6mj.‚ܸqã¾}û2žaáÂ…kÔ¨a†'Ož¬Dszo¶sçÎ?~|Ïž=‡²n*r¹Âzÿý÷7nÜØét€þçŒ?^Ä(ðtÏ=÷˜ØØØ xOШQ#óEóIIIÓ¦MËøª?ekݺuÍ]5Ë—/Ÿ1c†ÓÛw“dÍšUÛž#GŽÀÀ@ë¦"ñóóÓÈ   Gy䫯¾rz51dÈh Û;ï¼ãôÊ€?—¨¨¨aƙ穪U«¦r²O –Ê–-ÛÊ•+/^¼xøðá *,X0ƒæË—oýúõšòÂ… ‰‰‰mÚ´±ßNþw¥}R½zõ5jçÍ›7$$$""¢X±båË—ïСCÿþý;wîüOØÞ.\Ø«W/óŒ˜@zôèѯ_?3ܶmÛgžyÆã9G§OŸ~ã7bbb4¬Þzçw3˜áüùó?øàƒÔÔT__ß‘#G¶k×.sWxÏž=.÷Må™2·Ý»wgÏž½H‘"ø~G}ðÁgÍšår?Ò•Óô ü±vóæÍÛ´i“ÇJÏ6mÚøûû»Ü÷×›‡=e V­ZåÊ•s¹/ üôÓOccc3qmÍ}ëb’Ôi½´_–6§víÚæZûðŸ„âxË–-N¯Åµûî»ïæÎër_2Û©S'b¤íßÿþ·¹M>))iĈÞß,_§N¦M›ºÜߊ9zôèµk×f07Å«’Î\:ݧOŸL\Õ'NÄ»YwGÙó4ÍTÍÀŠ+4+s$Ø>üg°mÛ6ívmË_´Gõ¡å³Ï>3ÐmvikÛ¶­túôé.÷óê§L™Ò¾}{ëK€\î¯;ðÁ7nܸk×®¸¸¸Aƒ½ùæ›é}™Ô­[·I“&æ¦ï¿ÿ¾råÊ/¼ðB&®ð¥K—¶nÝêr_¬iòTcT“·Ür‹5l¦4ͪm 7Ï–·Ÿå7O¤/]º´}X¤¤¤DEEý÷9íY²hJå`Μ9ÏŸ?Uãí§û5Ï3gθÜ5¯uÖ°&3_(¯ÕŽˆˆp¹Ïk[,КknÚóæ˜´IR-ÅüöСC ¾¾¾Ö;ûÄfs‚‚‚ôSëf_„vHf]íàA%ýÒK/™ƒâ‘‘‘úÏóß'—Ò¡ÊÌŸ?¿) µÑ‡~ø«´žŽYµjÕ1cÆüš¾qãÆ•)SÆLœ'Os'þõ[»v­9æšÝM‰9dÈó%œ>>>ê<ý4ÃÁn¾¿S¯Y³F½ê¦Í­~ýúšÕ_|a ¿óÎ;úm¾|ùÜúYªT©þýû(ìßW>¾bÅŠÖ:›…ª)ýüüÌ:ÏŸ?óæÍšÞl…öÏàÁƒÐuêÔ1c4¥V^ãõG?~|­Zµ4FsPâoß¾½[·nú•éT}l°ïŸ%K–Ø'^´h‘­¿Z·É“'Ûaí‡ÌµsçNë!VöÿKÜMÒeºgúôé/^’’²~ýúÛo¿]ùuë÷í·ßj%}Ü÷ï߯1æ;ÜO:¥ÕÓ°9JšššªêÒo8 á*Uª|úé§Z¥GyDÉØ·o_s{–¶Ô «ó~úé§'NhëöìÙsäÈ‘cÇŽÅÆÆj&ÉÉÉ'Ož¼òñš•Yç½{÷~öÙgÚ«Ù²e3ë¬ÝûàƒN:Ukh¬nݺuÊ”)«W¯VDjÍÍN;ë¶téÒ7j¤Ö_%ª=ÿÃ?˜o[Õ{µ­[·68ÐÈ-Z¨×­‰µ2úœ9sF{@¾3fÄÄÄØ¡ýP¨P¡Lü¤M{â‰'Ì…ÅY³fÕü›5kf.~àšQ‘.]º<üðæ”Š6•Ÿ}µE«V­î¹çs_åÔ¯_¿ƒ¦7ÃJ•*uîÜÙ|å½bô駟Δ›™ÔšZaÆ}ðÁz©ÓuÞ¨Q£Ô©Zá‘#Gš‹æÎ«,ï¦lÕš«#""¬á²eË*Êyê?³¸•+Wêg‘"E (pUã3Xgí:•¢Væ’ûaGZI­À¶mÛÌšÿòË/0¿2ݯ)'NœhêvÙ²efžÚmHTT”ºßŒQpkÛ'ŽŽŽ6óÿî»ï† ¢bö^D&ò(QýWÑëzb\ÆÐ¡CkÕªe†L#FŒHNN¶O ²ìÚµë•÷h³fͬQ£ôéÓÇûî¨k ªÃn½õÖìÙ³§¦¦ºÜ½U¡Bs«}XS–,YÒ\=yúôé°°°QnæÊΔ””ÐÐÐk¸xñâæÒ‹/úùùiVp¹_ÕxëúTëV*û:Ÿ;wîý÷ß_µj•¯¯opp°¢ùìÙ³JCÍ¡ZµjV\.\Ðd*æ%Jè¥þ"¥J•RqîÛ·Oû_Ók[Ì‚4[‰µÉfÑz©™§·ˆLa/Q©Y³æc=f>ŠüÿÈôE€¿Ÿ &¨™Ìð¬Y³¾ùæ|ôîÑwß}7&&&ÍÃlš¦cÇŽ-[¶4\GŽÙ³gÏ£Gfʪš'XÃÛ·o7YlVþöÛoÓ¦MÓpÙ²eãââš¹)ÝvìØ¡uVØéWöáŠ+šyÞ{ï½öË^¯v¼uk¿=Ö­uÞ´i“vÎ+¯¼rÇw˜[Îõ+ñðáÃ'MšdŠÖP¼jü AƒÌ—jæÍ›711±\¹rŠ`­³y—YÐñãÇU¢[óѯÒ[Äõûõ×_;tè`•hÕªU_xáK8¸›\^HHÈìÙ³UH6lP¯Lž<ùðáà û½ó¦G]î/ ×4›7oþ׿þÕ©S§»îºËÜúm§‰;wî|àÀU«V©º¬JûòË/###3e…•¹*¿øøøÖ­[*T(_¾|Za (P@­¦%vëÖM?}||T~ÉÉÉšÒå¾WÝœï®Y³¦ë÷sßfX‘—Õ­K—.‹-Ú²e‹æ£º*X°àU7·ùk†§Nò^m­ê¡C‡>üðÃóçÏkzm…>h½ÿþûfµͽöêΕ+W~ôÑG.wÜ7oÞ\­©À5»:44ôôéÓfAS£F u¡5q‹-4±YbTT”6Pin_„öÒõÿ ´ˆ>}úh·›…ªõõ÷¸U+LŒ€+âÑ£ µ3gÎ<õÔSÖa?×ï=š-[¶iÓ¦¥¤¤$%% 8pݺu ²°°0æÍ›·{÷îýúõ[½zµhúôéê'“uIÀ•3Jº~?n†?øàƒqãÆíÞ½»xñâ?üðˆ#4¬B:uª"¯R¥Jšøî»ï¾çž{ÔÁæ-jSmÊIÕ¨—öázõêU¬X188¸N:æt­­Š°T©RW5ÞZUýÊ{µùZÏýû÷kOîÝ»×ÏÏïóÏ?W&nݺUe©~UUk´VÚ±?þøctt´¶¥eË–>úhDD„6MA©9¿ñÆšƒ™§Êò‡~èß¿¿5±¨­E9òé§Ÿ¶‘?~ý­¯ç¿Š´oß¾C‡5—s˜ëDõÃ~vÞå¾®WÁÊ×€«pèÐ!Ó£æeáÂ…Ÿx≠؟?ššš:cÆ E•bÔŒ‰ŒŒìÔ©Sýúõ͘ìâââ4å¬Y³Ì b…£:æ¸Aë¯2®^½ºË}G‘u&ݾu*TP5®Y³&wîÜÖpší4·®_ÿøŒ)”o»í6åÝùóçõ²[·nÊÊÌÝ'™»ˆ¥K—¾þúë .4‘©íرc«V­ì%ª¿µ&øöÛo<È£ÀUPNµnÝZíhN+°V¬Xaîžñóó3ÓdË–M/pûöíKLLt¹Û}üøñ’%KØg˜3gΪU«ž:ujÛ¶mÊM©™›#—Ö 3Ñ™3g,XP°`Á‡~8((Èã·JÏ9sæ(RŸþyûpš³Joõ®v|Æ´gvîÜ©2 SÕõîÝ;ÓwKf-B9ûþûï÷êÕËú¬R¨P¡'Ÿ|R%êëëkM¦ÿ3#GŽ6l˜ù¬Â‘QpÕ”˜ŠŒ‰'šÈš5kÍš5»víêqŧjcôèÑÓ§OOIIq¹¯ã,[¶lçÎ+W®ìqˆT9«)'MšdNì*g‹o¿ývÑ¢EÞV\}„èӧϲeˬÿÕªUëÒ¥‹ý*—ûæúo¾ùfùòåÖRW-GŽíÚµ;v옹ÜSý±ÿþ+Vh|±bŬ{êV­®1ßÀ™°dÉ’øøxMf?g­6­R¥ŠÆlܸñܹsšaLLÌÒ¥KÃÂÂÌÓˆð§¥?nÏž=õÉaçÎfŒþŽ<òˆ>œ„††Z“¥¦¦Îž=û³Ï>3€u¹?œ4nܘ×èÎ;ï,W®Ü‚ ÌáÌ“'O®ZµÊã\¼Â4""¢råÊqqqT…(J¶mÛ¦)ÏŸ?¯Ö´Î+MJ•*U¼xqÅyÌÓ¦M›–””T¡B…ñL\'}Àøî»ï^|ñÅ™3gž={ÖŒŒŒŒìÖíÿÚ;³˜¦š6ŽŸ"¢ ¸€  ²4ÈV°!,J€€ h½0&o^÷Fã­õ„ĀxaÔ°‚*QYd«Ej)Ú²ƒHD£äû§ó1ßI[*É+/|¾Ïï¢)§ç<çÌ ¿yfÎÌ_©©©â%ЈÅÅÅ¥¥¥|/ô[ ¬4LOAÄßB£Ñ>|¸¹¹™§»‚‚‚öíÛíääÄOƒªVUUݽ{—Í"Œ#¹¡¡¡™™™&gêt:ˆËóçÏÙÂõãÉÍÍ]î²ÿãñãÇ—.]jlldKM Æ„(4''G¼à×ÌÌ þ7ÐîÝÝÝü?D&“;wŽMê %‚ â7pñâE¨ _ _"‘ìØ±^¢P(øôPXGÿíÛ·›ššØ&@üL(idd$¸Ÿ­©©Á™|ex;;»ŒŒŒ³gÏ"àr—õßN}}ýõë×>|Ȧ^ÆFD» Â×U@_ }ïÞ½®®.Ö¯Œ Qt]òòòlmÿ»À(É(AA¿‡ŽŽŽ“'O¶´´p»pppصkäCüb¼¤»»»¼¼¼¹¹Y¬¤>>>ÉÉÉJ¥ÒÍÍ„¹–””ð©`\›óСC§OŸþ]kã‹Ç`0ÔÕÕ£‰¹†¢‰e2ú±±±âqy´]YYÚŽ½»&˜%D9$£AAüN®\¹RXXÈÇâãZ¤ÙÙÙbËŒJÚÖÖvëÖ-qÚ ¾²mÛ¶”””ˆˆ///È TB­Üðkƒ‚‚Nœ8qðàAñû1ÄÒ6ª¬¬,--U©Tl-Ra>¥››*že¦‡³Þ¿_¼ß©‹‹K~~~VVOˆrHF ‚ ‚øÍh4š3gÎp/ÓÝÝ=>>~÷îÝ2™Œ½\/VRÁ¸ {ZZÚÑ£G—»ÄoÞ¼ƒ¢Å©PõDC¤§§›k¨yÓ¬ZµÊÏÏïøñãQ+÷"%‚ b )//¿pႉ’Âc`3YYY|¢áìì¬Z­~úôi}}½ØiØùr¹œíÿíÛ·G™xÏš5köìÙSPP@Júwèëëkhh¨¨¨À'_ƒ‰^꽩TÊ› mªÓéÒÐcÇŽ) ñ>±!%‚ bÉYHIe2YRRRDD„»»;»ç£½°RF#»Ç ëׯ „âàKss3œÉDI•Jenn.œi¡AaÂæ UUU¨R½^/–CöbêÓd~ÅøøxWWÚ¨µµ•íêɰ±±ñõõ]¤†2HF ‚ ‚ø‡¨­­-**/.sóæÍ111ñññR©”þNOOwttÀJÛÚÚFFFøb–¼•zzzúûûCFqÂØØÿÕÖÖÖÛÛ{ïÞ½ÙÙÙááá0Ôå.÷JÕ;00û´è vvvèÈår8hhh¨xÉ-µZýâÅ‹—/_êt:q×Ú““ƒ«©¡, É(AAÿ(¯_¿.,,¬©©aû6q £qqqSˆ&ÛS¢2>>®Ñhêêê ƒA,@‚qÝJWWWœüùóç©©)±Øà'Èhff&Ä”^ræÕ›D+¼ÿu+®1T£‡‡lR©Túøø¬[·Ž¥BQç¨yè³gÏ £ây½ÀÞÞ>222??}ƒE>‰8 É(AAËüòòåË%%%&6‚;* “á{˜“J¥‚EAbLr¥ ‰D‚“üø177'>ÁB´ü ‡ïÇÆÆ;;;PaÞAÑعsg@@wPœ†z~õêUSSSOOB™\èì윚šºÿþE֪ŀ$£AA,£££eeeW¯^…$™¤<Ùð½\.‡$ùùùmذAœ+Õjµpš·oßâB“ +¿ÜDrøð}VVV``àl¥z½õÓÚÚ mkkÓétÓÓÓæÊçèèèëë,vP4Äððp__¤—úôÉäZœæêêªT*óòòÐ[øåóXH2JAÄòS[[{íÚµ'Ož˜ µ ƼÔúÏ­[·Â¢ØO333ííí---00‰ÑZD"‘@¡ a©©© þþþ|Näÿ#(¸Á`x÷îF£éééÁ—¡¡!T…É`:éáኊ óòòâ“táôƒƒƒˆËÇçÄÄ„y÷ÀÎÎW¥¤¤ÄÅÅ­^½Úúƒý2 ªÑHF ‚ ‚X)ŒŽŽVWWuttXÌwB_ £ÐGˆ©8]úýû÷ééi•JÕÙÙÙÛÛ‹8°1¾¥`Wì }–B¡€¡B|—»eüò勹z¢¼8¾Ô¡ŠPQ(—T* †ÿ­]»æs–… ‡ÓÃq óööö¾¾¾r¹ÜzFy1qk<*<;;[&“‘ŒA±â€Íܸq£¢¢¢¯¯Oüê=‡¥Ka¥Ðš   íÛ·ÃSÙ(3ÄÚßßßÝÝ 7ÕëõcccÇ©Íc:99mÙ²ÅÛÛŸ‘‘‘¸…££#‚ó½L—.ʽ r‰ïÐq¸&б›™™ÁA­V‹ãÖÕ“?$∲°Qx­Š äãÇEDÆ-Ìs– ‰Dõ‹‹KOO·â ¸vrrφn*|¡€¸;Œ6!!%¤¹ô“ŒA±r-ÕiiiB‰wâÀr<<<¤R)¬t›¨ÏüALGFFঃA§ÓMMMÁtñùõë×ÅX‚ÛÚÚ" › aezÊ~ÅOâÙM~5Qã_”…Y&û“©'s8&£sss‡Ú->¤³³3níââÉC øøøÀ§q\œ9Ö£«Õêááa‹¹gœç÷ôôLLL„ŽÃò-Þµ ãDM~øðŠ/0~óWÊÐ=€ ãa¢¢¢’““Ñ@h)ÓsHF ‚ ‚XùLNNªTª›7o644@}RI6ì¾iÓ&ô&´qãFî¦Â|o||b SWAO!‹Ù·ÄÔÊ*›¿Ìhþø%â3锑H$pGüÉ'-óö944YDá ,Clî‹‚QaÕÐÄððð´´4DƒÚšœ#ÖYDXè¬Å (¢¡Â$&&F©T&$$໕ýìù'¥1IEND®B`‚nagios-2.6/html/images/history.gif0000664000076500007650000000163407436604466016623 0ustar nagiosnagiosGIF89a÷!ÆÆÆÆÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ!ù,y0`€À‚ <ˆÐ`ƒ F|¸°¢B‰NÜ8ðáE… 2lH²$Ɉ(Sn K—-_Êlip&Ì›6=ªÜY3¦OT¢Í—E“ Õ¹3¥A¥C£B}J´ªT«L›n„ª4¨×¥W¯~-šUëH“h;nagios-2.6/html/images/hostevent.gif0000664000076500007650000000167607436604466017147 0ustar nagiosnagiosGIF89a÷ÿÿÿ!!ÿ))ÿ11ÿ99ÿBBÿJJÿRRÿZZÿccÿssÿ{{ÿ„„ÿ””ÿ¥¥ÿ­­ÿµµÿ½½ÿÆÆÆÿÎÎÿÖÖÿççÿïïÿ÷÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ!ù,›7¤@P Áƒ ¤°áÁ….œX0âŠ-^ÄXQãF†œà dÉ !"À²¥¼à€F Ì€@#„š%ðÒ"ƒ–,Tðx€À„¬)ƒ4Tm8ƒ4Ȱá‚ #XZX¹Cƒ ¥‹a¬{oÀj@ ;nagios-2.6/html/images/info.png0000664000076500007650000000253307436604465016072 0ustar nagiosnagios‰PNG  IHDRºWí?,tEXtCreation TimeMon 31 Dec 2001 11:21:44 -0600脟ÜtIMEÑ 9Ý'µ pHYs  ÒÝ~ügAMA± üaPLTE)k1s1{9„1s1{9{9„9Œ9”BŒBœB¥J­JµR½RÆRÎ9sB”RµRÆZÎZÖZÞcçcïk÷kÿ!B{!B„!k÷!sÿ)J„)R­)c½)cÆ)cÖ)s÷)sÿ1RŒ1Rœ9ZŒ9Z”9sÎ9{÷BZŒBsÎB„ÿJcŒJk­JsµJ„ïJŒÿRk”RkœZk”ZŒïZ”÷c”çk{”k{œk¥ÿs„œs¥÷s¥ÿ{„œ{¥ï„Œœ„”½„¥ç„­ï„­ÿŒŒœŒ”œŒ­ï””œœœœœ¥­œµÞœµçœµï¥¥¥¥Æï¥Æ÷¥Æÿ­­­­½ÖµµµµÎïµÎÿ½Îï½ÖÿÆÖïÎÎÎÎÞÿÖÖÖÖÞïÖÞ÷ÖçÿÞÞÞÞç÷Þïÿçççççïçïÿïïïï÷ÿ÷÷÷÷÷ÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿy”ptRNSÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ·abÒ*IDATxÚUÐKOÂ@Àñ=[lKìkÛ¨U"Aâk ¾ ’ª ‰ M¬Œ•~ÿ›3TþMûËn&–P“A·vptñð>ýJ=>kEß÷¸ë¬5Æ3ìïAªU~I±_ „¨œ;¶Q~l¢VQ=ÂÜ~œ°ïc?ák(RÔ®6XöÿŸTׇ¬Ë}Tñ<Å…;vË=TœŽˆÓ ]•ÏÙ‰KЏŽm™ZV®°†ãrîy@ÃÛJæŒÝÛ¤™¦Ês—¬gÛFƒ 2uU‘–šl\¶,›²ðZFÚí°¤W0ÒL¼‹¶róŒÿÞ6s”®©dùz'Fœ´WU*«È’´xÚ‚tŸ£½yE‘‘òÛ×­èoÉÉÏÓáf©´Q©7ãÙæ©è Âôý¡&R="#pIEND®B`‚nagios-2.6/html/images/left.gif0000664000076500007650000000211107436604466016043 0ustar nagiosnagiosGIF89a$ ÷½½½ÿJJÿRRÿZZÿccÿkkÿssÿ{{ÿ„„ÿŒŒÿ””ÿœœÿ¥¥ÿ­­ÿµµÿ½½ÿÆÆÿÎÎÿÖÖÿÞÞÿççÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ!ù,$ þH° €‚*T á‡Ppð`Ä‹$ X#F;zŒA‚"G2<`e×0cZ|àË“ ,`Рƒ Dˆ a .`ÀfËœ;{þ :´èѤf,ÐôæF<}JÔ(R‡Z%àê'X©c«šÅš6+µ]Ÿ¾KµìU´ÜeëjØ©d­žÍX0Þ¶_£òM<pVÖ+±Ü¿ŒÈ<8¯ÛÎqýžM™U³éȇS+¦‹@iȆáöm9ããÂ{=«¦ÀæÓ±wWfñuîÉŸ×͈[¦õ˜¡W>½Î=ûÒíÃ'3?Ý NòãÓ3_ŠR½{ñ'®W¹´7}ˆóï3ô®Ÿfå-;nagios-2.6/html/images/logofullsize.jpg0000664000076500007650000003132307507661353017646 0ustar nagiosnagiosÿØÿàJFIFÿÛCÿÛCÿÀM"ÿÄ ÿĵ}!1AQa"q2‘¡#B±ÁRÑð$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚáâãäåæçèéêñòóôõö÷øùúÿÄ ÿĵw!1AQaq"2B‘¡±Á #3RðbrÑ $4á%ñ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚâãäåæçèéêòóôõö÷øùúÿÚ ?þþ+ÇußÚ৆o¯4½{â‚ô­GOÌ»³»ÖícšÝ´¶Ðÿ>…ÉãµzWˆ&–ÛBÖ®!‘¡šßIÔg†e$4RÅg3Ç"• †VU çµçü_ö™øØ?no:týˆï>"E𾎞>-–ìY%©Ô,Dh,ªÈ.Ë“–Äg88ŠûÒÊò×Pµ·¾±¹†îÎîî-®`u’¡•CÇ,n¤‡FSœæ¿ÁËŸ|mᯈ:ļQ®É®húÍ–ª/ÛR¸yæ)pn'OÀ¶â§q'.AÜIæ¿Ö[þµÿqøû]üøgðÒëÇ6Ðü\Ð4 "÷NÕ/![‹É¢·f µÄþd²nwîó€bŠ€U)ÊI^Ýö)Úúl@Uâß?hOƒl­ïþ+xûÃþ†îEŽØjú…µ¤³Î ,Ò¨#§ œ“^ÑÓôëß·>õþl_ðw‡Çoˆ~Ôžøk¥x³XÓü5§è±ÞIcg¨^[¢ÞÆûTˆâœ.v€vŒp2[·KŸè%àOÚ×öqø“u ‡ƒ~/ø+Y¿¸( ´·ÖmLÓT*È|Â…rûI.*Aéšú&7I$ÖHäUt‘::0 ¬Œ§ ¥H Žæ¿Âßà·ígñëàÿ¼3âÿ üLñM­æ©i÷BÖ/ SÅm2Êöì¯/ Ê ž¹Ú28¿Øëþ eûDß~ÓŸ±_Á߉º³LúÅÿ‡l¡Ô¤œÆÒKp¶ÐÉ$’I2C,’’Of^IÎ)]Ù«3ôFŠ(  ¢Š(¢Œ÷#èqK@Q@Q@Q@¯Œüiá‡ÞÕ¼_ã-jË@ðö‹m%Þ£©ßÏA+0ä`È øœ($~f^ÁhÿàŸko Åñ¿Ã³Ü¥ÛÚHâþÑ^8Õäf"fÂrýÒxé^wÿåð÷ÅïÁ>þ&élu;ÿÜÛΓ̗oƒ>Z V X¨…ÏͰñÅ’MïÁ/Ú_M×ÞÇQðÄ›}j]KÉ‘$Ó5tžK˹2tMµY•IÝµç ˆ›jÖêENt“‡F¸¯Ã/Š^øÅá-;ǼCcâ_ j‘¤¶º…„É4d:$ˆ®cv˜ÝOŽ£9 ¡Wâüûð×â?Ã?ø'§Ã+âd:œ:åìpÝÆš¬“½Ê±H¥ŸÊಂ2y9?·ÕIÝ'ܨÞË›p¢Š)Œ(¢3žä‘ô ¢Š(¢Š(¢Š(¢¿’/Ûöƒñw‹|q቟hÿŒ<-âÁbŸÆ^/ø{¡ÁZ~%ü3ø5ðkþ ƒûmx öUøycoð#þ kûbü*—ÂÞ¿ðN¹ãOøÿâ‡ÄI'|eñþ:ü3øßáÿxOÅ?³wƆŸ ¬|!㟈ð|kø™à;Ç¿±/ì…ûUjŸ ¾$üw³aÇ¿xÆß´‡‹ücãy#:¯Š<=ðçDÕüM¨ø“ÅwZïŠõྼgyŸá/^\¹Hmô-UÝ‚?ñå2¨ î%™GLsϯñ;ÿ‚£êöúÏíÝûB_Z:ÉüAÖ_bÆ6Ç{6å €Q<Àüc$õ5þÙþ$²:—‡µí8#KöýU²òe¤ûUŒöþZŒ±ó0rkü\౟ üIð—ööøã§kºEΓ­â­KQÓ„ö¦(ç‚{ù¦YU¶#‘[wSú Š»ôòÕIWdK |¥”ŒcŒÿ!Šú§öEý¨SÀ¯ü1á­_ź͆¡ÚÉ}ªj$6¶ñ£âr#@ùØü„ø#®*Ï‹¼#âk·Þñ.™{¤êÖ<6·–²Ùɪîb¾`²¬>¸Ãg"·…iSº‡]? ?Ú§þ …ûuxöðý˜¼ ñ3Ãڵψ£Ñ,`ñ&›±5Õ­Ä6Öñ4󍻨$…È‘[$±5üÿÁݺTö·V‹rò3›ýI×æÊªµÌžR¨ÏÊÁ6ƒéœqßåŸø7çþ ÁâOØ[ö…Ð|âÍRæ„þ5Ô`Óõ k‹‰>ç,Ïmr­8Hò¸\Œ ( W¼ÿÁÓŸtO‹¿µ—‚ügá»û=CBÔ|e¨XÝYJ²©Œ²G#b3êyRI<šæo•¦ôkþtÔ[jzFßä+zc²_ZHAE[ˆÁÉe#,3žào^+ý‹?àßÉ"›þ »ðqâ ¤éÐï*ÂŒ@ÉùbžÀcŒWøíC¥Å<‚ccÔ Ì¬Á@n„!Æz„ô"¿Ø_þ í¿ðMŸƒ¨ÜÓ-ºóÉÉ=~””“vL—dÝžþû3ã/x_À>Ô|Mã sNÐ4M2ÞK«ËýJêXR8—syäPïŒp=rp2Gó§û^ÁÍÿ°ïìá}ªh>Õâ¹§ËqfÇLKn.b\«©…ðT3(a–PTå™G?9ÿÁÔš¯í‚¿<%¢|¶ñ4Þ½y_Äïá±3ܤl¢9öý„yˆÄ£ƒærBŒevãüÕõ¯…Ÿd¾AâøÜêwóÈmCKÔžæiÜà4ÒIlÁ$œÙêiI6´v6§ <’u%i-Wn‡úøþý›®¢º>3øy©[J·B8Ü:Ÿ#ç+(ØÃ$¡RÁ‡{wËñ?ü9û>ÛxŽÎü2Ô.ôLrò´ŠNÙ>`îí’JŸà*p¸6Iüÿ‚~ÿÁ±ß´Ïíyà}â_‹¯ÀÖR?"+èÚ)Þ;ánCHƒ1(GÉà+g¦¯¹?nOø6#á¯ìƒû+x·âmßÄ WÅþÒZúéms,(ï!R͹›ràç’AÇdŒÕí5eúèsÅóÝ­QýSÿÁ?¿à¾_±Ïíß¬Úø3BÖÓÁþ9»1¥®‘«\ÃWrÊÈž\&åÔü¬_$3ÀO5ûšŽ’*É«£ te`èèÀd`pÊAùë_à÷ðƒâß?gïŠZü ¬_iz·„¼Aosö“Ën×CL¹f–"måR•@ 6[<×ûÿÁÿl-GöÑýо|P×-e·ÖàÓltÝFI˜—ºa*LA\³™mç;‰%ƒ `d Òp–Û ¿¼ãÕ§z湤xkHÔuýQ´Ò4m&ÒkíKR¿™ µ³´KË4Ò¹T€K3PX€—ÿÛ«þ‡ý’ÿf/ßxáÒÿÂÆñŸ-ͽÅÕ”‘Ïh.mÀahÎÅFV¹l8~Õî_ðroí{¯~Ëß°w‰­vŸ£Ç<m¸\° Ñï,B›AepC.å'òSSÿƒ£ÿàž–þ“^±×n®õ$Ýtòà6¼ŠTC´2¶HùÎG#¯Àü þ Ÿã/ø)Wƹx—Tðî¿¢_[^Û½ÅÂÞ œ›i~Ï(ÚÂ6î<÷ ÛnîÿÒ9êS”ZiZûÇ$‹*$‘:IНˆÁ‘ÑÀeteÈu ‚8 Ön¹®iÒoµÝ{QµÒt}6´_ê7²ˆ­m!Þ‘ù“Èsµ|ÇQõ`+ùîÿƒ|?à©·?ðP/ÙÝt/ܧü,ÏÚ[X߉dk½Š¼’F¥²Í $»‹(³0.õñ?üsûtüKýœ¾øKá_ÃMNûמ?b𦳧ϵÛÛœ0Š;ˆñ,j‹ò–Ú M]ÒqMÚìÍ»&ûNþÝðsWìwû#xËTøá²ÿ5ý,oþ)Þ|Wø%ûMþ↧©Â{wáß‚> ý|UáË_ü_ñ†ü_ñ¯ÄžŸöœý’þ"êÿ GŽ|[àŸkž2Ñ|)ªè^ñ/м*¾7Õ|?sãmWÄ>#Ö~€ýš?f…Ÿ²‡Â½'áGÂ'ìºe¯Øo"°ðîƒáèðÙ½ùŸÇZ*5²‰-I$tU+‡,ðG=0Iãú´ÿƒŒ?àú—…¼áÚÛàï…$6·¾Òåñn›§Úy’¬’YÙÏutðÙC…“ÊX·Ï‚¡ñÎ?™/ø%•ý½g}мá¼y¤(IÙâÞÄîûØÆ×û=x¿áwƒ~2|ÿ…sãÍÛXðψ¼/§Ù_XÜÃÑ.—BUŽe*]VI#£0H5^ÓË@?Áö)®ôÝEn-Ì–÷¶WBXvI­¦¶—z«+´©Dàç@Àè=ŸâoÇ?ˆ¿mü6ž>Ö®5cá«tý6iL²Ü%´9h¢Ý,ŒÉ±ÈDZÏìWüÛþ ™qûþÔzäþÒ%µø[ã Ùõ=í­æ“O†k‹‡Y-S¬qp̨B€²m ¸Å~ ý½c·å¬{Kn±‚ÙnTXŽÅ°:W=VæÓޝ¯àgQ7d®Io;=ýº)2;Í0I$B¢ðÇ# ä±õ¯ö"ÿƒìï,ÿà›¿òÎ[9&Ñí&Q*•2#FádP{óWøêi3ý›U°º‘7¤7qLêʰ‹¶PŽø=Gjÿfø!ßìümÿæø wef–‘ØxvÊÉÄH‘£È–VÈìQ#vcÉn¬g¸Â1Ž÷‘Q‹Š»ê~~Ð>ü7ð¥®ü{Õ|)aàØc/<>'û‹8^[ì–÷Ž ¶#唨 Í– öÊÿ‚üC]gÄ7¿ð©#¹ðÛL&‰´Ý.9'žÙ¤%˜e‹.ÒÀ¨.xoç£þøùñOÿ¾ü=м_­i^Õìî÷C°ºk{)¥±[«Rn"*ëx’-¢» †œ® ¨'ø øA¡ê><øàÿi]Á‰ë¾>ðT~&ñ>§á-#VÔ/جÂ[ËëÞf’T•C¾ö`À(9\³-*ÿ‚¨ÿÁ'ÿà—^ý“üAáÛ=KÀß ©à2íâÛÜêŸd…æ¼û4rÌ€©Ê˜#+òä/, ·ù@xÚÇßê·g-–¿áTÛÜÛKŠD¹³šXØþ2£9ìy®i;/6É=V‹þùŸìoÿAøà‚ÿ°'Á¹!þÄz‡ÅÉìt½?ž¼2G¨ ;XîïH¹Ø÷[w¹ÞäŽYɯžÿà…ÿð^ßÙgMý•7¨l©Èp3Œã=ëü‰RC”Ú70BTíÛŒ¬ÁQÆ7 cÀÇLWú‚Á¢þ-ÖõïØ³Äzn§|×vÚVª«gM,¿gB-Fªä„NùBŽÔ7;*rZG[ýÝMfá8s¥f´?Hààï‡!ø“ÿÞø·cáût¸—H·}NåQöÅ>ð­ÉDüÇ~¢¿Ç—WµšÎþòÖeÛ$2E*á•EePÌûb¿Ùþ ³ûBø7àüóâÜÞ)º·Šoh·Ú™H‚i.&¶xÔÆ„dó.õlyÇøàëÚ‘Õu]Nÿæ suuî9a,ÓËÀîm¬2x$¹­Ô¿q(ùÿ‘<ÑöN6Ö÷üõ\ÿƒV¾xSÂðO}7[Ð58¯o¼E©VÝe%½ÀܲRùL4+ž0L ’ Áþw?àð¯ø×Pý¥þø>óí«àë0KjçÎû+Ì@Ê€~BÛ \ƒ’Š1ûÿ~ø£WÔÿdh××/5­ŽºÍf—7O+F®-]–vmÜ–ùFѰɃæ?ðx?Àß ]üðÆ“iéÚ‚éâX-Q³n¨iåUÎÐP0',ÄsÍb¢¥tôÐ)8:‰Õz/øùÉZEæ­¤ØÆ0..,-%P€ÊV@­×v×'ÓœWûÿÁ?goüý€þj‘ao¬ø«B´Ôu=F;Kdº™d¶ŠTV¹8áÔ†$‡xçürì¯ÏS²Ôsgyit‰Ù6î% yè@㻚ÿ\oø7ËöíøMñûö!øoàxüW£XøÏÀÚdZ]î‘{}µÔ‚ xƒÎ24h 3ƒÜJ4ýÖÒækþUŸ4›‹´‰mØúÃþ Að Áa/Œ±ø¯F´¿¿ð×…µ=SG¾{{fº²–+ie-òÄ^4€€¬0]Ž2Æ¿ÆsÅP®™¯ëzi`Eޝ¨[®ÕR¬°\K nW8y6 1êryä×úùÿÁv¿m…¿³ÿì?ñGD›ÅÚ-ωüc¡^i:~™§êš}åˈd‹Êš8.ËDY_%Ys‚§¡çü~uÛæÕ5SReUû}ýåîÔå7IÐqdgŒÕ(J)K–Ñôô3öµöm{±Õ3ú·ÿƒM>=k¿¿m»ÏÛÜÝ6…ã 0¥ÞŸ “ÃöQ¼±¡òÚF`Çi ȯéþÿ‚{üCý«g½âwÃ]>ï]Ö>,“Ýé6VÍ-ÃAn;<€]ÁH³ƒŒòBœ~ÿÁ ß³U÷ŠÿiügÔ4ÅŸIðŠy2Ï!IÇ(I¬™Ž2Å‹$kýþ-üFø]ðߦ­ñgÄÑ<+%´ß§ˆ.m#‚êÚ@ÂTò.\yÈ9'¢•ë»h¨v•»ÇþõóMè·v?ÂOWð‡Œ<3­K£jš·§ëzMÌ‚[WÓ¯"»µ’';$hÚÛvá7}Š‘œ×égìáÿ†ýº¿eÑto|Sñö6ˆÖÑC ê·?dö¬TÂ!”«•&3xÏÊ0  ÿA¯ø O‹þ3ÂE¬·ÂÛïø’èéìÖO¥½«ß3$¥Ú+ˆ,Abå‹|¥÷v<çí§ÿàþÄÿ¶—Ø|Wû:¶‹à­[S¶Z.± 4N™[Ć{i„}öÈ6§15¤j8«5x·þE¸JœcÍ7¯ä4~ÿƒ¹¿l¼Ð¢ñ§„|=¯iÖ2[5é¹µŠYfÈ‚v)9l¹UÈ$v‚Nkúàÿ‚tÁñ×í£a¡xcÄ>'ÓþüG¼ŽÆÍt]Q¢´¶¹¼‘Œmß"¬†ÆÕPHPV$cü÷?àªðE¯ŒÿðL‰´«ÿêÖz熵é¤}Ý£ÂÒom¯ l¨C±×ޏç·ä¯ÂxƒÁŸ|¯xgRºÓuKè÷6ím$°É<‰zÄßg`YNÜm9ÉÁ¥ßK R½´µ÷œµº¶½·†îÎâ »[ˆÖk{›i£žÞxŸ•’¢b²FF sÖ¬WÃßðNøƒÇ_±À¯ø¢æ[½fÿÁzQºža"»í³·ÛòÈIn ú[œäýÃRI‹âH>ÕáÝ~Ûi´hº¤@Éo:Æxöß;«üY?à¯|Sà?ÛÏãÊx‡Ãš†…ÿ5;Í0^ZË ÜÚɨÎ!‘ÉÇ NDƒØWûWÍ<6±<÷EÒM4‰Q©8ÜòH@Eɓ޿ÿlÿØ[þ wûOxÂÛ_øÿqà¼X³OÝG§E%ÔŽä¬r[|W@.U·në–`ó(ÿ‚ÇáÓÿøÞ'ðý¯‰,Ú8ìíî. Ÿ=6K*ìØÊGAÉ'šÿf}4Û6`Öq¼mehmapQá¶0F`‰Õ‰*Ë@A$‚:çšüNý—à•ßðK¯Ù£Ç:wÅO„ºOƒdñ‹-Í–£qwmtÉ(ÁŠX cåm*Ê „5úõ¨|\øa¥Ú}»Pñç…­­”;³É¬ZcÆæ–¼\WrÀår9 Ê¿ø-OüƒÃ·ÿìµâÛK†OˆÞÓ.õO ßEm¼/ko4ÀG:Äeóп)ÉFꪜÿ‘ÆÏÙßâ‡Àoˆÿ€üoàÿiš†‰¨ÝÚF÷ZMàŠâ;VK‰-ÈÚc*rz˜qÓýµ/mÙŠÆæ[Iþ1x0Í *:bÎ<–@ä…¸™0É ¸ÈÁ?(ø÷àüö¤ÔæÕ¼U¢|'ñf¹v“­Õä/§­ä‚bÈÌÓ¥¼‘ùžZª’#fdÞH4ìÓì‹æg{©ØÙÚÙÏu5Ìq¥œHÆg¹–SQ¨XIåöü£×WûÿÁü-â/ Á9~ iž#Ò®t›Ã¤[?‘r²®ãå6çE\¾Ólp$ðkÇ|1ÿ2ÿ‚Lè~6²ñŽá_ ¾¯i©Ãio%í»Ú%Ȧ rÜm1 ¤b7pÏ _¼>ðLJ<áÍÃ^Óí4Ïi6VöºMAm¤q¨„ÂS‡R›pG .(Ü®’¶ÇùùÁÞ¿³oÅßüHø{ñ^ÏÃ×Ú·l-o£·¾Ò¡=ÝÀv]ìGÝlwî ûä H(éêÞÖì5=¦±Ö4{øolîQ„rÛÝ[I0à”ut'#–àã“þîß>|1øõá+¿üUð¦›âÏݤŠÖšŒÍä´ÁYmŒÈË­…$©ã§ øñWþ ‚ÿ‚|üDñL¾"³ðÝׇ£šàÜOc`æ+y„[‡’ª@VîFã 3’“ºµÓ7R¡4¹×$¢’Ó®ÊçñcðŸþGÿ‚‹x?á—ŸÏwªÁ¦i¶ºU¦§i×w °dµŽ}Ð>W.Î$ÅþñÍ|Mñ³Lÿ‚‘~×^ñ¯íñ=~"ßx6Ý÷êRß.¥žÌ˜Å´D ¤Q+ÁšÿOoÿðCø'¯Àí4àÞ‹®:¬Dßêö2Îò#¼)Y-äùË0ïÐ`ä’kïydÿÙê_‡× áVø^?ÝÄÑÜiéÐE ›‹nvòÐ! Àñ‚4ÒqZ>]?Èæz]Gcü<|;ðÃÅÚìÊÉáýmÖYÛ:uÙÌß¼u%¥¶Ëä–8<òqšÿV/ø6~ûưþÁ:‡|] ^èQéW'û1n ’¹· CIäQÃÊAÀî¯Ò›_ø%Ÿì3dPZ|ðt&Y”.™e‚è0ió(À9뎕ö§Ãï‡ ø[áÛO øÃú†ô+% §B@¸'i(€ …;G*ªŽœ>±Ï/iRôÞÉ|.žõÏmVªö iÿ tšÞ§ø‡IÔt=Vq§j¶“Y^@Ø"H'Bޏ`A8ä œ|ÊFAÿ,Ïø/OüwãïÀßÚ7Çß~xQñÃê’jiý¹’Êk™žå‚ÛZBLh­#¢sÌq(S·h?ÚüGþ ¯Á/¼ákŸøUõÿx®qsOnÖÝKÆãÇîÙyNK)ÈÁ?˜ÿ±ÿü=û)~оo þؾÒ´K«råžûMó­ndÈŠ £#–YÂo,í¹‰ ·sÒKšMZÿÒ?ÏgÀ?³í ã¿iþð‡Ã?ÜkÚĶñG¤_[Gºå‘@5²„²†Ï&FF ~­|dÿ‚~Ðÿ³Ÿì¥®~Ò?¬®¼=p·¶¥JÍ5Ä‘Ü+9–v ÷ËÛgó_éû#~Ò?ðJ¯pÝøëà©øC¥êM?l‚ÂÎö©çZË2†Ý¾#¸·#)åœd/ãOüÿøcû+ÅðÀþ0ðÏŠ¼Iâ;°³[è×¶×gO¢ >Lk Äí\Àd`ÑRnÔµðÛ×ç6àõVé虽Â47€`XÏýÒT)c×åÀ?^ØÅ¡‡ü§ñÄZ„>3xâïþ$Zt«soh›•b˜—l2”’·Nˆƒ¢Šÿ=ëó³H¤;˜I${QQÖ"˜¤O™Õò¯Æ~f 2Ñ7þ çø'ã? |1ø¥ñ7VÓnôýÄWlÍÕ¤–¿iFŽ(¢’7—à ºdp03ZÝÓN^ô—ݱqs妞ªÚúè~¤ÁÌÿ²¯i?ØCX¹ðROsà‰%Ö$±·ŽâIn’’c Ku&Ed/…Ýå7þM:ž‹«hú…Þ•ªXÝZj6sIo-¤ÑO©,.ñ4~T±vß»þ÷~&ð·ã Qðç‰4ëmWFÕ-¤µ½²º‰%ŠXe‘ÁWgkÝðARAüsøÿ ÿ‚qüDñ“ø×Uø?a£-м’+h-’˜ÎJÃjTÈXýÞŽy';ô¾Œ³òkþ ð·ˆ4OÙ#Çzޱ¥ÞXÛj:¨62ÞY5³\¡’É™¡wL±«Fã¾ ž§¯ô!ÿý€¾ÁBþë~! ­ä–)eÑõ\#[Ýc(ŒÅÆwr®¸Á$7ÊC'Óþü+ý<kðÿá…l¼'á{AŽÂÊ8£aO.7”à $ ÏómÏÍŒíUQ츟çüùRülিðFoÚGþ ñãj}_Âúž¹ðÌêW#Bñ&Ÿmu:ý™g+¸q *²«y||¬ÕùÓðƒãŸíû?jêß ¼KãJå̲i3_ÁÜr3}s¶=¾ÁBôWû…|]øð«ã¿‡$ð¯Åè¾2Ñ\`Zêö‘\ˆŽðù@êAän âTs_êŸðHoø'Þ­iueqû<ø>(¯"xe{m>Æ9‚º•fIšÉŠ>:Ç¥\&á°ä-7lŸÛ¯ÅøVãXøƒñs[ÃÒ|ë­R8œ"ª™­X1WòÕ@$ƒèkÖ> Á'?lߌô¯…+ðoÅz õÍÝ”÷Z–‘} ¥¤Mµ¤2Éü‘‚Üvþ±_²×üWö.ýü_ªxÛá/Ã&Ï\Õ$’c=í½ÊÛ|G1A:®ö—t„8$Êû²\ãòëþ‹ý–ÿjoŽ|3â¿€×þ%¹Ñ¼.³¿ˆ4/^L'žWt‹%¬D7–w–àmç’wýa÷éÛ®?LÕ OKÓu›+7V°´Ô¬.£x®,ï-㸷™$VFWŽU#;]†zÙVVj6[•âÓ[£ü¼G¥|RðF¬ñø†ßź6­¦Ý¹’k¯í,ÙÌq˜ÒÏØâEÆAãnA_µÿ±7üIûlþÆÞ‡ÀZ6°ž0Ñ,m– q­ÝÜÏ, lò(V’]ÅÑŠ)#ý•_á¯ô«øíÿ†ý„h ?[µñ‡ÁO Û^ëžaŸQÓl-"–9$$–(`ÌÊ9Ú ‚æÝœçó«ÂßðkÏü—CÔ5K­GÂ÷zµ½ÔÍ%¤2§ËvfÜÑ4ûa‘ImÜOvÈåA4­.æ•*Ê­¹ºçÃûtÁLÿmø*¶«et[]Ò´É{}A²Ô5+x¤+(lL‡”T(@00>ñÿ§ÿ‚*þÔÿµ7Çokž#øcâ áÎâ ín÷V²¸´/gmuæÌѳÆ(M»°ç±§ZÝ6Ü»‡V ËŒ8' Šýð¿‚¼%à«5Ó¼#á­ÖJ¬¾F‘§[Y #JD¯ A¦ÙÌÇ€RIhŒŒ/„ßtO„Ÿ<ðãÃÐG•áOÑ­ÄHˆ’KtŽY@H“!¤ ·*Mªs¶½Š)ùïÿ5?Çì©ãsð ÎÑ÷2Fâ2µþh¾;ý™?à°ÿk.yÀÏ©É9$šÖ”ãù£Ì˜Ói¦·Gø­~Ïÿ¿oK½n= àÇ„~*h÷W2,B+Ö´Ë`Î0ef‡`vÎî¿tp8¯eý à™ðRM×Ä?~|Eñ[K§J[ùàÔ5i#ŽER#2¹r>M àŽAæ¯ö/ðÿÀƒ~¼þÐð÷ÃO逜\ZhvjゼBãŽä]ž«àÏ kÖrXë>е;Iâòd‚óJ²Û¼“¾DyÎ@ œŒ*c.IóÂé—9FQK—T’ü þ?ûTþÚ|;{âÏj¾ øq¦jÖÓê÷Úå´úy»¶‚]ÓCŸULÇ.î‰Á'‚Mªì£û3|>ý“¾ øGáÃÍ"ÓJÓt=*Æö´‚Þßíš„P>gѪɉd˜9b\mU÷?ø[Ã^±þÍ𾃤è™Í®“coc¶é4‹où„` gh;Fºuj{IsZÆaEV`QEQEQEQEQEQEQEÿÙnagios-2.6/html/images/logrotate.png0000664000076500007650000000207507436604466017141 0ustar nagiosnagios‰PNG  IHDRºWí?tIMEÑ &ü ¸â pHYs  ÒÝ~ügAMA± üaPLTE19BJcs{„”œ¥­­­Bµµµ!µJ½ZÆÆcÖœRcœ{ÿÖÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ°6~tRNSÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ'4 5™IDATxÚmÑ!Emc…Ö­,²ÌÿÿÐPjD'Žx/êÊŸå~Iö~Ÿa̘ ?o;& Ü^)¾‰ZL‘:\¹^Ì1%Ml!"Fçtø=WGÐÎ+«RwˆÉ@àµBÖañX!É;ŒÝv¯¥msªê AI!Uè™0œž]jâÚÔ€Ñã¡ZêÌË€¦ŸWªÛî˜ þl… ûIEND®B`‚nagios-2.6/html/images/ndisabled.gif0000664000076500007650000000175307436604466017051 0ustar nagiosnagiosGIF89a÷1119))999BBBJ99JJJRRRZZZc!!cRRk))s11„Œ!!œ11­­µççïïÿÿÿÿ!!ÿ))ÿ99ÿBBÿRRÿkkÿŒŒÿ””ÿ½½ÿÆÆÿÎÎÿÖÖÿïïÿ÷÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ!ù',ÈOŒ8A° Áƒ&ŽÐâ C‚% @)I—'`zà€A˜dt+Ä»Š6YVãÝ‚œ¡«Û”†Æx9£ÖŠœÁ¯ç‚ :$8aâ´ÃÖ;nagios-2.6/html/images/noack.gif0000664000076500007650000000163107436604466016212 0ustar nagiosnagiosGIF89a÷Ö!ÿÖÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ!ù,v@° ÈÐàÁ„ ,8± Ĉ %V|1#ÅŠ=v¨0¡Çƒ I~t¨ B†Nºäø2@ÌQ^ТÅ<'½hæÐ‘6ƒút92eÄŸ5[®45¡CA>µ(T)S©4ÚliõkÍ€;nagios-2.6/html/images/notes.gif0000664000076500007650000000307207436604466016250 0ustar nagiosnagiosGIF89a((÷!!!!!!)))!)))11)11)1111991JZ99!)911999BBBBBJRBZcJJJ11J9!J91JJJJRZR11RRRRRcRk{R{ŒZZZ!!ZB9ZZZZccZ{Œccc!!c))cJJcR1cRBcZZccccssk99kJ1kRRkcRkkkkksk„”kŒœk”¥k”­kœµs))ssss„„{{­Æ„99„{k„„„„„Œ„””„¥µ„­ÆŒccŒŒŒŒµÆŒ½Ö”””))œœ!!œ))œZZœ„cœœœœÆÖ¥¥!!¥ZZ¥„c¥„Œ¥Œc¥œœ¥¥¥­­­RR­ss­œ„­­­­½½µµ!!µ””µµ­µµµ½!!½11½99½¥”½½½ÆÆÆÆÆÎÎÎÎ!!Î99έ­ÎµµÎ½­ÎÎÎÖÖ11Ö¥¥ÖƵÖÖÖÞÞÞkkÞ½µÞÎÆçç!!çccç””çÞÖçïçïïïkkï­­ïµµïçÞ÷!!÷))÷ŒŒ÷½½÷ïç÷ïïÿÿÿÿ!!ÿ99ÿBBÿJJÿRRÿkkÿssÿ{{ÿ„„ÿ””ÿ¥¥ÿ½½ÿÆÆÿÎÎÿÞÞÿïïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ!ù®,((þ] H° Áƒ*\Ȱ¡Ã‡ ?Lˆ!¢(3‚PÔÉ!døa$£Â(M¢xi“ËMœ<бÅäA V<‘$êåKKG0Ú,ØC‹£h” å©¥KE`† dÁÂÕ–!ý ÃjU)§œ>•²Ä&„! x#ÒcX‘r ³Œ‹ ,j>ôñÄ•Ÿ!>иdA>“F}jɉ¤2/@qeÇ@?5X8Á˜V¨<ÁtÙ¸—%þ`2PDÁ; „ýàŒhŸ¤!!t` TUbP~) î—œÈhÀàƒ ‹)- ™Pá‰l‚vjþH2pp:qÚ©S§—¢y Å'õ›þax0Á7 ,°C#® ²tÑ$·mÊ*®¨ Ð8ÖLx˜À©qºÒˆ˜ñÉh.urŠ+„Œ]ˆa ,qÇk*\à4ò( 0P†à·Þz.Ua‚5¤QÐrZ¸’Æ£<É ¤Á„¤Okh°ÀŽ(wA LÊ—.°A°é%›œHaCÈæGš¸¢¬”Bš'V`Ð"ŸÈ‰âKÄ1i8ò€l— i¢ÜpfA¬bÊbÐ-JÚ'†,À®%aÙ¥.Ar€þA Æ*§ŒŠSXÈ&$—´ñ@Z¤Qƒ+¬¼DH‚4Dƒ‚"Ê}H:f ('nâI)¨€•+¡lÒ‰) ¤Ä t~"J(Ÿx­'ê²wÅCô)h'0È€Päñ'¥Û‰Sxâ^$|Ч*£2BHHêss^èØ'¦8!¤@­ðÑ¢B„@Eíâ&£OœBíÐC840ÀrÐ]{#oâ‚Ñ÷Ð ÁG»ZòÉÐæbaƒ@t8`RË ÀpE!¹B׉³—H‚€®Ð€„T24€`•ÈÌÞ'.ÐÐ_Hu#¶ZBè 6Bhì *¦ «Gs+Æ}‚I&3ôÝPh®øâŒK;nagios-2.6/html/images/notify.gif0000664000076500007650000000166307436604466016434 0ustar nagiosnagiosGIF89a÷!!!)))BBB„ÆÆÆÆÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ!ù ,H° Áƒ* ÀÂF|¨@€°ˆàbÆŒ"yÑ€ P†9’¤I˜Ù²&‚/c €Íš8MÆ$@€§Ï ]J ç@£J—.EÐÔd™ £j=PÕÀÕWnÜÚ5,B‹QË* pQ®^Ÿ>$—"Á°`í4«W`@;nagios-2.6/html/images/orangedot.gif0000664000076500007650000000050507436604466017100 0ustar nagiosnagiosGIF89a Õÿ  @@]11Goo jj™ee’\\…XXDDb++>""1$ÀÀÀqq¢ooŸjj˜ii—hh•ccŽPPsGGfEEcCC`00E!jj—aaŠNNo!!/ ajŠ?D<@—5712..¼¶)'ÓÁпʽðÅñÄý¾ûÀúÁÿ¸ÿ¹!ù, @b@‡Ð¡ Ãa"PŠÝf°Sæ!œxP¶lVÖê$¿`âb…z±H Ê¢ai³³”⻩`,ê×pa| _*.Z5% B/oY&B$4o0I !"#a¦§_A;nagios-2.6/html/images/passiveonly.gif0000664000076500007650000000173107674511553017472 0ustar nagiosnagiosGIF89a÷!!!RRRkkk”””­­­½½½ÆÆÆÆÎ!!Î))Î11ÖBBÖJJÖRRÖZZÞccÞkkÞssÞ{{ÞÞÞ焄猌甔眜便ﭭﵵス÷ÆÆ÷ÎÎ÷ÖÖ÷ÞÞ÷çç÷÷÷ÿççÿïïÿ÷÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ!ù&,¶MHÐD % š‘ƒ&>HÂÁ„&„0B&4T0!¡Â"$4‘aä„ Lh€B /,°Yb  ldÙ‚‚%d0†… >Ø!37z˜¨PáÁ®€(¶kY°g ¦U¸v`Û°hÇšx;W.]ºd @€îíû7° (ˆX1Ay2[»jûjÞÌY³ÜÏ;nagios-2.6/html/images/recovery.png0000664000076500007650000000260507436604466016776 0ustar nagiosnagios‰PNG  IHDRºWí?,tEXtCreation TimeMon 31 Dec 2001 11:54:39 -0600L„)ÂtIMEÑ ;0ß³Ù1 pHYs  ÒÝ~ügAMA± üaPLTE!!19JRZc!ckk!s!{!„!„)Œ)”)œ)s)„)Œ)”)œ)œ1¥)¥1­1µ1½1½9Æ9!{1!Œ1!­9!½9!Æ9!Î9!Ö9!ÞB!çB!ïB!÷B!ÿJ){1)ïJ)÷J1{91”B1¥B1½J1ÎJ1÷R9„B9µJBŒJBÆZB÷cJ„RJÆcJïcJ÷cJÿkRŒZR¥ZR­cZ”cZÆkZçsZïscŒkkç{s”ss”{sÿŒ{”{{”„{ç”{ïŒ{÷Œ„”„„½Œ„ÿœŒ”ŒŒçœŒïœ”””œœœœÞ­œï­¥¥¥¥­¥¥Þ­¥÷µ­­­­Öµ­ïµµµµµÿ½½ïÆÆïÎÎÎÎÎÿÖÖÖÖÖïÞÖ÷ÞÖÿÞÞÞÞÞ÷Þççççÿççÿïïïïïÿï÷÷÷÷ÿ÷÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿbQ+†ztRNSÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿè?è&JIDATxÚ5Ð[OÂ0à/L21$W;¸´»Ñn£58EAŒâTðˆg@P(‚û÷¶ ïEÓ>ýÚB‘Q§y™?¸xyŸBËçU†1J=w½ú=ÅÖŽïûKŒ&=—l·'ØÊøAŒÕuÈFOàGÞJåRàOïCø9d~:ñ´Ï€£2kÝ„ÐYf(Z,£H ÃÖjš”É„ßiËU™`kán“ŸÎ€‚‹`dêgpìQ Œ?“ãœS‘(@ÕõdD)E²™˜ºv ÷ŽkJ8‰%ÃB°¬$´ ´ÇÕ%tׂ‘:£¦jðµIˆ#Bˆ‘¥«ÊnÂöšMDl,&«ÊJí•ÿýq‹ d ÓÎCŽ¿wi‹Ç4ô„ª¤NêƒIŸ½=Cל´­J½ÿ_r8z.ä²ÙÜÑuíi8m^¤ÿÆÓŒ÷r9\¶•ZD'IEND®B`‚nagios-2.6/html/images/redudancy.png0000664000076500007650000001261707436604467017123 0ustar nagiosnagios‰PNG  IHDR²év“B®tIMEÑ  †þ pHYsttk$³ÖPLTEBJZcï÷÷ÿÿ÷÷÷ÿÿÿÿ÷÷÷ÿÿÿ!))Þ))ç))ç11Þ)1Þ11Þ91ç)1ç11ç91çB9Þ19Þ99ç19ç9JJJJRJk91k99ss1)s11s91s99s9BsB9s­ss­{sµksµssµ{{{19{9B{B9{­s{­{{µs{µ{„­s””œ”œœœœ¥½½½½½ÆÆÆÆÆ!Æ)Æ!Î!ÞÞÞÿÖÞÿÞÞÿççççççççççÿÞçÿçïïïïïïï÷÷÷÷÷÷ÿÿÿïïÿï÷ÿ÷ïÿ÷ÿÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ«ðªé"IDATxÚí]ýÛ¶¦ÏSîÎ[Ë@‚ÈhÏ?Ô·`I³K—b ¶[wËg —sº’ÏŠøÐÅ,ÿù#©oë‹IéÕÌ'¸œÏ¦¾z“|Iñí RÀ‚)±fž" ¶Ò"7ÔO·èB2$Š_«â‘ãÔËE2¾d¸.½*HÚÖ$=`ÉjÓëp‹'Vdþÿ“ k剀qêã‘Oª 4O*#Í<œX¤ùAšyú)Ù^‘d5÷Šqªâ1’qÞ+dÛú!Y¥ªxrœC>NŒklSÀL²Útœ’ÉòôŶuÛ໬È-õ<✱«kC#Yžê¶ÜÎÕEðI&Ï“ç4¥Lâvªú8ªxD9ñ^d<<%ÔmƒßÕCi·ðð4ã4¥ ˆ[ Û–¢nÝÙ¶uÛ€ìȶ¥¨Ûd·@¶-EÝ6 »²m)ê¶Ù-mKQ· Ènl[Šºm@v dÛRÔm²[ Û–¢nÝÙ¶uÛ€ìȶ¥¨Ûd· pÎFUÎaa%<%·Ý6ø\ öy{Ö£À6.žê¶¼”µ-EÝ6 »²m)ê¶Ý¸Ü"ËÓÛŒdUœ À|œªxò¼]€{{§¸âÃZy².©ˆaDÂU<0$²ExhGOgc.<à$Knï3uíó$À"[©èæ$æêtòà‚WŸpI:½<9´/.}'Çzyš.¾ó¶*@¥L™-zî Ì6âF²R¨Ý¢=Ý¢‚¸=%÷„ò7Õà&ó<’u¢„³yÛ;ñèª ÌÍt†y;,u<%ƒZ5”™çÈ™.püÜ’Ë6œt˜ Ÿó¿ãP+§yµ’EC±R¦eßáÌʼnö‡!âg?ïQ)Ù5=¡ä!Éêy„î3¹°„2áÄrD¦5I¯ ñ7,úÆ¢pÀ0w»*xø…UJÞFˆƒiÈ¥D8EPD„“ìDÍëñèZÚÕ)ƒxGßjyÄc‡pd0,Á(WRÃò2¬5.~–,=Ü`„R)Û§<Ÿ¨Ñ ”ðjg]H)P€ƒx¥Ž¨O’ø¥qÅÈÁÓ¬-CYÇ‹œœ(se†Hè‹X;@Î/q„³ŸKò†üµÀE”Ù'‘Q(Ác® ê«dÙh*Yï-Ü/+æIhªLãí—á,>$Â=“L£-ò<5#Ñ|mcñP~m&-Üž:D¶ÔÝ«80JÆ×±(%ÎRá‚Ïß^È ý5´EO}>ŠnZ’B)ÃaÏ´AJ Oêr\ôK”¤ä¦OÜ H¦Ú5<`Ç5’õÎ6#Yïl3’õÎ6#Yïl3’õÎ6#Yïl3’õÎ6#Yïl«¥ð}?x±¥¯ùHi:zozxnl[-Å–€þöÙËzBª’ïoÃË8.éȶñ—2N‰¤üv”òµ­^²ôkŸK?ÄÁÕ}r dÛ8(¨÷I-·Ûq •2Uw¾pÍÈ-mã§ŠM­Q{ç}Mø¡ƒ‡£- ~ˆtÃH`uòh/V3r dÛê#Æä¥5w¦S»Žãÿ'“‰íÜ?ýÁDŒx(¶Öc¢Æ'¶3%ªÂL‰49Œ{Bµ›Þ{'V3r dÛD(¬/l¦×8„àa¾”M ~I¤$¸÷ïÞº²mB’ÍmçÔªiÀNNH#6ýý±cŸþ°ë«[ Û&$ÙSÛ9 Ûª°Ý š®Lí¹õÕ¥mŸ¾3£±RæØç¤›’vjÄ97?³Ç§Ö×—öôÞ½u dÛ„$#áÇùýGQÕ8 ŠëFk~6¥šÒˆÑt¥•óˆ–²³É¥õÍSÒàƒ‡ãøSûÌ>£QˆMJ™PÈÈ-m¯¿°^=vXèÖŒöôlrN¤Û¦bÔÂ#1’DB‹yØk.îKÓRÆ^É´ðÉzg›‘¬w¶Ézg›‘¬w¶Ézg›‘¬w¶Ézg ÉÊ÷Ý\=©ˆ's—Ÿ4œ¨[’9§ÊJ™ªs-uŸó¦ò€'%¦bÁÓ‹RÖh*ya?ñœ›ÐÜ„&¢¥ìô>[Úàj›ÎR¦ªbÞœO¨Ÿxø¡KV7Oä\2ÁR¦ÂFM<\”ƒ_Åf" ìGÖ«9’S2ùc<ɦM"F6¶ÁÓƒlØSéÉ¥õâ ¢ÇÔqÆN~ö0yË>ÿ䜕¶SÁ©§º]q|’a:õ”–26Q‘TË…³uÈÖ%:7~xï?°\q|’‘ŠÑqÎH)š:l"£Sí U¤Kr§$îŸ|ri©ùPéŠã‘,“¼8>%-¬0S¥Ì´egƒ÷¬Õ!.ŽØ#˜“k”ª SOÌ·JZ3#YÃl‚òþ^<=µ¾žŸZ»|bYO/-‹ŽsX/È;/žw=µ¬ËöÜÚ³ ’+ŽN² 9B¯>x?xðbJ[4Öž±QÏ&ÑãÛ~d±f$ë<d=>›°0¤Rüó|B÷qÎÛ™[/.çÖ«'Ó)ªs>%ᇯ¨[f$“É£¾º$’ÐÐzüÐyBg[ÑòþùdB§}龞ÛÚO¬ÝNl×ý®8JÉâ~Yi QŸŒ„!4(¡[X±÷âûAkvÅñIv0DƒlcõðÖs ÚFã‹fÀ F6­ŸÅf$ë"6ÉJ }<¨6d­ÁHÖE6 l4’µ#™\6¨ä2”4aªM7’ÉeS.YòJ±íF2¹lÉ¢',ôFOȰ‘ Z6‡gÚ£ðr”üÚ³°jãdrÙÄ0cÉ‚ŽJ3É eÃ.À)ɘˆ8&R¶Š[½+ŽZ²tŘþ—‡'\a$KýNÚ²ý+·ÞH&—MqÄýŸÔ]q¬’u#YÙÈ Ù<^ÅûýÁ4†í~[È“W)û 4µÜ6è—Å;\‰ï^%ogs@’ 5%Ž ¥ËßÍØ0lº¹³ËSgó†ïƒÂÉ#ž;›’d¼æÔ ÿ£çoãøp½f Y'l½¦1ÿf³\ÓªòÎsof,}xvv»vêôQ{ùöƒ¸“ q—¤“¸TÅQâ ý»#;%|Ô¢5ÀÕ®òº‚6d(¨ QLO^×èYØTÐV˜ÙÙ€$ ÌAÔÁOÕ‹ÃÑoÑóųÙóºçÀb6»þþââÚÛ¼œÑwÿý›‹}÷Æ]^_tjg³¼A¡ô[‰ÿ,5œnì‡ ÏŸɸ îéŠv×Ýx›Y/?z>¬½»·³®ìlî#åŒræP_¤«Ýu|. ~Ê ß² b0»¹¢`XDÿüë]ý´ùñ53ú³ò^“x„NêéÈN é@8¬p"OÃy¹óI‚#Ê:<Ûý}ô;3¾¤ÏÌÐlá‘îó—oYOúöŠD®w·ZÌèVHÞšHÖ ã¤ÄΦ€%™Šˆ‘eQbzŒâ`q0ˆƒƒA n;%|Ô¢bàúf'Ú…j?é&3ï2 d¦ÜÎf(™ªÛÓ}þuëçk‡(Y{觨=•¬«o8ôT250¥Ì ôR²c®JV6[e+ªâi~ûºùër„rWTÞŒG·ú<‰+âá»Ô¹Õ8šYQ¿RˆƒG³šêox’UŸ[U<õ’Õò04v+ÿ1L×Iµ±+Âs«qfÜ•g=^5l[ÆÅ¯ÅC:H¥ ª:·šÓnNÝvêò$ÄmDú™n¾Bão˪ytÚy4mÙ¡+ Û ˆ±ŒGÒ¡|vêó GbÉ£{ñ~YŠ~Y ÿñ”2ƒ:Éz#Yï`$ëŒd½ƒ‘¬w0’õF²ÞÁHÖ;Éz‡ÿÖ§MS”ê>IEND®B`‚nagios-2.6/html/images/redundancy.png0000664000076500007650000001261707436604467017301 0ustar nagiosnagios‰PNG  IHDR²év“B®tIMEÑ  0ŠC.… pHYsttk$³ÖPLTEBJZcï÷÷ÿÿ÷÷÷ÿÿÿÿ÷÷÷ÿÿÿ!))Þ))ç))ç11Þ)1Þ11Þ91ç)1ç11ç91çB9Þ19Þ99ç19ç9JJJJRJk91k99ss1)s11s91s99s9BsB9s­ss­{sµksµssµ{{{19{9B{B9{­s{­{{µs{µ{„­s””œ”œœœœ¥½½½½½ÆÆÆÆÆ!Æ)Æ!Î!ÞÞÞÿÖÞÿÞÞÿççççççççççÿÞçÿçïïïïïïï÷÷÷÷÷÷ÿÿÿïïÿï÷ÿ÷ïÿ÷ÿÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ«ðªé"IDATxÚí]ýÛ¶¦ÏSîÎ[Ë@‚ÈhÏ?Ô·`I³K—b ¶[wËg —sº’ÏŠøÐÅ,ÿù#©oë‹IéÕÌ'¸œÏ¦¾z“|Iñí RÀ‚)±fž" ¶Ò"7ÔO·èB2$Š_«â‘ãÔËE2¾d¸.½*HÚÖ$=`ÉjÓëp‹'Vdþÿ“ k剀qêã‘Oª 4O*#Í<œX¤ùAšyú)Ù^‘d5÷Šqªâ1’qÞ+dÛú!Y¥ªxrœC>NŒklSÀL²Útœ’ÉòôŶuÛ໬È-õ<✱«kC#Yžê¶ÜÎÕEðI&Ï“ç4¥Lâvªú8ªxD9ñ^d<<%ÔmƒßÕCi·ðð4ã4¥ ˆ[ Û–¢nÝÙ¶uÛ€ìȶ¥¨Ûd·@¶-EÝ6 »²m)ê¶Ù-mKQ· Ènl[Šºm@v dÛRÔm²[ Û–¢nÝÙ¶uÛ€ìȶ¥¨Ûd· pÎFUÎaa%<%·Ý6ø\ öy{Ö£À6.žê¶¼”µ-EÝ6 »²m)ê¶Ý¸Ü"ËÓÛŒdUœ À|œªxò¼]€{{§¸âÃZy².©ˆaDÂU<0$²ExhGOgc.<à$Knï3uíó$À"[©èæ$æêtòà‚WŸpI:½<9´/.}'Çzyš.¾ó¶*@¥L™-zî Ì6âF²R¨Ý¢=Ý¢‚¸=%÷„ò7Õà&ó<’u¢„³yÛ;ñèª ÌÍt†y;,u<%ƒZ5”™çÈ™.püÜ’Ë6œt˜ Ÿó¿ãP+§yµ’EC±R¦eßáÌʼnö‡!âg?ïQ)Ù5=¡ä!Éêy„î3¹°„2áÄrD¦5I¯ ñ7,úÆ¢pÀ0w»*xø…UJÞFˆƒiÈ¥D8EPD„“ìDÍëñèZÚÕ)ƒxGßjyÄc‡pd0,Á(WRÃò2¬5.~–,=Ü`„R)Û§<Ÿ¨Ñ ”ðjg]H)P€ƒx¥Ž¨O’ø¥qÅÈÁÓ¬-CYÇ‹œœ(se†Hè‹X;@Î/q„³ŸKò†üµÀE”Ù'‘Q(Ác® ê«dÙh*Yï-Ü/+æIhªLãí—á,>$Â=“L£-ò<5#Ñ|mcñP~m&-Üž:D¶ÔÝ«80JÆ×±(%ÎRá‚Ïß^È ý5´EO}>ŠnZ’B)ÃaÏ´AJ Oêr\ôK”¤ä¦OÜ H¦Ú5<`Ç5’õÎ6#Yïl3’õÎ6#Yïl3’õÎ6#Yïl3’õÎ6#Yïl«¥ð}?x±¥¯ùHi:zozxnl[-Å–€þöÙËzBª’ïoÃË8.éȶñ—2N‰¤üv”òµ­^²ôkŸK?ÄÁÕ}r dÛ8(¨÷I-·Ûq •2Uw¾pÍÈ-mã§ŠM­Q{ç}Mø¡ƒ‡£- ~ˆtÃH`uòh/V3r dÛê#Æä¥5w¦S»Žãÿ'“‰íÜ?ýÁDŒx(¶Öc¢Æ'¶3%ªÂL‰49Œ{Bµ›Þ{'V3r dÛD(¬/l¦×8„àa¾”M ~I¤$¸÷ïÞº²mB’ÍmçÔªiÀNNH#6ýý±cŸþ°ë«[ Û&$ÙSÛ9 Ûª°Ý š®Lí¹õÕ¥mŸ¾3£±RæØç¤›’vjÄ97?³Ç§Ö×—öôÞ½u dÛ„$#áÇùýGQÕ8 ŠëFk~6¥šÒˆÑt¥•óˆ–²³É¥õÍSÒàƒ‡ãøSûÌ>£QˆMJ™PÈÈ-m¯¿°^=vXèÖŒöôlrN¤Û¦bÔÂ#1’DB‹yØk.îKÓRÆ^É´ðÉzg›‘¬w¶Ézg›‘¬w¶Ézg›‘¬w¶Ézg ÉÊ÷Ý\=©ˆ's—Ÿ4œ¨[’9§ÊJ™ªs-uŸó¦ò€'%¦bÁÓ‹RÖh*ya?ñœ›ÐÜ„&¢¥ìô>[Úàj›ÎR¦ªbÞœO¨Ÿxø¡KV7Oä\2ÁR¦ÂFM<\”ƒ_Åf" ìGÖ«9’S2ùc<ɦM"F6¶ÁÓƒlØSéÉ¥õâ ¢ÇÔqÆN~ö0yË>ÿ䜕¶SÁ©§º]q|’a:õ”–26Q‘TË…³uÈÖ%:7~xï?°\q|’‘ŠÑqÎH)š:l"£Sí U¤Kr§$îŸ|ri©ùPéŠã‘,“¼8>%-¬0S¥Ì´egƒ÷¬Õ!.ŽØ#˜“k”ª SOÌ·JZ3#YÃl‚òþ^<=µ¾žŸZ»|bYO/-‹ŽsX/È;/žw=µ¬ËöÜÚ³ ’+ŽN² 9B¯>x?xðbJ[4Öž±QÏ&ÑãÛ~d±f$ë<d=>›°0¤Rüó|B÷qÎÛ™[/.çÖ«'Ó)ªs>%ᇯ¨[f$“É£¾º$’ÐÐzüÐyBg[ÑòþùdB§}龞ÛÚO¬ÝNl×ý®8JÉâ~Yi QŸŒ„!4(¡[X±÷âûAkvÅñIv0DƒlcõðÖs ÚFã‹fÀ F6­ŸÅf$ë"6ÉJ }<¨6d­ÁHÖE6 l4’µ#™\6¨ä2”4aªM7’ÉeS.YòJ±íF2¹lÉ¢',ôFOȰ‘ Z6‡gÚ£ðr”üÚ³°jãdrÙÄ0cÉ‚ŽJ3É eÃ.À)ɘˆ8&R¶Š[½+ŽZ²tŘþ—‡'\a$KýNÚ²ý+·ÞH&—MqÄýŸÔ]q¬’u#YÙÈ Ù<^ÅûýÁ4†í~[È“W)û 4µÜ6è—Å;\‰ï^%ogs@’ 5%Ž ¥ËßÍØ0lº¹³ËSgó†ïƒÂÉ#ž;›’d¼æÔ ÿ£çoãøp½f Y'l½¦1ÿf³\ÓªòÎsof,}xvv»vêôQ{ùöƒ¸“ q—¤“¸TÅQâ ý»#;%|Ô¢5ÀÕ®òº‚6d(¨ QLO^×èYØTÐV˜ÙÙ€$ ÌAÔÁOÕ‹ÃÑoÑóųÙóºçÀb6»þþââÚÛ¼œÑwÿý›‹}÷Æ]^_tjg³¼A¡ô[‰ÿ,5œnì‡ ÏŸɸ îéŠv×Ýx›Y/?z>¬½»·³®ìlî#åŒræP_¤«Ýu|. ~Ê ß² b0»¹¢`XDÿüë]ý´ùñ53ú³ò^“x„NêéÈN é@8¬p"OÃy¹óI‚#Ê:<Ûý}ô;3¾¤ÏÌÐlá‘îó—oYOúöŠD®w·ZÌèVHÞšHÖ ã¤ÄΦ€%™Šˆ‘eQbzŒâ`q0ˆƒƒA n;%|Ô¢bàúf'Ú…j?é&3ï2 d¦ÜÎf(™ªÛÓ}þuëçk‡(Y{觨=•¬«o8ôT250¥Ì ôR²c®JV6[e+ªâi~ûºùër„rWTÞŒG·ú<‰+âá»Ô¹Õ8šYQ¿RˆƒG³šêox’UŸ[U<õ’Õò04v+ÿ1L×Iµ±+Âs«qfÜ•g=^5l[ÆÅ¯ÅC:H¥ ª:·šÓnNÝvêò$ÄmDú™n¾Bão˪ytÚy4mÙ¡+ Û ˆ±ŒGÒ¡|vêó GbÉ£{ñ~YŠ~Y ÿñ”2ƒ:Éz#Yï`$ëŒd½ƒ‘¬w0’õF²ÞÁHÖ;Éz‡ÿÖ§MS”ê>IEND®B`‚nagios-2.6/html/images/restart.gif0000664000076500007650000000171107436604466016602 0ustar nagiosnagiosGIF89a÷ÆÆÆ!Î!1Î1BÆ9BÖBJÖJZ¥BZÖZcÞckÞksµR„„„„„¥c„Ö{ŒŒ!Œ!Œ)Œ!)ŒkJŒçŒ”!”!1”ZBœ)1œçœ¥!1¥)1¥)9­)9­19­ZZ­”sµ)9µccµïµ½)9½ï½Æ1BƽœÎ1BÎ1JÎçÆÖJZÖRcÖckÖ¥¥Ö÷ÖÞcsÞ÷Þçÿçïÿï÷ÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ!ù:,¦uH° Áƒô°@…Bƒ78ð°  ä¨8PÆ48ê°!q_H(P`€YD@À€7‚Ð"DˆOpÀP"âDHPhÀ´A #:˜‘ÃÆ«@˜p¢A5–ÂH#ƒ‡³gÆxpAG‹m9^xcCƒ"»šx@A†H ,x©c-Ó±„—Z ,ðBŒ;nagios-2.6/html/images/right.gif0000664000076500007650000000211207436604466016227 0ustar nagiosnagiosGIF89a$ ÷½½½ÿJJÿRRÿZZÿccÿkkÿssÿ{{ÿ„„ÿŒŒÿ””ÿœœÿ¥¥ÿ­­ÿµµÿ½½ÿÆÆÿÎÎÿÖÖÿÞÞÿççÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ!ù,$ þH°`A*\H€C†!" aÄ‹ 8TÀ"FŒ9vüxq"Å x”谥˗Q"8°R¡Ã &L!„4hÀ`Á‘3i2œˆS'OŸ@…5ŠôÀ5šlº³çÏ C‹•iÕ@¬™æì ìÔ±)Ë8kpëÚ§_¥Š­zu.¬jz–*Ù¾ XiWp[½†ã"V¼8#®x ¿åk6ñ€,6f›·0ܤ)3Öˆy°Û½‡SWÖªñò]×OËM ˜õíǦ9Ïí}ówéͱé& LZ3lÉXmÖ†I½%_´´«k¯Š=­ÆïÁ(‹™²{öñèC¢4ï=¼ûô'Ù“Ì^q~ÉéöA~Ï1<ÿûÿõg_@;nagios-2.6/html/images/sblogo.jpg0000664000076500007650000001174507507661353016423 0ustar nagiosnagiosÿØÿàJFIFÿÛCÿÛCÿÀ&Œ"ÿÄ ÿĵ}!1AQa"q2‘¡#B±ÁRÑð$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚáâãäåæçèéêñòóôõö÷øùúÿÄ ÿĵw!1AQaq"2B‘¡±Á #3RðbrÑ $4á%ñ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚâãäåæçèéêòóôõö÷øùúÿÚ ?þsàˆŸðG%ÿ‚¼üDøÅàÉþ1Kð†Çá7†4M¨[øuÇ]»7æÚÕ†ù^7–&vS…VäWúüMð§Ã/ŒžñÀÿÛèž$Óýí§žóÃzºO§Kröå„%Œ%Ûòȃ+:’’²‚M­ïýi u?ÇÃþ—ÿµ°ÿ‚°~ÔúÿÀ}sâ>¡ðÇÃ^øw«xóYñ•¥Ã«jR [»]2ÆÆÖÚåÖ0^òò6bÇ;"lr+Õ¿à¸?ðDýþ ã?…ÐÚ|Q?þü[±ÕäÐ|As¤G¢jºf¯¢¼÷IÔlâ™ÑÿsqÇ"œ2œEU_ðFßø&Äø%ïü#öœøw-ÅÏÁ|×¼Qð{ÅM5®©á›ßirÛhÏp«µu=åxfŒÅ9æ¼7þkToþÅ«rþ!ø„¥zŒgé…r3×’? Ñ]«ÛA)-Uµ]Oóߢ¿½?ø#GüßÿÛø­û)ø ö°ý¯¾7hõoø^o_xEñþ™á¿ x Ji¬|B¶÷kww¨CN×ö*ò¡N+×¾ ~Æßðk'í ûKÛþÉŸ4¯|HøŸãË­WKÓït/xÆ h·ºrM<¯a­NéJ 2*:‰íPx"´ºÖÂŒ¹“vi'k¿Ðÿ<óŽÇ?†)0}=¿Jýêÿ‚øÁ"m?à”´¾…áïkwÞ"øñsJ¼ñÃ+Ífâ;wIû Âêø{T‘p×-o,±ùsb0ÎHÉþœàŠðmìWã/ØËáŸíOûmhZÄŸü_ðªxò ßë÷ƒ¼á;ß:}/Ì2F×m§¢Ï4ÒHîã`JwIÚ×(ÿ:Jrç û㞟JÿK/Á¹ŸðDŸÚÛö…“Æß³ÅȼWðÛá¶§«èþ øâ#k–úɉƖöš¤R5Ö™whêê Å B÷.ó±ÿ.ÿÁ,?dø&¯Æ€zW칩꺯Å/ ëÞ(øy­ëSø‚ëBM*öÞÞÓÄ6÷—?øVþ‡žñ6ƒgñoâè-´Ÿøzþì‹«™&¸oß_µ”‘Y‹mÈÅUÔ”yáÁÉlÚ÷z£òÿÐñ×Ú”€1ŽãŸ¯q_é1ñOþ ôÿƒe/øá¿íñÇÄžøƒñ:ÆÃÃ^Ñ|[ñR2þÿ]ž%¶ýµ”V¹²Š[ÀÅZp°n`¹3Ô,µ¹5¿ ÚÂ×—šÏ…õ[;d/s  2y'"HÔ²ž3MÅ¥s8TKò½¿3øV£®8õ¯ê«þ Öÿ‚ø þ xþ8ø÷ûDx—T°øð·ÅVþÿ„#Óý‡[ñLjMÛ®m®µD;ô­*å·ÜQ|ÇbT9¯ÞþÉ¿ðj¿ƒ¿hO~ÅÞ;ðÆ™ðïâß„îß@Õu_ë¾;ðö”ºÄÆd´‡ÆÂYÍy‡\0;³´àV|럓gkš;¤¯søý–ÿg[ßÚ_â=ï‚`ñ)ðž—¡øfçÅÞ#× ðõï‹u[M wÃþS¢øSO¼·—ÄZÖ|Q¤µŽæ)šÕn$¶[«¨à²¹æh¯‚z·ìïñ‡Åÿµ­V nóÂòéRǪCjtù.´ýwEÓ¼C¥›ý7íWKÖNÕ-£½µK›¨­®âš®î£E¸“öþ û>~ÇðOÿڃ×ßðLÿÚgKø•àÿxk[ƒÅ>Óµ'Çö¾ ”Ý-µß†u¹ï­n,¼M¡Ý*C4v×°Ü"KeáD°ÄéøkâÿøŸÇÞ#Õ<[ã bë^ñ³,RßêW†0î¶öðÙÙÚÛÁn‰†mcomoikq[Z[ZÅmmPEk@]ßðgOì¯cñ_öÍø¡ûB\xó_ðõÇì÷á=<Øø[Cºû-¿‹¤ñ„—vÁâsq¤B+ˆÀ;¤^q€kõËþ ßÿ@ø£ÿÊÿ‚½~Çü'çjž‹à­æñGÁ°ÝI~.ð†¯âÙ£ÔmÞ/0¢_Ûˆ„ÖÎT"œþh?àÞoø)¿Šàš?>-ø¢ÓösøûAx3â—ƒôýÄ6? tÛëïhw:ÜÚ•…Ü]´˜Êë*Ɇ C/q\÷ü/öÍñwü{öµð¯Æ_†ß²÷Æï‡Zw‡¼¦ø ÄÚ·ªë:…õ­ýÕÜ“ýŠÊÁ¡Óþ{›cù¤#,I©q‹wkP?Õ“à'ÅÏ…Ÿµ?ÂÏ…´§Ã!¥kÞøƒà»MgÃ~!ò­eÕ4ý'\†Þæ÷H’éh%Žæ3Ä@…ÛFG?ÅüÔÚ¨Òÿb+¬"þÇ—RøŠçQ3~óûLÛ饧’8(`,Å»Å~}Á¿à²Ÿ·üoàæ«ð?ã?ìiñ·ãÀwÖ×Zð{K ø—CÕ¼×ì‡S°Ó®/´¹!ŸJ”æT…¶‘Ž85òçü#ÿ–´ÿ‚¢jŸt/ ~Ïþ<ø#ោɮêªÿb1kÚæ±­‹hfÐÇ FºtQZÇ‚71g$໾Uì—ãê>geOÚŸÙƒþ ¶ý”ü ÿçðíû@þÑ´пÂþ<üAðÇÃ-môQðlþÿ„ŽçÁ6ºTnZV’Ô˜ž\îrÍ‘ƒ^·ÿ}ÿ‚‘ÿÁ&üUûZü+øMûÁ3|sðãZÔ,n<*>< '‰u]ùâÁ6¿©Y‰šÂ „YL×rI@0@Í|ËûÿÁÚ_þþÈ^ýœk_Ù×Å~'Ôþ|<´øy ǃFÔ¼/ã LÓKµ³ÔôZDu”kÈCÂrÇšñoÿÁØŸ¾ø÷F‹ö[ÿ‚s|6øCð‘õM^ûÇf‰6¥ø¿Å‚xîKhu-;MX´æI¤IeÎüò«Õ¾eF|®_uˆ‹sÒQp׮߅ô;Ïø=‹ÃÒEñ³ö<ñL¾(šho¼ã-&?Â;±ë³Í­Bq´¼Âd²r #Œf¿¤ßÙÅz_í‡ÿ Ѽû'x´ë¾/—öDÔ~éSZ]=SIø‰¤ø=ô«­ é‘Õ¬õx hr« ŸÇü¿þ :?à®ÚÿÁÛø~ Åð°|+ƒ\µ‚âã\]kSÔ†½-»S%:—ˆ|¨ê:DVº©6ƒv$ÚIˆÍk";íçÔ¨ò{²Ÿµ·]“ûõÐÚ´!Nn1¨ªÅ%v®–«T¯Ûc¸ÿƒR?àž_·ìáûd|røŸñÏá—¾|2±ø©ø3[²ñÆ›|]>­¶oa Æ~Þ–æ¥7*"a†;«ç_ø=GÀÒéßµÏì¹ã¿´™—Äß5­lB9x¤ÐüG¸È¯ÑÚAz£uõû—ÿ~ÿ‚¢ÿÁK?à£_·_Ä9¾6~ÏÚ¯ìýû0ü7ð«ð¥×†uÍ '.¯ì­¬â¿×µËH›\ÔÕ ¹%*D®O9Í~]Áí)ðŒž ýŠ<;g¥·4Ëoˆ:ÅýŒ/o&­i¡Ý>•„·A2ñZµôìÃÈSÍïYZO_Xíùö3tÒ娞²Nÿ—ÞC¿ü3ñ;Ä?ðo‹á5Ǽ{wûêv’½´B ½6^6šZ'ÎÇ—J†×p<âàœf¿¿àÊï‰úÏÃ/ÚÿàÒR?h^:ðÏŽ¯uਲê:]ý¤ÚLVr¹œEwg#ÆžIÆq_xþÏÒ,?à›òþÊ^<ýž¼Gâ/¶ÿ®¾ ÚøâË]Ó-¼!©Z¿‡¤ðÕŸˆ/ìÊ âž==¢-½â8#9¯æö ÿ‚‰~Ò_ðNŽ6¿¿gK¢j3É.ðµá{ x×EóÌÒèúþšX-Ì_;˜äÀx˜îR¢ ‘$š!Á8òÝÛúgíÏü+ð[ö“Ôà®þ!Ö[Áþ:×|;ã ü<‡àÝö•¥êúŽŸ5½½¤VsXhóÙÂéäzÀÈŠU•˜1àf¿Ðsáz^|%ÿ‚Pø[þ°Ô|ûAÄ´×$/+MgðåÓRµÔšã$Ü>[îËn$E(:?üuðkİi³|Uýƒ§Ô|E£èrK§kvÞ$Ð5µ¶ñRÙƒ ¶iªé‚]?L“P\±üÄCÆZ¿à¢ðsïí™ûzüÖ¿g4ð‡ƒ~ ø/Å—W–þ3¼ð=Æ¢ú׉|4×ì¼==Í܇ìvßfX–äÆGœA)Å%ÎÚR³‡ãЫ-ì“[3×àßÿø*çí+ûxããÇ€>þÉßÿjÙûÇþ4Ô|S7‡>hú…Þµà}ç¹I¹·Ô¢³{so5µŽX¥e#jºuÿF¿à«_ðG¯ø)_Æ;·ìq¤|ý§ï$±Ó£šâì«¶ã,9×ò9ÿSÿ‚óøÛþ +aã¿Þü!Ѿ.ü&øƒ­[ø“PÓ㺋Dñ^®Ao›\iÚ³@ËshðF7C.eʰɯÝOŠ¿ðtü¯Xñ¥·í á¿ø&ä¾0ý¦tÍ*Þ÷CñÇ‹ôÙÝéÞ%H·[vžâe…Ô¸Dó0A\µÊÞ­}ëb}ç&¤—'Nÿ?ëÔù×þmÿ‚~Ê¿°ÏÂïþ×ÿ²ùÔ¼cã/ˆðxSÄÿ ¥¼ž†]fÚêöKÂþr™lQf…Ãý£Tq· þ'ëöûþ ëÿÌý£ÿà­7> Ð> xoß ¾xþãVðçÃÏ \^]Å6³soögÕu½Fì†Ô.ËìUy+×ÄI[­Ë?i?à›ÿð[/Ú þ ™ðãÅ¿¾|1ø;â¸|[â×î|A㯠E©k¶ŒcH¦±†ìDZK6D +6qÀõý8›þäý«–-¯ì«û-êlÊj#ÂDMÉSþ”¬!%¤mlp:ö¢Š`rz'ü»ÿŠþcã…Ÿ³Ÿ49C ßø;kh²ìP‰#,dØ… ”É#<~ZÁM¿à­¿à§~Ÿâ'Â_„¿ !ø|/—OO†º isj/|¸s©Oå«J‹ü+’3ÏQ@“TQE(8 úWõÿòÿƒ¨¿lŸØsà/‡¿g¿|=ðOíàÿÚG¤øSñž¥«é^#ðþƒ"ßC—PÓ÷NÂ!a(dA·qëE2I­{¯Ì ´ÿø<§öéÓ¼KâF€ŸÚÄ7?Øš½¤Ú%ãÃ*Aw6©m2¶ªDÎ •>/€xþe?l_Ûã¿íÏñËÅ_´í âÙ¼WãÏJ«•ßIÑ4¸ [CÓ•ŠiúlaU“ÌKÑE>T¤åoyõI$–ÈùbŠ(¦0¢Š(¢Š(¢Š(ÿÙnagios-2.6/html/images/serviceevent.gif0000664000076500007650000000167607436604466017632 0ustar nagiosnagiosGIF89a÷ÿÿÿ!!ÿ))ÿ11ÿ99ÿBBÿJJÿRRÿZZÿccÿssÿ{{ÿ„„ÿ””ÿ¥¥ÿ­­ÿµµÿ½½ÿÆÆÆÿÎÎÿÖÖÿççÿïïÿ÷÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ!ù,›7¤@P Áƒ ¤°áÁ….œX0âŠ-^ÄXQãF†œà dÉ !"À²¥¼à€F Ì€@#„š%ðÒ"ƒ–,Tðx€À„¬)ƒ4Tm8ƒ4Ȱá‚ #XZX¹Cƒ ¥‹a¬{oÀj@ ;nagios-2.6/html/images/start.gif0000664000076500007650000000162507436604467016260 0ustar nagiosnagiosGIF89a÷)µÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ,z   € "DhðàÀ† *”X0¢@ˆ^œ¸±bFƒB†„(@C!Ž,˜2ÀJ”&²ðp¤Kšo*l™2çË›{– j²"Oœ3‰îÄiS)ÌšEŸ:•úr¦H’WOjLè±ãÖœ\·ÊìÖbÙŒfÁ‚ ;nagios-2.6/html/images/status.gif0000664000076500007650000000165307436604467016447 0ustar nagiosnagiosGIF89a÷3f™Ìÿ333f3™3Ì3ÿ3f3fff™fÌfÿf™3™f™™™Ì™ÿ™Ì3ÌfÌ™ÌÌÌÿÌÿ3ÿfÿ™ÿÌÿÿÿ333f3™3Ì3ÿ333333f33™33Ì33ÿ33f33f3ff3™f3Ìf3ÿf3™33™3f™3™™3Ì™3ÿ™3Ì33Ì3fÌ3™Ì3ÌÌ3ÿÌ3ÿ33ÿ3fÿ3™ÿ3Ìÿ3ÿÿ3f3fff™fÌfÿf3f33ff3f™3fÌ3fÿ3fff3fffff™ffÌffÿff™f3™ff™f™™fÌ™fÿ™fÌf3ÌffÌf™ÌfÌÌfÿÌfÿf3ÿffÿf™ÿfÌÿfÿÿf™3™f™™™Ì™ÿ™3™33™f3™™3™Ì3™ÿ3™f™3f™ff™™f™Ìf™ÿf™™™3™™f™™™™™Ì™™ÿ™™Ì™3Ì™fÌ™™Ì™ÌÌ™ÿÌ™ÿ™3ÿ™fÿ™™ÿ™Ìÿ™ÿÿ™Ì3ÌfÌ™ÌÌÌÿÌ3Ì33Ìf3Ì™3ÌÌ3Ìÿ3ÌfÌ3fÌffÌ™fÌÌfÌÿfÌ™Ì3™Ìf™Ì™™ÌÌ™Ìÿ™ÌÌÌ3ÌÌfÌÌ™ÌÌÌÌÌÿÌÌÿÌ3ÿÌfÿÌ™ÿÌÌÿÌÿÿÌÿ3ÿfÿ™ÿÌÿÿÿ3ÿ33ÿf3ÿ™3ÿÌ3ÿÿ3ÿfÿ3fÿffÿ™fÿÌfÿÿfÿ™ÿ3™ÿf™ÿ™™ÿÌ™ÿÿ™ÿÌÿ3ÌÿfÌÿ™ÌÿÌÌÿÿÌÿÿÿ3ÿÿfÿÿ™ÿÿÌÿÿÿÿÿ!ù×,ˆ¯   Aƒ&¨¡Ã@4ذ€Å†2„È¢GŽ%2dèñâH‰×Fv,É1"Ê‚/Bt‰2åC‡45R Ô¡'F„ 1òìéscN*‰ )$Q¡G'ÞüYiCX1Ö<«×™5 õšÕhS†d=´| òëÚ—o†­z°®Â€;nagios-2.6/html/images/status2.gif0000664000076500007650000000167507436604467016535 0ustar nagiosnagiosGIF89a÷3f™Ìÿ333f3™3Ì3ÿ3f3fff™fÌfÿf™3™f™™™Ì™ÿ™Ì3ÌfÌ™ÌÌÌÿÌÿ3ÿfÿ™ÿÌÿÿÿ333f3™3Ì3ÿ333333f33™33Ì33ÿ33f33f3ff3™f3Ìf3ÿf3™33™3f™3™™3Ì™3ÿ™3Ì33Ì3fÌ3™Ì3ÌÌ3ÿÌ3ÿ33ÿ3fÿ3™ÿ3Ìÿ3ÿÿ3f3fff™fÌfÿf3f33ff3f™3fÌ3fÿ3fff3fffff™ffÌffÿff™f3™ff™f™™fÌ™fÿ™fÌf3ÌffÌf™ÌfÌÌfÿÌfÿf3ÿffÿf™ÿfÌÿfÿÿf™3™f™™™Ì™ÿ™3™33™f3™™3™Ì3™ÿ3™f™3f™ff™™f™Ìf™ÿf™™™3™™f™™™™™Ì™™ÿ™™Ì™3Ì™fÌ™™Ì™ÌÌ™ÿÌ™ÿ™3ÿ™fÿ™™ÿ™Ìÿ™ÿÿ™Ì3ÌfÌ™ÌÌÌÿÌ3Ì33Ìf3Ì™3ÌÌ3Ìÿ3ÌfÌ3fÌffÌ™fÌÌfÌÿfÌ™Ì3™Ìf™Ì™™ÌÌ™Ìÿ™ÌÌÌ3ÌÌfÌÌ™ÌÌÌÌÌÿÌÌÿÌ3ÿÌfÿÌ™ÿÌÌÿÌÿÿÌÿ3ÿfÿ™ÿÌÿÿÿ3ÿ33ÿf3ÿ™3ÿÌ3ÿÿ3ÿfÿ3fÿffÿ™fÿÌfÿÿfÿ™ÿ3™ÿf™ÿ™™ÿÌ™ÿÿ™ÿÌÿ3ÌÿfÌÿ™ÌÿÌÌÿÿÌÿÿÿ3ÿÿfÿÿ™ÿÿÌÿÿÿÿÿ!ù×,š¯ @° A^¨aCƒ.,ذ@‚Ð2B‹˜a †1fDÈ‘äÇ@!GvTÈäÅ‘¬X]cU’¤Ç—вÚ(q¡ÃcòìH1P‡£vn$Øñ¡Ñ£H!ÖlùêIˆ&=Z½:qªÇŸ94ȃهD¥–5{v¬A§lÛ¢8ðd\\%R]‹7¯Þ¯?™ö(U°Ä€;nagios-2.6/html/images/status3.gif0000664000076500007650000000166707436604467016537 0ustar nagiosnagiosGIF89a÷ÿ!!!)))999B9BBBBRRRcccsss{{{”””­¥­­­­µµµ½½½ÎÎÎÖÖÖÞÞÞççç÷ï÷÷÷÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ!ù,”1  Á‚* ¡C #b`è°!D‰ )V¼ˆQ Æ‡ 42a P(90(`‰Â0œ|P²BZH 2$ƒNi#„ "î”3AN…C‹&¬€àÀJ‰KgzÉQ$ÙŠÊz¼À–mA´j'¶uû1mDs/¼Ýx7/Y„ É;nagios-2.6/html/images/status4.gif0000664000076500007650000000200507436604467016523 0ustar nagiosnagiosGIF89a÷s)111199!!BBBJJJJcccckkkkss99{„))„„„ŒŒŒŒ”””!!”„„œœ!!¥¥¥µµµµ½½BB½¥¥ÆÆÆÎÎέ­ÖÖ””Þ¥¥çç!!çççïï99ïïï÷÷÷„„ÿÿÿ11ÿBBÿccÿssÿ„„ÿµµÿÆÆÿÖÖÿççÿïïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ!ù@,â  Á‚* ¡C #aè°!D‰ )V¼‘+ZŒØƒ†I6œp²*8,X°‚  Š bB 5|pbDÍ 2À²C…hÌxƒFŒ- ðH€¥h°Ha XšâU` &z¨`ÆòÉ`Wà täà±£fƒ$Ù"ƒ (6ì<‰ÁƒÂÉ4\pHÐâ‚V D¬pÐA‹‰*9L­qä°a©Z €Ø²[¨=w„Ù#ÞÆÍš7ë€;nagios-2.6/html/images/stop.gif0000664000076500007650000000171307436604467016106 0ustar nagiosnagiosGIF89a÷ÆÆÎ!!Î))Î11ÖBBÖJJÖRRÞccÞkkÞssç„„çŒŒç””ï¥¥ïµµïÆÆ÷ÎÎ÷ÖÖ÷ççÿïïÿ÷÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ!ù,¨-(p*\˜€C.T¸àáC°øPBÆBø(0€€ N ñã‚ÀT€‘¤…  s¤M røS ‡ *x@‚?8 @ d¬x’àd `%‚ Àæ´´ù À¸]ö€À9Ì%¸@‚€´(•¥Â/U;nagios-2.6/html/images/tacdisabled.jpg0000664000076500007650000000241207436604467017370 0ustar nagiosnagiosÿØÿàJFIFHHÿÛC  !"$"$ÿÛCÿÀL"ÿÄ ÿĵ}!1AQa"q2‘¡#B±ÁRÑð$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚáâãäåæçèéêñòóôõö÷øùúÿÄ ÿĵw!1AQaq"2B‘¡±Á #3RðbrÑ $4á%ñ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚâãäåæçèéêòóôõö÷øùúÿÚ ?òÊ+ÆZ2êÚ[ùvë5äJ~ϹʀI»Ðw®fçóÏŠß i!eýój[ÂŒŒåsÈ#"¾"†•X¦çgòýd¯òGõ&kã°5åNžž6M4ê;ï§»Ji4×Y%f÷·¡QEÂ}9ŸâKk«ÍêÚÆO.âEÂØî23î2?ã Ð5³›TÑ~Êâí¦·¹ûh?f W#å¸P2k§ñ¶&–÷ú…ƒ^ý•IDYÌ@=Ó×¥s7:m­¤"âïÁ/•Y—S.y (9'&½œÜiZ/wå¿—¿ýÝl~kÅxxÖÇsUó›÷nÝål=E S³ROÝRºi[Ш¢ŠñÒŒ?[iGJkýVÑ®–Њ$e9bcëŠänmì-ÄæoˆÄ¥µB6ïû¿ÏZîd::à烊õð¾ÉB<ÒZþŸŸg«0ž.«£JMGk_Þ÷b쬕ôõ»êvÔQEyè&O†5›}cNIcu*,yå[ü+Z¼2ÆîæÊán-&xe^Œ¦»¯ x§S¿˜Ar-ßï„!äqúW³ÊÝçð—G3Œpؘ?j–êÖ~{Ý>ûþ‡sET/è´W‘ÊÏÑ}´OÿÙnagios-2.6/html/images/tacdisabled.png0000664000076500007650000000246107436604467017400 0ustar nagiosnagios‰PNG  IHDRLê¹,tEXtCreation TimeMon 31 Dec 2001 13:25:57 -0600|qîtIMEÑ 1qõ¬ pHYs  ÒÝ~ügAMA± üaˆIDATxÚ¥W_hEŸ™Ëî^î.iîOó§I®1I!MhkI ¦PkiÁ'"}èC} B@ (TQZŠ…">ˆôÅA#BìC•(õA#hc#­Ö˜—äÒ\þçºÙ${{»3Î^¤dg7íÝøñ±ìÌý~ó›ù¾oæf5HOcbJ© “ˆÎ"ÈÅ@˜Éñ”ŸÜ jœ8%!É4]í®“ìùÙÂü]}ýjrDšm}0›n”‰lJ½~e:u¸<)Ønî—•KSƶ ŠÜ31ÊüqOg8Ì!õ³Ï[Û^ªŠU`ÌQ¸¨f=®ïËŠ¿¦EÈ»3©ƒÃwöü:Èšgþº·hšÆ?BoNO~œ™›3M66kéë'F9Œ¿æWËËŸ6µÌ=¶ÆïÛ:×5³kÅëÄ6 ±4(Òu"éÏìŽÆz§&™;úý7ö<KÅ¼Ú Jè›Õ•ŒiÆg Úz éË ¶ÜíÆá;»A§Ý¥ìO7¦œ­¯â²•¿<›Ô5Ͷ÷`üB¤â­šº¸4':Žx™/OŒonììéPƒýÍÜš~ëœÊå®ÕÕŸ W„%i‹oµìûósÙzýb(ડIEND®B`‚nagios-2.6/html/images/tacenabled.jpg0000664000076500007650000000276507436604467017226 0ustar nagiosnagiosÿØÿàJFIFHHÿÛC  !"$"$ÿÛCÿÀK"ÿÄ ÿĵ}!1AQa"q2‘¡#B±ÁRÑð$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚáâãäåæçèéêñòóôõö÷øùúÿÄ ÿĵw!1AQaq"2B‘¡±Á #3RðbrÑ $4á%ñ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚâãäåæçèéêòóôõö÷øùúÿÚ ?èè®7⋵¿ ^Ù¥—…WTµ»x ŽàêQÁ›‰ªÄ$àžœŸCTÇ-³Õ4«]oÀ+¦Á¨ßGf· ­C VlöUäàŽ3Œu"¿ §•â*SU#k;ÛÞôßKßð?šidغ´£V¶wkß‚nÛèå};Zç ÑEçžQÆü_“F_ ÛÛkkl¾ŠÚÒÌMäï¸lìýæFÎ7sïï^uàäðmµÏ„üEógmªÜˆmïFªóýžëÍ‘|¶?7ú°Û±ŸQ^ƒñ-u{ô4_ãñ>™$k#Èú¤vÛ$Üß(æÈÀÿ=k’ð…åÒüGcyÁ¨ôò³¨7oâ%¸û:“ƒ F'%FNŸâ=z=Mð´š®œ“Ãwq*jqÛ‰6³•°Ø+ƒ¸ •Éé> Ôàñ>…{§|1—ÃÂ×PŠ[›¨üD³“8`T±ãH$;× ü]Ñ5]{ÂðÚiP}¬Å{×6hò>× çt[ÿ‡9>ÕçZOÃ]JÇÅz<ö¾ ‚Öu(/ä½}TÉäE€ÍnSwÌÈùÀù¶Œä_c•âá'´Œ~-.õÓªö±M¾žëòê}þKŽ„rßgíc )iyk¦­¯mÛéî5Ûª=ÚŠ(¯Ž>â>3èÚž»á‹;=3K“T+¨Ã-Ūݭ¸’ ¹Y˜ŽƒH=«†Ò|7g¤x‡G¹¼øKo£nÔ HnåñXm’oJ¡oÞ0Á!KcÝx›Â:Æ«âØ|Uáÿ s§-‘Æž—;ãó ™Ë6I»uæ°ôo…šÕŒŸ?¾Ó¤èú„wðYÿe"eÕËŸœ>îw7\ã=8õXm*EIÖK{¯Þ§ªwøZ‹ékÝ;»ÚÚý¶[˜PÃ`UˆŠZÝ~ùKTî½Æ ìÒJ÷M7{ZÏÔ¨¢ŠùSâOøñ.Ê÷J¶ðιt_Û¨ŠÖYtusýáÓøïšöAÏJø>½#á_¼WoªÁ¥¦·rÖgÊ—=`H¿GÏxJ3”ñ8i%Õ§·ËüÖ¸“cRsÅá&£}\^Þvkò·Ìú¢ŠÃ°¿»’Î)\±£ü(¯ÏžIØüºXY§kŸÿÙnagios-2.6/html/images/tacenabled.png0000664000076500007650000000213107436604467017215 0ustar nagiosnagios‰PNG  IHDRLê¹,tEXtCreation TimeMon 31 Dec 2001 13:25:50 -0600¹Ö®`tIMEÑ 3Ÿûî€ pHYs  ÒÝ~ügAMA± üa°IDATxÚÝWKLAž™ÝÒòhÁ¶<ãÈ#R„ $ ñâÁ1&) QJº*Ì ñ¥|ñ½bg"5oóÏå‡?…u6ÊE©â„¶[²ÖÕíJVRH5÷¡D$¬®Ê˜š t'¸O¸ÓÎwOû¤ ÅkRÍÙ¹ýÌùÓóÌyzfÊ¢PçJÉëmUÙ¿»æË”C2¹†ha´¥——2ÊÒdSZ“ jbz%®šÓÀäPâ›b{ŠÊÁKnIËРÚaŽä–x ÍP­Ml(Wr®Iu¨ ‡1:„`ž:³1Så ¨>VUuL2YÇ Ÿ,sfwË,`t<µL"!€1¬† [-“¼®`bÚ2"'cà ¬˜ÀÞ c•qà/è(TV¡æŽ1's€œ;$ç *s¦"küx“&S\@±±Ë̬щÛäÏ€ÒØ •+¿ó4•Ëè+IEND®B`‚nagios-2.6/html/images/thermcrit.png0000664000076500007650000000106707436604464017140 0ustar nagiosnagios‰PNG  IHDRdU9,¤,tEXtCreation TimeSat 12 Jan 2002 13:36:14 -0600ø;tIMEÒ ) Çn»ê pHYs  ÒÝ~ügAMA± üaŽIDATxÚí™!nÃ0…½ÊÀf ˜ÃJ&“ZPc´l§éz„Á^# `  aµTèH6‹¥ ìÓ¡)Y‚ìIÿ§8JØÓÓó‹í<ÇË¥¹Ý2N^Ï//žšª’y.Ò4´¤HÑZ«²ìÍú¼^7Ûía¿ghÖVëóùLïwÚóz8)CKŠ—4Ë ¥Êª¢Ì¹\J&DhIQ™²ì;Ëií¬ ­'j Rp§`Ss:9ÆBë‰=˜ƒù ™`°ˆÂà+LÖ$†stxA«æà§!cœóÐJ¢f(øUhÿ_S>Y+ì¬IXבÁ,‚5œ†óðNÙ¡åD <Çd-ÍZ@_ðÜ/µB+‰îýÁd-`[\dÍ„>œÂíÎ4þ¼Ï/JñÔáO°³–B‰ÂdMÒ=Ž•3ÖfyZOÔ´Æ$¡©uÓH) þ7Ø ÌúÚí´RV©$IB‹ŠÛ¶7c²Í¦ÿª®{SJ`m « Ù­×þð¯(Þë:õ†üÆÀðþ Xu‘:/nIEND®B`‚nagios-2.6/html/images/thermok.png0000664000076500007650000000141007436604466016602 0ustar nagiosnagios‰PNG  IHDRdU9,¤,tEXtCreation TimeSat 12 Jan 2002 13:34:16 -0600‹’ú•tIMEÒ $Çõ1 pHYs  ÒÝ~ügAMA± üa_IDATxÚí™OoÓ0Àí6íH´K] —v `Ñ.c“ŠÄW˜âƇé'àĉ+‡øÕHp`´'Êþ©‚ÃÖ D“v¢qúgÁNá²­aM…l6ÿEɳl=?½?z6¬T*o¿¿k4`r×r&žëÐ0ƒÓ§F™Üx$eœêЮ7è‘ÉàÌ™)]‚³òˆ¡ˆÕŽè7÷ØeƒJå圥±¯Z³^´JfÁœe9† ®O’›çËçÙ3aÊùòˆ¡ˆÕ àÖ|ï†nèñöÕjµªMn¬ƒÚêÊêú³õ,ÎÎh,™ñG>J¢xs:¯7ö’M­m·Ÿ<jå—DoG^òs ;åÝzõ£F±o— $/Z%©¹wûîæ›*ÏY‡´åðܬ˜Å}öÖ\ÚyÑ|‰oÑúH =ôØ›{D¢„h}¤fl" `@Ña̲zE€$ðÁ±öûCÑúüpcé­‰ÔPƒç,•ª.Ü™¸g„ɉª†QPü§2NŒ@´>r¶á* / Â0Ä!D7Dë#5>¦,ø”gM2Ö„íI°H­‰Ô°&(ÏšŠ„ôŒy„xÕÐPØBc ìõwxÎböRÆŠf|*gM6>œ7ŠŠIÐ^ØbŠÜ¶»˜+‰ÖGjœ#Ç 2ZÁÌÝúbÝ·²`ÖKV™ñA˜§Ámàt÷Ý4$ÚÃáƒ{¿ÑÝΦ/õ%ëÀG©˜EÌvíöö•…ǼzŸî¾ú„ó—ùHkä’$o.µ=PÞY[äÆ*ãµÚûzÏŠÞÑ¿¤âF!€NP‚Eöñ ~¾°œ{EIEND®B`‚nagios-2.6/html/images/thermwarn.png0000664000076500007650000000124407436604467017146 0ustar nagiosnagios‰PNG  IHDRdU9,¤,tEXtCreation TimeSat 12 Jan 2002 13:36:21 -0600ÄOÅtIMEÒ &6öŠ pHYs  ÒÝ~ügAMA± üaûIDATxÚíšAkÛ0Ç%W©ß3”LƒµNOmÆ ì°6šOQhOÝ—É'Ø';•Ýúº c0–ÜCIØ)q6¨K£4¥šdo;µži~Øéö×ã½§'Ë´Óé|ÿq:ž‘‡ÂÚÚ:W!¦W‹™T*ˆP‰é"›®VPÙ?Ó2<­·×Ÿ¼`j4v›Í­°ÆM/óÞáÙS0-Åx<îŸ}ÔΚ/¾´Z­ýý]€Ç¦×f)i::<üà­œ³I|qðf¯6MK²þ(l·£ããóAÔ·Ÿ#ÖLK²šz½qtt¢kÖLŒ@$¦õX )e™éùðíæ&˜Öc5£Qæ,õú>]õ©i=V£\@TÍ"AõM뱚 PF°|â»,,v¢ˆ¦•X ¢®Yžiÿ :õòDºÈ*@Ÿ"Õ,@iZݤڸ4,…Ì2A†ÎDÇÝDé"k œ³– ï³T/ïºÒ"ò>ÔEÖxRΩ;–ƒåž¢Ä¥áßÉ›R ÎY…ä!åjÖ°ßÛ ‹¬"./³/¥sI’lll›Öc5“I"%gœ×º_¿5MJܽáíHr1L=Ze7ׯâ8J§ýjõáÝHßiGý$ _êÝ0êÏÞ¿‹ÂЕ­Û‰cÑë’×Ï´³hþÔã¼ì_ÿIB=ªkúOŸ‡Ð–8VIEND®B`‚nagios-2.6/html/images/trends.gif0000664000076500007650000000154607436604467016424 0ustar nagiosnagiosGIF89a÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ!ù,CH° Áƒ*\Ȱ¡ÃQ`EˆF¬HqãÆ‚!bÄÈqäE‘''fL9R¢H—/]²„I³¦Í›8;nagios-2.6/html/images/trendshost.png0000664000076500007650000004472607507661353017344 0ustar nagiosnagios‰PNG  IHDR„,üêÆ+tEXtCreation TimeWed 3 May 2000 15:07:26 -0600 ÌÑßtIMEÒ,.Oˆf pHYs ð ðB¬4˜gAMA± üaI.IDATxÚìÝxÕÂÆñ I ”@BK(DzèJDšŠ"¢F¬¨(xñZ€«"^‰X@AAP±€ ½ƒzï-’ÐP¾÷îùœ;î&¡ñÿ{|ö9;{æÌ™Ù<øî9S|.\¸àœÍéàï‹0 Ç\Nõñqº·¸©\rõH¢ö·*›ÿ€ËqiaTAÓ~“ÉöW®‚Àå»X5CžÞIÔ,ñN¢ ‘à’ùeö¡G µ˜…Þ1J €Ë‘qõN¢z›É¨'—)ãiúŒÂ%¡Y„ûŒÀ1„Q8æ2Ã(sôÈ:ŒŒÀ1ÿFßyç/íÚµ»âv÷íÛáôÞà†öÿaôµ×^»à¶uëÖÒ¥K›ò?üpÅí.[¶¬AƒNïnhžÓôÓ§O¿ûî»M911±aÆ}ôQ¾|ùRRR:qâDS¡[·nË—//V¬ØW_}e–¨NîܹcccçÏŸoÂèСCµDkYuÃ3ŒNž<¹eË–¦¼víÚ¸¸¸°°°äääaÆmܸQK”2Ÿzê)«r||¼öéÓçèÑ£S¦L1KråÊõᇚ0úâ‹/ªÂìÙ³{ôèáôÎàÆâsÁvüéÓ§=•&\îaÎéÓ§Oš4IåråÊ)Œšj~~~iii»víªW¯Þž={K–,yüøñèèheÖJ•*é#%Ñ;v¨r«V­Ž9Ò¿ÿºuë:½³¸±üidtþüùµjÕ2IT”>­){•/üAIÔT6cŸ³gÏnܸ±Ë}ž¨’¨©l0:a„çܺwïîôÎàÆò§0jŸ£w¹§é+T¨`Ê¥K—7n\bbb“&M†ê²…QLf ›1cÆàÁƒ=ÍGùòå[¼xñƒ>8räÈ!C†8½³¸±ü)ŒÚ¯^rý9Œ4èÅ_ŒŠŠRZ}òÉ']î jDµ–)ôéÓ§sçΊ­GŽ1aT4&&ÆÇǧuëÖ£GvzgpcùÓ9£ÀõĘàÂ(C€c£p aŽ!ŒÀ1„Q8†0 ÇFàÂ(C€c£p aŽ!Œpm¥¤¤téÒ%44ÔÇÇ'""â7Þ8wîœù(!!!óu/ZÁÎÇ&GŽMš4Ù´iÓÕô\í\eࢣ\[111*Tعsç… âââΞ=Û«W/ó‘–g¾îE+x¸ð‡øøø ´nÝÚé½.ÂG¯N÷€›YöìÙSSS}}}ÍÛÄÄÄÒ¥K'''»Ü#‹™ÿø¢2©|îܹ\¹r:uêŠ{žµÝÒÅÈ(×–¢gŸ>}¬©ù+‰ºl3Ý‹-ªR¥ŠÞ†††>Ü»‚Rl“&MôV¯*g¾Ñ”””þýû¿þúëæ­Öúè£Ê”)“Q;Þ[·ÓºÝ»w7å„„„Ûo¿=wîÜöjZhµiN-жvíڥªU«´|É’%*oÛ¶ÍôAKbcc‹+¦¤>nÜ8Óˆ z«n»í¶ X=wú ĵEàÚ6lØèÑ£K–,Ù­[·‰'._¾Ü,7cŠÖÈbçÎõvРA/¾ø¢w…^½z 2Do;vìhMô{°ÎÍ•+—’hÑ¢E­Â–-[–Q;Þ[·(‰îܹsàÀæ­šmݺõ‘#GLkVßÚ·o¯ÕŸzê©=zhIãÆgÏž­‚^­²–›Uâãã·nÝ:vìX­h–¨ ­«õD}³%ÜÄ]àš;wÛü?( >öØc®Œ§¹­åö ¡¡¡‡RáèÑ£*TسgOFk¹Ü#£JÀ~øá† ÌG'Nœ º¬vTé6oÞ<ëS­¾qãÆ„„\S3_¾|{÷îUû§OŸÖÂäää)S¦hÅ~ø¡Y³f•+W^¼x±iÕª•Òj‹-ìý±6פI???Eázõê™ðw@àºZµjUãÆM´ÇÇÄÄÄAƒ­]»V±Õ\íäQÁcÂÚûÿàÞÑ6ÝP›n;m½}ûöZ8a„R¥Jyo%£öUV.Y²¤šÒëÖ­[õª´j–(h¦Ûˆúpÿý÷+¶*’*²W«VÍéï ×Óô\[¹sç>}ú´õ¶R¥J'Nœð®v÷Ýw§¦¦vìØÑÌh{ ¾`sÑí*j•Kl'£­=ºW¯^o¿ý¶µ¤@æ¬Pûm§Ô¦6§‚öÔlT‰³B… ¸zÍ›7oåÊ•û÷ï¯r&Cž!!!óæÍ;räÈ€Z¶léÄwF¸¶î¿ÿ~¥«mÛ¶¹Ü3ã±±±Ö ‘f‰)¬]»VË7nüá‡ÚW·*´nÝÚÜ7ô«¯¾ŠŽŽÎ|£ZË~æ¥]ºíd´u__߇~8..nÕªUÖêC† 9wîœvÊÞæØ±cU˜|Øéï ×Ëp-ÅÇÇ+ŠåÊ•ËåAìѣlj'ÌG-[¶ôóó3e…¹Ò¥K«‚B¤õ?h{ÓŽ>ŠŠŠÚ¸q£÷†ìÿW;;w¶6äúó-H½ÛIwëVÁ\xdÊGŽQ9,,lôèÑVs[S—;tªlš+œ/^¬²^UV¨õîU^¸p¡¹¯ªvùÇô®‰›çŒÀ1~Nw€›·ÉÌ* ŸÝ¬€c¸€ Ž!ŒÀ1„Q8†0 Çp5}ÖëÛ·¯Ó]\[½{÷vº ÀM‚0zMðÜÄt²Óôp aŽ!ŒÀ1„Q8†0 ÇFàÂ(C€c£p aŽáq Y†§ÃÀ߇õo>Ï®a4ËXÿ‘Jà¦G² Óôp aŽ!ŒÀ1„Q8†0 ÇFàÂ(C€c£p aŽ!ŒÀ1„Q8†0 ÇFàÂ(C€c£p aŽñsº7¾}û:ÝÀubý›ß»wo§ûüµF³Œõï©nzdP «0MÇFàÂ(C€c£p aŽ!ŒÀ1„Q8†0 ÇFàÂ(C€c£p aŽ!ŒÀ1„Q8†0 ÇFà?§;póèÛ·¯Ó]\'Ö¿ù½{÷vº/À_a4ËXÿ‘Jà¦G² Óôp aŽ!ŒÀ1„Q8†0 ÇFàÂ(C€c£p aŽ!ŒÀ1„Q8†0 ÇFàÂ(C€c£p aŽ!ŒÀ1„Q8ÆçÂ… N÷á&Ñ·o_§»¸Þz÷îít€¿6Â(Ã4=C€c£p aŽ!ŒÀ1„Q8†0 ÇFàÂ(C€c£p aŽ!ŒÀ1„Q8†0 ÇFàÂ(C€c£p aŽ!ŒÀ1„Q8†0 ÇFàÂ(C€c£p aŽ!ŒÀ1„Q8†0 ÇFàÂ(C€c£p aŽ!ŒÀ1„Q8†0 ÇFàÂ(C€c£p aŽ!ŒÀ1„Q8†0 ÇFàÂ(C€c£p aŽ!ŒÀ1„Q8†0 ÇFàÂ(C€c£p aŽ!ŒÀ1„Q8†0 ÇFàÂ(C€c£p aŽ!ŒÀ1„Q8†0 ÇFàÂ(C€c£pŒŸÓø+9pà€)œ8qbݺugϞͨæÉ“'ããã}}}3i-Ož<¦ìïïŸyålÙ²/^\Õ2©P¸pa«Bîܹ>ZGø“5¶nÝš––¶dÉ’ãnkÖ¬9wîܱcÇŽ=jjž?^2iêÂ… WÖŸŒ>Ê™3§g&+)RÄ £%J”(P @PPPÅŠýüüTÖ- Í•+—ëÆH«>W|˜þº:·lÙ²oß>7ׯ_Ÿ˜˜xúôéC‡)={VÑÓuòZPÖT5»Ê£9räPA©T1Ô××·lÙ²J·… 2½›O¯ßNÝP‡ Ë¿¯ò™3gœ=JJº¹råR 5¨aaa+V UBU¹páÂ×j»„Qp“Qúܸqãï¿ÿ¾dÉP%ÑÔÔÔsçÎ]bìñõõ 0å¼yóæË—¯X±b&k–*UªH‘"ZnÕÏž=»Âh&sëÔ …Qû¿’±:¹mÛ6õÓåN«{öì1‰ÙT8}úô• ˆªóŠ’ùóçOv»ÜMBU<-T¨Pùòå«T©¢×·¬ú²£àf·lÙ²9sæ¬X±BÁîÔ©S [JZ9räP¬T´2áR1TY³›©d]c$Ê‹ ‹¦ì+MˆTÎKwsг µVÌÕ[EXû«:c%Zm%%%åÈ‘#æm‚›ÒªÙ)eÊ;vèõR2¥6¤jGŠ/®½‹ŒŒ,Z´hRRÒ•5¨C¡h«¦”J«W¯®xZ¢D‰«7%Œ€¿*P¥ÏY³f©à1ñíÁL¬›ùt%§ *äË—OMéPÑJAͺŒÝdMeYA%3…KkœÒå7½'ܵb&áJIΚÍWîTg²gÏnÞÚ£ª5k–¨{Ê©zkebåÅ#n ”JêÛÚµkMùäÉ“™OúkO•¼K—.]ÍÍ\žÅ *©,XPdzN:5jÔ(W®ÜåSÂ(ø+9pàÀ¼yó&MšôË/¿|ØÌ’+x™¬©‚r˜²¦™7wŠ ¯êyΜ9MtVÁœ'P @“e͵óÚuÛdG½.[¶lçÎ{÷î5·EI%ÝJ•*EGGW®\Ùž#Óm0óÑSõV-¨&Mš(æ–)SF©ú¢ûHŠžS§N•„ׂ‚‚2Šž жZ¢å—{ýueºa®û±ÞZ7Q2víÚ¥ZoU>~ü¸õöÔ©S™Œé¦KTÉO{§}T05§(š¨mÅÓ””í]rròE£¤ÖRSµÜÔ ¹÷“5zª£·bÅ íÔîÝ»õ]¤;¬¢0Z³fMSÅÓLÎ1%Œ€”ÂÓĉ§OŸ§—îhœ"Thhhùòå¡”AƒÝ¬ô©ä¤ÌteÑSY3,,LÙN¹ÓlÂÜ­Ó|ê7=¨÷­‘ìéÓ#ŒÚ£ªRéêիׯ_o–¨Ÿê¼*_4°i—M>>ÝqßlÙ²)Á—+W®FuëÖÍhÚ]}ÓÁùdúôéÞ÷æÌ;wÅŠëÖ­«Ìl=o]K‘kýúõÊ7*¤›·”™¼ŽrOíÚµ|ðÁƇ„„8½ë×–¢¹ÂèòåËW®\©Âš5k’’’ҽ̨T©RåË—WÖWÁ:áÌ™3GŽQÊ_´h‘Ò­÷A67d}ì±ÇtH/åÑS™4HøôÓO?ÿüóµk×z gFEE5lذ\¹rÖm8M]¼xñŠ+vïÞí=#GŽ””û“\îÉ}%­xàŽ;î¸õÖ[Þog¬[·...NGO<Ý`ªÃ^¼xñªU«šKé­Tªƒ¹cÇŽ 6üòË/7nÔᵯ¥Ù²e˦M›f>woñn0 ®«?þ866vÏž=ö¢Ð^­ZµÛo¿½L™2Ö\|æÔ<œS1ôàÁƒñññö$ùûû«;ï¼³M›6ÊX7Á\|V±‚éÎ;-ZdnæoÉ(•êÈoÙ²EõõE(MÚ¿OÁ‚÷›7o~‰‘ÔÞ a\ûöí{ÿý÷¿û„{ü0ÓñJÕ«WWÙ\¯¬³qãF}¼3hþüùK–,©¨¤è³råJÕ´g£¿ÕtüUÒá3gÎôéÓׯ_¯4oÿÈJ¥uëÖŠŠ²Q¯^½zîܹ«V­JLL´¾Js:iÆ Û·ozé} Œ€kËÄЯ¾úÊzÒºË]J”(q×]w)ƒzLÇÿþûïJHqqqöIas=xddd­Zµ^÷îÝ;uêÔuëÖY1T´¼sçÎÊCÛéø+¦#9ÕÍ{?((¨råÊúµm ”ž;wNáUytæÌ™öoAråÊÕ´iÓK¤„Qp­¤C}}}‹+Ö¢E ¥FëFñ $û÷ïÿõ×_gÍšå1 lÕWÊ“'BêÏ?ÿl@~~~·ÜrËO<ñÀ„‡‡;½Óm:°Ê—£G^»v­ýþ¬úµ ß Mš4©S§N‘"E̶Ë}½ü’%K<¾×åDRÂ(¸&zöì9lØ0{ 5'µjÕªJ•*ùóç7 EvíÚ5eÊ” :tÈ{¿Q£FªàzÌÅI]»vU® szoÉÉÉ¿üòˤI“¦OŸ®_ÖreP…Ëúõëë·A‰%¼#éÆíçT(’¶lÙò±ÇËä\RÂ(ÈbãÇùå—wîÜi-Q¬¬W¯^ãÆF­‹“¬:oÞ<û£ÛU¡xñâ   4ˆˆˆðõõ]¾|ù7ß|c¡ùòåkݺu‡F¹8éÚ±¦ïW¬XqìØ1kyôÀ;’*ŒÎž={áÂ…ö›7éwÂ3ÏW%½¹Fûnè 4h~3X÷ÚëŠ+>üðÃÕªU³Æ>Í™ÁãÆ³ÿ´°‘FÀ•ëÞ½û§Ÿ~jݨP¡B1117¶îêrçË |ùå—{öì1KôiíÚµX=N$=yòä„ ”o¬3DUáõ×_஬{&Ÿ[µj5f̘ù^´°V­ZÖ(i¾|ùn®¾Ÿ«V­R òóó›6mڻᆱž.\Ø,¯_¿¾ú£O•´õððpÿ?¨Ï+W®Tš¬Y³f@@€ª5nÜxáÂ…ª“;wî¢E‹*THmª5½j¡R}[3fÌèÕ«—>UR,R¤ˆYEÆgoPPYVaάeZS¾4 J¸›úVºtiÕÑZ5Ò±²÷|îܹ¨ žØûÓ¯_¿–-[š¸™+W.¥OE[íŽR©vä—_~12{qŶmÛÖµkWûh¨öýÿøÇ¬Y³ì_´þHô§b¯ÆÈ(¸< ,hÓ¦Mrr²y[¬X±N:)!Ù'ÜSSS•ÿF•””d–(š<òÈ#3øÆþýû °bÅ óViiàÀÍ›7ÏÂ>ÇÇÇÿç?ÿQf2×ͼôÒKÚ ó‘B¡âšDTH:{öl\\Ü|°téÒM›6Ÿ:ujöìÙyòä1uÔˆ’ebb¢Ë}Ç"…Km)–©US®Uì3«DFFöìÙsûöíVƒ½{÷Ö.¯Y³&§›”¢¤y5c´f†½G:>ZK92%%å7ÞÐŽX=W›§OŸ^»v­½{gÎ;×·oßóçÏkùƒ>hÆ, ÕˆvA±[k™ Ùo#z´ƒC‡½ë®»bcc/^|ÁýH-ý¢ØºuëOû¬Q£F•*U:qâ„IAZ˜7o^å<%¶ï¾ûNAJÉX™Uû¨gÍš5cÆŒþýû‡‡‡+´©Î÷߯òí·ß®ÕÇŒm&¸­m)mk[~~~¯¾úªV4«DDDÔ©SÇ£ÁC‡),êÓ°°° XýY¶l™ jÍÊi3gÎÔÛÝ»w×®]ÛÞs…TõÜÞˆësF­þhïÔeMÛÐÐбcÇ*ƒ&¸=Z ¶mÛÖå¾-K.ÃWîW¸>|¸91Ã|û]ºt±ßøÉå¾þiðàÁŠãŒŒ€KeO¢ -[¶Œ‰‰±ìiìß¿?66V!Ã&}Ú®]»{ï½×>3kQ5%?s+J___E–Þ½{_‹›7)+±•.]Z=ÑæôVý7óÚê§â£^µ¤L™2æù¥§NR}…H­år?^Èìµyk:¬ÐìàTAíhCUªTQè´VñnP ¨V­ÚÑ£G­ÕÕ«   ³9Ck)ÇçÎ[-xô\MïF,êä·ß~»wïÞ®]»®Y³F?ƧŠ-Ú¼ysEÕQ£F¹²î†Púú>þøcí{ß¾}wíÚ¥îÍ›7O}ëÑ£‡=j^{í5õ'ÛUl üØ“¨’eûöíŸzê)ï$ªp¹|ùr“DË•+÷æ›oªfºItûöí4ITI«gÏžÿþ÷¿¯EU S0*P ÀÖ­[»wï®§ô©Ô Aƒnݺ…‡‡+ä¹ÜWýÿòË/S¦LQYiR055uÈ!Jo.wªönvË–-ö§žš…ÇŸ0aÂã?n?oA;èÝ ¥–Œ1bðàÁgÏž55UøÏþ3fÌkXTu¾þúë•+W*Òy÷<ÝFìâããµS&sרQ#::ÚÇ­S§NJ¢êS7¹JÚý¯¾úªfÍšæ­~u¼õÖ[«V­²×ÑПÓôàâ<’è“O>ÙªU+{ØrýùÔO}¤|S¨P¡t´WVP{ï½÷ž~úé,ï¶ýnGìСCbbb¿~ý6lØ xçr:ž>}Z{tæÌ%9åTÅ;3š¨l7þ|s ¦^Ÿ}öYåHÓTÁ‚Õì¾}ûT³H‘"а%K–ô¾=“Ç’† Ú|ýõ×gÏžý믿*#jÓf˜388øðáÃAAAfŽ[©}U.^¼x•*UL–5=WM忏¸8«ìÓôiii:¼'NœÐ7òꫯ*j¿”ȵP¿ÒívÚµk—~èP›¸¯}éÑ£GÕªUíu˜¦qàÀGyÄšïØ±ãE“è=÷Üãqmµ’Ö_|a*+ÏýóŸÿ¼ITòäÉS¡BSPÒ3fŒrØæÍ›ßÿýÈÈHeAE·°°0ÅÄgžyF±R¥Jª©½»ÿþûëÕ«»dÉ-oé¶páBÓ”V™6mÚÀwìØQªT)%Bmyo]¯ ¸ö{öìÙ©S§ýë_Û·oW²Ü³gO`` Ž5J)Óv-ùàƒFŒ¡:Š-Z´07gµzþÄO+V¬ÿþöFÌæÌÖ:”?þý–èÖ­›Ë}’®ªÞšyyïng¡%J|ôÑG9rä:t¨ò¨þH ¤xª>[uQ»víÅ‹»2N™ ï½÷Þ%&ÑóçÏ6lìØ±*(‰>ùä“ÊRögH^×ttÐYÇ·ÛuëÖÕ­[755uÁ‚ÖúuèC¯^½LÕÛªU«þãÿ°†Ì9gd¦{÷îK–,1å5jØoÓc(ÙŒ9ò“¨Ì˜1c„ æÎöM›6}ûí·M¢®?FåZŒ:ËãØ;vÌ<%ëº%QÓýÞЯýöp¹ÏÕŒõhPFF@†,Xp÷Ýw›ÜP¬X±¾}ûzÜžIABÉòÓO?5Wy_4‰nذ¡OŸ>æ™eË–ýñdzê.N¸Dc¥×s»ÖøhöìÙŸyæ™Ö­[ûøø02 2ôôÓO›$Ø©S'ï…®_¿~Ô¨Qæ~¢õë×Ï<‰&%%)‹˜$š/_¾’D¯?§Æ¡µÝ·ß~»iÓ¦.÷¶ôgcÊL }ýúõ3R—&MšÔ«WÏ£ÂñãÇGŽiž±T®\¹.]ºd’DeΜ9ææ>¾¾¾¯¼òJÖ>cé XÏ£7²eËf.åI·‚õÈøëÓŸk´9ýøàƒÌ#\îoí¥—^ÊèŽYN¿@>ùä“ÄÄÄ%K–˜'#¼ù曄QŽ;v¼ÿþûæt>¥¢‡zÈû1ž3fÌX¾|¹ AAA:uòxÄŽ‡Ã‡›»]ªÜºuëgŸ}ÖÙTòS¼¶jjtîÜù£>J·‚‚ÔÂ… ¯]½›Ó&>ûì³Ç|ĈGÍ›7oLLŒ²é{ï½wvÊ›y,ê£>zòäIýñLž<™0 ÒñÒK/™gùøø´hÑÂ;h*\*I˜ë5jT¹råÌœ7oÞ®]»\î1¿nݺ9~ÑÒ±cÇ”üÌí< íéèÑ£»vízë­·¦[á*ŸÞ~¹ýÉòÍé7Æ ¢¢¢V¯^ýå—_:thäÈ‘Ö(éusß}÷Íœ9óóÏ?×Ï?üÀ9£ÀÓòå˧M›fÊåË—¿óÎ;=*\¸paüøñ&\f4njgmÖ¬YýúõÞÅt¨{§OŸþàƒœîȵj ú:”úé§Ûo¿Ý‘ž¼ð æü㤤$Â(ð4xð`sßuEÌûî»ÏûI˜Š¡3gÎTzËhÜÔÃÒ¥K­aÑktû,‘’’¢ˆö믿^ÿMëÈÜrË-æ¹özUùÚÝg*oÞ¼­ZµZ½zµSaT¿pž{î9ó0*¦é€§yóæ™Â­·Þê}CJeÐ)S¦>|Øå~ÀãE‡9ÓÒÒ-Zd†E6lxc‹ZN:Õ»wïY³f]´æ:dÊÙ²e+\¸pHHHF•UßœÕàïﯔ¯àk>2×*ɨQ£Ì©ì}ÂèŽ;Ž?îrqjsmëØ±c»wï6Ûò¨\®\¹7¶iÓ¦jÕª_~ùåû￯%Žçx`øðáëÖ­#Œ€?Ù²e‹b“Ë}å]wÝežui—””dV®\Ùšü͈"ÔêÕ«Mƒ÷ÜsÓûw©©©¿ýöÛìÙ³ ,˜nÐW^yeéÒ¥gΜQ 4OÒ«"fddd»ví:uêd?#vÙ²e/½ô’Žªbn@@€Ù„¢¹YÑõǵJ.÷#Ò½€iïÞ½Ÿ~úéøñãããã•zÍ“«´­öíÛ?üðÃaaaÖ¶C¿ýöÛÏ>ûL«˜;ÌkCê˜Z{úé§ŸyæõÄ\M?cÆ ×WÓ;rœÃÃÃ;vìøê«¯FÀŸL™2ÅÌч„„TªTɻ¦M›”Š\î;4ÕªUËL¶fBÑÇŒç.\øŽ;îpzÿÒ§§Ðfnªš––ööÛo0 ÝšJêß}÷’¥÷GŠékÖ¬Y¹råÈ‘#Í’Q£F=ÿüó'OžTrÍdëæZ¥t/`šRlUÀ½ãŽ;”ø­…úšŽ;väÈ‘}ûö}öÙgÍ›7ߺu«ÓÇØSÙ²e £àRV3ÓôJ¢½ ”ã4hШQ#k²>]111ãÇWÈSÚSâ Rj/^¼¸÷Zö±R¡ÓKdOÃ*gÔ‚>òññéÚµk©R¥©säÈaÿÔ\ê´wïÞ/¾øÂéì),,Œ0 ®¡ÀÀ@3¼wúôiïKÂo@o¾ùf&atÇŽóæÍ3óø.÷ðð}÷Ý7wîÜQ£Fy£Ú—œ={v÷îݦœÑuQòçÏoîj­eµ°yóf«ÅÐbÅŠ%$$<óÌ3J¢={ölÑ¢EDDDáÂ…ÿ{ã¤?ÆVÏœ93vìX§®'ýIpÎ(¸BéÎb{(T¨ÛÉ“'»9Ýå‹«P¡BóæÍÇgNõ ]°O› ˜œœ>^q¹Y³f/¼ð‚Òÿˆ#”_­>hõÿ:_2Ÿ9õ™0 þ§`Á‚ [çÎ3WÍ—*UÊ£BpppÞ¼y•oN:µgÏs»õL˜û™ú»víªX±¢Ó»xq¯½öÚœ9sŽ;æýýýí ÓÒÒ” ÇŽ«<êq3Qó Të zݾ}{ß¾}Õ‚*_Ê ±B|ûöíßyçÓ‚ŽáÞ½{_ýuu@ekdÔÏϯC‡.÷%eæÌiӦ͞=;00PÑÓžYkÔ¨qC%Q—{ˆ—izð? —J-.÷¤pRR’w…9r˜YlE"ó¦Ìåus¹ç©/¥þ 222&&&Ý!EEEEGGÛo«”˜˜¸mÛ6+‘QŸž={YSíJŠP"÷ˆ¹æáOéö¤K—.ú=`¾Ó‚V·ß_+¶iÓ¦aÆÖ*jùÈ‘#‡ÒOÌÕcÚ„zòÆo8}h=mذ0 þ§páÂÖEô[¶lñ® 0jÝÔzS&ìWå¯\¹Òéý»TJùòåK÷ÖNo½õVþüù­OUÐ[ûùF­Zµbcc *¤4i*›š9sæ´_h¯CšÑÍžÂÂÂ&L˜P¯^=­¢Üi! m©MÅå¶mÛ~öÙg.÷ÝOUYͪ5+¼ª¾Þê£âÅ‹<¸zõêNWOK—.ešü‰"Ë”)S\î)Ô“'O*Ù?Uœ*]ºôܹsM…øøøðððLZS„*Q¢ÄŠ+T^¾|ùs΢"Ú-·Ü¢þh.\¸ ^Ù‡BµS/¿üòÇlÞÚ+Ô®][qèС۶m;|ø°VW ŒŽŽž:uª—Gk 4øÉmñâÅŠ†ú($$d÷îÝ«W¯¶¶U @ªV­Ú=÷Ü£WÓHÉ’%-ZdžbzðàAs[(¥REêfÍšµlÙò¼•ÁvìØás)çÏ€¿1cÆtìØÑ䡨ØXïÇ&ÅÅÅõêÕ+55ÕÌD7oÞ<ógÍšÕ¯_?5¨`¤Pu¹·Û¼¦¬kªÒÈö+®.%C{´¶sçÎzõêé@•/_^©´N: ¯6l2dÈÑ£GÍ ²¹ÿ›o¾¹”þÜd²[´hÁÈ(ø“† æÌ™3%%EÁhÙ²eÞa´T©Rŋ߼y³òåo¿ýÖ´iSïj;E±ÐÐЃ&''Ï™3ç† £™g¾ËM„õ;¦]>yòä’%KV¯^=jÔ¨Ó§OŸ:uêĉÖé :tO<ñÄoñ/mâĉJêœ3 þ¤páÂÖs#gΜyøða LMš41'A®[·nÏž=™7X¤H‘èèhSþùçŸÑœÞÅëíÌ™3Gݹs笋Š\î›°Þÿý5rºƒÐ_θqãT ŒO÷Üs)ìÚµkÞ¼yÞ6lh4Ÿ””4eÊ”ÌÏúSl­S§Ž¹ªféÒ¥Ó¦Mszÿ®“lÙ²ißsæÌd]T¤%ZüØc 4Èén:cذaûöíSÁ·OŸ>NwÜX¢¢¢¾üòKsÿ %†jÕª)9Ù+(Kùúú.[¶ìüùóñññ·Ýv[Á‚3i0$$dÍš5ªyîܹÇ·mÛÖ~9ùÍJǤzõêÑÑÑaaaùóç/\¸pDDDÉ’%+T¨Ð¡C‡ØØØ˜˜˜¿Ãqð¶`Á‚W_}ÕüqHGÏž= `ÊíÚµ{æ™g<îs”’’òÚk¯ÅÅÅ©¬¼Õ§OŸ   Lœ;wî»ï¾›––æïïÿõ×_?øàƒYÛá;wºÜ•gIk;vìÈž={Ñ¢E=ʸzÉÉÉ=ôÐŒ3\î[º2MÒñþûï[ÁnΜ9ëׯ÷¨ èÙ¶mÛÀÀ@—ûúzs³§LÔ¬YóÖ[ou¹O 8pà®]»²°·æºu1‘ÔZh½µ—/J»S«V-s®‚½|ƒP8Þ¸q£Ó½¸r_}õÕìÙ³]îSfyäÂ(Hß¿ÿýos™|RRÒÈ‘#½Ÿ,_»ví&Mš¸ÜOÅ=zôªU«2iMáU‘Μ:¹dÉ’¾}ûfaW;vÐͺ:ÊOÓª™øý÷ßÕ” ¶—o›7oÖa×¾üEó¨~´|øá‡æfúãÑŽpk'¾víÚ)ƒN:Õå¾_ý¤I“Ú·oo=Èå~ÜùC=´nݺíÛ·'$$ 2ä7ÞÈèaBR§NÆ› ˜¾ùæ›Ê•+?ÿüóYØá .lÚ´Éå>YÓÄS-QšÌ;·U65MfÕ¾/^ÜÜ[Þ>ËoîHË-·ØËªššõßû´ûø¨¦â`®\¹Îž={YËíÓýjóÔ©S.wšWŸÃÂÂTV5ó@yu;""Âåž×¶nY ž«5y3&m"©¶b>=pàÀ¡C‡üýý­%vöÊfw‚ƒƒõª¾Ù7¡’Ug;xP’~ñÅÍ xdd¤þxþûãä@”2 (`’„²Qÿþýç{ÑBëî˜U«V3fÌüŒ}÷ÝwåÊ•3•óåËg®Ä¿z«V­2c®ÙÝ1‡ fÂéçç§œ§WSsóÿƒñÊ•+•ÃÝTPkõêÕSSü±UîÓ§> QàÖkÙ²ecccsäÈ¡`§ð}éË+V¬hõÙlT™2 Àôyîܹ6lP}³:>C‡U€®]»¶Y¢šê¼–ëK7n\Íš5µD-(âoÙ²¥{÷îúÈäTýl°Ÿ_ýÕ^yáÂ…Ú´¾µ¢n?ÿü³}ÖqÈZÛ¶m³nbeÿ[âjz!“{¦Nzþüù3gÎ(›*nZÏš7”º”óé8Ìo»í¶ŒnÞž+W®bÅŠ©rJJJjjêš5kî¼óNů«ìgBBÂ_|¡Nú¹>|xïÞ½Ôó ÷'N¨{*›QÒ´´4¥.}ºoß>•«T©2pà@ué±ÇSdìׯŸ¹¯_¿^§GwÝu—¹ä\)1b„ &Ñ ¯Z>dÈóPÍüùó>|øÖ[oUVŸÍݸ̆Ž=ª$êQÙjGe´‰«7þü:XI´jÕªÏ?ÿ¼Ç)\M.®páÂ3gÎTBZ»v­òÊÏ?ÿ¯`a¿vÞäQ—ûôª³aÆýë_<òH³fÍÌ¥ßvª³oß¾åË—+u :T)í“O>‰ŒŒÌ’+æ*ùúèÈ‘#UVB4§§s朙é‡ß<3gfìíí-èÞ(â#éâÒyxxÀóòòlllø±Ñe;Ù«ë¿~¾w ÊAAAл®®.|ݾ};´²ë¤o¡R©öîÝ›™™É$½xñb±‰¢­‘ >>¾ººš–v"‚ â'€NEFFÂÙ0ëéÓ§ìísss–ÆÄÄ_!p¦±±QÐ-Ûž““ÓÚÚ*“É,--ÅZ[[{yy}þü¹´´ú‚”ÈœE.y†ýÈ—/_222ÆŒckk«÷+Ô3==’ºuëVñ±Ñ¬zz¼Ÿ=ß;¨™ŠŠ ˜±T*…ÕíÛ·¯ß«¥¿n=räÈž={x_ÅÎÎnãÆ0Q333ž ÿ™óçÏ'$$°¾ EF ‚ ‚øi ˜Œääd&C† ñõõݰaƒÞŒOØFbbâ­[·ÚÛÛÝ.ÄÁƒŸÜ¼y³¹¹ÙÃÃãw,Iü"è`œ;wnÛ¶mwîÜéèè`''Nœ¸}ûöÐÐPñ hÄ„„„ÄÄD¾€ú-ÖM›6Ñ0=AA¿„Z­^½zuNNw¹»»/]ºÔÏÏoèС<TõÆW®\a³HÝH®§§ç¢E‹ôRj4ˆË£GØÂõÈÐß߯5Ðe%þËÝ»w;–Í–štQ8è’%KÄ ~µµµá¿v/**âÿ¹\¾k×.6©ƒd” ‚ ˆ~àèÑ£P¾¾D"™2e ¼$ €O…u¼}ûöÒ¥K*•ŠmÄSBI}||øÀ}{{{zz:Rò•áÍÌÌÂÃÃwî܉ º¬ÿv233Ïœ9sûöm6õBÐ5"Ú=¾®úhè«W¯²~…  ˆ¢ë²råJSÓÿ,0J2JADÿPPP°aÆÜÜ\n³fÍ‚|ˆ_l‚—¥¤¤ää䈕ÔÙÙyîܹJ¥rÔ¨Qì$ÌõÂ… —”))䵸¸˜Ü :ã=zôìÙ³ÿúë/¹\Î^®+© Û„=,,lÍš5ÁÁÁ]â?‡/^ÀAÑ‚âP(€z¢!.\h¨¡†M3dÈI“&­]»2Ú˽HF ‚ ‚ø¤¤¤:tHOIá1°™ˆˆ777>Ѱ½½½¬¬ìÁƒ™™™b§aé Û¾££ãÎ;zÞ3lذùóçoÚ´‰”ôW(//ÏÊÊJMMÅ'_ƒ‰^ê½™LÆ› mªÑhzÒÐØØØ€€ñ>±F!%‚ â·Ó“’ÊåòooïÑ£G³±{>Ú +U«Õâ±{$9rääÉ“¡88ÈÉÉ3é)©R©ŒŠŠ‚3õ4(LÂôƨҚš±²ËPŸzó+š›› ÑFyyylWO†‰‰‰‹‹K5”A2JAÄ?Ľ{÷âââÄ ¤ :Å7nœ¿¿ÿìÙ³e2üÕjµ°Òüüü††¾˜¥Ðm¥R©ÔÕÕ2ŠMMMüWSSS''§ DFFzyyÁPºÜƒTïû÷ïaŸFÔÌÌ Ý…Bõôô/¹UVVöøñã'Ožh4q×Úêçç·dÉ\ÕG e’ŒAñòüùóǧ§§³}›8ÑÀÀ@ˆ)D“í) QinnV«ÕÎÚÚZ± ºu+‡ŽÄŸ>}jmm‹ ~‚Œ.Z´bJ/9 ÝŠj„M¢***P·âC5ÚÛÛÃ&•J¥³³óˆ#X(uŽš‡€>|ø2*ž× ÌÍÍ}||bbbÐ7è㓈3$%‚ b€_ž8qâÂ… ?~Ô³8Ü1 @oøæTRR‹‚ÄèÅJ‰‰»ºº¾ÿ.>ÁBnË—/ÿß755UUU½~ýº'º}€3f¸¹¹qE2Ôó³gÏT*Õ›7o•Þ…ÖÖÖ¡¡¡Ë–-ëc­Íd” ‚ ˆ£±±1))éÔ©S$½'¾W(¤I“&3F+­¬¬„Ó¼zõ êEXùåz’Çï#""&Ožü[iMM ê'//šŸŸ¯Ñh´Z­¡òYYY¹¸¸xxxL:Uì hˆúúúòòrH?.¯®®Ö»Ɇ®T*W®\‰ÞŸ§÷ IF ‚ ‚xîÝ»wúôéû÷ïë µ º¸ÔúèííÏ &À¢ØOmmmïß¿ùòenn. Æ£g´F‘H$P(HXhhhPP««+Ÿùÿ ^[[[ZZªV«ß¼yƒƒºº:T…Þ`:ioo÷õõ6mšƒƒŸ¤ §¯ªªB°||~üøÑ°{`ff†«æÍ›hiiÙûƒý0CT;r#%‚ b°ÐØØ˜––WPP`4Þ }ŒB!¦âpigg§V«-))yýúuqq1òñ({vÅÞЇ`ÀP!¾] =‚2~þüÙP=Q^œïIêPE¨(”K&“M:þgkk‹‚ Ý1Kd… ‡ÓÃq ÃÌÍÍ]\\ÂÃà Eïå¾dˆ[ã1Pá‘‘‘r¹œd” ‚ ˆAl&>>>55µ¼¼\üê=‡…Ka¥Ðww÷‰'ÂSÙ(3ÄúöíÛ¢¢"¸iMMMSS“ÑqjÃ<‡:~üx'''|úøøXXXàVVVÈœïeúû¨ÜÛ —8†ŽÃ5Q|ˆ][[NVVVâ|ïêÉ qDYØ(<ŠÆÖÅ…ÈäÇEäŒ[Æ,‰ê¸páÂ^×¶´´àÙÐ @…÷”!î£ bi.ý$£AA ^`Ké:rss¡PâÝ€8°{{{™L+uÔã‘?ˆiCCÜ´¶¶V£Ñ´¶¶ÂtñùåË—¾X2755E†lr$„•é)û?‰wf×ûU< DG|Qf™ì+SOæpLF¿ÿnt¨ÝèCZ[[ãÖ666<Ô€³³3|çÅ‘ãJpô²²²úúz£±g¤ÇóK¥Òàà`è8,ßèQ«0NÔä»wï  8€ñ¾R†îlãëë;wî\4ZJ? É(AAƒŸ–––’’’sçÎeeeA}zRI6ì>vìXô&dggÇÝTèã577CLace:àUÐSÈ__Fö{bÚË*›?Œhþø%ògÒ)Ó!‘HàŽøÊ'-ÝöYWWYDá ,Blè‹‚NaÕÐD//¯°°0äµÕK#ÖYdˆl¡³F# È ŽLüýý•JePPŽ{)ÑßH Máãr!JIEND®B`‚nagios-2.6/html/images/trendssvc.png0000664000076500007650000004512707507661353017156 0ustar nagiosnagios‰PNG  IHDR„@kÊ%ç+tEXtCreation TimeWed 3 May 2000 15:22:45 -0600E°@tIMEÒ-(¿ðòv pHYs ð ðB¬4˜gAMA± üaI¯IDATxÚìÝ œNõâÇñg̘Æ2c ÃØÆÖ±+D²JIªIQ)Eèjn7¢¢(E‘t‹²ïÄ¥Ð`ìû¾Í`Æ:Œýÿ½Ïïß¹§ç™Ûp¤Ïûu_ó:sžóœm¼ºŸçlÏ¥K—\€29½øû"Fà˜«‰Q§×·•+ŽQµÿªaó?àj\YŒ*4í÷9™î´ÿä.(\½ËŨ9äé]¢fŒw‰rˆWÌ/½=2ÔbFz¿ÄQR\´cÔ»Dõk:G=iP\¥´OÓ§—D'2Ï€cˆQ8æ*c”sôÈ8€cþ?Fß}÷]/­[·¾æùîÛ·/22Òé­À-íÿcô7Þ¸ä¶uëÖâÅ‹›á~øášç[·n]§··4ÏÓô3f̸ï¾ûÌpbbb½zõ>úè£ý:tèÐÈÈȰ°°‰'š :wî¼|ùò‚ ~ýõ×fŒ¦Éž=ûÀùå£Ã‡×½Ëš0÷ÜsÖÄñññš¬OŸ>ÇŽ›:uªÆœ8q"[¶lƒ61Ú¥KM0gΜîÝ»;½±¸µø\úó ò!!!JO3­Sö¾ô•¨ÆX'âç̙ӠA—û:Q•¨™Øº`T-û¢[×®]ÞXÜZþ£ösô.÷iú2eʘáâÅ‹?>11±aÆÇwÙbT¦YÃÃÕ³C‡Uzš—BBB/^üÈ#Œ5jذaNo,n-ŠQûÝK®?Çè!Cºté¥Z}öÙg]î5Dõ.3ЧOŸgžyFÙzôèQ£jИ˜Ÿ-ZŒ3ÆéÀ­ÅóšQà¦á˜àbŽ!FàbŽ!FàbŽ!FàbŽ!FàbŽ!FàbŽ!FàbŽ!F¸á’““;tèæããÙ«W¯ .˜—Òïe'°ó±É’%KÆ 7mÚt=k®ù\ç@úˆQn¸˜˜˜2eÊìܹóÒ¥KqqqçÏŸïÙ³§yIãÓïe'ðpéñññuëÖmÑ¢…Ó[¤ÇGÿX^ns™3gNIIñõõ5¿&&&/^üÈ‘#.÷‘Åôÿ¿ø²¤3ñ… ²eËvúôék^óŒ]=ÀGF¸á”ž}úô±N͇††Z%êúó™îŠ+ê×°°°/¿üÒ{UlÆ õ«~j8ý…&''÷ë×ïÍ7ß4¿ê]}ôQ‰%Ò™ÇÒíôÞ®]»šá„„„:uêdÏžÝ>™FZó4—hY»víÒÀªU«¬Mضm›Y8p`Á‚UêãÇ7¯j@¿ê¥²eËZsæJ€Û1 À ·aÆ1cÆ)R¤sçÎ'N´Æ›cŠÖ‘ÅR¥J­\¹R¿2¤K—.ÞôìÙsذaúµ]»vÖ‰~Ö5£Ù²eS‰(PÀz)<<<666­ùx/Ý¢ݹsç AƒÌ¯šm‹-Ž=jæf­[›6môöçž{®{÷îÓ Aƒ9sæh@?ß}÷]3¬ñæ-ñññ[·n7nœÞhÆh@K×LÖ¬Y£Nµï%Ü®8´ÀÍpáÂ__ßþýûÿâ¦|òÉ']iŸæ¶ÆÛ' ;tèŽ;V¦L™={ö¤õ.—ûȨ xðàÁJaóÒÉ“'ƒ‚‚®j>å6þ|ëU½}ãÆ¡¡¡ \3eHHÈÞ½{5ÿ3gÎh¤9ôÛºuë~ø¡qãÆ*TX²d‰fÒ¼yóÉ“'{¬µ¸† úùùMŸ>]+o^Âmàf[µjUƒ LÚó111qÈ!k×®5w;yLàqÂÚûÿĽÓ6Õ¨Mu>i-½M›6ùóÏ?+VÌ{)iÍ_à Ê"EŠhVú¹uëVýT­š1 ÍTg¢ux衇”­JÒ'N8ý‡ÂÍÀizn¸ìÙ³Ÿ9sÆúµ|ùò'Ožôžì¾ûîKIIi×®9»í-88ø’Íe—«Ô[®p>i-}̘1={ö|çw¬1¹sç6W…Ú;¥yjqЖš…ª8Ë”)£ÀÕÏœ9sV¨P¡_¿~Nçghhèüùó=:`À€|ùò9ñ·ÂÍFŒpÃ=ôÐCª«mÛ¶¹Ügƨæ³^Õ3°víZoРÁàÁƒío·&hÑ¢…ynè×_þBõ.ÅŸ}A–Tç“ÖÒ}}}{챸¸¸U«VYo6lØ… ´QöyŽ7NS¦LQך‘š›¦1¿Ú‡ÓRªT©‰'¨w>ìôß 7Å%pƒÅÇÇ+ŲeËærAìÞ½ûÉ“'ÍKÍš5óóó3ʹâÅ‹kE¤õÿÑö Ì|ôRTTÔÆ½dÿ¿xÍç™gž±äúó#H½ç“êÒíïÒ[ÌÀÑ£G5>fÌkóXS—;:5l_%û°¢6ÕñÖ°y®ª6ùÇô~·®€cüœ^ns<&3£pí¶Ä‘Q8†˜àbŽ!Fàn`Ê`}ûöuz7VïÞ½^àöAŒf<þ#·1:‹Óôp 1 Ç£p 1 Ç£p 1 Ç£p 1 Ç£p 1 Çðu ƒo‡€¿ë¿ù|ÿ3pýˆÑŒaý÷ˆ*€Û d NÓÀ1Ä(CŒÀ1Ä(CŒÀ1Ä(CŒÀ1Ä(CŒÀ1Ä(CŒÀ1Ä(CŒÀ1Ä(CŒÀ1Ä(CŒÀ1Ä(ãçô Ü&úöíëô*në¿ù½{÷vz]€¿gÏž­ß̉us>]åT¦L™%šêPi¥P³nc7­©–UªÌ—ÖqJ—WnzŸp×Ó‰+•œu6_Ý©•Éœ9³ùÕžªÖ±X3F«§NÕ¯V«º)(UZ·µkךáS§N¥Ò_[ªò.^¼xe7s{þ5ÏP¥ž'OíÏš5kV­ZµT©RW¦Ä(ø+9pàÀüùó'Ož¼pღ  ,sö¼@EŠ©R¥Š ÌŒQÒ™ôT)=U“‡6gÉ^¦55 SkšóæN1ñª5Ïš5«Ig ˜ërçÎmZÖÜ;¯mÑj›vÔÏØØØ;wîݻ׸M+%µTºåË—ŽŽ®P¡‚½#SaúGOµ¶šƒæÓ°aCen‰%TÕ—ÝFbü(=§M›6eÊ%‘òÈ;`Ì…žæœ»©O•r-(((­ôLHHPÚjŒÆ_íýCÖ醹ïÇúÕzˆ’±k×.-ÔúUÃ'Nœ°~=}út:ÇtS¥Uùië´ SsiBФ¶•§ÉÉÉÚº#GŽ\6%}||ô.ͪº›fhžýdg=ÕÞ[±b…6j÷îÝú[¤z0X;D1Z­Z5…©ò4kL‰Qp‹RQåœ:uÊ{sµedddÍš5MråÊ•ËÜúc Ia¤äZ»vmZ…äMÍ”#GŽÚµkßqÇŠ9e¨j¬@¦änþÃáM­jÍ÷îÝ»qãF³ÔÓ¿þú«6JU­—‚鄜ÖÜ\ «,^¼xÑ¢E…Y³fu¹ï»Òü·oß®Y™9r$ÕÖP×¶jÕ*::ÚþV÷K:3ÔÒµ2÷Þ{oëÖ­+UªôÿMbÜ"æÎû駟Λ7ïØ±cÞ‰b.—TW•v ³Žù>Þ#õçÐ{­+A/ûœÿËÎP\b8fîܹŸ|òÉŒ3¼ŸÍ™={öråÊÕªUKÍl}ߺKɵ~ýzõRí-5“wá¨{jÔ¨ñÈ#4hÐ 44ÔéM¿±”æŠÑåË—¯\¹RkÖ¬IJJJõ6£bÅŠ•.]Z­¯ëj„³gÏ=zT•¿xñbÕ­÷N6d}òÉ'µK¯ä«§Ò™!1 ðé§Ÿ~þùçk×®õ8œU¯^½R¥JEFFZá4 ºdÉ’+VìÞ½Ûû|t@@@–,Y’““íßlärŸÜWi=üðÃwÝu×wÞéôv;cݺuqqqÚ{Úᩆ©v{¡B…*Uªdn¥·ªT;sÇŽ6lX¸páÆµ{íïR†-Z´Y³f5JÿܽÅ{†Ä(¸©>þøãîÙ³Ç!ŠÎˆˆˆÊ•+שS§D‰Ö¹øôÔ|9§2ôàÁƒñññö$ùûûk>÷ÜsOË–-ÕX·Á¹øŒb…éÎ;/^læoI«Jµç·lÙ¢éõ‡PMÚ‹ßÇÇ'Ož<Êý&Mš\a’ÚgHŒ€›aß¾}|ðÁ÷ߟ`Ïs:^ÕX¥J ››âÕ:7n4éãÝ ¹rå*R¤ˆRIé³råJMio£¿Õéøë¤Ý;wîÜ3f¬_¿^5oɪÒZµjEEEÙQ¯^½zÞ¼y«V­JLL´þ”ærÒzõêµiÓ&,,ìÊ×7–ÉЯ¿þÚú¦u—»] .|ï½÷ªA=NÇÿþûï*¤¸¸8ûIas?xÑ¢E«W¯®xÝ»wï´iÓÖ­[ge¨&ÐøgžyF=ô·=Í´'§¹yŸÄ ªP¡‚>-DGG[J/\¸ xUΚ5ËþWlÙ²5jÔèÊ“”7Jªêëë[°`Á¦M›ª­Å+Höïßÿ믿Ξ=Ûã,°5½b(GŽŠÔI“&ÙÈÏÏïŽ;îxúé§~øáˆˆ§7ú¯M;V}9f̘µk×ڟϪO úÌаaÚ5kæÏŸßÀv¹ï—_ºt©Ç_Äu5IJŒ€¢G#FŒ°g¨¹9©yóæ+VÌ•+—©Ùµk×Ô©S,XpèÐ!ï3øõë××ôÞÑcnNêØ±£º6<<Üé-¾}9rdáÂ…“'Ož1c†>QXãÕ ŠË»ï¾[Ÿ .ì¤7n´_S¡$mÖ¬Ù“O>™Îµ¤Ä(È`&LèÖ­ÛÎ;­1ÊÊÚµk7hÐ@1jÝœdeèüùóí_Ý® *¤­[·ndd¤¯¯ïòåË¿ýö[{††„„´hÑ¢mÛ¶ŠQnNºq¬Ó÷+V¬8~ü¸5>wîÜúऊÑ9sæ,Z´Èþð&}NèÔ©Ó]wÝ•ê"ˆQavìØñÊ+¯¨/­jÌ”)Såʕ۵kW¶lYû)Íw~*[=2´Zµj<ð@‰%ÌWîß¿_ÓÌœ9ÓŠÿæÍ›wîÜùî»ïvzsÿF,X0|øp}l°ßç”j’^¼xqÍš5cÆŒÑG ›‘úDQ³fM%©÷7Ý£ c|ñů¿þº=.óçÏߪU«FÙ¿Û]¨i¬»ví²:DY£¸¬[·®uã¶rvÑ¢E£GÞ¾}»™F¹S½zõ—_~ù‘Gqz[ÿ¦Ö­[7yòd…æúõëí;%iË–-õ綦ԇ}„Ð }œ°FæÌ™³C‡Mš4±,!FÀõÚ±cÇ‹/¾8cÆ ëH˜u̬H‘"Öd)))êËï¾ûN}iˆ ¦V­ZG×T0šlöìÙÖˆZDLLÌízm¨¹ªÁ¾»œšÉeíÛ·ïßÿþ÷ˆ#”¤ÖH-Ô<ýÞþÁCëãq†24::ºK—.Ö!Rb\— &<÷Üs‡2¿6lØðÁ´Ç¥(@G­µÎà«ZÔ.­ZµR—ØOò.[¶ìóÏ?·ˆfÍšµ]»v/½ôÒµ=°I=d]ì˜'OžŒjÙT³ÏZ–’«P¡BW~1«ÞX»vm hÿ\sJzÏäm»¡?Ð!Cô™Á:q¯­.W®Üc=V¹reëØ§¹2xüøñööC¤Ä(¸v]»výôÓO­gåÍ›7&&¦AƒÖsC]î¾\°`ÁW_}µgÏ3F¯Ö¨QCÁêq!é©S§~þùgõu…¨&xóÍ7~øák[=Óg4¿-Zô§Ÿ~*UªÔunuªíh_–ÚºJ•*Šo-ñJf¸zõjM¯ØØXõܵ­•ÇL<¶]š^½zuìØñ:·ÝÃo¿ý6pàÀÉ“'[ÿôãÑGmÑ¢…¹ê×Ð'9sæŒ5*!!ÁŒ1‡H_}õU¿Œ]!ð7qàÀV­Z-]ºÔØ27*µoßÞ#õ’’’~øá‡‰'*4ÍÕ›2´aÆö) _~ùå¤I“̹~ÿÇ{L%z…=—ªãÇ«ÆTB9räHIIÙ´i“êGåd^ݸq£Ê2Lë ¦¦ÑϨ¨(—;75“àà`Ôlµá¿ÿþ»ëã£Ö²4†ýõ××^{­ÿþæ-úi&³ÏÐå~ˆ’]+¦¹)a÷ï߯E[Ç5ÍÌ:¤½­b½Ë¾æÞ3ñØöœ9s^¸païÞ½ï¼óŽþF¡¡¡fþæy®%K–¼ž“ûúPñã?~þùç}ô‘9k¯¿ãˆ#¶lÙòøã[;}ühܸ±¡Ï$æÆ&Ñ?žnݺý÷Ø)ÀUY¼xq‰%¬"Éš5kÛ¶my¿ØÌŸ?èС*T°òHõÙ¼yó±cÇþâE#«W¯n% QÜ\ÿz®ZµJäçç7}úô÷ß_k’/_>3þî»ïÖúèU’–áÿ­óÊ•+U“ÕªU Ðd 4X´h‘¦Éž={òæÍ«yjnú©‘ª:û²fΜٳgO½ªRÌŸ?¿y‹Œ?Þ>C% ZV1gÞe榾43”7­[ñâÅ5ÞU¿~}í+ûšÏ›7Ïc&КØ×ç½÷ÞkÖ¬™ÉÍlÙ²©>•¶ÚU©6dáÂ…fAf+®Ù¶mÛ:vìh?ªmÿÇ?þ1{ölûZÿHôOÅ>GFÀÕY°`AË–-9b~-X°`ûöíUHöî)))ê¿Ñ£G'%%™1J“ÇÜã ¾±ÿþ¬X±ÂüªZ4hP“&M2pãããÿóŸÿ¨™Ì}3¯¼òŠ¶Â¼¤(T®™ƒˆŠ¤óçÏÇÅÅ}øá‡Ë–-Û´iSppðéÓ§çÌ™“#G3f¢²LLLt¹ŸX¤¸ôX–²LsÐdêZeŸyKÑ¢E{ôè±}ûvk†½{÷Ö&¯Y³&«›v”RÒü4ÇhÍöîÝ»kÿè]êÈäää^½ziC¬5×<Ïœ9³víZûLì+sáÂ…¾}û^¼xQãyäsÌRQ¨™h”Ýz—Yý1¢×@8|øð{ï½wàÀK–,¹äþJ-}¢ØºuëÓO?mÕ§Òü™gžÑ'ë² ®WÁ^¢ê›J•*½ð gÒ•D£FRŒš{•©JUûI[»U«V 6lÆ f†÷ÜsB°lÙ²²¶æ2Jõe–,YΞ=«ùöÙgõë×/_¾üÉ“'MidΜ9Õy*¶ï¿ÿ^!¥2V³jõÆÙ³gÏœ9³_¿~Š6Móïÿ[ÃuêÔÑÛÇŽmNp[ËRmkY~~~¯½öšÞhÞY³fM:tH±¨WÃÃÃëÖ­k­Oll¬47«ÓfÍš¥_wïÞ]£F ûš+Rµæö™¸þ¸fÔZmÖA­©}6nÜ85h‚Û˜1c4ÃV­Z¹Ü7¢eÈmøê~Åý—_~i.Ì0ý:Øüärßÿ4tèPå8GFÀ•²—¨"£Y³f111Ö{û÷ï8p "Ó^mݺõ<`?3kÑd*?ó(J___%KïÞ½oÄÛ”Å*¶âÅ‹kM´8ýªõ7çµµžÊGýÔ˜%J˜ï/=}ú´¦÷÷÷WDê].÷× ™­6¿šV4{œ&Ð|´ Š+*:­·xÏP ¨\¹ò±cǬ·k­‚‚‚Ìâ ½KŸ={vÍÁcÍ5 Ðôž‰E+ùÝwßíÝ»·cÇŽk֬ч„ñãÇÇÅÅé¥ 4iÒD©:zôhWÆ=J¾?þXÛÞ·oß]»viõæÏŸ¯uëÞ½»½GµEo¼ñ†Ö'Óu, üØKTeÙ¦M›çž{λD—Ë—/7%ZªT©·ÞzKS¦Z¢Û·o4h)Q•V=þõ¯݈U)ŒrçνuëÖ®]»*àTŸŠ¤ºuëvîÜ9""B‘çrßõ¿pá©S§jX5©LII6l˜êÍå®jïÙnÙ²Åþ­§fä—_~ùóÏ??õÔSöë´Þ3TPjÌÈ‘#‡zþüy3¥þóŸÿŒ;Ö:,ªi¾ù曕+W*é¼×<Õ™ØÅÇÇk£LsW­Z5::ÚÇ­}ûö*Q­#7 ¹NÚü¯¿þºZµjæW}êxûí·W­ZeŸF{@ÿ„8M.Ï£DŸ}öÙæÍ›ÛcËõçK?õ’ú&&&&oÞ¼©ÎÐ>±B­ÿþÏ?ÿ|†¯¶ýiGlÛ¶mbbâ{ï½·aÃåË}ÐñÌ™3Ú¢³gϪäÔ©Ê;s4Qm÷Ë/¿˜K0õó…^PGšYåÉ“G³Ý·oŸ¦ÌŸ?¿¶H‘"ÞgòS¯^=û ß|óÍ9sæüúë¯jD-Úæ >|øpPP9Ç­—4“‰.T¨PÅŠMËš5×”êæ¸¸8k&°Ÿ¦?wîœvïÉ“'õyíµ×T„Ú.¹Fê3Cª«víÚ¥ÚÕ&÷µ-Ý»w¯T©’}NÓ€Ë8pàÀã?no×®ÝeKôþûï÷¸·ÚN¥õÅ_˜‰Õs¯¿þú(QÉ‘#G™2eÌ€JkìØ±ê°Í›7ðÁE‹U *ÝÂÃÕ‰:uR –/_^Sjëzè¡Úµk8péÒ¥ßÌmÑ¢EfVzËôéÓ ´cÇŽbÅŠ©=–å½týTàÚgØ£GöíÛÿóŸÿܾ}»ÊrÏž=9zôhU¦Ùíóᇎ9RÓ(›6mjÎj­ùÓO?]°`Á~ýúÙgbg–~èС\¹r…††ê³DçÎ]î‹tU¨úÕœ—÷^í T¸pá>ú(K–,ÇWêÉ!C”§ZgkŽŒ€Ë¨Q£Æ’%K\iWfBBBÿþý¯°D/^¼8bĈqãÆi@%úì³Ïª¥ìß!yóÝУƒÎ:qâ„}ß®[·®V­Z))) ,°Î¡ß„uèÙ³§éQýZ©R¥üãÖ!s®ééÚµëÒ¥KÍpÕªUíé1T6£FºÂ•™3gþüóÏæÉö5zçwœ-Q×GåFt–Ǿ=~ü¸ù–¬›V¢fôyCŸ:ôÙÃå¾~Tÿ`¬¯åÈ(HÓ‚ î»ï>Ó  ìÛ·¯Çã™*ËO?ýÔÜå}ÙݰaCŸ>}ÌwB–,YòÇ̨§8á y+½™ËµŽfΜ¹S§N-Z´ðññáÈ(HÓóÏ?oJ400°}ûöÞ ]¿~ýèÑ£ÍóDï¾ûîôK4))I-bJ4$$dРA”èÍçÔqh-÷wÞiÔ¨‘Ëý¤-ý³1_Ê L uï½÷žù"uiذaíÚµ=&8qâĨQ£Ìw,•*UªC‡锨Ì;×<ÜÇ××÷ÕW_ÍØïXºÖ÷Ñ™2e2·ò¤:õ•ñ7g}nÐâôIàÃ?4_1àrÿÕ^yå•´žxáô ä“O>ILL\ºt©ùf„·Þz‹©Ø±cÇ|`.çS=úè£Þ_ã9sæÌåË—k ((¨}ûö_±ãáðáÃæi—nѢŠ/¼àìªü”×Ö—šÏ<óÌG}”ê ©E‹ݸ½ ‹Ó">ûì³§žzjäȑǎË™3gLLŒÚ´ÿþ7h£¼™¯E}â‰'N:¥>>M›6õMÅ¥JÂ܇T¿~ý *¤?ÃùóçïÚµËå>æ×¹sgÇoZ:~ü¸ÊÏ<ÎÓЖŽ3¦cÇŽwÞygª\ç··_íúdøâô™aÆ QQQ«W¯þꫯ:4jÔ(ë(éMóàƒΚ5ëóÏ?×?ž~økF€§åË—OŸ>Ý —.]úž{îñ˜àÒ¥K&L0q™ÖqS;ûaÑÆß}÷ÝNob*´zgΜùðÃ^‘%,,Ì èÏ¡üé§ŸêÔ©ãÈš¼üòËæú㤤$bx:t¨yîºóÁôþ&Leè¬Y³Toi7õ°lÙ2ë°è z¾}†HNNV¢ýúë¯7ÑÚ3wÜq‡ù^{ýÔð{ÎTΜ9›7o¾zõj§bTŸp^|ñEóeTœ¦žæÏŸoî¼óNïRªA§Nzøða—û /{˜óܹs‹/6‡EëÕ«wkµœ>}ºwïÞ³gϾì”8tèΔ)S¾|ùBCCÓš811QÓ›«üýýUù _ó’¹WIFm.àà`ï FwìØqâÄ —û§—Ö²Ž?¾{÷n³,‰K•*µqãÆ–-[VªT髯¾úàƒ4Æ‘ýüðÃùå—ëÖ­#FÀŸlÙ²EÙär_Cyï½÷šïº´KJJ²ŽV¨PÁ:ù›%ÔêÕ«Í ï¿ÿ~§·ï2RRR~ûí·9sæäÉ“'Õ  ¯¾úê²eËΞ=« 4ß*¤ŸJÌ¢E‹¶nݺ}ûöö+bccc_yåíUen@@€Y„ÒܼÑõǽJ.÷W¤zÓÞ½{?ýôÓ &ÄÇÇ«zÍ7WiYmÚ´yì±ÇÂÃíe)C¿ûî»Ï>ûLo1O˜×‚´bšÛóÏ?ß©S'­‰¹›~æÌ™®?î¦wd?GDD´k×îµ×^#FÀŸL:Õœ£ -_¾¼÷›6mR¹ÜOhª^½º9Ùš¥9ž—/_¾»îºËéíK"OÑfªzîܹwÞygÀ€©N©RÿþûïU–Þ/)Ó׬Y³råÊQ£F™1£G~饗N:¥rMgéæ^¥To`š2eÊ‹/¾˜`}e‘¡‰µcGŽùÓO?•(QBc¶oßÞ¶mÛµk×jݬ↺gÏžõë×ŠŠº™÷ΧOë£jçšQð'*-3P¨P¡Tz*wÌQ½ðððÒ¥K_v†ŠW3 *^¼¸ÓÛ—:…µ9l) ÇßÿýÇLkâ´ú[¯‚Ôœ8q¢~ýí·ßºuë¦1é—h:Ö­[³{÷nu¹y&''oÞ¼ù±Ç3ÙÚ±cG¥°Fz”¨Ù"ýɬÕ0Ÿ Ò¾ Š+Á‘Qð?Gµ·£¿¿¿Çjš;wša•¨÷½MTQÖôU«VuzûÒ”)S&??¿ÀÀ@“}ÊÊaÆYgÒ=˜åYÝräÈ¡ÈKJJ:yò¤¹.ÖÜ’ÿÀ¼õÖ[ÇŽ³Ò0Ð-$$D#5uÍh:¬@´¾¼]‹ Ò¯ZI-Îå>ˆ«:ujõêÕãâ⬫fAÙ²eKLLÔ²LŒZ³µ_EÖðMZ¢D ŽŒ€ÿQ!Y'  ,è=ÊÆ|Ÿ§Ë£—=G¯²fX²dI§·/MŠËîÝ»«Þ¬ÕV𥣪Ï2eÊÜ}÷Ý#FŒX°`ÁäÉ“5P´hÑœ9sš ‹k׮ݼy³2Ñ:P @,Y²äÛo¿µú2ÚosçÎµæ  ­W¯Þüùó'Mš”'OësÂùóçúé'5«¬÷jþZÜË/¿IIIÖÝú.w_¾ùæ›æüO<ñD¿~ýÌx5èºuëô÷²¯­VI#_ýõL™2©°Û´ióÌ3ÏÜè¯3½‘‘‘ÿcçõóó³õyL`¦ ¸’U™#v™3gÎ;·ÓÛ—õ\Ïž=­+GÞ_ºÜwuéÒå©§ž?~üöíÛ÷ìÙsðàA·Çiwµ©5+3·J•*]Õúh†JIëWýE¬Kx••úÕzIÙªÀ½ë®»TüÖHý™Ž?~ôèÑ}ûö}öÙgMš4Ùºu«ÓûØSÉ’%‰Qp©ÕÌiz•èe帺uëÖ¯_ß:YŸª˜˜˜ &(òT{*Π  U{¡B…¼ße?Vêqèô ÙkXÃiÍA/ùøøtìØ±X±bJê,Y²Ø_5·:íÝ»÷‹/¾pz{ 'FÀ hï9sÆû–ð[Ð[o½•NŒîرcþüùæ<¾Ë}xøÁœ7oÞèÑ£½£ÚÇœ?~÷îÝf8­û¢<äÊ•Ë<+Ôz—5‡Í›7[3Q†,X0!!¡S§N*Ñ=z4mÚ4222_¾|ÿ}pÒÇVÏž=;nÜ8§÷®'ý“àšQpR=‹í!oÞ¼*¶S§Npsz•/¯L™2Mš4?~¼¹4Öƒ6Á~êÜ„à‘#GFŒá±7‚‚‚²dÉb]öpéÒ¥nݺ½øâ‹áááß|óÍ•ÜÀ¤”Œˆˆ°VCËêܹs¯^½4fذaÖM™3g®X±¢¤W.7nÜøå—_Vý9Rýj­ƒÞ¢õ¿É·Ì§OëLŒ€ÿÉ“'bëÂ… æ®ùbÅŠyLœ3gNõÍéÓ§÷ìÙc·žóü#3ý®]»Ê•+çô&^Þo¼1wîÜãÇ{'£¿¿¿}ä¹sçÔ…ãÆSz*hÀÜ=¦EhMzõêåô®õ´aÃbüO¾|ù¬›è·lÙâ=bÔzþ¨õULé°ß•¿råJ§·ïJ©CBBR}´ÓÛo¿+W®ÀÀ@ëU èWûõFõêÕ˜7o^Õ¤™ØL™5kVûöÚ¥i=ì)<<ü矮]»¶Þ¢î´®в4Oår«V­>ûì3—ûé§šX³ÕܬxÕôúU/*ThèСUªTqz¿zZ¶l§éÀŸ(Y¦NêrŸB=uê”2ÈþªrªxñâóæÍ3ÄÇÇGDD¤37%TáÂ…W¬X¡áåË—ß:×,*Ñî¸ã­¶èÒ¥KZ+û¡PmT·nÝ>þøcó«}‚5j(‡¾m۶ÇëíªÀèèèiÓ¦iwyÌ­nݺ?¹-Y²Di¨—BCCwïÞ½zõjkY¹sçÎá–êú”(QB{{Μ9Ó§O×»Î;wñâE½T¹råûï¿_?ÍLŠ)²xñbó-¦4…R•*©7nܬY³[ðQرc‡Ï•\? þ>ÆŽÛ®];ÓCôþÚ¤¸¸¸ž={¦¤¤˜3ÑMš4I†³gÏ~ï½÷4C…‘¢êj·yCY÷T¥šÈö;®®¤¡=æ¶sçÎÚµkkG•.]ZUZ³fMÅë† † vìØ1sPÙÜÿí·ß^ÉúÜfÙM›6åÈ(ø“zõêeÍš599Yaë£ÅŠ+T¨ÐæÍ›Õ—¿ýö[£F¼ÏPÛ)ÅÂÂÂܪU+ûíä·+í“*UªDGG‡‡‡çÊ•+_¾|‘‘‘EŠ)S¦LÛ¶mówØÞ,XðÚk¯™`ÜÀRÑ£G˜áÖ­[wêÔÉã9GÉÉÉo¼ñF\\œ†Õ[}úô Jg†óæÍ{ÿý÷Ï;çïïÿÍ7ß<òÈ#»Â;wît¹o*Ï¹íØ±#sæÌ ðÆõ;räÈ£>:sæL—û‘®œ¦©øàƒ¬°›;wîúõë=&Pz¶jÕ*00Ð徿Þ<ì)ÕªU»óÎ;]î ( ´k×® \[sߺ˜$µFZ¿Ú‡/K›S½zus­‚}ø¡8Þ¸q£Ókqí¾þúë9sæ¸Ü—Ì>þøãÄ(HÝ¿þõ/s›|RRÒ¨Q£¼¿Y¾F 6t¹¿s̘1«V­JgnŠW%¹tréÒ¥}ûöÍÀU=~üøA7ëî({ž¦šªéøý÷ß5+s$Ø>|+ؼy³v»¶å/Ú£úÐ2xð`ó0ýãцðh'ºÖ­[«A§M›ær?¯~òäÉmÚ´±¾ÈåþºóG}tݺuÛ·oOHH6lX¯^½Òú2!©Y³fƒ Ì Lß~ûm… ^zé¥ \áK—.mÚ´Éå¾XÓ䩯¨&³gÏn ›)M³j[ *dž-o?ËožHÇw؇5AJJJTTÔŸÓîã£)•ƒÙ²e;þüU·Ÿî×ír×¼Ö9<<\ÚÌ|¡¼V;22Òå>¯m=²@k®¹iÏ›cÒ&Iµóê:äïïo±³Ol6'88X?µnöEh‡dÔÕTÒ]ºt1Å‹-ª<ÿýpr ªÌܹs›’Põë×ï/i=³R¥JcÇŽý%mßÿ}©R¥ÌÄ!!!æNüë·jÕ*sÌ5³›sĈæK8ýüüÔyúi†ÃÝüÿ  ^¹r¥z1ÂMš[íÚµ5«?þØîÓ§^ UpëgÉ’%˜%K…âûÊÇ—+WÎZg³P5e@@€YçyóæmذAÓ›­Ðþ>|¸ºFfŒ¦ÔÊk¼þ(ãǯV­šÆhJü-[¶tíÚU/™NÕÇûþùõ×_í/Z´H‹Ö_­€Û¤I“ì‹°öCÆÚ¶m›õ+û¿%î¦i2Ý3mÚ´‹/ž={VmªÜ´¾kÞPu©ó”t óeË–MëáíÙ²e+X° &NNNNIIY³fÍ=÷Ü£üºÎõLHHøâ‹/´’~n‡Þ»wïÁƒ5Æ|‡ûÉ“'µz6GIÏ;§êÒ«ûöíÓpÅŠ ¤UzòÉ'•Œï½÷ž¹=K[j†Õy?üðÃñãǵu;wîLLLúè”)S´†æÀê¦M›&Ož¼bÅ E¤ÖÜì´3n¿ýöÛºuë4Rë¯Õžÿî»ïÌ·­ê½ŠÚ–-[šGhdÓ¦MÕëÖÄZý NŸ>­= ?ßôéÓãââì‹Ð~È›7oþCÒ¦uèÐÁ\Xœ)S&Í¿Q£Fæâ®éiß¾ýOqâD ˜—L÷kÊŸ~úÉÔí’%KÌ<µ Ú¨¨(u¿£àÖ¶O¼téR3ÿ¯¿þzĈ*fïEd Õ?ýƒ±®÷ FÀe|ùå—ÕªU3à ¦Q£F:uÊ>ʲcÇŽWÞ£5²rDÒ·o_ﻣ®f¨«S§NæÌ™Ï;çr÷VÙ²eÍe¬öaMY¢D sõdrrrÁ‚G»™+;SRR"""òåËg +VÌ\BzñâÅ€€ÍJ.÷‘ã«o]ŸjÝJe_ç³gϾûî»Ë—/÷÷÷W4Ÿ9sFi¨9T®\ÙŠKãÂ… šLÅ\¼xqýª¿HÉ’%Uœ{öìÑþ×ôÚ³ ÍÖcbm²Y´~ÕÌÓZD†°—¨T­Zõé§Ÿ6Eþdø"Àíg„ j&3¬4\¸páÔ©S5\ºté„„„FnJ·­[·jvzÉ>\®\93ÏxÀ~ÙëÕŽ·ní·ÇºµÎëׯ×ÎéÞ½û½÷Þkn9×K â‘#GþüóϦh Å«Æ6Ì|©f®\¹>|çw*‚µÎæi\fAÇŽS‰zLlÍG/¥µˆë÷Ë/¿´mÛÖ*ÑJ•*½ôÒK—pp7=¸¼|ùòÍš5K…´víZõʤI“âããö{çMºÜ_@¯i6lØðÏþóñÇoܸ±¹õÛNÇÄÄìÛ·oùò媮áÇ«Ò>ùä“¢E‹fÈ +sU~lÙ²eÞ¼yCCCµÂ S«i‰]»vÕO???•ß©S§4¥Ë}¯º9ß]µjU×ç¾Í°"/“[ûöí-Z´qãFÍGu•'Ož«onó× Ož<é½ÚZÕôë×ïüùóš^[¡ÏÚEï¾û®Yí   s¯½º366¶ÿþ.wÜ7iÒD­©À5»:"""99Ù,Hc¢££Õ…ÖÄM›6ÕÄf‰QQQÚ@¥¹}ÚK×ÿ'Ð"úöí«ÝnªÖ×_ÜãRT­01 ®ˆG*ÔNŸ>ýÜsÏY‡ý\ô¨¯¯ïÔ©SSRR’’’>ýôÓÕ«W+È ,è1Ã\¹ruëÖmÀ€+V¬PM›6Mý¤`². ¸ræBI×ÿµw¦1Q]m¿†MRÔ¢¢–egQ`D@F:k¢V´Q\âŒÆhÓ¤[ÒÅÔöK“Z£&‰ jÔÔ±*D«ŒƒZGdØ…"•šþsÏËyofÄW(¾íóû0¹sçÜsÏ2~ç9çžÛ5ÎŽ¿ÿþû#GŽ˜L&…B‘œœ¼wï^ÃP333!yÁÁÁHf—ÀMQ;˜¬_¥Ç‘‘‘AAA^^^Z­–=ŽÒÂU*Õ+çEÅO¶eFõQÎêêj´dUU•³³ó¶mÛ ‰F£f …U£ (öèÑ£ƒuyÿý÷W¬X!—ËQ5%rþâ‹/Ëfyøðáü‘'ðc~ëýû÷§¤¤ð[xzz¢¯_ç¯ݺuëž={Ør¶N éì¼ ®ë…°Òë@ ‚ ‚x, óQöuôèÑ«W¯ŽŽŽ–î?úüùó³gÏBª £ìŒ¿¿ÿÒ¥K§M›Æ6`’RWW‡”çÏŸgÄGxÌÂ… û©ü0ãÐÐPA|¢ˆÏ¤Kkk,((ðððàÇv·íd®¿þùž(GEEAï:;;ñuÓ¦MÐʾm“¾½…^¯ÿüóÏsss™dB@—,YòÁHM}©©©555´µAA¯t*11îȦ€!Xׯ_gOÏ8;;³4ø 3›Í‚¸m»Á`hmmU*•®®®Ò ÝÝÝCBB?~\ZZ }AJdÎ"—<Ã>äÉ“'999#FŒHNN2dˆÕ¯PÏììlHê† ¤Çv³ê®x¯z¾gÐ20coooXÝ—_~ÙçÍÒW·€Î~÷ÝwŸ}ö«Œ9ríÚµ0Q'''ž ÿ™ýû÷§¥¥±± EF ‚ ‚xe ˜Œ'N0‘4hPxxøš5k¬V|Â6ÒÓÓýõ׎ŽA\ǰ|ùrFc"…Î"åÉ“'ÙÄ.t²øÕW_ùúút]‰^!Ä7ß|síÚ5þ—˜# 5Q©T …röyzøðá™3gš››ûc Lâ5Ácß¾}7na‹:HF ‚ ‚è¶nÝ 5á;áËd² &ÀK´Z-_ ë¸ÿþáÇõz={ O % ã÷ÙÙÙHÉw†wrrŠ‹‹ûøã‘á@×õßNnnî®]»Îž=Ë–^b'¢_0 äû*`,Ž>~üxqq1Wb@C—E‹9:þgƒQ’Q‚ ‚ ú†¢¢¢5kÖäççs»pqq™6mäCú`¼¤¤¤äÔ©SƒAª¤r¹|Ö¬Y:ÎÓÓ“„¹8p€‡HqoÎÅ‹¯_¿¾¯öÆ'zOmmmNNNZZº˜k(ºX­Vc,1uêTé¼<úîСCè;öìš`åŒAÑ—üüóÏ[¶lásñ‚¸ibb¢Ô2QI <( ›ÁW|}}gÏžêãã¹Ê@h 5~m@@ÀªU«.\(}>†è?ÐG§OŸNOO7l/R¡+¤””$]e®‡³ž8qBú¾Säää„„åŒAÑǘL¦Í›7Ÿ9sÆÖ2§NŠöJz¡kAaFF†TIqõ¡J¥š9sfpp0\Öb±@n 8ÜqÙÊÔ%K–ÄÅÅA‰ºÆÿLX(ôرcz½ž½Õ“ÁWVHûB)+++óòò²²²pÀ ÓÁÁ¾nݺîÞêD2JAD¿púô鯿þúÖ­[þù'?ééé ƒ•B%ùZR¦¤×{÷îñ‰{A4ÎáÇOŸ>ýÝwßU«Õìáz©’ âKØccc—.]=Ð5þçðûï¿ÃAуÒP(€z¢#æÎk«¡¶]3hР±cÇ._¾2ÚýHF ‚ ‚èGN:õí·ßZ))<6“0nÜ8¾Ð°£££¬¬ìÒ¥K¹¹¹R§aé5 {;üÓ§OÏ;gå=o½õÖœ9sRRRHI_‡òòòË—/gddà“ïÁÄÀ(m‹QR©ä]†>5›ÍÝiè²eË´Z­ô=±v!%‚ ¢ßéNIÕjõÌ™3CCC‡Îæîùl/¬Ôd2Içî‘àí·ß?~<ƒÎd¥¤:.)) ÎÔݤ0a sÐÌÌL4©Åb‘Ê!{° íiµ¾¢¹¹¹¸¸}TPPÀÞêÉpppP(½ÔPÉ(AA.\ؾ}»tƒtATÌÑ£GGDDLŸ>]©TòÉß¶¶¶¢¢"XiaaaCCßÌRè²Rooo•JE‚¦¦&þ«£££ŸŸß{ï½—˜˜Cèz¿‰ y«ªª`ŸvÔÉÉ ÃF ’n¹UVVvõêÕk×®™ÍféÐÚ:eÊ”yóæáª^j(Ëd” ‚ ˆ¿•›7onÙ²%;;›½·‰ãâ⌌„˜B4Ù;E!*ÍÍÍ&“)''ÒY[[+ AÜ·rèСHüÇ´¶¶JÅ?AFããã!¦ô“Ð% hFØ$z¡¢¢m+m14£——lR§ÓÉåòaƱP(Ú-ýí·ß £Òu½ÀÙÙ9,,,99cƒ^–Dš!É(AAürÛ¶mxôè‘•ÀàŽZ­Öjúæd4aQ«X)C&“!qggç‹/¤ç!XÈíÃ?üNß755UWWß¹s§;ºc€É“'7Ž;(’¡oܸ¡×ëïÞ½‹¬¬.tww‰‰Y°`A/[Õn†$£AA ‡Ú±c$É*äɦï5 $iìØ±#FŒÆJ+++á4·o߯…VV~¹•äðéû„„„ñãÇÿƒ­Ôb± }  ………f³¹­­ÍVùÜÜÜ E``àĉ¥ŠŽ¨¯¯///‡ôãòšš«k‘lèС:nÑ¢E-¼´<=gH2JAÄÀsáÂ…;w^¼xÑjª]ãvPèchh(>ßyçXû©½½½ªªêÖ­[ùùù00•ÑÚE&“A¡ a111QQQ*•Н‰ü¯­­---5™LwïÞÅA]]šÂj2ôòò‚ˆ‡‡‡ûøøðEºpúêêjäËÇç£Gl‡NNN¸jöìÙ‘‘‘®®®=쥢ّÉ(AAo YYYÛ·o/**²@F¡Si¸ôÙ³gmmmF£ñÎ;÷îÝC>°1þ"Ê€]±'ô!XZ­† ñèfèÔññãǶê‰úâ|wR‡&BC¡^J¥râĉð¿!C† âBWÌY¡ÁáôpGÜÂ6ggg…B§ÑhzŽ(÷&CÜÅ@ƒ'&&ªÕj’Q‚ ‚ Þ8`3©©©åååÒGï9,\ +…ÖøûûÃSÙ,3Äzÿþý’’¸©Åbijj²;Om›çàÁƒÇŒãçç‡Ï°°0ÜÂÍÍ ™ów™ö_•{äÇÐq¸&ª±kooÇÉÊÊJœïY=y!Q`ˆ#êÂfáQ5¶?(.D&>„,"gÜÂ6fÉÉdPÿÈÈȹsçöà ¸¶¥¥eÃ0 Þ]†¸;Œ6**Ф¹ô“ŒAñæ[ÊÉÏχBIßÄåxyy)•JX©¯TŒGþ ¦ pÓÚÚZ³ÙÜÚÚ ÓÅç“'OzcAÈÜÑѲőV¦§ìWü$}3»Õ¯V 05ñE]˜e²¯L=™Ã1}ñâ…Ý©v»…twwÇ­=<< yh¹\ŸÆyiä¸RŽ^VVV__o7öŒô(¿··wtt4t–o÷ŽhU'ZòÁƒPÀøm)Ãð6ŒÂ„‡‡Ïš5 „ž²NC2JAÄ›OKK‹ÑhÜ·oßåË—¡>Ý©$›v5j„ z 9r$wS¡+Œ×ÜÜ 1…•‰À« §¿ÞÌì÷ Ä´‡]6_Ñ|)ðKäϤS)"“ÉàŽøÊ-]öYWWYDá ,Blë‹‚¨Œ°jhbHHHll,rƒÚZ¥‘ê,2D¶ÐY»Pä†G&:.** Ç=Ôè/ E¾uècIEND®B`‚nagios-2.6/html/images/unknown.png0000664000076500007650000000257507436604466016645 0ustar nagiosnagios‰PNG  IHDRºWí?,tEXtCreation TimeMon 31 Dec 2001 11:56:15 -0600Íô”ötIMEÑ ##ÛP¾ï pHYs ð ðB¬4˜gAMA± üaPLTE!)R)Z)Z9k1k9s9sBsB{9{B{J!„B„B„J!„R)ŒBŒJŒZ1Œc9ŒcBŒkJ”J”R”c9”sR”sZ”{kœJœRœZ1œsRœ„kœ„sœ„{œŒ{œŒ„œ”Œœœ”œœœ¥R¥¥¥­Z­c)­sJ­¥œ­­­µZµZµ{Jµµµ½Z½c½k1½œ„ÆcÆcÆk)ÎcÎkÎ{9΄BÎÎÎÖkÖs)Ö½­ÖÖÖÞkÞsÞ½œÞÞÖçsç¥cç¥s組罜çççïsï{ï”JïœZï­{﵄l|ïÖµïÖ½ïÖÆïçÖïïï÷{÷„!÷„)÷”9÷œZ÷­s÷Æ¥÷Î¥÷çÖ÷÷÷ÿ{ÿ„ÿ„!ÿ„)ÿ”BÿœJÿ­kÿµsÿ½„ÿÎ¥ÿÖµÿÞ½ÿÞÎÿçÖÿçÞÿïÞÿïçÿ÷ïÿ÷÷ÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿJÝàœ~tRNSÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÌ>ær>IDATxÚ5ýKÂ@ÇË^P¤X1-#Û¢$u®—YÌ8XµŠÙÊä*ÂÐÃÒMÄ’,÷¿wÓÏÇ݇ç¹çî 2¼·Ÿ:ãS¸ü´[ŒRêØ—ÕáTö?9çŒQ×±ÉùK(û-îû>µ®m‘råà•ûÝ^-JãØ à÷q¿÷u·8³1”Úiß-†•s 2 „T·o C)›ÜéBåÆ!<»”±pz¢ÄÔinñB&5 ª“’––2Pµ—"ZdžÓP奸·„E³)±u˲C,BJº"ÇWò0<#ÄBLCͱõ"õ²IÑ+ÜjîDü½R2]SÑ%²EOÈQe_(iYŠÇ–· Í0ÏÆ,Ë’P‰µ\¡6 9ø»ÚL%“©L6äM“Gj‚ëæxÿYYpÒŸÁÌIEND®B`‚nagios-2.6/html/images/up.gif0000664000076500007650000000152007436604467015541 0ustar nagiosnagiosGIF89a ÷YYYÿÀZÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ!ù, -H° €X˜¡Ã‚ Œ8±¢D‹3*L¸‘£Fƒzü8@@;nagios-2.6/html/images/warning.png0000664000076500007650000000255207436604466016606 0ustar nagiosnagios‰PNG  IHDRºWí?,tEXtCreation TimeMon 31 Dec 2001 11:58:03 -0600|G‘átIMEÑ ­.˜ pHYs  ÒÝ~ügAMA± üaPLTE91JBRBZRcZkZkcscscsc{k{k{s!„s„s„s!„s)ŒsŒ{Œ{1Œ„9Œ„BŒ„J”{”„”„9”ŒR”ŒZ””kœ„œŒœŒ1œŒRœ”kœ”sœ”{œ”„œ”Œœœ”œœœ¥Œ¥”¥¥¥­”­”)­œJ­­œ­­­µœµœµ¥Jµµµ½¥½¥1½µ„Æ­Æ­Æ­)έεε9νBÎÎÎÖµÖ½Ö½)ÖέÖÖÖÞ½ÞÆÞÖœÞÞÖçÆçÖcçÖ„çÞœçççïÎïÖJïÖZïÞ{ïÞ„ïÞœïçŒïçµïç½ïçÆïïÖïïï÷Î÷Ö÷Ö!÷Ö)÷Þ9÷ÞZ÷çs÷ç¥÷ï¥÷ïÖ÷÷÷ÿÞÿÞ!ÿÞ)ÿÞBÿçJÿçsÿïkÿï„ÿï¥ÿ÷µÿ÷½ÿ÷Îÿ÷Öÿ÷Þÿ÷çÿÿÞÿÿïÿÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ™ùMÛytRNSÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥TŠì0IDATxÚUkOÂ0†xù0‚™NPŒ8Œ"°0/›NSƒÊÔ©’ˆÐ©è²8B%²ŸoÏ&>šöIßžôß÷î{pò—ïW›1J-ó²6šÊÁ‡ëºF«V™œ?…r`»žçÖ$Æq å׳ëõú= Ú¡ãÃÏ s½þgÿO*'> möÿffóº”u‚7#‘‰\Û‡Ç*Z>=Åé†*‹ÛpkQÊÙË$DWRbj¦U¥ÈüœY´ß‚»·ˆ8Eã;Ð$¤l"ÄÐUYó0:#!†¦ò°°Z¿yj„è<ËÝRîˆÿ½¢kˆªdÐŲE‡Ëqe7ÑS’( …vØgkoY’D®b+¹B}R²?¾ZO&Ét6àL›Gêœëv°ÿ"ñn ¨ù«4IEND®B`‚nagios-2.6/html/images/weblogo1.png0000664000076500007650000000736307436604466016665 0ustar nagiosnagios‰PNG  IHDRf/žê(‘+tEXtCreation TimeMon 4 Feb 2002 23:14:53 -0600+LÈ8tIMEÒ"¤¡üC pHYs  ÒÝ~ügAMA± üaKIDATxÚíZ pSÕNnö6iÒ$]ÓBéBkd¶"*àŽ #*›ŽOAŸçsžoQ(:•ÅÑ'Hme)øP–¢¨T ¯µ¬-t¡´}4)M›4mš=7¹÷}7Ch“6l.3ýÊ͹ÿýϾó/ß¹Àá ÈU hšþ½ÝøÓ—Ë彑——·téÒÞ×ìWö¢Ç û5LåÀ¹'ê­ìï1دñÞú¡VÚÛPk¿,t/Yæ“À ÿx¨k¿~oSt0é1ʲÿk˜–ýƒ¡æ ªæŒl:¡àº!1­¦òÕJ(Oò|rÃ÷½v",«áIøø^ƒå Ð,õÉM2Jø}ÜëíM õp|e•ÉÖ~-Ýù e.TíëÛÉðe c^ cþÞ. È€ Háõ«¡R© …Õjí}+**Êårý–î&%&%ÄÆ‹Åb‹Õò[Î(!‹Y’F3{Î\E´"{X¶"J¾nÝÚ]»¾T˜6mÚ³Ï<ãt:‹ŠŠÎ;w³}½÷Þ{_ÿçr©¬¥E—÷îòã'OÜð)¢££‡ ÒÖÖÖÒÒ‚Xéè踊‡ï™vNwÑîp’Òãqoß^¨V+Ö­]KºÜ^Òc·ÚV}°òfãY¾|¹ÛER$ÕÑÞñЃݤY.\˜››;a„·ß~;¨BH*Ëçó#$b‘P@p ‚àN™:åõ7þ1xp’_A©R<nŠÄbL³!«;WWYUÕ¬Õž®ªjºð¿›4‹Ñhlmm5jTCCCpdB=Iq(šCs¹øV®J¥|á…ç^Þ²f³Y*• E"®pä6Áçüë:HÈd2‡å>t ¾,(;Z.•EÚíöúúúë„F%ã<¬ÑÜuŤeeeøM’¤P(¼:ÈðÇóB3 ŽCHÄÒ9sæÿR~jëÖ­V«ÅåvÑåpA„±Ú@:œ˜œ¿ÐétƒXìܱ£¨hgmmݵC†žõÊ+¯*•*, A¡×·cÊaÃn}íµ×Ðt84Bà/“ƃÍfegÁ‚O=õ”¯‡Rry4:o—¹«Ý¨—ÉÄ z.¥ÑÄÅĨ #BL&•1Ç´]šø5áöƒ)¸Ü(…222¢«³ã55µ6›=R(ññ ı©¥µepZªËóÐ^kÀ)Š´;¹ 7pÍãñ…B.¶ný*"B<ë±Çn§422#=]­Æ¸&!13#ûÍ7ß:xð`ß…$S£|B.AQLÅàúõ ¿BÍg4°L†±¼ÑhÐÁXzz:*:âÀkÉ’7yäáÇ›µpႯ¿þ M¥§¥² ½B‰D?E¢©•Ê1£Ç°SO:%>6Y‰Ó$jÔj5;.Š„<>¢Û€c FÚômGKK9/4Á«5É¿ÿƒ’5"€½6ÍÍZ_œšV­^=ïÉùàsçÌ]òæ[%‡~6:°kb±d̘1Ó§O¿®Äd·ˆ½`k.xÓ¦ÍwÜq×°ìl` ?“Dl\‚T*íîîÆb;P‚MßÿƒÑÈdÊðÃLè¿—ÏïBííb¢úŸ|òɰì[ÇŽ'’£¢â‰Ä‡žË@ ³øè¡Ê)SeÒ(6£Ù¨´ê.4“»¾àá™3~úñdzg«§ zpæt¾¢ÓgΜimeØVRrò„œ‰ñšD»ÕºÏÞµëÖnßQ4oÞ¼¼¼e2Y$Ø^tà!v8¾Úl2¡Œt²ãÇŽUä/^¼X*“¡îûxîeL Ÿòõ|E×›ýÄìfmóÄœ X è˜H æx(žç¬K(?qbßþ½#G·dg ÍÌÀ„`qdŸË‘a\\ 4kY™Y¨æ~vÍZ¨­©;_>++ à"º7n\ú ’˜••é«’L«Ý·w8&ŠÆ’·–Ìš=[({\λ§Lý2¿”0--U @ð‡ýÔ©SýBRî¾ûnƒÁÀÒ%ìÒСC/Çü AàŸHU02Ô¼eåå,•1fÔ±ªJ·Å&v[,Fc‡Åb»p¡¹«ÓL9¼ƒó\Ù™±#Fû­>¢¸¸lŒYê¶)=úÉÇkÛuz†Ò”Ãnyî¹K¬õý÷ßÝaïÊ•—_L›6íÀàw^/IÓ d Ü.S§ÁdêÐiµï,7:úÒ …eyËÛ&ée4\.œÀœ ².ÂbÛ¶mXZ¿È„|_+‰‰‰àe`z555{öìAB±·@pdE¾ ú"3‚Û·mÛ»w/nµµê]n2.>A$‘¸=$NKU•§úé§uëÖu¡)êMÕ•Õ‡Kÿpø‹ÝÆZ梢B§ÕU×T­^½æ\uÝŒé*”L‡•Ù¿¿øø‰“Ðΰ1"‘°°°°¶¶–µÐÔÔT^^Ž d|CC£¥ÛvñbÛŠ½·c{Ñ·ß| :»L¬&ˆÑ`$]nÄŸH(Dm%I7(¬mÙ²å³Ï>í²¾^þƒ[%$$ éàkssso…ØØØ¸¸8\€—¢0ùÇSÓ32³2aÓùó/¶øß:)åJ@ìF49/½°D †‘ï~߬ՂӱƒwæLÊÏߟ”Nå´»½´hó_°·Ð7 lL½ýQ(HFüFI­« I ¥F“˜š:Õ¤ÖÒÒÒ/RýC†‰Gdd$b v1‚£Êp„C>òÙ (}½’º¶£,ºÞ®»Ptjêê2•§«Š‹÷óùÄ Ï/xrþ •ôÝép!¡PˆâÔB±•»Ûl}÷ÝkÖ¬ù½QºB‚wL0†ÌÌL¥R‰$ÂQ<Þǘº tÈV„!z.hh(1W;7â÷ÃרTЉ9ãBOD)dm­­`/ŠhyggÇæÍ[ò}G¨?”„LÌ#F ¦€€39Â$&¾"²ðb\¥RˆV­V‹qm ÇO¾cN‹^Š®oh¨?w^•‘ž†úòã‡~o|d@äÏ!—jÙÀÿdéWþË€ ÈY.ç'Ëï/85Î늇ƒé‡zÖ?Ò£(·‡\Õý®¢…ôP åóå{ìí@sAÛBÁÀ§ü·‚ém?Ô`¾õ;E³ô±¾¯G®x‘ÍþËE(woˆ ¥>⫇oá´­ «¸>÷|÷ßÛ'®OÂYLø+¿Ù‹¼±„ ‡{ü~è+™Ã›¦Ç³AÁ ñ „ƒ‘?¹úPëÛZø1> r#äÿ@< r@™âIEND®B`‚nagios-2.6/html/images/zoom1.gif0000664000076500007650000000175407436604467016173 0ustar nagiosnagiosGIF89a÷J)R)R1R1R9R9!R9)Z1Z9c9cJ1cRJk9kBkZRsBsJsZ9{J{J{Z9„J„R„kJ„{s„„„ŒRŒc1Œ{s”Z”Z!”ŒŒ”””œZœcœc!œ{J¥c!¥k!¥¥¥­k!­k)­s)­­­µk!µs!µs)µ„Bµ¥Œ½s!½s)½{)½ŒR½½½Æ{)Æ„)Æ”RƵ¥Î„)΄1ÎÎÎÖŒ1Ö½œÖÖÖÞ”9ÞÆ¥ç¥JçÞÖçÞÞçççïµcïïçïïï÷ïç÷÷ï÷÷÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ!ùL,É™xdH‘™,ññ"… `(A˜ÇŒ‹.RŒ°@aˆÀ%8nìiÃÅC ™1²ÇŽ34ZHÀ ‘=Œ‰bc‚DT°Ü!¤‡ =gXabÆ :lÌhQÂÄ>ŒzQ† %4<8 )\|51Âj‚Nä°0¢D‰¶&4`%&XР¡„| €8H$B‚  À@‹`0 s þ"DÂãÄ'jLø‰ë%;nagios-2.6/html/images/zoom2.gif0000664000076500007650000000175507436604467016175 0ustar nagiosnagiosGIF89a÷JJJRRR!R!!ZZZ))cc))cBBcJJkss11sJJ{{{cc„„{{ŒŒ11ŒZZŒ{{Œ„„ŒŒŒ””!”!!”ŒŒ”””œ!œ!!œ))¥!!¥!)¥ZZ¥œœ¥¥¥­!!­!)­))­11­„„µ!!µ!)µ))µBJ½))½½½Æ))Æ)1ÆZZÆccÆÆÆÎ))Î)1Î11εµÎÎÎÖ)1Ö11Ö19ÖÖÖÞBBÞ¥¥ÞµµÞÖÖçJJçÖÖçççïZcïççïïï÷ïï÷÷÷ÿ÷÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ!ùP,Ê¡¸I’¡KZQcmveuw•ÇáÐÙ×»­ŽQg•‹q|iV:1(I;2Rz…°®¼¾„¹ßÒž¤´¼˜i1Ul2LtJ(9GVw{mv¦Äμ¾ä¿” Ã°„[sŒpQ=OA'.Y_NBWch­Â¯­ÒÔœŒÊçÍ…ƒÅ¦‚?3- &4Rmw–ºËñöǼéÿë¹–Ô«ˆftB,C002(&,Lbv™ÅθØÞüÿöÑÎÒǧ‰oN.--  &HZ_€¢¯½êöÎàÿþÒÂϨ~apM:/! (>IUu¤¤¡ËùÚ¼óÿÙšÂÑ¡xˆmD2B/*&%,>L\ “¹çßµåÿö¶Ãá¾™ƒyQGA,"*" #8CPo’ŸÅÜÅéÿÿâÂåֲޅ_NU@-!&->J_}– ¸ÚÐÐðÿÿåáØ¸“yX?K<"+& "3P@Jfw¥Éææãÿܾâ伕›‰jJ=+(!5A>BXp«ÒÜÊòÿÏÂçÍ™w¢…cJR0'8NBUp{¯ÌÍàûéÆèä»|”¡vUYA(-&'9(&6Xp|‘¸Ó¶Æõæ·Üÿ繑³‘gJ`4-N8 -?#6Ymv—ÁÑ¿àÿÚ¹îþ಩®‰kR0+857;Xe|œ¿ÊæÿÿÝØçãÐÓ¾˜€uU6' ;7#2M]}›©ÀâÿÿåÜèζ¹µ‰tuR:/&DeGL`~™ŸÁæôÞúöÖ½Á³ |\xZ=#<&3"8USQo{•ªÉ×å×ëÞ½ÅãÄž‹oR<2 ,)/@RMKVoŒ¢ÇëÖÝÿí¿ÄÏ­€t“xYLN(&2.V^Um€„š·ÓÌÞÿà¾äצq“’oRM3'0'19--?_{‰–³ÕÆ¿õù¾Àú缋ª`=_7(MA'G0 4Vmu”»ÐÉÒöëÄ´ÛÔ¸¡ŒxnU8/ 7N24Qhp«ºÚúÿïØåߪ‡¨˜|]SN<$&!-Ncdg„¤±©ÊàìéõîÔµ²ªPZdA!I47CLVpŽœ»ÇÉÚäͰ¹ÙÁ…xX@:;3(.HZ^Zey‚xŒ½ÐËêæÂ²º­˜‚{ˆh`U?,(3BNVe|…ŽŸž£ª¼ÔƶÄÁ¢Œw`WNLV_YKJIFJ_t~±Àµµ»´¬©ª¶·¢’†lPKI9=HHDNTWUU[l„ž²¿ÉǼ´±¬¥©§œ‰xcQB54<89KXVR[dmš­½ÊÉÇÌÏŸ´° †uhQ<7=2-1=8;DRevˆœ«¹ÈÐÎÐÔÒȽ´¥‘|gTG=5/./129AMYp‹›®ÇÔÓØÛÝÖÑÌÀª–~VIN@//961)+5JXfºÇÅÌÓÙÑÙÞÔ¾± ƒheS@0.(7:86D]_hv}—¸¾½Þå×Ç¿µ¦Ÿ™šŒr`X;)8@:4CHGMi·º´µ±¬¾¿ª¢¯¡„h]SQOY^WKMK:DlŒxŠµÈ¦Ÿ¯°¢£²µ­«š~kdYTPX[XMOdlcgjq‚–¤¸±©§¬³§”Š~tzzpgbXSZdcb_vxt‚——œž¥£¡™ž’ƒ€€mc\]kyoowra]_c–•“—š‘„€–”™Ÿ™ˆuhbw…‹|zwpKG|Ÿ„š¢‘|uft†‚ˆ–’jWj|sx‚…€‚}rp’Ÿ‰u”ˆihЉobrvoijjv{oiv‰ˆzx—¦¢š™‘Œ•Š‚‘£oeqnaY`b\\meW{‡u˜Äªƒ{ ˜œ ¬žkagi^]t~oirm\`}Žˆ’®·–w°‘f‡Ãµ‘v—”vYUMbpcYt“vT_z†€”ž¦°¹´’‰¬®Œw”©‹]cˆ^GPU:^~rVr•Šjnƒ–“¤¼ÌŽœŠ“˜€jƒ˜|_lsUKW[MOh|h[~zmh‹¤©¡¯Ã¾¦‹nYg}iq‰–zXEHJKNb›—ŽŒ‹£—˜®·³‹ŽlVcgJ:M\dZYqmliZj“üÂÌѬœŒŒ’ˆ}}c6+NTCV|~dYy~‚•š|–ÌÔ½¤©º˜pn`Uw„os‚_=@ICWxªª®°™n…¬±œ´Â¼‡j†{Xaz_O\:.\‚dL€¼¯lc’´¨§ÎйyZx§{hŠ˜utpM.LujckŠ{M=už}ž¼®…„\r¬°ª¢°‘tt`/N„kLl„jLr‹sYа¢Ž¡¾¢t›Ð hh˜{Xi‡sSFlicdqe‡ye~–Žx‡Æáº›™}ˆxcn°™_PŒ…M0]|jL{°j–¦n~Ä´p¬Î¤’ª®ˆe_^^ccclh^PQ[_Wnˆ•³Í¬z˜ÝД£ØÂqk|rUFUW@5GK`tsl~£³®¤¦ºÊÆ®¡¥•i^s|kTDBI66\g\q€‡©¡’Ž…„¶Â«ª¦~WdS*9Qgi€¤ÏÒÞÞÒÃÍȼ® µšrY]5(1* 9?6FRlv†˜²²ÄàѲæñÜ¿µ®vf?.EG6NN0,BSL`‡±—­çÕšÒúÝ–Á­{ev_87<5-9)'/LGYz–•¯ÍβÖÿùÄŽÅ̧„\?;8$/7*!:O]dzœ ¤Ôüß¼×óÞΧƒqJ*'(9Lk† ¾æÿðÙéøÉ»Ð¿œ‘z]G4'$HS;BZ{“˜ºÜßÜÿÿáÁÓίocG-= ( 5I=Dbp†—±Çàê÷ÅÄêüÔ®°¡]G50,1CF59C[lˆ¥ÏêßîÿæÝÕϳš•—_N<"# &OORm‚„•½ÏÈèÿ߯ïᯀ¢šzZ?".4"DG/)Edxv‡­Ð²Êÿé¼ôÛ¤~±Ž\Bp:&I<@)0O_mН¸¼ÌüÜ´Ôþà·ž¯—}[153%8(1S_gˆ¤ºÛøÿåáááÓÒʧŠ}\A*0J/(@[p¦»ÝÿÿÿãÑÔÉ£~‰gP7)*Co\MS`~•«ÒÿìðþäÈÊ´§œw|~X:6! 7'IaMSq¥°ßíÝÓÿà¶ÐçÁ¤‹„rP4- +*.@NMKVhxˆšÈéÆÛÿÙ›Úߦp¤ž|[K@.&!AU?Iciv…§ÄÙÚöñËÏ䯋v¤ŒlTH#-+:15Qo„‰–¹Æ´áÿÞ»ïöÓ›”©xMDD"AH79 'Ilxƒ­Ûмêü¾§åîËŸžžz^J$:9KR.2Okp­ËÐíÿðÏÎÔ¹Ǫ„ylK)! NT2:Wf„¤­ÌóÿÿèÛܾ¬·²ƒ~z[A2 "--`wNRd€”—¹åêÙôïĮʼžjd…]<"./+-GXGGev¥ÌàÞßóŶÙܳЄlF2. 51,EWKK\uŠ•©ÝöÉÚÿܬ½Ít‘qTA4 ..>k]]{‡‰ŒŸÅÙÈêýʬâјgš”mOF.+6,!7E65Mp„ŠšÅÞ´ÒÿמÔöÑš®~PFZ%0Q+0E.+Ip~¢ÒÓÀìÿÏ­éöÍ™˜§dG!<1 GH,0Njnƒ¤ÆÊéÿôÎÈÔȹ¿©ƒqdF$%#QO-;Wh„¢°ÆìÿÿèÒØÂ¦®°‚mwS<-2 %VUO^v•Ÿ¾èÿãùô×¾·«—w^zbC: B%7YkUo„£³ÔåâÔä⳺æÎ«ˆ…p`<, -94Qa[JVf€£ÌûÜÔÿ颶תwm“{[=G% !=#-\gWt†‡’©Äãßäüä¿ÙÒ eŠ•pQB$/*-D44Kl„’š­ØÆµðñ«©îÚ©v¥…W4S&!Q<*U58\pt˜ÆÕÁ×ÿÒœ¼ðͦ’¦‚iK&48 :Q:.Kgkzš¸¾æÿýÔÕÜϸñˆxrQ5"#FT67PdŸ¯ÅíÿÿìØÔ´¹·†z€[C5- .XpJV`|— ÃîöëÿçÄÅʶ wv~Y9,$"7%*PaIMh™±âûãÞÿʲááµ””ŠpM>0 3,3HNKN`p…’¤Õä¾ßÿɦÜÑœo’pSF0/!@Y@Pmty†©ÌÑÚúì¹Ðäºy‚£`OB )6 98)4Xv€‹¬ÔÅ´îï´½ùå¶‚ª“e@\2'R='G):_vu¾Ù¸Ïÿ×¥ÒùÝ®™¯ŽpV<+J$8U6$?Zhn‘²ÅÐõÿÞÅÑáÉÎʧ‰‚c@"0 9J-&BTiФµÚÿÿößèÝ»Â˧}oV=*/ 8hK:Lhˆ’­ÓøÜøúáÅÌÁ®„e†eH*: 0-QOC`uŽ¡ÇÛÜÓð×¹ÓóÍ¥š–tV<& 2*1DP?:Lh{Œ©ÙíÍàÿϳ×Ô¡u—™sSQ:5$AXAQnuxŠ£ÄÌÒûðÊá쀓®ŒhXE(93(@,$5Woz†ŸÆ´¶ðò°Èÿî·¾ pGn=/YB+J$+QdjŒºÈ¼ÖÿÛ¯×ýà·¦¸—|[72= 0H. =U\j‹©³ØÿÿÓÎäãÊÐÄž…}[<"7>"&?Tp¤¹ßÿÿèÙÝνÁÅ—}‰aH6 +Dc>DOlŒ“µáôÜÿïÆÀÕ¾°…tjK174/":ZMAYl†“ºäæÊðâ°ÈöÔ«™¥‹jKE!&2-9KD?Kar€¶âÌÐÿôµÔîÀ€˜°ŽlZI.&(UE=^prv”¹×ÑôÿØÑùߟ{¸›uZZ0*7"27$&Cds{œÈçàñ·¸ùùÌ¥­{KXM#CN&=. D`hz¡É³ºìí®Êù뽜´¢€aF D* J1.M_`‚ ¸ÃéÿéÆÌãÕÍÐ¯Ž‚iH"-% /H1&=Pc… ªÎùÿóÔàâÁ¼Êµ…‰y[A7 1 5d\@Kb‡— ÉôÞåþçÁÈżœpwƒZ8928&'ASBNh~‘«ÑãÝÛõÃÂêîÅž§“sR@(3,8FG;jMFSkŒ™±ØøÕöóÔ³Ô¾¯‹fjL-2&.0PG:Ti‡•½äéÒõâµÌôѧ—œ|\@8!$'4C;9G^r—¾æÏÒÿó¼ÑèÀ…ŽªƒeUC +"*SC?^pu~›¼ÑÒöüÖÙöÜ¡z®™vYS0%1 .6 $=_s~”»É°ÙüÒ½õÿß§Ÿ¸‹_O\07L//33Wes•¼Ã¿æÿÓÄõÿß´®°‹pS,52 9< =W^w•²½áÿúÐÕäÝÎÓ¹”‚mM- ! 2%Ja:DXx“šÁëïÝÿ÷ËÆØÇ®r‹_A170$ ;PAD`sŽ¥ËãâÞüÉÁì÷Í£©šyXC/ -(2CD79Ljw¬ÙàÐòÿÑÈäÚ§}¨–tXS. +=Q7Hdqs„¤ÄÍäÿøÙøõÍŒ•±‹jXF'0*7"*Khy†¥Ì¼»ñï²Öÿíº¶”h?_9+H3"9(L`l»Á´Øþ̶êýܲ¨°ŠnO(41 :>P1.53Tdo‘¼Á´Ùþνïÿå½­¹–{\91>5D 8RYnŽ®¸ÙÿÿÓÓèéÖÞΩ†dF" )5<"5Jeˆ¡®ÒûÿùçíãÌÎÖºŽ˜y^C4 00bJ4CZ~ŒžÅò×êÿä°ÐÒĦz‡_;9..#?D3AXo„ŸÄÙÒáð¸ÇüëÀ¡´•vUG, "+(3E8/5Ldo„ª×ÇÅõý¿ÊêÙ£‚´{_Z2!0CH2E_jl~¡½ÁæÿàÑÿòÁ†«µkdF-8*&;-Slt†«Ç§Ãõݰêÿé¬Ä•eLm?BW9282R^m’¾·±ÝûÀÆúÿß·¸º”vX-B9D=>RVq¬µÞÿóÅÔæßÐÚÁ›ˆ{X8 $82"I`…£ÐùÕ÷þÚ±ØÊ½™r’~[4C',7!4LE5L^z‹­ÎÛÑìèµËÿæ¹¥³’qRD# .12?M?8@ZmxŒ¸ßÁÈþè´ÄãÆ“‰¬ŽlVK(+(UI:Rilq…«ÆÄëýØÃïàªu¡ª„e\;*1(&8#4Wnxˆ©Ã§ÉýÝ«ãÿ⤒Á^Fm9=\:/?4XfkŒ¼Â­Ëų̂Üÿã· ¹™|];.J&2T36R^jЬ¸ÖÿÿÐÓÞÜÊÐˤ‡…gI##& 2I1&;OjŽ¡­ÕýÿõâàÝÀÀǬŽoR=.7BoOCMf‹§ÖóÓöðϰǼ±Œd†xR(;%*6#6OI;Qe‚’²Ñ×ËàÙª½ñÖ«—¤ŠiI>! &05COE>D\o}½áÈËýê¶¹ØÀ~¨”qWN" *7,[]GYosuƒ©ÄÅáýß¹ââ²x–°l\D271"2@-(?`x|ЫŤÉý×¢Ýÿ៌Á‘]Fq@:aA1E5Yji†ºÁªÇûΦÖÿä¶œºœ|\74M!>V3!)!0?)8VVASm‡•´Ö×ÈÝÕ«À÷Úµž¤’pND&47>4';>1/Ig{zƒ¢º›ÅöÌ›×ûØ–Ž¾UNo;Eb7:@:`fi’µ¥Õñ³žÜöΙ¢µŽoR%D>OO,'Eb_s˜¸ºëÿæÅÎÏÆÀ̶’‡zZ50!'WO+5QaœŸÀíÿùÙÎ׸¬¼»†…‡eHC(57]wSKTu‘޳áèÙëâű¹»ªƒt”tS8J77IF9L`RB[n…°À»±Ðµ¢Áíͧ¡‘jOI,@FIU]OHJ^o~Š»á¼¾ü׳ֱƒˆ®•pTP77:lQD^gjp…¬Å¸Ý÷Á¥áÒ”g¡°†dX=7?8%6@3,Dd|y€ ¾™µïÕ—ËûÜš‡Ã•\QvAJnE%>K%;dme‹Âº¡Ìú¼”ÊûØ ˜Â›|_5DQ"L]>'Adej’·µÜüòÂÈÍʼËÄž‰†iD!/+ PY2,GTn’ªÙÿÿçÓØÌ§¸Ç¡|•uWE2>"Kx\EGc†ˆ›Îñ×äèÓ¬²¾µŽn‚V'^_dŒ±µÚøóÃÉËÀ¯ÆÇœ‚…lI""0B_>*DWq“š¦ÔüýìÖÑÉ©·Â§}uYD6 C#M|iJId‰‘–ÌîÓÜðÛ°·Ã½œu‚‘_.:A17G*?>'#?>4?Vrzyƒ¯·‘Êù¼‘×úЊ—¾ˆP\f=S_5&II('Ihdk™Å·¨áð¬ŽÑ÷Ì™¡»˜xZ/CLRhE&?_aeв¸ØööÉÊɾ³ÌÍ¥ŠŠvR)0=bB$:RjŠ–ŸÊ÷ÿúßÒÓ°ºÆ´„Ž‚bH> 0" :`nLDSwˆ·äØÓíá½¶¾¾ zn“e6)G.)>.0GS;>_t£¾º¶¾Õ´°ÞìÅ ››ƒXF5!I=GQPC9C]t~•ÒÙ²àÿ¿¾Øª„”±ŠaLHF2!KrWS^hsy޶ÐÀðôµ¨åБs­²„_WGDB.*DD;CWq|}‚¯¹‘Ëý¾Öü·—ÂŽT]qDX_3+NH!'Fe`iœÉ¹¥èñ©ÚüË•«¾—wX,GFWe5!?cYj”¹µáûìÃÆÄ½¹Ì¿“…b>&(RX.(FTr’¦×ÿûàÎÐÀ¤¸¼š}tWE02"Dm]HCe‰‡™ÍèÍãðÛ¿ÁÄ·–u‡]-CB*(B)/HT:Ee‘§¿»¸Å×Àºáë̦  ‰aN9&NAIQUG@aF+(3?^xƒžÈà¶”¦»¾ÀÔÝ˸§ˆZWbH/CGRFLIFZinppЍ¸£¾¼Ç­¢¨š”™¬˜ƒutV:7^ePO^wJ9h•nÀ¯¤“Œ‘™Œ ¥‘x]burdhf\jdURƒ’zu—­¢we‹›”©¬¤Ž}gqwt`fz…XPt{das€Žˆ•™™”™§ªŠ}…‹„xƒŠ|oeefmqhlk~~|…”•Ÿ¡¥’ŒŒŒŒ‘‰uhjbNhˆŒtq„}wikgt’‘—«œzˆ–Ї““‡ˆ‰xsŠ…h_q„|em{t[_}}}„‡‡…|“”‰•¨¥rrptrx‚|f\`pm`^iqu~Š•Ž“š¤£Œ ”†Ž‰y^Zeddejfgjlpxxt~Œ¦°Ÿ›¢Ž†§­’~Œ‰tadMSZ]V`svfdn…€Š§½³²·©“œ«ž†’‡i`kcTMPYbimjsv}‹šŸ‹‘¨®¦¦šŽ‰€u€„yilurkfjpmt{v……qX|¯­‰À·‚…uŽw€Œ•rTR]UA^sntˆ€juœž‡‰©±ŽƒŸªŽus|kjecXbXWYghc_r œž™ž¦œ¡µ«‹ˆt][WQSY][`aYUh……qm­Í­¢ºÊ¯‘‹Œ‹|}~xPETOIRhoyŠ€w‡¢¢™°È»™¤ž‚z…lllb]ZQQ[pr{~†Ž–‘‘œ¢›˜ž®™†‡‹yjlpnfimrpqytitƒ‚‰ Ÿ{m¦±™†£°˜~~n}‡tcxˆjT[ic_m‡…†ˆ‰qb‰£„rv—Œy{ƒy€}hkt^G„‹t‚~uyqz†Œˆˆ–‹pl}ƒ~‹’…†sZrŠ…msˆ“sh…‡|uz‰†„|`c‹ž–‹ª§„lzqo„…Ž«”tuxh\u”ž‹‹mb‚”vm‚’ƒhx¡…o|ŸŒ—€†{mnvmy†ŠŽ|ŒvSTbe¨²¶¸•|yt†™ƒ‡|`IXinszˆ„omŒ‡˜Ÿ…Ž‹wˆ}}|vpeYfoZ|¤Œoy†|u~}‘–‘ˆ‚„|liƒŒunuoj~ths—xmƒhi—›€p‚~ƒ†‡vnnt…‹~€‘‘g`z„nd€‡‰YY‚‡©©„t‚’Œž›—•iTh€u`mƒzPIlmo{¢©‘}”§‘˜Ÿ˜v~‡z_Xv}wV^orsd^‰«˜„¯ŸŽ‰™‘‹Œ‹•eHlx]p~€`\|yivŒ”›ˆ‡Šƒpˆˆ””~s||zphf~ulk~‡n\~––Ž‹…‡„}ƒŒŒˆŒzz~tdnƒ‚psmvuop€†‚‚‡ŠŒ‚„Œ‘‘…„†}{|{rknsotuo|{qn„‰ˆŽ•›”‘”Œš†}oegljeentljouu{’—™œ› ¤¥™˜–‰}zqhfb\\`abbfrs|‡“—•›¦ª§££ž’’Œrt„tc[f_QNV\lrpxˆ€‰˜ £¨¬¨š–‘~‡‚mii`PLZb]aipkpx{yˆ”› ¦¤š’–˜Œƒ€zvogbeb][gj^XrŠv¨Ÿ‹“Œ‘ž ”•—ŠwlelheglhgkdYo‰‹€Œ¨¦ŒŒª¢Ÿ¤”…wqokhbacd`\cpqvy‚‹—””£´±¢¤¨žŒ„„}xrfXRQGEYhpgp€‘‹‡ˆ¢±´´¸¿±™Œ†~pic\XSKRld\l{vqvŒœ£›¢££‘‰‘”xvpl_[cggfidgtrnz˜›’™›Ž‘‹ƒ||{ohahtgN]~~px““ˆ‚z{”˜‘¢°“tu~xotxz€€q`g|sft›|m~‘Š…•˜›”Œ‡†}x~‡}rr{{wsmq~|oqЙމ’œ‘†ˆŽŒŽŒ…€rfirpihtxqiu‚€| šš–˜›‘‘˜|z|skhjfefjb\j|rn€•’‡¢¦—” ˜†{yzojg`\YSXciiq{}†ˆˆŸœ™ž©¤“˜…|ypda_]Z`fc`fsrny——œ œš™˜‘„|xqeefcaefehkmlzˆ–šœ™œœ—‘ŽŒ…€‚{ttqllnmmtuv|ƒƒ‰Ž’™–‹‰†~~{vytnppopux|~}€…ˆˆ’””‘’І†…„|yysnnpnmoonpy~~‰†ˆŠŒ‹Š‰ŠŠ†zuutqqrponklpuy€„…†‰Ž“”Š„€zvutrpmiffhjnx{‚†ŠŒ“•”“”–‘ˆ„}yvtnjhjhnopuvvy…‰’—œ›˜˜˜—“Žˆ~{vqkjkjlmllomr€†Š–•–—–––”‘ŽŠ„{vrpkhgihjlmryƒˆŒ“•–—™œ˜‘””‰ƒ‚~vqrlklmkkqtqpz‚„‡‹‘‹Š‹†~~zqtuplpolnuuw~ƒƒ„†‹‡‰Š‡‡†„ƒ~wvvusqrsrpryy{€‚‰ˆ‰ˆ‹Œ‡ˆ‰‡ƒ‚€yvvutuuusuxzy~ƒƒ‡ˆ‹ŠŒŽ‰†††ƒ~}}}yuvvsswy|~‰ˆ†ˆŽŠ„‚|ywtstpmpvkjŒ„„€•‰“Œ‰Š†xsxxssurtxpftytƒ”‚ƒ’„‡‰ƒ„…}uxvqkttkmxwuwwy€„ƒ…ˆ‹Œ‰ŒŒŠ…€{xvuqrsqptxrqv‚~}…‹‡‰‰ŒŠŒ‰Š…„‡ƒzzyxttuwwvsu{|~„‰ˆˆŠŠ‰Š‹Œ‹‡Œ‡€zz}|yzzy{{z|„„‚…‡ˆ‡ˆ‰Š‰Š‰ˆ‚ƒ€~}zxzurturqy||‚‚Œ‰Œ‘‘‘‹Š„ƒ}|{xwstsqptwuy~€‡…ˆŠ‰‰ŠŠŠ„||ysrqqqokltuup{…ƒƒ‹€Š–‰“ŒŠ‰~}…|lotspjjuxqqzƒƒ€…ŽŽ‘…†‡‚€|uxzrpuuttww|~}{„Š‹’Œ†Œ‘‰„}|vtxwwvvx|wx{€„‡…‡ŠŠ‰‹‹ˆˆ‡ƒ~|yvwwwspssrqw}€ƒ‡ŠŒŠŽ‘‹‹‹ˆ…‰~}{{uttqrtrqrvwu{‚‚ƒ…†„„††‚€|zxvqssprtqqqtx|}€‚„…†ŠŠŠŒŒ†ˆ‰…}}{wqttqqrnnpwzy‚ƒŠŠ’ŒŒ‡€~zxuttqqqtqswyz„„‡Ž’’Ž‘ŒŽˆ…„|xvwttutuvvxy~„‹ŠŒŒ‹‹ŠŠ‰‡ƒ€|zyvrtrrrsxvy~‚ˆŒ‘“ŽŒˆ…„‚}}wstsqqsppsuxz|~€…ˆ‰Š‹Š‰ƒƒ…ƒ~{zwtsqpppnmpvvuz~ƒ‡ŠŠ‹ŒŠ‹†„}|xqsqplnnmnrutzƒ†Œ‹‰ŒŽŠ‡‡~}zuuursutrtwy{ƒ†‡‹Œ‹‹‹‹ˆ„ƒzwwwvxwwuxyvyƒˆ‡…‡Ž…”†Ž‹‹‹Š€€…„€w}soklnmlsvx‚‡‡‹ŽŽŽŒ†…ƒ~||{yxzxww{z}ƒƒ„……†‡…„…‚‚‚€zxusqpqpprtqquxz{‚…‡…‡ˆ‹ˆ‡‡„„z{zusuuuusswy{~ƒ€Š‰ŒŒŒŠ‰‡‡†„~}zxwvwvuvx}}€‚ƒ†‰‰ˆˆ‰‡‡…†…„‚€€|{{zzyz|{}}{~‚‚„ˆ‡„…†„ƒƒ‚€€}{zyyxzzz{}~€…‡‡ˆŠŠˆ‰ŠŠ‡†„ƒ‚‚‚~|}zzyzyyz}|}}~€€‚ƒ‚€€€€}}zxxzzyyxwwzzz|€‚‚‚ƒ‚ƒ„„‚ƒ~xyywuxwwxwx{wy}‚‚†ˆ†‡ˆ…„…„‚ƒ‚€|yyywwyyyy{|{z€ƒ‚…Љ‰‰ˆ‡‰‰‡…„‚€€€}|{{yz{y|||}‚ƒ‚…‡……‰†‡‡†…„„€}~{|{zzz{yyx{|‚ƒ…ˆ‰ŠŒ‹Š‹‹‰‰ˆ…€€€~z{zyyzz{|{{||~€€‚‚‚‚‚‚€€~}~~{zzxvwyyyyy{{|~€€‚„„„„ƒ~~~|{zyxyyxxxyzz~€€€ƒƒƒ„…ƒ‚‚ƒ‚ƒ~}}{z|{|{z|}~€‚„……†††††‡†…„…„€€€~|}}|{~}~~€€„………„„„ƒ‚‚‚€|{{zyxyz{z|}ƒˆ‰Š‰ˆˆ‰‰ˆˆ‡…„‚€~|{yzyzzyyz|~~€€€€€}|{|zzzzyyz{|{z{~}{|~€€€‚€€€€}}~|{||}|}}~}}|~€€€€€€€€€€}~€€‚‚‚‚ƒƒƒƒ„„„„„ƒ‚‚‚‚‚‚€€~€€€€€€€€‚ƒ‚€€€€€€~}~~~~€ƒ„…††……„„……„„ƒƒ‚€~}}}}}}~|{{z{|~~~}}}~}|||||||zyyzy{||z{||}}}~€€‚‚€€€~}|||z{|}}~~~~~€~~€€€€€‚‚ƒƒ„„„„†……„…„„ƒ„ƒƒ‚ƒ€€€€€€€€€€€€€€€€}~}}|||~€‚‚‚„……†‡‡†‡†‡…„€€~~}~~~€~~}}~~~~~}}|||||{|{|}|z|}}~€~~~}}~~}}}}}|}}||}||}|{|}}}~~~}~~~~~~€€~~~~~~~~€€€€€€€€‚‚‚‚‚‚ƒ‚‚‚‚ƒ‚‚€€€€€€€€€€€ƒ€€€€~~~||||}~~€‚ƒ„„„„………„…„ƒ‚€€~}}|~|z}|||||}~~~~}~~zy~‚~z|}xvty}}yz€€|zz}~~~~€‚zz€‚}y{€z{~}|}}}|€}~€€~~€€~||€~}‚‚‚‚‚‚ƒ‚ƒ‚ƒƒ‚€€‚ƒ‚„ƒ‚‚‚ƒƒ‚€€€€€€€€€€€€€€€€€€€€€~}~€‚„…„…„„„…ƒ‚ƒ†…‚„ƒ€~€€€~€|{|}|}}}~~~|||~|z{}}zy|}{z|}}|||}}}||~~||~~}}}~}}~~|}~}}~~~~€~~~€~~€~}€‚€~~~€€‚‚€‚ƒ‚ƒƒƒƒƒ‚‚‚„‚€‚‚€€€€€€€€€€€€€€€€€€€€~~~~~€‚ƒƒ„„…„„„„…ƒ‚‚€€€~~~~~}}}}}nagios-2.6/html/media/warning.wav0000664000076500007650000002137207436604471016426 0ustar nagiosnagiosRIFFò"WAVEfmt ++dataÍ"†xŒŒ€€v‚‡zs}z‡ipƒ{‚—€~‚€fvwv|x~}†Œ‡w‹†„uj}}ou{‡Œ|€Œ‡‰vywwzƒxh||†‚}ˆ˜„ƒx‚†pn}|ut…†|~y’~Š„€it|uwt|…|„‡Œs‡‡{s~nqv‚Œ{ƒ”Ž…|xˆyqvx…€n}„}vˆ•„„„…‡sjxx|suŽ‹~Œ‡v€‡†„pwƒtoq|ŽŽŽsƒ‚wut„‡qw~€‚v“ŒŠ€Œ{isv~xq†Œ„‚z…Ž|}ƒ‰‹up€vsos‰‰€‰ˆ“‡tz…{{p‡xswy†yyŒ‘…{‹poq{q}‡‡†v}Ž„~ƒ…‘|rvwusiƒ‹†…†Ž‘vz}‚xs‰{ynt‚uˆŽ•Œ}ƒ…vsjwƒyv‚„Šxwˆˆ†ƒ‚Ž‹rtoztkvŒ‡‹€ˆ‚v||‹{v~„vtg€Œ™}vko„y{€‡€q€…Œ‰€‹~rop|ktŒ‹ˆ|†w|‡‰v}}~skm„{‡€’–Žyy~pm|„~|v„vw‚‹’ƒ‡Ž†xmkwvo|“‡‹~€u‡‹ƒz|x}jjvƒƒ‡„›†x|z~kz†~uxƒyv{†“…Œ‡‚rgrxtv~Š|€€†||‘‡…wzzrdry‡††—†‚r~xs‚ƒ†ts{yxx“”‰Š‡†xhnxwzz†„z~~ˆ{‰“†€r|qkjvƒŒƒ‹Žww„{|{„…|ntvyx{Ž–‰‡„klrz}{~‹„|v{ƒ…~ŒŽ‘‚wrvkll‹‰†‹‡xu~‚€€‡€rmqvzx†”•†ƒukpw~{ƒ†}vt†…ˆ‘Žzrqpklu‰‹ˆˆˆ‡tzƒ‡„€„„vljpxz€—•Š|pot€ƒ}~~xqw„ˆ‹Ž’“„tponnp€‹‹†„„ƒyx€ˆŠ…‚„|pgis{~‰“˜ƒ}wrt|†‚}{|wqp}ˆŽ’“{plooqxˆŠ‰€€€~x‡†‚~sidmx„”•‡~|zxv{„ˆzvvqnu…Ž“’“ƒsmlsrx€‹†ƒy}||}‡”‹„~vkdft|„‹’“{{{{{„‰…zupqlq~Œ”–’’ˆznmpwv„ˆ{u|z~„–“ˆwofclz‰Œ‘Žƒzz|ƒŒˆ€tmklkx…“˜•‘~umpv{|„ƒ„xrsy|…Œ—™†{pkcgt‡Š‹…{zz‚…‡‹Ž„{liijq‹˜–’„ztox|‚‚{oorx„Š”œ–Œ€soggpy„‰†ˆ„|yyŠŠ‰€rfgemxƒ’—“‡zrx€†‚~zojlr‰‘›”ˆxqlgnt~†ƒ‚yzw|Š“•Œ†wgdcht|‹”‘‡xz‚„‰„|xnghjy†›œ—‘vrlptyƒ€~|vwx{‰‘–šŠ~mfbdpv‚މƒ€††‹ˆ|xnfgfr‚Š—›—•‡|wpsvv}zyrtyz‡–œ”…skdalr{‡‡ŒŠƒ‚‚‰ˆ‹Œ€yodgek|…’˜•–Œ‚vwyuzzvwppxxƒŽ’œ˜Šzqkbipt€†Š‚„…ƒŒŒŒ…}sefdft|‹–“–’‡†|y~xyzsvpksv€Œ›œ”‚xsggmoz|}†ƒƒ‡„Ž‘‰yhfecnv‘‘“”ŒŒ„|‚}{zqsphor{ŠŒ–ž—–‰}zmhljtxv€ƒ‡„Ž““Œ…€nfeajpw‹’–Ž‹€ƒ||pqqhlmt…ˆ’œ™šskkgqvr|}€‡ƒ‹”‘–‡‡thf_gkoƒ‹–’„…~€spqhkim€…Žš™ž–‡‚znnclvpxy|‡ƒ†’’˜”‹Œ}nh^cjiy„Œ—”‰ˆƒ€„zqqijidv‰——ž Œ‰|upifsotxu‚ƒŽ‘™œ†vm_^ggp~†•‘”Œˆ€†„wtjgj`kxƒ“—š¤˜Œƒtvnfopsvpx~ŠŽ›©›ŽƒyvgRWYf}~ŽŽ•¥©”—“”‰nRP[D=LZv˜›¦¸Íʲ§“~‰‰lZH=AFV_†¼À¹ØÙÀ›[+(;@Tt‚¯Ç·£Ž{m\WCIm„‰©»ÇȬ…_TQ7C^o¯¨¡Œ|rqpt©°¢‘zpPD1Njlx›ž®¼·©¢¡~xUAJZCQa‰˜§ œš³Ž…†‹‚Œ{qZcbZfqqš´ª˜™–“vuZk€€d|wƒ}Š„‹¢„‹{hg}ninŸ››‹|“€fcwx‚v|`qxyt“†¬±‘‚€_^QRt‡ssƒ’”‘›‘‘¦ŽyreRa^`U}˜—›„˜ Šx€„neWIdbav’œ¶»´‹†l]^YkŠmj€…v‡Œ¦²”x`c[UP„‚†…ˆ†¤˜Œ}˜ †tnYbk_d~š˜£‡t|€bof{ˆš~tyš~~‚‡Ž¡†tjnbXekf‹¡˜••Žš—n|\`LYcje‚ ·§±§‡†ˆndcgpws\\ƒ„x†—£·§’z„za\l]qƒ€wx~†Œ–‡¥¢~ogfnmhmŒ¨”Ž’~u}qkk|ƒ…Šzg†”€~ˆ—”}egy`Wlt’–ˆ’–Ž–x‰“sWMT\ckoйµŸ¥œ‡~pelvgiiTcƒ„Ф³¬Ÿ…t‰~^`krsvrjq‡ƒ‹ž“–©}cgmgjkl”£‰~ƒ„~xzsyއy…tq€„~‡Ÿ‡s]j~g`n‡ŒŠ‰…~—”ˆ“•‡Š…sNKY``ur—´µ–˜›ž‚~rituZ\__f}‹Š¯¯¢˜x‹h[qyoah\x…†Š£¥¦ž›|dnodkjr•€p{z}{‡•~vw€x~†Šy‚wkcr~ukx™€|„–Œ„Œ—|whQTc_lu†š¯©“¦€|nrrgNS_qi€“ž®¡™Ž„ƒ†j`ww_XYd~„ˆ¬³¦’˜vunm`kixz‰vnƒ•„€Š‘Ž{pxŽ~yƒ‡~‰zvfpky|‡pŽ—’y|zŽ‹‹}ˆšpof__cdp|‘“¤£—‘©•‡otmnXQIous{”š¥ œŽ„€ƒpgsp\RUlv……‘ªÀ¢˜ŽŒ|sdc`olmywt†“…„“Œ|q~‘ƒw{ƒ„wpghqws…‹ˆ˜~x€‡ƒ„v…”Šniipcdgr†“›£œœ—‚ppj`XMTs{{~˜¦¦—–‹•z€vpiiZR\ktƒ‡–±¹§–“—‚na]bk_do|~‡“‰’“ˆ~w‡Œ‚sw„}kc_jvswˆ—œ–˜’ƒ~€{{vu‰€mgvtifl|Ž—£¥™”~rl_YRP_s€€‡¢¬¢–Ž”‡zv~~oec\Y_frŒ ¯¸ª››™l[\b`X[k€„—˜™“މ‚€‚‡tx€vf[\lqtx¤¨œš•Œ‚wqqptw}}pnwyplq†Œ”¤§—ŠƒvdYRQT^n‚Š”¦®¦•ŒŽwrrc`__Z`n€’Ÿ¬µ±¤Ÿ–†l][]WQSg~„‡‘¡¦ž’އ„~}|yyqbT[dns€–°°¦š˜‘niknnmsvuuy|x‹Ž‹†œŸ“Œˆˆs^POQW_tŠœ¥«­£…ƒ€xqu€~rccge\etŒ•Ÿ¦¯¬¦˜“„p_ZTNHSi~Š“Ÿ°®žŒ‡ƒ}vz~†zpl]VWep|Œ¥²´¦›–xgchgcckt}|ƒŠŽ‡ˆ‰Š€†“—–ŒŒ†rVKMSXf|—«¯«©ŸŒzxwspwy|sifmlgh|‹”–Ÿ¤«¤›“ybSLCCNe}”¡¬¶µŸˆ|tsv€††wlgbWWdt”¤°³«œ”Ž~hab^WXaq€‡Œ˜ —Їyv}‰”˜“Š„rWHNU]m…ž°³ª¡œŠwquspqsssmjqxss€ŒŽŽ“𢥕’cNFAAOf€š¬°µ³Ÿ…{yurx~qccc\\m€Œ™¦«¬¨™€k^[UMQ_p†”™¤¬Ÿ‹|spy„—ŽylWLS`i{’¡¯° —’†tovslmmnttq{„{‚‰††’¤Ÿ•Ž~`HDDFWp‡¢°®®ª›w{wv{{yxlaagffw‰™£¥§¤—Š‚iWTOJSbvŸ£§« ‡|ypozŒ‡xol\R_nw‡— ¨¨œŠ„tntohjkpw||‰|~…‚‡Žš£ †y_HIKQcy¡®«£¢—v}{yxurpmbanqn~Œ™Ÿ¢  ™‹‡€eQPMNWi~•¨¨¤§Ÿ…zvpqy‚„€pjnc]l{…˜ž ¢–ƒƒ„tmnkgipr{‡‡‡‹{||ƒŽ” …|t`OPV`n…œ§¦˜š‘~y~€vtrnmpcfu{x€Œ“–žž—ž—‡‚x`OMTQ`t‰™«©Ÿ¥™‡uutsy}wy{jkmnjz‡˜™—Žx}ughkhlwv‚ŽŠˆvxz‘ŒžƒswcZUhjzˆ”£œ“ŽŒ{qtpnksepvˆx„‹—Ÿ“•—˜„yocOSXXe€Š¥§š —‰m{rwszhxrsftw{“Œ‘˜—ƒ|vsgdrfvs‚š…|zyyo…†‹}yts\cpv|‡ˆŽ™˜‚„‚qttmmnso†~‘““–ƒrnhUY\^n‚‘”¡£˜š‚szxtppkpvsgx„ƒ‰—‘Š€…yw~qeirmsxƒ‰™˜‡‰Ž€vwpt}І„Šƒx{tdnv{y‡‰’”‚€ˆ‚{stungtzvƒ„ŽŠˆ’–~qrl\Z]fq†ŽŸ¤›–’w{|qjplnvqm€‹Šˆ‘Ž}~‡}zyphmsnm~ˆ‹›•‰‹Ž€qnqs}‰‚Œ‡|zups||s‡…Œ„ƒz}uqukgx€|ƒƒŠ‹~„‘“’ƒvvp`Uajq…Š‹š¥œ‘Œ†|~~lgqnlsrtŒƒ‹‰‹‡z‰‡{vvmjqijŒŽ••Ž‹Œƒkluu~„~€ŒŠ~u{xu~xq|†ƒ„†‡‡’”€y~woqjn{†‚z„„„‚y„“–‘މ{uq^Uels~†Œ˜£›‹‹Ž‚zjhopimx}„’ˆ‹Ž†ƒ€…wvwlhigm„‘˜“ŠŠzjpzy{}Љxw~xzrs{†|‰Ž”zz{sijqu‚Šz‡‚}|{}Šš—ŒŒŒytiZ\iqqzˆ—¢”Š“’†|sihnncp„‰Œ„Љ‚{†ŠŒ”ˆwvvhaajs‡“Œ›•Š„upuys|‚€…„v|ƒvsut|…~’—•†zvwock||†‡|„‚wu}†Œœ”Š‹|nd_`kslw‹’–œ•’—–‡srkfkkes†‡†ƒ„€†‰~}”“‘„ysqdY`pv†Š’š˜‰|xz€vn|€~|€…ppyw|ƒ‚‡—“†€xpribq„ƒ„€‚‚su…Œ—Š‹‡xfeedmojzŽ•–—›™™”~mpkdghnz‰‡}„€…‡ˆ˜’‡‚wnj\Vgt{„Œ•œ—†„~}zooz{w‚‚„xmu}}…“œš‡|{pjiejz‡‡~ƒ†ƒ|s~‰†ndjigjlq”˜“š¡œ—ˆrknjbcpx€‡€y…‚„†Š’žœ‰sibW\my{–˜œ”‡‰ˆ€wqoox~vu‚„}spyƒ‚€Œ˜˜š~wvmdcjr}Š„‡Š†|zƒ„…Œ‡ylhmmgfpy…–™•£œ~qjlkadu~€‚||‚‡„‚Š“•œ–…~{rd\Z`mzy|››”Ž‹omposxsx‚…}wuxІ…“š„xspi_cqx€‡„„ŒŽˆ€€‚†ˆ|‚‰„{qmmpofhz„Œ–˜šŸ “voikhaj{‚~{|‡Š„ƒ’˜—”Œ‚{wl^[`fqyyƒ– ž—”’Žˆvimqooquz‚xw}€†‹Œ—ž•„{uolc\gw}€ƒ‰Œ‘‡…†……~y~„€snpqsohqƒ“™œ˜ˆxsnhgfgp~ƒ|{‚‡‹Š„‡•𓉅ysg\_fjpx‹™¢œ•–“‚pglqnhnw}€~x}†ˆŠ’—˜Œ{vrlg_^k{„”•‡…‰‡€{yyz~xoptvupq{Œ’šœ—|trngchov€‚~ˆŒŒˆ‡‹”–‰€wlb_fmnq{ˆ‘›ž˜––‘†xmilpieo{€~{}†ŠŽ••“€vrmf`_fr€‚‹—š”Œ‡‰Šƒwswwvtqpuyywx}†‘‘‘˜˜trqlccnw|€‚ƒ‰Œ‰‡‰ŒŒ€{||shcgosqt‚”————•Œtnjkjfgs~~~„Ž‘‡–”‹‚{upjb`fmwƒ‡››“Œ‹Œˆ}pnstolovz~||†ŠŒ”‘…xrppibgs€€„‹‹†ˆ‹Š‡‚{wywohipwxuy‡’“‘’–—’…ysokgfgnx€ƒ€„‹‘‘‹‰•Ž‚zvtnf`ent{€‡Œ•™—‘ŒŠƒukkppiks€ƒ‚…‰Œ‹Š‹ŒŽ†{soolggp}„ƒƒ‰‘“Œ††Š‰„|zwvvrppuy}{z€‹‘ŽŒ–”Š|urogdgnw}‚ƒ†‰Ž‰‰Ž†yuuskdenwy{‹‘–•”’Œ„zmhhljio|‡ˆ„„‹‡‡ŠŒ‰ƒ|vronkknx‚†…†Ž“’ˆ…†Šƒyssvtsqvz~~~ƒ‰‹‰‹Ž”ƒvssogemv†‹ŽŒŠ‰ˆ‹…~ustsmhlv}z{Œ“”‘“”‘‰}ukgghimv‹Šˆ‡ŽŒ„„ˆŠ„zvstnklqv}ƒ…ˆ‰’‘‰…††|qmnttst~„†€€€ƒ„†‡ŠŒŽˆurtojir|‚€‚‡‰‰ˆ‰‡„}yttussot{~yz‚Œ’‘–ƒwpjgfflt~†‹Œ‹ŠŽ‡ƒƒ‡…~urtvolqw}‚…БЄƒ~sjjotuw|‡Ž‡€‚‚€ƒ‡ŠŠ…‚|utspmpz€‚‚ƒŠŒ†…‡‡zwvwwuvxwz||y{„Œ’•‹{qnlgfiq|„†ŠŽ‹…ƒƒ~xsqwwppv~†Œ‘Œ‰ƒ|wpklquy}Ї€ƒ‚~}€„ˆ„~|xttssv~€‚„…‹‹„‚…ƒ{vtw{{wz~~{yzy}„‰Œ†yoonihnv††ˆŽŒ‰‡…~xwsuwxtrx€~}‡’‹Œ‰€tpkhmqv}„ˆŽˆ€„€||„†€{|~{tuvw{ƒ†ˆŠ‹‰€}utuz~|}ƒ€ywyz~ƒ†ŒŒ‰‚woqojmr|ƒ‡…ˆ‰…†‚}ywxxwwywu|~}~„Бމ‰‡yplllpsy‚‰ŒŠŒˆ‚‚}{{‚z|€|twz|~~ƒŠ‰‡‡‡||xtty}€…€wvx|~‚…ŠŽˆ„€xrqpnpv~‚††‡ŽŽ†‚ƒ‚zywz}xwzzwz|~†ŒŽˆ‡„wnloopv|„Œ‹ˆ‹ˆƒ€}z|~~{}€|vw|~}„‹‰„„„zxwvw}~‚„ƒwvy}|…ˆŽ…‚€ztprqsz}†‡‡‹Š…€‚}{zy}~xwz|xx|~€‡‹‹Œ‡ƒ€wnmqpry}†Œ‰‡ˆˆƒ|~}{~~|||~|wx~~‚†‰‡‚ƒ~wwxw{ƒ…„€€xv{|}‚…ˆŒŠ„€€|srttx|}†‡††ˆ„‚}|{|}}zwz}xw}ƒ‡‰‹Œ‡€~woprqu{€†‰‰…†ˆ‚|~~}~~}~€}z|~y{~€‚„…‡‡‚€ƒ~wwyy|~€‚……~~xvz|~‚†ˆˆ‰„}|tsvwy{~„‡ƒƒ‡…€‚€~|}|{}{wy|xw|€ƒ†‰ŠŒ†~}xqprtv|ƒ‡‰„„‡ƒ~~€~~}||x{~{{}€€„ƒ…‡ƒ€~xwxzz~…„~}~zxz~€ƒ‡‡†ˆ‚|}{wtwyy|~~ƒ†ƒƒ‡†‚€|}{z~|xz{yx|ƒ‡‹ŠŒŒ„~{xrpsvx~€††ƒƒ…„€€‚~~{z}{x{~|z~€ƒ„ƒ‡‡ƒ€~wvyy{€€„‚~|~|y~‚„†„„„€{{|xvzzy}~~ƒ†…„‡‡€|||z{}|xx{{x}‚„‰‹ŠŠˆƒ|yxsrvwx}~€„†„ƒ‡‡ƒ‚‚}|yy{|yz~|{€€ƒ…†‡ˆ…~~xvxy{€€€ƒ||€ƒ‚ƒ„‚{z~zwyyz|~~‡‡…‡‡|zz{{|}yx||z~‚†ˆ‹‰‡‡„{xxutvwxz~††„‰‰„‚~{zywz}zz}||~€ƒ‡ˆ‡ˆ„~}|wuwy{}~ƒ€~‚‚ƒ‚€‚}~~z|~{xx{{|€„Šˆ…†„€||zx{|z{|yz}~}€†‡ˆ‰‡„…zxxwvvww{‚‡‡ˆŠ‰ƒ|xxww{|yz|~}~‚‚†Šˆ†‡ƒ~|zvtxyy|}}„‚„†„‚‚~€}{}}|||{wz||~‚„‡‹ˆ„ƒƒ~yzxx{|y{}||~€€ƒ‡‡††„ƒ‚zxzxuuvw|€€„‰Œ‹‰ˆ‚~~zwwxx{|zy}€~ƒ„ˆŠˆ…„ƒzyvtwxwy}‚……„‡‰…€~}}|y{~{{zx{}}€„‡ˆ‰‡ƒ€|wwwx{|z{€‚‚„‡„ƒƒƒ‚€zyzyttvx|€ƒ…‹Ž‹‡†€}|xuvyzz|{z€€„‡ˆ‰‡„ƒƒ}xwuuvwvy~ƒƒ‡ˆ‡‰ˆƒ~~|{zzy{}zz{{}€‚‡Šˆ‡…‚~xuuxxy|{~ƒƒ€‚ƒ„„ƒ‚‚‚€}}{zzwtuy|ƒ†‡ˆ„‚{yvuw{zz{|~€…ˆ‡‡…ƒƒ|vvuutvw{‚…†ˆ‹ŠŠ†|||yxxy{~|zz}~„‰‹‡…ƒ}{vsuxxy|~‚…†ƒƒ……ƒ€€~€€~|||{ywvw|~€ƒ‡ŠŒ‹†‚€~ywuux|{{}€€‚†‡………ƒ‚zuvvtsvx~„‡‡‰Œ‹ˆ„{{zwvx{|}|{|€€€‚„‡Š‰…ƒ‚zvsrvxyz~ƒ†‡†„„…ƒ}}}~|z|}{yxx{€…‰‹Š‡‚~{vtvxz||}€ƒ‚€€„†…ƒƒ„ƒ€|xvwvttx}‚†‡ˆ‹Œ‰„€|zzxuvz||||}€€€ƒ‡ˆˆ‡ƒ€|vsstwyz|ƒ‡ˆ‡†††„€|{|||{z{~~{yz|~‚‡‹Š‡ƒ€~|xttx{|~~€ƒ„€‚„„ƒƒ}yxwwvtv{€ƒ„‡‰‹Œ‡‚~|yxvtw{~||}€‚€€…ˆˆ†„‚~ytrsuwy|…ˆˆ‡†‡†ƒ~zz|{yy{}~|{}€‚„‡Š‡ƒ€~|yvsvz}}~€ƒ„ƒ€‚ƒƒ‚€€‚{yyyywvy~‚ƒ…‡‹‹ˆƒ}{xvuvy}~}}€‚ƒ‡‰‡ƒ‚~{ustwwy{ƒ‡‰‡‡‡‡ƒzxzzxwy}}|~€€€„†‡‡ƒ}|yvtvz~~€ƒ…ƒ€ƒ‚€~€€~|z{{{ywy}ƒƒ…‰‹‰„}|zvuwz|~}~‚‚…‡‡ƒ|wttwxxy}‚†‡‡‡‡‡…‚|yxyywx{€}~‚€‚…‡†ƒ€~|zxvvx|€‚…†„€‚ƒ€}|~~}{|}}|zy{~‚‚…ˆ‰†~}|yvuy|~}}~ƒ…†„€~{wuwyzyz~ƒ†††‡‰‡„{yxxwwy}€€~€ƒƒ€ƒ††ƒ}}{xwwy|~ƒ……ƒ‚}z{~~}{|€~{{|~€€ƒ†‡†‚~}}|xvy|~~|}€‚‚€ƒ……ƒ€~|yxxz|zy|‚…†…†ˆˆ…€|{yxwwy|~€€‚ƒƒ€‚„…ƒ~|||zwwz|~~€ƒ„…ƒ‚‚~zz{}}||}|}„…„‚€~}|{yy|~}|~‚ƒ‚„„‚€~}{zz{{|zz~‚„„„†‡‡ƒ}{{zxww{~~‚ƒ„ƒ‚ƒ„ƒ€|{||zwx|~~~~„„ƒ‚ƒƒ|zz{|||}€‚‚~|€~ƒƒ~~}|{z{}~}|}‚ƒ€€‚„ƒ}~}z|}||{{|ƒƒ„††…|||{xwy|~~}ƒ„ƒƒ‚ƒƒ‚€}||||zy{~~}€ƒ…„‚‚„ƒ€|{zz{{{}€€‚~}‚~}€€~||}~~~|~€€‚€€‚ƒ€|}~|{~}{{|~€ƒ…†„ƒ}}}{wx{}~}}„„‚ƒƒ€}|}||{{{|~~|}€ƒ„ƒƒ„ƒ~{{{{{z|€€€€~}€}~€€~{|~~}||€~|}~|}€~z{~€ƒ…„ƒ€}|zxz|}}}~‚„„€ƒƒ€~|}~~|{}}}~}|~‚ƒ‚‚ƒ„ƒ}{||{zz|€€‚€€~~€€~~€}|~~||}€€‚€~}|~~~}~€€}z|~~}~€ƒ„ƒ€€‚}{zz{|||~€‚„ƒ€ƒ‚|}~~{|~}||}ƒƒƒƒ|{||zy{~€€€ƒƒ€~~~~€€€}|~}{|~€‚€€‚ƒ~}~~~~}~€€€€}||~}|~ƒ„ƒ€‚€|z{{{||}€‚ƒ‚‚~}~~~|}|{|~~€€„„ƒ‚€~|||yy|~€€ƒƒ€~~€~~€~}~~|{}€€€‚„}|~~~}|~~}|~||ƒƒ‚‚€{z|||{{}€‚‚€}~~~~~}~{z|~€‚……ƒ€~|{zy{}~€€€€‚‚~€€€~~€}~}}|}~€€‚‚ƒƒ|}}}||~€€}~~||}|~€‚‚‚‚€~z{||{{|€ƒ‚€~~~~~~~~}zz}~~„……€€~{zzz|}~~€€€€€ÿnagios-2.6/html/ssi/0000775000076500007650000000000010532717606013750 5ustar nagiosnagiosnagios-2.6/html/ssi/README0000664000076500007650000000234510520313106014614 0ustar nagiosnagios========================== NAGIOS CGI SSI FILE README ========================== This folder may contain optional header and footer files that will be added to the CGI HTML output. The files you put can contain server side include (SSI) statements. There are two types of header and footer files - common headers/footers and CGI-specific headers/footers. Common header/footer files (if present) will be included in the output of ALL CGIs. CGI-specific header/footer files (if present) will be included in the output of the CGI they are intended for. The order in which headers/footers are included with regards to the CGI output and each other is shown below: 1. COMMON HEADER 2. CGI-SPECIFIC HEADER 3. CGI OUTPUT 4. CGI-SPECIFIC FOOTER 5. COMMON FOOTER The header/footer files you create must be named exactly as shown below in order to be included in the CGI output: Common headers/footers: common-header.ssi common-footer.ssi CGI-specific header/footers: -header.ssi -footer.ssi Some examples of CGI-specific header/footer file names are shown below: tac-header.ssi tac-footer.ssi status-header.ssi status-footer.ssi avail-header.ssi avail-footer.ssi notifications-header.ssi notifications-footer.ssi nagios-2.6/html/stylesheets/0000775000076500007650000000000010532717607015527 5ustar nagiosnagiosnagios-2.6/html/stylesheets/avail.css0000664000076500007650000001164710141063404017327 0ustar nagiosnagios .avail { font-family: arial,serif; background-color: white; color: black; font-size: 10pt; } .errorMessage { font-family: arial,serif; text-align: center; color: red; font-weight: bold; font-size: 12pt; } .errorDescription { font-family: arial,serif; text-align: center; font-weight: bold; font-size: 12pt; } .warningMessage { font-family: arial,serif; text-align: center; color: red; font-weight: bold; font-size: 10pt; } .infoBox { font-family: arial,serif; font-size: 8pt; background-color: #C4C2C2; padding: 2; } .infoBoxTitle { font-family: arial,serif; font-size: 10pt; font-weight: bold; } .infoBoxBadProcStatus { font-family: arial,serif; color: red; } A.homepageURL: Hover { font-family: arial,serif; color: red; } .linkBox { font-family: arial,serif; font-size: 8pt; background-color: #DBDBDB; padding: 1; } .reportRange { font-family: arial,serif; text-align: center; font-weight: bold; font-size: 10pt; } .reportDuration { font-family: arial,serif; text-align: center; font-size: 8pt; } .reportTime { font-family: arial,serif; text-align: center; font-size: 8pt; } .dataTitle { font-family: arial,serif; text-align: center; font-weight: bold; font-size: 12pt; } TABLE.data { font-family: arial,serif; font-size: 10pt; background-color: white; padding: 2; } TH.data { font-family: arial,serif; font-size: 10pt; background-color: white; text-align: left; background-color: #999797; color: #DCE5C1; } .dataOdd { font-family: arial,serif; font-size: 10pt; background-color: #DBDBDB; } .dataEven { font-family: arial,serif; font-size: 10pt; background-color: #C4C2C2; } .optionBoxTitle { font-family: arial,serif; text-align: center; font-weight: bold; font-size: 10pt; } .optionBox { font-family: arial,serif; font-size: 10pt; background-color: #EEEEF4; padding: 2; } .hostUP { font-family: arial,serif; font-size: 10pt; text-align: left; background-color: #33FF00; font-weight: bold; } .hostDOWN { font-family: arial,serif; font-size: 10pt; text-align: left; background-color: #F83838; font-weight: bold; } .hostUNREACHABLE { font-family: arial,serif; font-size: 10pt; text-align: left; background-color: #F83838; font-weight: bold; } .serviceOK { font-family: arial,serif; font-size: 10pt; text-align: left; background-color: #33FF00; font-weight: bold; } .serviceWARNING { font-family: arial,serif; font-size: 10pt; text-align: left; background-color: #FFFF00; font-weight: bold; } .serviceUNKNOWN { font-family: arial,serif; font-size: 10pt; text-align: left; background-color: #FF9900; font-weight: bold; } .serviceCRITICAL { font-family: arial,serif; font-size: 10pt; text-align: left; background-color: #F83838; font-weight: bold; } .optBox { font-family: arial narrow,serif; font-size: 10pt; font-weight: bold; } .optBoxItem { font-family: arial,serif; font-size: 8pt; font-weight: bold; color: red; } .helpfulHint { font-family: arial,serif; text-align: left; font-size: 8pt; font-style: italic; text-align: center; } .dateSelectTitle { font-family: arial,serif; text-align: center; font-weight: bold; font-size: 12pt; } .dateSelectSubTitle { font-family: arial,serif; text-align: left; font-weight: bold; font-size: 10pt; } .dateSelectItem { font-family: arial,serif; text-align: left; font-size: 8pt; } .reportSelectTip { font-family: arial,serif; text-align: left; font-size: 8pt; font-style: italic; } .reportSelectTitle { font-family: arial,serif; text-align: center; font-weight: bold; font-size: 12pt; } .reportSelectSubTitle { font-family: arial,serif; text-align: right; font-size: 10pt; } .reportSelectItem { font-family: arial,serif; text-align: left; font-size: 8pt; } TABLE.logEntries { font-family: arial,serif; font-size: 8pt; background-color: white; padding: 3; } TH.logEntries { font-family: arial,serif; font-size: 10pt; background-color: white; text-align: left; background-color: #999797; color: #DCE5C1; } .logEntriesEven { font-family: arial,serif; font-size: 8pt; background-color: white; text-align: left; background-color: #C4C2C2; color: black; } .logEntriesOdd { font-family: arial,serif; font-size: 8pt; background-color: white; text-align: left; background-color: #DBDBDB; color: black; } .logEntriesINDETERMINATE { font-family: arial,serif; font-size: 8pt; background-color: #ACACAC; } .logEntriesOK { font-family: arial,serif; font-size: 8pt; background-color: #33FF00; } .logEntriesUNKNOWN { font-family: arial,serif; font-size: 8pt; background-color: #FF9900; } .logEntriesWARNING { font-family: arial,serif; font-size: 8pt; background-color: #FFFF00; } .logEntriesCRITICAL { font-family: arial,serif; font-size: 8pt; background-color: #F83838; } .logEntriesUP { font-family: arial,serif; font-size: 8pt; background-color: #33FF00; } .logEntriesDOWN { font-family: arial,serif; font-size: 8pt; background-color: #F83838; } .logEntriesUNREACHABLE { font-family: arial,serif; font-size: 8pt; background-color: #F83838; } nagios-2.6/html/stylesheets/checksanity.css0000664000076500007650000000455610141063404020541 0ustar nagiosnagios .extinfo { font-family: arial,serif; background-color: white; color: black; font-size: 10pt; } .errorMessage { font-family: arial,serif; text-align: center; color: red; font-weight: bold; font-size: 12pt; } .errorDescription { font-family: arial,serif; text-align: center; font-weight: bold; font-size: 12pt; } .warningMessage { font-family: arial,serif; text-align: center; color: red; font-weight: bold; font-size: 10pt; align: center; } .infoMessage { font-family: arial,serif; text-align: center; font-weight: bold; font-size: 10pt; align: center; } .infoBox { font-family: arial,serif; font-size: 8pt; background-color: #C4C2C2; padding: 2; } .infoBoxTitle { font-family: arial,serif; font-size: 10pt; font-weight: bold; } .infoBoxBadProcStatus { font-family: arial,serif; color: red; } A.homepageURL: Hover { font-family: arial,serif; color: red; } .linkBox { font-family: arial,serif; font-size: 8pt; background-color: #DBDBDB; padding: 1; } .Title { font-family: arial,serif; font-size: large; text-align: center; font-weight: bold; } .SectionTitle { font-family: arial,serif; font-size: 12pt; text-align: center; font-weight: bold; } .optBox { font-family: arial narrow,serif; font-size: 10pt; font-weight: bold; } .optBoxItem { font-family: arial,serif; font-size: 8pt; font-weight: bold; color: red; } .DynamicData { font-family: arial,serif; font-size: 10pt; background-color: white; padding: 2; } .StaticData { font-family: arial,serif; font-size: 10pt; background-color: white; padding: 2; } .TableHeader { font-family: arial,serif; font-size: 10pt; background-color: #999797; color: #DCE5C1; text-align: left; font-weight: bold; } .Item { font-family: arial,serif; font-size: 10pt; text-align: left; background-color: #C4C2C2; font-weight: bold; } .DataSource { font-family: arial,serif; font-size: 10pt; text-align: left; background-color: #C4C2C2; } .Number { font-family: arial,serif; font-size: 10pt; text-align: left; background-color: #C4C2C2; } .Value { font-family: arial,serif; font-size: 10pt; text-align: left; background-color: #C4C2C2; font-weight: bold; } .ValueOk { font-family: arial,serif; font-size: 10pt; text-align: left; background-color: #33FF00; font-weight: bold; } .ValueError { font-family: arial,serif; font-size: 10pt; text-align: left; background-color: #F83838; font-weight: bold; } nagios-2.6/html/stylesheets/cmd.css0000664000076500007650000000314610141063404016771 0ustar nagiosnagios .cmd { font-family: arial,serif; background-color: white; color: black; font-size: 10pt; } .errorMessage { font-family: arial,serif; text-align: center; color: red; font-weight: bold; font-size: 12pt; } .errorDescription { font-family: arial,serif; text-align: center; font-weight: bold; font-size: 12pt; } .warningMessage { font-family: arial,serif; text-align: center; color: red; font-weight: bold; font-size: 10pt; } .infoMessage { font-family: arial,serif; text-align: center; font-weight: bold; font-size: 10pt; } .infoBox { font-family: arial,serif; font-size: 8pt; background-color: #C4C2C2; padding: 2; } .infoBoxTitle { font-family: arial,serif; font-size: 10pt; font-weight: bold; } .infoBoxBadProcStatus { color: red; } A.homepageURL: Hover { font-family: arial,serif; color: red; } .cmdType { font-family: arial,serif; font-size: 10pt; font-weight: bold; text-align: center; color: red; } .commandDescription { font-family: arial,serif; font-size: 8pt; text-align: center; background-color: #DBDBDB; padding: 5; } .descriptionTitle { font-family: arial,serif; font-size: 10pt; text-align: center; font-weight: bold; } .optBox { font-family: arial,serif; font-size: 8pt; text-align: left; padding: 5; background-color: #C4C2C2; padding: 5; } .optBoxTitle { font-family: arial,serif; font-size: 10pt; text-align: center; font-weight: bold; } .optBoxItem { font-family: arial,serif; font-size: 10pt; text-align: left; background-color: #C4C2C2; } .optBoxRequiredItem { font-family: arial,serif; font-size: 10pt; text-align: left; color: red; background-color: #C4C2C2; } nagios-2.6/html/stylesheets/common.css0000664000076500007650000000000010141063404017500 0ustar nagiosnagiosnagios-2.6/html/stylesheets/config.css0000664000076500007650000000301310141063404017464 0ustar nagiosnagios .config { font-family: arial,serif; background-color: white; color: black; } .errorMessage { font-family: arial,serif; text-align: center; color: red; font-weight: bold; font-size: 12pt; } .errorDescription { font-family: arial,serif; text-align: center; font-weight: bold; font-size: 12pt; } .warningMessage { font-family: arial,serif; text-align: center; color: red; font-weight: bold; font-size: 10pt; } .infoBox { font-family: arial,serif; font-size: 8pt; background-color: #C4C2C2; padding: 2; } .infoBoxTitle { font-family: arial,serif; font-size: 10pt; font-weight: bold; } .infoBoxBadProcStatus { font-family: arial,serif; color: red; } A.homepageURL: Hover { font-family: arial,serif; color: red; } .dataTitle { font-family: arial,serif; text-align: center; font-weight: bold; font-size: 12pt; } TABLE.data { font-family: arial,serif; font-size: 8pt; background-color: white; padding: 2; } TH.data { font-family: arial,serif; font-size: 8pt; background-color: white; text-align: left; background-color: #999797; color: #DCE5C1; } .dataOdd { font-family: arial,serif; font-size: 8pt; background-color: #DBDBDB; } .dataEven { font-family: arial,serif; font-size: 8pt; background-color: #C4C2C2; } .reportSelectTitle { font-family: arial,serif; text-align: center; font-weight: bold; font-size: 12pt; } .reportSelectSubTitle { font-family: arial,serif; text-align: left; font-weight: bold; font-size: 10pt; } .reportSelectItem { font-family: arial,serif; text-align: left; font-size: 8pt; } nagios-2.6/html/stylesheets/extinfo.css0000664000076500007650000001743610141063404017711 0ustar nagiosnagios .extinfo { font-family: arial,serif; background-color: white; color: black; font-size: 10pt; } .errorMessage { font-family: arial,serif; text-align: center; color: red; font-weight: bold; font-size: 12pt; } .errorDescription { font-family: arial,serif; text-align: center; font-weight: bold; font-size: 12pt; } .warningMessage { font-family: arial,serif; text-align: center; color: red; font-weight: bold; font-size: 10pt; } .infoBox { font-family: arial,serif; font-size: 8pt; background-color: #C4C2C2; padding: 2; } .infoBoxTitle { font-family: arial,serif; font-size: 10pt; font-weight: bold; } .infoBoxBadProcStatus { font-family: arial,serif; color: red; } A.homepageURL: Hover { font-family: arial,serif; color: red; } .linkBox { font-family: arial,serif; font-size: 8pt; background-color: #DBDBDB; padding: 1; } DIV.dataTitle { font-family: arial,serif; text-align: center; font-weight: bold; font-size: 12pt; } DIV.data { font-family: arial,serif; text-align: center; font-size: 12pt; } DIV.perfTypeTitle { font-family: arial,serif; text-align: right; font-weight: bold; font-size: 10pt; } TABLE.data { font-family: arial,serif; font-size: 10pt; background-color: white; padding: 2; } TH.data { font-family: arial,serif; font-size: 10pt; background-color: white; text-align: left; background-color: #999797; color: #DCE5C1; } .dataOdd { font-family: arial,serif; font-size: 10pt; background-color: #DBDBDB; } .dataEven { font-family: arial,serif; font-size: 10pt; background-color: #C4C2C2; } .optionBoxTitle { font-family: arial,serif; text-align: center; font-weight: bold; font-size: 10pt; } .optionBox { font-family: arial,serif; font-size: 10pt; background-color: #DBDBDB; padding: 2; } .commandTitle { font-family: arial,serif; text-align: center; font-weight: bold; font-size: 12pt; } TABLE.command { font-family: arial,serif; font-size: 10pt; background-color: #DBDBDB; padding: 2; } .command { font-family: arial,serif; font-size: 10pt; } .commentTitle { font-family: arial,serif; text-align: center; font-weight: bold; font-size: 12pt; } DIV.commentNav { font-family: arial,serif; font-size: 10pt; text-align: center; } A.commentNav { font-family: arial,serif; font-size: 10pt; } TABLE.comment { font-family: arial,serif; font-size: 10pt; background-color: white; padding: 2; } TH.comment { font-family: arial,serif; font-size: 10pt; background-color: white; text-align: left; background-color: #999797; color: #DCE5C1; } .commentOdd { font-family: arial,serif; font-size: 9pt; background-color: #DBDBDB; } .commentEven { font-family: arial,serif; font-size: 9pt; background-color: #C4C2C2; } DIV.comment,A.comment { font-family: arial,serif; font-size: 10pt; background-color: white; text-align: center; } .downtimeTitle { font-family: arial,serif; text-align: center; font-weight: bold; font-size: 12pt; } DIV.downtimeNav { font-family: arial,serif; font-size: 10pt; text-align: center; } A.downtimeNav { font-family: arial,serif; font-size: 10pt; } TABLE.downtime { font-family: arial,serif; font-size: 10pt; background-color: white; padding: 2; } TH.downtime { font-family: arial,serif; font-size: 10pt; background-color: white; text-align: left; background-color: #999797; color: #DCE5C1; } .downtimeOdd { font-family: arial,serif; font-size: 9pt; background-color: #DBDBDB; } .downtimeEven { font-family: arial,serif; font-size: 9pt; background-color: #C4C2C2; } .notificationsENABLED { font-family: arial,serif; font-size: 10pt; text-align: left; background-color: #33FF00; font-weight: bold; } .notificationsDISABLED { font-family: arial,serif; font-size: 10pt; text-align: left; background-color: #F83838; font-weight: bold; } .checksENABLED { font-family: arial,serif; font-size: 10pt; text-align: left; background-color: #33FF00; font-weight: bold; } .checksDISABLED { font-family: arial,serif; font-size: 10pt; text-align: left; background-color: #F83838; font-weight: bold; } .eventhandlersENABLED { font-family: arial,serif; font-size: 10pt; text-align: left; background-color: #33FF00; font-weight: bold; } .eventhandlersDISABLED { font-family: arial,serif; font-size: 10pt; text-align: left; background-color: #F83838; font-weight: bold; } .flapdetectionENABLED { font-family: arial,serif; font-size: 10pt; text-align: left; background-color: #33FF00; font-weight: bold; } .flapdetectionDISABLED { font-family: arial,serif; font-size: 10pt; text-align: left; background-color: #F83838; font-weight: bold; } .notflapping { font-family: arial,serif; font-size: 10pt; text-align: left; background-color: #33FF00; font-weight: bold; } .flapping { font-family: arial,serif; font-size: 10pt; text-align: left; background-color: #F83838; font-weight: bold; } .downtimeACTIVE { font-family: arial,serif; font-size: 10pt; text-align: left; background-color: #F83838; font-weight: bold; } .downtimeINACTIVE { font-family: arial,serif; font-size: 10pt; text-align: left; background-color: #33FF00; font-weight: bold; } .processOK { font-family: arial,serif; font-size: 10pt; background-color: #33FF00; font-weight: bold; } .processUNKNOWN { font-family: arial,serif; font-size: 10pt; background-color: #FF9900; font-weight: bold; } .processWARNING { font-family: arial,serif; font-size: 10pt; background-color: #FFFF00; font-weight: bold; } .processCRITICAL { font-family: arial,serif; font-size: 10pt; background-color: #F83838; font-weight: bold; } .modeACTIVE { font-family: arial,serif; font-size: 10pt; background-color: #33FF00; font-weight: bold; } .modeSTANDBY { font-family: arial,serif; font-size: 10pt; background-color: #FFFF00; font-weight: bold; } .hostUP { font-family: arial,serif; font-size: 10pt; text-align: left; background-color: #33FF00; font-weight: bold; } .hostDOWN { font-family: arial,serif; font-size: 10pt; text-align: left; background-color: #F83838; font-weight: bold; } .hostUNREACHABLE { font-family: arial,serif; font-size: 10pt; text-align: left; background-color: #F83838; font-weight: bold; } .serviceOK { font-family: arial,serif; font-size: 10pt; text-align: left; background-color: #33FF00; font-weight: bold; } .serviceWARNING { font-family: arial,serif; font-size: 10pt; text-align: left; background-color: #FFFF00; font-weight: bold; } .serviceUNKNOWN { font-family: arial,serif; font-size: 10pt; text-align: left; background-color: #FF9900; font-weight: bold; } .serviceCRITICAL { font-family: arial,serif; font-size: 10pt; text-align: left; background-color: #F83838; font-weight: bold; } .commandPanel { font-family: arial,serif; background-color: white; } .commentPanel { font-family: arial,serif; background-color: white; } .stateInfoPanel { font-family: arial,serif; background-color: white; } .stateStatisticsPanel { font-family: arial,serif; background-color: white; } .stateInfoTable1 { font-family: arial,serif; font-size: 10pt; background-color: #DBDBDB; } .stateInfoTable2 { font-family: arial,serif; font-size: 10pt; background-color: #C4C2C2; } .dataVar { font-family: arial,serif; font-size: 10pt; } .dataVal { font-family: arial,serif; font-size: 10pt; } .queueTitle { font-family: arial,serif; text-align: center; font-weight: bold; font-size: 12pt; } TABLE.queue { font-family: arial,serif; font-size: 10pt; background-color: white; padding: 2; } TH.queue { font-family: arial,serif; font-size: 10pt; background-color: white; text-align: left; background-color: #999797; color: #DCE5C1; } .queueOdd { font-family: arial,serif; font-size: 9pt; background-color: #DBDBDB; } .queueEven { font-family: arial,serif; font-size: 9pt; background-color: #C4C2C2; } .queueENABLED { font-family: arial,serif; font-size: 9pt; background-color: #33FF00; } .queueDISABLED { font-family: arial,serif; font-size: 9pt; background-color: #F83838; } nagios-2.6/html/stylesheets/histogram.css0000664000076500007650000000362510215426344020235 0ustar nagiosnagios .histogram { font-family: arial,serif; background-color: white; color: black; } .errorMessage { font-family: arial,serif; text-align: center; color: red; font-weight: bold; font-size: 12pt; } .errorDescription { font-family: arial,serif; text-align: center; font-weight: bold; font-size: 12pt; } .warningMessage { font-family: arial,serif; text-align: center; color: red; font-weight: bold; font-size: 10pt; } .infoMessage { font-family: arial,serif; text-align: center; font-weight: bold; font-size: 12pt; } .helpfulHints { font-family: arial,serif; text-align: center; font-size: 10pt; } .infoBox { font-family: arial,serif; font-size: 8pt; background-color: #C4C2C2; padding: 2; } .infoBoxTitle { font-family: arial,serif; font-size: 10pt; font-weight: bold; } .infoBoxBadProcStatus { color: red; } A.homepageURL: Hover { font-family: arial,serif; color: red; } .linkBox { font-family: arial,serif; font-size: 8pt; background-color: #DBDBDB; padding: 1; } .dataTitle { font-family: arial,serif; text-align: center; font-weight: bold; font-size: 12pt; } .reportRange { font-family: arial,serif; text-align: center; font-weight: bold; font-size: 10pt; } .reportDuration { font-family: arial,serif; text-align: center; font-size: 8pt; } .reportTime { font-family: arial,serif; text-align: center; font-size: 8pt; } .optBox { font-family: arial narrow,serif; font-size: 10pt; font-weight: bold; } .optBoxItem { font-family: arial,serif; font-size: 8pt; font-weight: bold; color: red; } .reportSelectTitle { font-family: arial,serif; text-align: center; font-weight: bold; font-size: 12pt; } .reportSelectSubTitle { font-family: arial,serif; text-align: right; font-size: 10pt; } .reportSelectItem { font-family: arial,serif; text-align: left; font-size: 8pt; } .helpfulHint { font-family: arial,serif; text-align: left; font-size: 8pt; font-style: italic; text-align: center; } nagios-2.6/html/stylesheets/history.css0000664000076500007650000000307610141063404017731 0ustar nagiosnagios .history { font-family: arial,serif; background-color: white; color: black; } .errorMessage { font-family: arial,serif; text-align: center; color: red; font-weight: bold; font-size: 12pt; } .errorDescription { font-family: arial,serif; text-align: center; font-weight: bold; font-size: 12pt; } .warningMessage { font-family: arial,serif; text-align: center; color: red; font-weight: bold; font-size: 10pt; } .infoBox { font-family: arial,serif; font-size: 8pt; background-color: #C4C2C2; padding: 2; } .infoBoxTitle { font-family: arial,serif; font-size: 10pt; font-weight: bold; } .infoBoxBadProcStatus { color: red; } A.homepageURL: Hover { font-family: arial,serif; color: red; } .linkBox { font-family: arial,serif; font-size: 8pt; background-color: #DBDBDB; padding: 1; } .dataTitle { font-family: arial,serif; text-align: center; font-weight: bold; font-size: 12pt; } .navBoxTitle { font-family: arial narrow,serif; font-size: 10pt; font-weight: bold; } .navBoxItem { font-family: arial,serif; font-size: 8pt; font-weight: bold; color: red; } .navBoxDate { font-family: arial,serif; font-size: 8pt; font-weight: bold; } .navBoxFile { font-family: arial,serif; font-size: 8pt; font-weight: bold; text-align: center; } .optBox { font-family: arial narrow,serif; font-size: 10pt; font-weight: bold; } .optBoxItem { font-family: arial,serif; font-size: 8pt; font-weight: bold; color: red; } .logEntries { font-family: arial,serif; font-size: 8pt; } .dateTimeBreak { font-family: arial,serif; font-size: 10pt; font-weight: bold; color: red; } nagios-2.6/html/stylesheets/ministatus.css0000664000076500007650000001474110141063404020431 0ustar nagiosnagios .status { font-family: arial,serif; background-color: white; color: black; } .errorMessage { font-family: arial,serif; text-align: center; color: red; font-weight: bold; font-size: 12pt; } .errorDescription { font-family: arial,serif; text-align: center; font-weight: bold; font-size: 12pt; } .warningMessage { font-family: arial,serif; text-align: center; color: red; font-weight: bold; font-size: 10pt; } .infoMessage { font-family: arial,serif; text-align: center; color: red; font-weight: bold; } .infoBox { font-family: arial,serif; font-size: 8pt; background-color: #C4C2C2; padding: 2; } .infoBoxTitle { font-family: arial,serif; font-size: 10pt; font-weight: bold; } .infoBoxBadProcStatus { font-family: arial,serif; color: red; } A.homepageURL: Hover { font-family: arial,serif; color: red; } .linkBox { font-family: arial,serif; font-size: 8pt; background-color: #DBDBDB; padding: 1; } .filter { font-family: arial,serif; font-size: 8pt; background-color: #DBDBDB; } .filterTitle { font-family: arial,serif; font-size: 10pt; font-weight: bold; background-color: #DBDBDB; } .filterName { font-family: arial,serif; font-size: 8pt; background-color: #DBDBDB; } .filterValue { font-family: arial,serif; font-size: 8pt; background-color: #DBDBDB; } .statusTitle { font-family: arial,serif; text-align: center; font-weight: bold; font-size: 12pt; } .statusSort { font-family: arial,serif; font-size: 8pt; } TABLE.status { font-family: arial,serif; font-size: 8pt; background-color: white; padding: 2; } TH.status { font-family: arial,serif; font-size: 10pt; text-align: left; background-color: #999797; color: #DCE5C1; } DIV.status { font-family: arial,serif; font-size: 10pt; text-align: center; } .statusOdd { font-family: arial,serif; font-size: 8pt; background-color: #DBDBDB; } .statusEven { font-family: arial,serif; font-size: 8pt; background-color: #C4C2C2; } .statusPENDING { font-family: arial,serif; font-size: 8pt; background-color: #ACACAC; } .statusOK { font-family: arial,serif; font-size: 8pt; background-color: #33FF00; } .statusRECOVERY { font-family: arial,serif; font-size: 8pt; background-color: #33FF00; } .statusUNKNOWN { font-family: arial,serif; font-size: 8pt; background-color: #FF9900; } .statusWARNING { font-family: arial,serif; font-size: 8pt; background-color: #FFFF00; } .statusCRITICAL { font-family: arial,serif; font-size: 8pt; background-color: #F83838; } .statusHOSTPENDING { font-family: arial,serif; font-size: 8pt; background-color: #ACACAC; } .statusHOSTUP { font-family: arial,serif; font-size: 8pt; background-color: #33FF00; } .statusHOSTDOWN { font-family: arial,serif; font-size: 8pt; background-color: #F83838; } .statusHOSTUNREACHABLE { font-family: arial,serif; font-size: 8pt; background-color: #F83838; } .statusBGUNKNOWN { font-family: arial,serif; font-size: 8pt; background-color: #FFDA9F; } .statusBGWARNING { font-family: arial,serif; font-size: 8pt; background-color: #FEFFC1; } .statusBGCRITICAL { font-family: arial,serif; font-size: 8pt; background-color: #FFBBBB; } .statusBGDOWN { font-family: arial,serif; font-size: 8pt; background-color: #FFBBBB; } .statusBGUNREACHABLE { font-family: arial,serif; font-size: 8pt; background-color: #FFBBBB; } DIV.serviceTotals { font-family: arial,serif; text-align: center; font-weight: bold; font-size: 10pt; } TABLE.serviceTotals { font-family: arial,serif; font-size: 10pt; background-color: white; padding: 2; } TH.serviceTotals,A.serviceTotals { font-family: arial,serif; font-size: 10pt; background-color: white; text-align: center; background-color: #999797; color: #DCE5C1; } TD.serviceTotals { font-family: arial,serif; font-size: 8pt; text-align: center; background-color: #e9e9e9; } .serviceTotalsOK { font-family: arial,serif; font-size: 8pt; text-align: center; background-color: #33FF00; } .serviceTotalsWARNING { font-family: arial,serif; font-size: 8pt; text-align: center; background-color: #FFFF00; font-weight: bold; } .serviceTotalsUNKNOWN { font-family: arial,serif; font-size: 8pt; text-align: center; background-color: #FF9900; font-weight: bold; } .serviceTotalsCRITICAL { font-family: arial,serif; font-size: 8pt; text-align: center; background-color: #F83838; font-weight: bold; } .serviceTotalsPENDING { font-family: arial,serif; font-size: 8pt; text-align: center; background-color: #ACACAC; } .serviceTotalsPROBLEMS { font-family: arial,serif; font-size: 8pt; text-align: center; background-color: orange; font-weight: bold; } DIV.hostTotals { font-family: arial,serif; text-align: center; font-weight: bold; font-size: 10pt; } TABLE.hostTotals { font-family: arial,serif; font-size: 10pt; background-color: white; padding: 2; } TH.hostTotals,A.hostTotals { font-family: arial,serif; font-size: 10pt; background-color: white; text-align: center; background-color: #999797; color: #DCE5C1; } TD.hostTotals { font-family: arial,serif; font-size: 8pt; text-align: center; background-color: #e9e9e9; } .hostTotalsUP { font-family: arial,serif; font-size: 8pt; text-align: center; background-color: #33FF00; } .hostTotalsDOWN { font-family: arial,serif; font-size: 8pt; text-align: center; background-color: #F83838; font-weight: bold; } .hostTotalsUNREACHABLE { font-family: arial,serif; font-size: 8pt; text-align: center; background-color: #F83838; font-weight: bold; } .hostTotalsPENDING { font-family: arial,serif; font-size: 8pt; text-align: center; background-color: #ACACAC; } .hostTotalsPROBLEMS { font-family: arial,serif; font-size: 8pt; text-align: center; background-color: orange; font-weight: bold; } .miniStatusPENDING { font-family: arial,serif; font-size: 8pt; background-color: #ACACAC; text-align: center; } .miniStatusOK { font-family: arial,serif; font-size: 8pt; background-color: #33FF00; text-align: center; } .miniStatusUNKNOWN { font-family: arial,serif; font-size: 8pt; background-color: #FF9900; text-align: center; } .miniStatusWARNING { font-family: arial,serif; font-size: 8pt; background-color: #FFFF00; text-align: center; } .miniStatusCRITICAL { font-family: arial,serif; font-size: 8pt; background-color: #F83838; text-align: center; } .miniStatusUP { font-family: arial,serif; font-size: 8pt; background-color: #33FF00; text-align: center; } .miniStatusDOWN { font-family: arial,serif; font-size: 8pt; background-color: #F83838; text-align: center; } .miniStatusUNREACHABLE { font-family: arial,serif; font-size: 8pt; background-color: #F83838; text-align: center; } nagios-2.6/html/stylesheets/notifications.css0000664000076500007650000000535410141063404021102 0ustar nagiosnagios .notifications { font-family: arial,serif; background-color: white; color: black; } .errorMessage { font-family: arial,serif; text-align: center; color: red; font-weight: bold; font-size: 12pt; } .errorDescription { font-family: arial,serif; text-align: center; font-weight: bold; font-size: 12pt; } .warningMessage { font-family: arial,serif; text-align: center; color: red; font-weight: bold; font-size: 10pt; } .infoBox { font-family: arial,serif; font-size: 8pt; background-color: #C4C2C2; padding: 2; } .infoBoxTitle { font-family: arial,serif; font-size: 10pt; font-weight: bold; } .infoBoxBadProcStatus { color: red; } A.homepageURL: Hover { font-family: arial,serif; color: red; } .linkBox { font-family: arial,serif; font-size: 8pt; background-color: #DBDBDB; padding: 1; } .dataTitle { font-family: arial,serif; text-align: center; font-weight: bold; font-size: 12pt; } .navBoxTitle { font-family: arial narrow,serif; font-size: 10pt; font-weight: bold; } .navBoxItem { font-family: arial,serif; font-size: 8pt; font-weight: bold; color: red; } .navBoxDate { font-family: arial,serif; font-size: 8pt; font-weight: bold; } .navBoxFile { font-family: arial,serif; font-size: 8pt; font-weight: bold; text-align: center; } .optBox { font-family: arial narrow,serif; font-size: 10pt; font-weight: bold; } .optBoxItem { font-family: arial,serif; font-size: 8pt; font-weight: bold; color: red; } TABLE.notifications { font-family: arial,serif; font-size: 10pt; background-color: white; padding: 5; } TH.notifications { font-family: arial,serif; font-size: 10pt; background-color: white; text-align: left; background-color: #999797; color: #DCE5C1; } .notificationsOdd { font-family: arial,serif; font-size: 8pt; background-color: #DBDBDB; } .notificationsEven { font-family: arial,serif; font-size: 8pt; background-color: #C4C2C2; } .notificationsOK { font-family: arial,serif; font-size: 8pt; background-color: #33FF00; } .notificationsUNKNOWN { font-family: arial,serif; font-size: 8pt; background-color: #FF9900; } .notificationsWARNING { font-family: arial,serif; font-size: 8pt; background-color: #FFFF00; } .notificationsCRITICAL { font-family: arial,serif; font-size: 8pt; background-color: #F83838; } .notificationsACKNOWLEDGEMENT { font-family: arial,serif; font-size: 8pt; background-color: #AAAAAA; } .notificationsHOSTUP { font-family: arial,serif; font-size: 8pt; background-color: #33FF00; } .notificationsHOSTDOWN { font-family: arial,serif; font-size: 8pt; background-color: #F83838; } .notificationsHOSTUNREACHABLE { font-family: arial,serif; font-size: 8pt; background-color: #F83838; } .notificationsHOSTACKNOWLEDGEMENT { font-family: arial,serif; font-size: 8pt; background-color: #AAAAAA; } nagios-2.6/html/stylesheets/outages.css0000664000076500007650000000337510141063404017701 0ustar nagiosnagios .outages { font-family: arial,serif; background-color: white; color: black; font-size: 10pt; } .errorMessage { font-family: arial,serif; text-align: center; color: red; font-weight: bold; font-size: 12pt; } .errorDescription { font-family: arial,serif; text-align: center; font-weight: bold; font-size: 12pt; } .warningMessage { font-family: arial,serif; text-align: center; color: red; font-weight: bold; font-size: 10pt; } .infoMessage { font-family: arial,serif; text-align: center; font-size: 10pt; } .infoBox { font-family: arial,serif; font-size: 8pt; background-color: #C4C2C2; padding: 2; } .infoBoxTitle { font-family: arial,serif; font-size: 10pt; font-weight: bold; } .infoBoxBadProcStatus { color: red; } A.homepageURL: Hover { font-family: arial,serif; color: red; } .itemTotalsTitle { font-family: arial,serif; font-size: 8pt; text-align: center; } .dataTitle { font-family: arial,serif; text-align: center; font-weight: bold; font-size: 12pt; } TABLE.data { font-family: arial,serif; font-size: 10pt; background-color: white; padding: 2; } TH.data { font-family: arial,serif; font-size: 10pt; background-color: white; text-align: left; background-color: #999797; color: #DCE5C1; } .dataOdd { font-family: arial,serif; font-size: 10pt; background-color: #DBDBDB; } .dataEven { font-family: arial,serif; font-size: 10pt; background-color: #C4C2C2; } .hostUP { font-family: arial,serif; font-size: 10pt; text-align: left; background-color: #33FF00; font-weight: bold; } .hostDOWN { font-family: arial,serif; font-size: 10pt; text-align: left; background-color: #F83838; font-weight: bold; } .hostUNREACHABLE { font-family: arial,serif; font-size: 10pt; text-align: left; background-color: #F83838; font-weight: bold; } nagios-2.6/html/stylesheets/showlog.css0000664000076500007650000000256710141063404017716 0ustar nagiosnagios .showlog { font-family: arial,serif; background-color: white; color: black; } .errorMessage { font-family: arial,serif; text-align: center; color: red; font-weight: bold; font-size: 12pt; } .errorDescription { font-family: arial,serif; text-align: center; font-weight: bold; font-size: 12pt; } .warningMessage { font-family: arial,serif; text-align: center; color: red; font-weight: bold; font-size: 10pt; } .infoBox { font-family: arial,serif; font-size: 8pt; background-color: #C4C2C2; padding: 2; } .infoBoxTitle { font-family: arial,serif; font-size: 10pt; font-weight: bold; } .infoBoxBadProcStatus { color: red; } A.homepageURL: Hover { font-family: arial,serif; color: red; } .navBoxTitle { font-family: arial narrow,serif; font-size: 10pt; font-weight: bold; } .navBoxItem { font-family: arial,serif; font-size: 8pt; font-weight: bold; color: red; } .navBoxDate { font-family: arial,serif; font-size: 8pt; font-weight: bold; } .navBoxFile { font-family: arial,serif; font-size: 8pt; font-weight: bold; text-align: center; } .optBox { font-family: arial narrow,serif; font-size: 10pt; font-weight: bold; } .optBoxItem { font-family: arial,serif; font-size: 8pt; font-weight: bold; color: red; } .logEntries { font-family: arial,serif; font-size: 8pt; } .dateTimeBreak { font-family: arial,serif; font-size: 10pt; font-weight: bold; color: red; } nagios-2.6/html/stylesheets/status.css0000664000076500007650000001760610141063404017557 0ustar nagiosnagios .status { font-family: arial,serif; background-color: white; color: black; } .errorMessage { font-family: arial,serif; text-align: center; color: red; font-weight: bold; font-size: 12pt; } .errorDescription { font-family: arial,serif; text-align: center; font-weight: bold; font-size: 12pt; } .warningMessage { font-family: arial,serif; text-align: center; color: red; font-weight: bold; font-size: 10pt; } .infoMessage { font-family: arial,serif; text-align: center; color: red; font-weight: bold; } .infoBox { font-family: arial,serif; font-size: 8pt; background-color: #C4C2C2; padding: 2; } .infoBoxTitle { font-family: arial,serif; font-size: 10pt; font-weight: bold; } .infoBoxBadProcStatus { font-family: arial,serif; color: red; } A.homepageURL: Hover { font-family: arial,serif; color: red; } .linkBox { font-family: arial,serif; font-size: 8pt; background-color: #DBDBDB; padding: 1; } .filter { font-family: arial,serif; font-size: 8pt; background-color: #DBDBDB; } .filterTitle { font-family: arial,serif; font-size: 10pt; font-weight: bold; background-color: #DBDBDB; } .filterName { font-family: arial,serif; font-size: 8pt; background-color: #DBDBDB; } .filterValue { font-family: arial,serif; font-size: 8pt; background-color: #DBDBDB; } .itemTotalsTitle { font-family: arial,serif; font-size: 8pt; text-align: center; } .statusTitle { font-family: arial,serif; text-align: center; font-weight: bold; font-size: 12pt; } .statusSort { font-family: arial,serif; font-size: 8pt; } TABLE.status { font-family: arial,serif; font-size: 8pt; background-color: white; padding: 2; } TH.status { font-family: arial,serif; font-size: 10pt; text-align: left; background-color: #999797; color: #DCE5C1; } DIV.status { font-family: arial,serif; font-size: 10pt; text-align: center; } .statusOdd { font-family: arial,serif; font-size: 8pt; background-color: #DBDBDB; } .statusEven { font-family: arial,serif; font-size: 8pt; background-color: #C4C2C2; } .statusPENDING { font-family: arial,serif; font-size: 8pt; background-color: #ACACAC; } .statusOK { font-family: arial,serif; font-size: 8pt; background-color: #33FF00; } .statusRECOVERY { font-family: arial,serif; font-size: 8pt; background-color: #33FF00; } .statusUNKNOWN { font-family: arial,serif; font-size: 8pt; background-color: #FF9900; } .statusWARNING { font-family: arial,serif; font-size: 8pt; background-color: #FFFF00; } .statusCRITICAL { font-family: arial,serif; font-size: 8pt; background-color: #F83838; } .statusHOSTPENDING { font-family: arial,serif; font-size: 8pt; background-color: #ACACAC; } .statusHOSTUP { font-family: arial,serif; font-size: 8pt; background-color: #33FF00; } .statusHOSTDOWN { font-family: arial,serif; font-size: 8pt; background-color: #F83838; } .statusHOSTDOWNACK { font-family: arial,serif; font-size: 8pt; background-color: #F83838; } .statusHOSTDOWNSCHED { font-family: arial,serif; font-size: 8pt; background-color: #F83838; } .statusHOSTUNREACHABLE { font-family: arial,serif; font-size: 8pt; background-color: #F83838; } .statusHOSTUNREACHABLEACK { font-family: arial,serif; font-size: 8pt; background-color: #F83838; } .statusHOSTUNREACHABLESCHED { font-family: arial,serif; font-size: 8pt; background-color: #F83838; } .statusBGUNKNOWN { font-family: arial,serif; font-size: 8pt; background-color: #FFDA9F; } .statusBGUNKNOWNACK { font-family: arial,serif; font-size: 8pt; background-color: #FFDA9F; } .statusBGUNKNOWNSCHED { font-family: arial,serif; font-size: 8pt; background-color: #FFDA9F; } .statusBGWARNING { font-family: arial,serif; font-size: 8pt; background-color: #FEFFC1; } .statusBGWARNINGACK { font-family: arial,serif; font-size: 8pt; background-color: #FEFFC1; } .statusBGWARNINGSCHED { font-family: arial,serif; font-size: 8pt; background-color: #FEFFC1; } .statusBGCRITICAL { font-family: arial,serif; font-size: 8pt; background-color: #FFBBBB; } .statusBGCRITICALACK { font-family: arial,serif; font-size: 8pt; background-color: #FFBBBB; } .statusBGCRITICALSCHED { font-family: arial,serif; font-size: 8pt; background-color: #FFBBBB; } .statusBGDOWN { font-family: arial,serif; font-size: 8pt; background-color: #FFBBBB; } .statusBGDOWNACK { font-family: arial,serif; font-size: 8pt; background-color: #FFBBBB; } .statusBGDOWNSCHED { font-family: arial,serif; font-size: 8pt; background-color: #FFBBBB; } .statusBGUNREACHABLE { font-family: arial,serif; font-size: 8pt; background-color: #FFBBBB; } .statusBGUNREACHABLEACK { font-family: arial,serif; font-size: 8pt; background-color: #FFBBBB; } .statusBGUNREACHABLESCHED { font-family: arial,serif; font-size: 8pt; background-color: #FFBBBB; } DIV.serviceTotals { font-family: arial,serif; text-align: center; font-weight: bold; font-size: 10pt; } TABLE.serviceTotals { font-family: arial,serif; font-size: 10pt; background-color: white; padding: 2; } TH.serviceTotals,A.serviceTotals { font-family: arial,serif; font-size: 10pt; background-color: white; text-align: center; background-color: #999797; color: #DCE5C1; } TD.serviceTotals { font-family: arial,serif; font-size: 8pt; text-align: center; background-color: #e9e9e9; } .serviceTotalsOK { font-family: arial,serif; font-size: 8pt; text-align: center; background-color: #33FF00; } .serviceTotalsWARNING { font-family: arial,serif; font-size: 8pt; text-align: center; background-color: #FFFF00; font-weight: bold; } .serviceTotalsUNKNOWN { font-family: arial,serif; font-size: 8pt; text-align: center; background-color: #FF9900; font-weight: bold; } .serviceTotalsCRITICAL { font-family: arial,serif; font-size: 8pt; text-align: center; background-color: #F83838; font-weight: bold; } .serviceTotalsPENDING { font-family: arial,serif; font-size: 8pt; text-align: center; background-color: #ACACAC; } .serviceTotalsPROBLEMS { font-family: arial,serif; font-size: 8pt; text-align: center; background-color: orange; font-weight: bold; } DIV.hostTotals { font-family: arial,serif; text-align: center; font-weight: bold; font-size: 10pt; } TABLE.hostTotals { font-family: arial,serif; font-size: 10pt; background-color: white; padding: 2; } TH.hostTotals,A.hostTotals { font-family: arial,serif; font-size: 10pt; background-color: white; text-align: center; background-color: #999797; color: #DCE5C1; } TD.hostTotals { font-family: arial,serif; font-size: 8pt; text-align: center; background-color: #e9e9e9; } .hostTotalsUP { font-family: arial,serif; font-size: 8pt; text-align: center; background-color: #33FF00; } .hostTotalsDOWN { font-family: arial,serif; font-size: 8pt; text-align: center; background-color: #F83838; font-weight: bold; } .hostTotalsUNREACHABLE { font-family: arial,serif; font-size: 8pt; text-align: center; background-color: #F83838; font-weight: bold; } .hostTotalsPENDING { font-family: arial,serif; font-size: 8pt; text-align: center; background-color: #ACACAC; } .hostTotalsPROBLEMS { font-family: arial,serif; font-size: 8pt; text-align: center; background-color: orange; font-weight: bold; } .miniStatusPENDING { font-family: arial,serif; font-size: 8pt; background-color: #ACACAC; text-align: center; } .miniStatusOK { font-family: arial,serif; font-size: 8pt; background-color: #33FF00; text-align: center; } .miniStatusUNKNOWN { font-family: arial,serif; font-size: 8pt; background-color: #FF9900; text-align: center; } .miniStatusWARNING { font-family: arial,serif; font-size: 8pt; background-color: #FFFF00; text-align: center; } .miniStatusCRITICAL { font-family: arial,serif; font-size: 8pt; background-color: #F83838; text-align: center; } .miniStatusUP { font-family: arial,serif; font-size: 8pt; background-color: #33FF00; text-align: center; } .miniStatusDOWN { font-family: arial,serif; font-size: 8pt; background-color: #F83838; text-align: center; } .miniStatusUNREACHABLE { font-family: arial,serif; font-size: 8pt; background-color: #F83838; text-align: center; } nagios-2.6/html/stylesheets/statusmap.css0000664000076500007650000000227610141063404020252 0ustar nagiosnagios .statusmap { font-family: arial,serif; background-color: white; color: black; } .errorMessage { font-family: arial,serif; text-align: center; color: red; font-weight: bold; font-size: 12pt; } .errorDescription { font-family: arial,serif; text-align: center; font-weight: bold; font-size: 12pt; } .warningMessage { text-align: center; color: red; font-weight: bold; font-size: 10pt; } .infoBox { font-family: arial,serif; font-size: 8pt; background-color: #C4C2C2; padding: 2; } .infoBoxTitle { font-family: arial,serif; font-size: 10pt; font-weight: bold; } .infoBoxBadProcStatus { color: red; } A.homepageURL: Hover { font-family: arial,serif; color: red; } .linkBox { font-family: arial,serif; font-size: 8pt; background-color: #DBDBDB; padding: 1; } .optBox { font-family: arial narrow,serif; font-size: 10pt; font-weight: bold; } .optBoxItem { font-family: arial,serif; font-size: 8pt; font-weight: bold; color: red; } .imageInfo { font-family: arial,serif; font-size: 8pt; font-weight: bold; text-align: center; } .zoomTitle { font-family: arial,serif; font-size: 12pt; font-weight: bold; } .popupText { font-family: arial,serif; font-size: 8pt; font-weight: bold; } nagios-2.6/html/stylesheets/summary.css0000664000076500007650000000736410141063404017731 0ustar nagiosnagios .summary { font-family: arial,serif; background-color: white; color: black; font-size: 10pt; } .errorMessage { font-family: arial,serif; text-align: center; color: red; font-weight: bold; font-size: 12pt; } .errorDescription { font-family: arial,serif; text-align: center; font-weight: bold; font-size: 12pt; } .warningMessage { font-family: arial,serif; text-align: center; color: red; font-weight: bold; font-size: 10pt; } .infoBox { font-family: arial,serif; font-size: 8pt; background-color: #C4C2C2; padding: 2; } .infoBoxTitle { font-family: arial,serif; font-size: 10pt; font-weight: bold; } .infoBoxBadProcStatus { font-family: arial,serif; color: red; } A.homepageURL: Hover { font-family: arial,serif; color: red; } .linkBox { font-family: arial,serif; font-size: 8pt; background-color: #DBDBDB; padding: 1; } .reportRange { font-family: arial,serif; text-align: center; font-weight: bold; font-size: 10pt; } .reportDuration { font-family: arial,serif; text-align: center; font-size: 8pt; } .reportTime { font-family: arial,serif; text-align: center; font-size: 8pt; } .reportDataEven { font-family: arial,serif; font-size: 8pt; background-color: #B4B5CC; padding: 2; } .reportDataOdd { font-family: arial,serif; font-size: 8pt; background-color: #CDCEE9; padding: 2; } .dataTitle { font-family: arial,serif; text-align: center; font-weight: bold; font-size: 12pt; } .dataSubTitle { font-family: arial,serif; text-align: center; font-weight: bold; font-size: 10pt; } TABLE.data { font-family: arial,serif; font-size: 10pt; background-color: white; padding: 2; } TH.data { font-family: arial,serif; font-size: 10pt; background-color: white; text-align: left; background-color: #999797; color: #DCE5C1; } .dataOdd { font-family: arial,serif; font-size: 9pt; background-color: #DBDBDB; } .dataEven { font-family: arial,serif; font-size: 9pt; background-color: #C4C2C2; } .hostUP { font-family: arial,serif; font-size: 9pt; text-align: left; background-color: #33FF00; } .hostDOWN { font-family: arial,serif; font-size: 9pt; text-align: left; background-color: #F83838; } .hostUNREACHABLE { font-family: arial,serif; font-size: 9pt; text-align: left; background-color: #F83838; } .serviceOK { font-family: arial,serif; font-size: 9pt; text-align: left; background-color: #33FF00; } .serviceWARNING { font-family: arial,serif; font-size: 9pt; text-align: left; background-color: #FFFF00; } .serviceUNKNOWN { font-family: arial,serif; font-size: 9pt; text-align: left; background-color: #FF9900; } .serviceCRITICAL { font-family: arial,serif; font-size: 9pt; text-align: left; background-color: #F83838; } .optBox { font-family: arial narrow,serif; font-size: 10pt; font-weight: bold; } .optBoxTitle { font-family: arial,serif; font-weight: bold; font-size: 10pt; } .optBoxItem { font-family: arial,serif; font-size: 8pt; font-weight: bold; } .optBoxValue { font-family: arial,serif; font-size: 8pt; font-style: italic; } .helpfulHint { font-family: arial,serif; text-align: left; font-size: 8pt; font-style: italic; text-align: center; } .dateSelectTitle { font-family: arial,serif; text-align: center; font-weight: bold; font-size: 12pt; } .dateSelectSubTitle { font-family: arial,serif; text-align: left; font-weight: bold; font-size: 10pt; } .dateSelectItem { font-family: arial,serif; text-align: left; font-size: 8pt; } .reportSelectTip { font-family: arial,serif; text-align: left; font-size: 8pt; font-style: italic; } .reportSelectTitle { font-family: arial,serif; text-align: center; font-weight: bold; font-size: 12pt; } .reportSelectSubTitle { font-family: arial,serif; text-align: right; font-size: 10pt; } .reportSelectItem { font-family: arial,serif; text-align: left; font-size: 8pt; } nagios-2.6/html/stylesheets/tac.css0000664000076500007650000002240610141063404016775 0ustar nagiosnagios .tac { font-family: arial,serif; background-color: black; background: black; color: white; background-color: black; } .errorMessage { font-family: arial; font-weight: bold; font-size: 12pt; background-color: black; color: white; } .errorDescription { font-family: arial,serif; text-align: center; font-weight: bold; font-size: 12pt; } .warningMessage { font-family: arial,serif; text-align: center; color: red; font-weight: bold; font-size: 10pt; } .infoBox { font-family: arial,serif; font-size: 8pt; background-color: #C4C2C2; color: black; padding: 2; } .infoBoxTitle { font-family: arial,serif; font-size: 10pt; font-weight: bold; color: black; } .infoBoxBadProcStatus { font-family: arial,serif; color: red; } A { font-family: arial,serif; color: black; } .title { text-align: left; font-family: arial; font-weight: bold; font-size: large; background-color: black; color: white; } .titleItem { text-align: left; font-family: arial; font-weight: bold; font-size: 8pt; background-color: black; color: white; } .infoBoxBadProcStatus { text-align: left; font-family: arial; font-weight: bold; font-size: 8pt; background-color: #C4C2C2; color: red; } .healthTitle { text-align: left; font-family: arial; font-weight: bold; font-size: 10pt; background-color: #999797; color: black; } .healthBox { text-align: left; font-family: arial; font-weight: bold; font-size: 8pt; background-color: #C4C2C2; color: white; } .healthItem { text-align: left; font-family: arial; font-weight: bold; font-size: 10pt; background-color: #C4C2C2; color: black; } .healthBar { text-align: left; font-family: arial; font-weight: bold; font-size: 8pt; background-color: gray; color: white; } .perfTitle { text-align: left; font-family: arial; font-weight: bold; font-size: 10pt; background-color: #999797; color: black; text-decoration: none; } .perfBox { text-align: left; font-family: arial; font-weight: bold; font-size: 8pt; background-color: #C4C2C2; color: white; } .perfItem { text-align: left; font-family: arial; font-weight: bold; font-size: 10pt; background-color: #C4C2C2; color: black; text-decoration: none; } .perfValue { text-align: left; font-family: arial; font-size: 10pt; background-color: #C4C2C2; color: black; text-decoration: none; } .featureTitle { text-align: left; font-family: arial; font-weight: bold; font-size: 10pt; background-color: #999797; color: black; } .featureHeader { text-align: center; font-family: arial; font-weight: bold; font-size: 10pt; background-color: #C4C2C2; color: black; } .featureEnabled { text-align: center; font-family: arial; font-weight: bold; font-size: 10pt; background-color: #ccffcc; color: #8f8f8f; } .featureDisabled { text-align: center; font-family: arial; font-weight: bold; font-size: 10pt; background-color: #ffcccc; color: #b3b3b3; } .featureEnabledFlapDetection { text-align: center; font-family: arial; font-weight: bold; font-size: 10pt; background-color: #ccffcc; color: #8f8f8f; } .featureDisabledFlapDetection { text-align: center; font-family: arial; font-weight: bold; font-size: 10pt; background-color: #ffcccc; color: #b3b3b3; } .featureItemEnabledServiceFlapDetection { text-align: left; font-family: arial; font-size: 8pt; background-color: #ccffcc; color: black; } .featureItemDisabledServiceFlapDetection { text-align: left; font-family: arial; font-size: 8pt; background-color: #ff0000; color: black; } .featureItemEnabledHostFlapDetection { text-align: left; font-family: arial; font-size: 8pt; background-color: #ccffcc; color: black; } .featureItemDisabledHostFlapDetection { text-align: left; font-family: arial; font-size: 8pt; background-color: #ff0000; color: black; } .featureItemServicesNotFlapping { text-align: left; font-family: arial; font-size: 8pt; background-color: #ccffcc; color: black; } .featureItemServicesFlapping { text-align: left; font-family: arial; font-size: 8pt; background-color: #ff0000; color: black; } .featureItemHostsNotFlapping { text-align: left; font-family: arial; font-size: 8pt; background-color: #ccffcc; color: black; } .featureItemHostsFlapping { text-align: left; font-family: arial; font-size: 8pt; background-color: #ff0000; color: black; } .featureEnabledNotifications { text-align: center; font-family: arial; font-weight: bold; font-size: 10pt; background-color: #ccffcc; color: #8f8f8f; } .featureDisabledNotifications { text-align: center; font-family: arial; font-weight: bold; font-size: 10pt; background-color: #ffcccc; color: #b3b3b3; } .featureItemEnabledServiceNotifications { text-align: left; font-family: arial; font-size: 8pt; background-color: #ccffcc; color: black; } .featureItemDisabledServiceNotifications { text-align: left; font-family: arial; font-size: 8pt; background-color: #ff0000; color: black; } .featureItemEnabledHostNotifications { text-align: left; font-family: arial; font-size: 8pt; background-color: #ccffcc; color: black; } .featureItemDisabledHostNotifications { text-align: left; font-family: arial; font-size: 8pt; background-color: #ff0000; color: black; } .featureEnabledHandlers { text-align: center; font-family: arial; font-weight: bold; font-size: 10pt; background-color: #ccffcc; color: #8f8f8f; } .featureDisabledHandlers { text-align: center; font-family: arial; font-weight: bold; font-size: 10pt; background-color: #ffcccc; color: #b3b3b3; } .featureItemEnabledServiceHandlers { text-align: left; font-family: arial; font-size: 8pt; background-color: #ccffcc; color: black; } .featureItemDisabledServiceHandlers { text-align: left; font-family: arial; font-size: 8pt; background-color: #ff0000; color: black; } .featureItemEnabledHostHandlers { text-align: left; font-family: arial; font-size: 8pt; background-color: #ccffcc; color: black; } .featureItemDisabledHostHandlers { text-align: left; font-family: arial; font-size: 8pt; background-color: #ff0000; color: black; } .featureEnabledActiveChecks { text-align: center; font-family: arial; font-weight: bold; font-size: 10pt; background-color: #ccffcc; color: #8f8f8f; } .featureDisabledActiveChecks { text-align: center; font-family: arial; font-weight: bold; font-size: 10pt; background-color: #ffcccc; color: #b3b3b3; } .featureItemEnabledActiveServiceChecks { text-align: left; font-family: arial; font-size: 8pt; background-color: #ccffcc; color: black; } .featureItemDisabledActiveServiceChecks { text-align: left; font-family: arial; font-size: 8pt; background-color: #ff0000; color: black; } .featureItemEnabledActiveHostChecks { text-align: left; font-family: arial; font-size: 8pt; background-color: #ccffcc; color: black; } .featureItemDisabledActiveHostChecks { text-align: left; font-family: arial; font-size: 8pt; background-color: #ff0000; color: black; } .featureEnabledPassiveChecks { text-align: center; font-family: arial; font-weight: bold; font-size: 10pt; background-color: #ccffcc; color: #8f8f8f; } .featureDisabledPassiveChecks { text-align: center; font-family: arial; font-weight: bold; font-size: 10pt; background-color: #ffcccc; color: #b3b3b3; } .featureItemEnabledPassiveServiceChecks { text-align: left; font-family: arial; font-size: 8pt; background-color: #ccffcc; color: black; } .featureItemDisabledPassiveServiceChecks { text-align: left; font-family: arial; font-size: 8pt; background-color: #ff0000; color: black; } .featureItemEnabledPassiveHostChecks { text-align: left; font-family: arial; font-size: 8pt; background-color: #ccffcc; color: black; } .featureItemDisabledPassiveHostChecks { text-align: left; font-family: arial; font-size: 8pt; background-color: #ff0000; color: black; } .outageTitle { text-align: left; font-family: arial; font-weight: bold; font-size: 10pt; background-color: #999797; color: black; } .outageHeader { text-align: center; font-family: arial; font-weight: bold; font-size: 10pt; background-color: #C4C2C2; color: black; text-decoration: none; } .outageImportantProblem { text-align: left; font-family: arial; font-size: 8pt; background-color: #ff0000; color: black; } .outageUnimportantProblem { text-align: left; font-family: arial; font-size: 8pt; background-color: #ffcccc; color: black; } .hostTitle { text-align: left; font-family: arial; font-weight: bold; font-size: 10pt; background-color: #999797; color: black; } .hostHeader { text-align: center; font-family: arial; font-weight: bold; font-size: 10pt; background-color: #C4C2C2; color: black; text-decoration: none; } .hostImportantProblem { text-align: left; font-family: arial; font-size: 8pt; background-color: #ff0000; color: black; } .hostUnimportantProblem { text-align: left; font-family: arial; font-size: 8pt; background-color: #ffcccc; color: black; } .serviceTitle { text-align: left; font-family: arial; font-weight: bold; font-size: 10pt; background-color: #999797; color: black; } .serviceHeader { text-align: center; font-family: arial; font-weight: bold; font-size: 10pt; background-color: #C4C2C2; color: black; text-decoration: none; } .serviceImportantProblem { text-align: left; font-family: arial; font-size: 8pt; background-color: #ff0000; color: black; } .serviceUnimportantProblem { text-align: left; font-family: arial; font-size: 8pt; background-color: #ffcccc; color: black; } nagios-2.6/html/stylesheets/trends.css0000664000076500007650000000361410141063404017525 0ustar nagiosnagios .trends { font-family: arial,serif; background-color: white; color: black; } .errorMessage { font-family: arial,serif; text-align: center; color: red; font-weight: bold; font-size: 12pt; } .errorDescription { font-family: arial,serif; text-align: center; font-weight: bold; font-size: 12pt; } .warningMessage { font-family: arial,serif; text-align: center; color: red; font-weight: bold; font-size: 10pt; } .infoMessage { font-family: arial,serif; text-align: center; font-weight: bold; font-size: 12pt; } .infoBox { font-family: arial,serif; font-size: 8pt; background-color: #C4C2C2; padding: 2; } .infoBoxTitle { font-family: arial,serif; font-size: 10pt; font-weight: bold; } .infoBoxBadProcStatus { color: red; } A.homepageURL: Hover { font-family: arial,serif; color: red; } .linkBox { font-family: arial,serif; font-size: 8pt; background-color: #DBDBDB; padding: 1; } .dataTitle { font-family: arial,serif; text-align: center; font-weight: bold; font-size: 12pt; } .reportRange { font-family: arial,serif; text-align: center; font-weight: bold; font-size: 10pt; } .reportDuration { font-family: arial,serif; text-align: center; font-size: 8pt; } .reportTime { font-family: arial,serif; text-align: center; font-size: 8pt; } .optBox { font-family: arial narrow,serif; font-size: 10pt; font-weight: bold; } .optBoxItem { font-family: arial,serif; font-size: 8pt; font-weight: bold; color: red; } .reportSelectTitle { font-family: arial,serif; text-align: center; font-weight: bold; font-size: 12pt; } .reportSelectSubTitle { font-family: arial,serif; text-align: right; font-size: 10pt; } .reportSelectItem { font-family: arial,serif; text-align: left; font-size: 8pt; } .helpfulHint { font-family: arial,serif; text-align: left; font-size: 8pt; font-style: italic; text-align: center; } .popupText { font-family: arial,serif; font-size: 8pt; font-weight: bold; } nagios-2.6/include/0000775000076500007650000000000010532717610013624 5ustar nagiosnagiosnagios-2.6/include/Makefile.in0000664000076500007650000000037007717034222015673 0ustar nagiosnagios############################### # Makefile for Include Files # # Last Modified: 08-14-2003 ############################### clean: rm -f *~ distclean: clean rm -f Makefile cgiutils.h config.h locations.h nagios.h snprintf.h devclean: distclean nagios-2.6/include/broker.h0000664000076500007650000002340610353050230015253 0ustar nagiosnagios/***************************************************************************** * * BROKER.H - Event broker includes for Nagios * * Copyright (c) 2002-2005 Ethan Galstad (nagios@nagios.org) * Last Modified: 12-16-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. * *****************************************************************************/ #ifndef _BROKER_H #define _BROKER_H #include "config.h" #include "nagios.h" #ifdef __cplusplus extern "C" { #endif /*************** EVENT BROKER OPTIONS *****************/ #define BROKER_NOTHING 0 #define BROKER_EVERYTHING 1048575 #define BROKER_PROGRAM_STATE 1 /* DONE */ #define BROKER_TIMED_EVENTS 2 /* DONE */ #define BROKER_SERVICE_CHECKS 4 /* DONE */ #define BROKER_HOST_CHECKS 8 /* DONE */ #define BROKER_EVENT_HANDLERS 16 /* DONE */ #define BROKER_LOGGED_DATA 32 /* DONE */ #define BROKER_NOTIFICATIONS 64 /* DONE */ #define BROKER_FLAPPING_DATA 128 /* DONE */ #define BROKER_COMMENT_DATA 256 /* DONE */ #define BROKER_DOWNTIME_DATA 512 /* DONE */ #define BROKER_SYSTEM_COMMANDS 1024 /* DONE */ #define BROKER_OCP_DATA 2048 /* DONE */ #define BROKER_STATUS_DATA 4096 /* DONE */ #define BROKER_ADAPTIVE_DATA 8192 /* DONE */ #define BROKER_EXTERNALCOMMAND_DATA 16384 /* DONE */ #define BROKER_RETENTION_DATA 32768 /* DONE */ #define BROKER_ACKNOWLEDGEMENT_DATA 65536 #define BROKER_STATECHANGE_DATA 131072 #define BROKER_RESERVED18 262144 #define BROKER_RESERVED19 524288 /****** EVENT TYPES ************************/ #define NEBTYPE_NONE 0 #define NEBTYPE_HELLO 1 #define NEBTYPE_GOODBYE 2 #define NEBTYPE_INFO 3 #define NEBTYPE_PROCESS_START 100 #define NEBTYPE_PROCESS_DAEMONIZE 101 #define NEBTYPE_PROCESS_RESTART 102 #define NEBTYPE_PROCESS_SHUTDOWN 103 #define NEBTYPE_PROCESS_PRELAUNCH 104 /* before objects are read or verified */ #define NEBTYPE_PROCESS_EVENTLOOPSTART 105 #define NEBTYPE_PROCESS_EVENTLOOPEND 106 #define NEBTYPE_TIMEDEVENT_ADD 200 #define NEBTYPE_TIMEDEVENT_REMOVE 201 #define NEBTYPE_TIMEDEVENT_EXECUTE 202 #define NEBTYPE_TIMEDEVENT_DELAY 203 /* NOT IMPLEMENTED */ #define NEBTYPE_TIMEDEVENT_SKIP 204 /* NOT IMPLEMENTED */ #define NEBTYPE_TIMEDEVENT_SLEEP 205 #define NEBTYPE_LOG_DATA 300 #define NEBTYPE_LOG_ROTATION 301 #define NEBTYPE_SYSTEM_COMMAND_START 400 #define NEBTYPE_SYSTEM_COMMAND_END 401 #define NEBTYPE_EVENTHANDLER_START 500 #define NEBTYPE_EVENTHANDLER_END 501 #define NEBTYPE_NOTIFICATION_START 600 #define NEBTYPE_NOTIFICATION_END 601 #define NEBTYPE_CONTACTNOTIFICATION_START 602 #define NEBTYPE_CONTACTNOTIFICATION_END 603 #define NEBTYPE_CONTACTNOTIFICATIONMETHOD_START 604 #define NEBTYPE_CONTACTNOTIFICATIONMETHOD_END 605 #define NEBTYPE_SERVICECHECK_INITIATE 700 #define NEBTYPE_SERVICECHECK_PROCESSED 701 #define NEBTYPE_SERVICECHECK_RAW_START 702 /* NOT IMPLEMENTED */ #define NEBTYPE_SERVICECHECK_RAW_END 703 /* NOT IMPLEMENTED */ #define NEBTYPE_HOSTCHECK_INITIATE 800 /* a check of the route to the host has been initiated */ #define NEBTYPE_HOSTCHECK_PROCESSED 801 /* the processed/final result of a host check */ #define NEBTYPE_HOSTCHECK_RAW_START 802 /* the start of a "raw" host check */ #define NEBTYPE_HOSTCHECK_RAW_END 803 /* a finished "raw" host check */ #define NEBTYPE_COMMENT_ADD 900 #define NEBTYPE_COMMENT_DELETE 901 #define NEBTYPE_COMMENT_LOAD 902 #define NEBTYPE_FLAPPING_START 1000 #define NEBTYPE_FLAPPING_STOP 1001 #define NEBTYPE_DOWNTIME_ADD 1100 #define NEBTYPE_DOWNTIME_DELETE 1101 #define NEBTYPE_DOWNTIME_LOAD 1102 #define NEBTYPE_DOWNTIME_START 1103 #define NEBTYPE_DOWNTIME_STOP 1104 #define NEBTYPE_PROGRAMSTATUS_UPDATE 1200 #define NEBTYPE_HOSTSTATUS_UPDATE 1201 #define NEBTYPE_SERVICESTATUS_UPDATE 1202 #define NEBTYPE_ADAPTIVEPROGRAM_UPDATE 1300 #define NEBTYPE_ADAPTIVEHOST_UPDATE 1301 #define NEBTYPE_ADAPTIVESERVICE_UPDATE 1302 #define NEBTYPE_EXTERNALCOMMAND_START 1400 #define NEBTYPE_EXTERNALCOMMAND_END 1401 #define NEBTYPE_AGGREGATEDSTATUS_STARTDUMP 1500 #define NEBTYPE_AGGREGATEDSTATUS_ENDDUMP 1501 #define NEBTYPE_RETENTIONDATA_STARTLOAD 1600 #define NEBTYPE_RETENTIONDATA_ENDLOAD 1601 #define NEBTYPE_RETENTIONDATA_STARTSAVE 1602 #define NEBTYPE_RETENTIONDATA_ENDSAVE 1603 #define NEBTYPE_ACKNOWLEDGEMENT_ADD 1700 #define NEBTYPE_ACKNOWLEDGEMENT_REMOVE 1701 /* NOT IMPLEMENTED */ #define NEBTYPE_ACKNOWLEDGEMENT_LOAD 1702 /* NOT IMPLEMENTED */ #define NEBTYPE_STATECHANGE_START 1800 /* NOT IMPLEMENTED */ #define NEBTYPE_STATECHANGE_END 1801 /****** EVENT FLAGS ************************/ #define NEBFLAG_NONE 0 #define NEBFLAG_PROCESS_INITIATED 1 /* event was initiated by Nagios process */ #define NEBFLAG_USER_INITIATED 2 /* event was initiated by a user request */ #define NEBFLAG_MODULE_INITIATED 3 /* event was initiated by an event broker module */ /****** EVENT ATTRIBUTES *******************/ #define NEBATTR_NONE 0 #define NEBATTR_SHUTDOWN_NORMAL 1 #define NEBATTR_SHUTDOWN_ABNORMAL 2 #define NEBATTR_RESTART_NORMAL 4 #define NEBATTR_RESTART_ABNORMAL 8 #define NEBATTR_FLAPPING_STOP_NORMAL 1 #define NEBATTR_FLAPPING_STOP_DISABLED 2 /* flapping stopped because flap detection was disabled */ #define NEBATTR_DOWNTIME_STOP_NORMAL 1 #define NEBATTR_DOWNTIME_STOP_CANCELLED 2 /****** EVENT BROKER FUNCTIONS *************/ #ifdef USE_EVENT_BROKER struct timeval get_broker_timestamp(struct timeval *); void broker_program_state(int,int,int,struct timeval *); void broker_timed_event(int,int,int,timed_event *event,struct timeval *); void broker_log_data(int,int,int,char *,unsigned long,time_t,struct timeval *); void broker_event_handler(int,int,int,int,void *,int,int,struct timeval,struct timeval,double,int,int,int,char *,char *,char *,struct timeval *); void broker_ocp_data(int,int,int,void *,int,int,double,int,int,struct timeval *); void broker_system_command(int,int,int,struct timeval,struct timeval,double,int,int,int,char *,char *,struct timeval *); void broker_host_check(int,int,int,host *,int,int,int,struct timeval,struct timeval,char *,double,double,int,int,int,char *,char *,char *,struct timeval *); void broker_service_check(int,int,int,service *,int,struct timeval,struct timeval,char *,double,double,int,int,int,char *,struct timeval *); void broker_comment_data(int,int,int,int,int,char *,char *,time_t,char *,char *,int,int,int,time_t,unsigned long,struct timeval *); void broker_downtime_data(int,int,int,int,char *,char *,time_t,char *,char *,time_t,time_t,int,unsigned long,unsigned long,unsigned long,struct timeval *); void broker_flapping_data(int,int,int,int,void *,double,double,double,struct timeval *); void broker_program_status(int,int,int,struct timeval *); void broker_host_status(int,int,int,host *,struct timeval *); void broker_service_status(int,int,int,service *,struct timeval *); void broker_notification_data(int,int,int,int,int,struct timeval,struct timeval,void *,char *,char *,int,int,struct timeval *); void broker_contact_notification_data(int,int,int,int,int,struct timeval,struct timeval,void *,contact *,char *,char *,int,struct timeval *); void broker_contact_notification_method_data(int,int,int,int,int,struct timeval,struct timeval,void *,contact *,char *,char *,char *,int,struct timeval *); void broker_adaptive_program_data(int,int,int,int,unsigned long,unsigned long,unsigned long,unsigned long,char *,char *,struct timeval *); void broker_adaptive_host_data(int,int,int,host *,int,unsigned long,unsigned long,struct timeval *); void broker_adaptive_service_data(int,int,int,service *,int,unsigned long,unsigned long,struct timeval *); void broker_external_command(int,int,int,int,time_t,char *,char *,struct timeval *); void broker_aggregated_status_data(int,int,int,struct timeval *); void broker_retention_data(int,int,int,struct timeval *); void broker_acknowledgement_data(int,int,int,int,void *,char *,char *,int,int,int,struct timeval *); void broker_statechange_data(int,int,int,int,void *,int,int,int,int,struct timeval *timestamp); #endif #ifdef __cplusplus } #endif #endif nagios-2.6/include/cgiauth.h0000664000076500007650000000411110341755747015431 0ustar nagiosnagios/***************************************************************************** * * CGIAUTH.H - Authorization utilities header file * * Last Modified: 11-24-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. * *****************************************************************************/ #ifndef _AUTH_H #define _AUTH_H #include "common.h" #include "objects.h" #ifdef __cplusplus extern "C" { #endif typedef struct authdata_struct{ char *username; int authorized_for_all_hosts; int authorized_for_all_host_commands; int authorized_for_all_services; int authorized_for_all_service_commands; int authorized_for_system_information; int authorized_for_system_commands; int authorized_for_configuration_information; int authenticated; }authdata; int get_authentication_information(authdata *); /* gets current authentication information */ int is_authorized_for_host(host *,authdata *); int is_authorized_for_service(service *,authdata *); int is_authorized_for_all_hosts(authdata *); int is_authorized_for_all_services(authdata *); int is_authorized_for_system_information(authdata *); int is_authorized_for_system_commands(authdata *); int is_authorized_for_host_commands(host *,authdata *); int is_authorized_for_service_commands(service *,authdata *); int is_authorized_for_hostgroup(hostgroup *,authdata *); int is_authorized_for_servicegroup(servicegroup *,authdata *); int is_authorized_for_configuration_information(authdata *); #ifdef __cplusplus } #endif #endif nagios-2.6/include/cgiutils.h.in0000664000076500007650000004173610364217475016247 0ustar nagiosnagios/************************************************************************ * * CGIUTILS.H - Header file for common CGI functions * Copyright (c) 1999-2006 Ethan Galstad (nagios@nagios.org) * Last Modified: 01-20-2006 * * 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. ************************************************************************/ #ifndef _CGIUTILS_H #define _CGIUTILS_H #include "objects.h" #include "cgiauth.h" #ifdef __cplusplus extern "C" { #endif /* should we compile and use the statusmap CGI? */ #undef USE_STATUSMAP /* should we compile and use the statuswrl CGI? */ #undef USE_STATUSWRL /* should we compile and use the trends CGI? */ #undef USE_TRENDS /* should we compile and use the histogram CGI? */ #undef USE_HISTOGRAM /**************************** CGI REFRESH RATE ******************************/ #define DEFAULT_REFRESH_RATE 60 /* 60 second refresh rate for CGIs */ /******************************* CGI NAMES **********************************/ #define STATUS_CGI "status.cgi" #define STATUSMAP_CGI "statusmap.cgi" #define STATUSWORLD_CGI "statuswrl.cgi" #define COMMAND_CGI "cmd.cgi" #define EXTINFO_CGI "extinfo.cgi" #define SHOWLOG_CGI "showlog.cgi" #define NOTIFICATIONS_CGI "notifications.cgi" #define HISTORY_CGI "history.cgi" #define CONFIG_CGI "config.cgi" #define OUTAGES_CGI "outages.cgi" #define TRENDS_CGI "trends.cgi" #define AVAIL_CGI "avail.cgi" #define TAC_CGI "tac.cgi" #define STATUSWML_CGI "statuswml.cgi" #define TRACEROUTE_CGI "traceroute.cgi" #define HISTOGRAM_CGI "histogram.cgi" #define CHECKSANITY_CGI "checksanity.cgi" #define MINISTATUS_CGI "ministatus.cgi" #define SUMMARY_CGI "summary.cgi" /**************************** STYLE SHEET NAMES ******************************/ #define COMMON_CSS "common.css" #define SHOWLOG_CSS "showlog.css" #define STATUS_CSS "status.css" #define STATUSMAP_CSS "statusmap.css" #define COMMAND_CSS "cmd.css" #define EXTINFO_CSS "extinfo.css" #define NOTIFICATIONS_CSS "notifications.css" #define HISTORY_CSS "history.css" #define CONFIG_CSS "config.css" #define OUTAGES_CSS "outages.css" #define TRENDS_CSS "trends.css" #define AVAIL_CSS "avail.css" #define TAC_CSS "tac.css" #define HISTOGRAM_CSS "histogram.css" #define CHECKSANITY_CSS "checksanity.css" #define MINISTATUS_CSS "ministatus.css" #define SUMMARY_CSS "summary.css" /********************************* ICONS ************************************/ #define STATUS_ICON_WIDTH 20 #define STATUS_ICON_HEIGHT 20 #define INFO_ICON "info.png" #define INFO_ICON_ALT "Informational Message" #define START_ICON "start.gif" #define START_ICON_ALT "Program Start" #define STOP_ICON "stop.gif" #define STOP_ICON_ALT "Program End" #define RESTART_ICON "restart.gif" #define RESTART_ICON_ALT "Program Restart" #define OK_ICON "recovery.png" #define OK_ICON_ALT "Service Ok" #define CRITICAL_ICON "critical.png" #define CRITICAL_ICON_ALT "Service Critical" #define WARNING_ICON "warning.png" #define WARNING_ICON_ALT "Service Warning" #define UNKNOWN_ICON "unknown.png" #define UNKNOWN_ICON_ALT "Service Unknown" #define NOTIFICATION_ICON "notify.gif" #define NOTIFICATION_ICON_ALT "Service Notification" #define LOG_ROTATION_ICON "logrotate.png" #define LOG_ROTATION_ICON_ALT "Log Rotation" #define EXTERNAL_COMMAND_ICON "command.png" #define EXTERNAL_COMMAND_ICON_ALT "External Command" #define STATUS_DETAIL_ICON "status2.gif" #define STATUS_OVERVIEW_ICON "status.gif" #define STATUSMAP_ICON "status3.gif" #define STATUSWORLD_ICON "status4.gif" #define EXTINFO_ICON "extinfo.gif" #define HISTORY_ICON "history.gif" #define CONTACTGROUP_ICON "contactgroup.gif" #define TRENDS_ICON "trends.gif" #define DISABLED_ICON "disabled.gif" #define ENABLED_ICON "enabled.gif" #define PASSIVE_ONLY_ICON "passiveonly.gif" #define NOTIFICATIONS_DISABLED_ICON "ndisabled.gif" #define ACKNOWLEDGEMENT_ICON "ack.gif" #define REMOVE_ACKNOWLEDGEMENT_ICON "noack.gif" #define COMMENT_ICON "comment.gif" #define DELETE_ICON "delete.gif" #define DELAY_ICON "delay.gif" #define DOWNTIME_ICON "downtime.gif" #define PASSIVE_ICON "unknown.png" #define RIGHT_ARROW_ICON "right.gif" #define LEFT_ARROW_ICON "left.gif" #define UP_ARROW_ICON "up.gif" #define DOWN_ARROW_ICON "down.gif" #define FLAPPING_ICON "flapping.gif" #define SCHEDULED_DOWNTIME_ICON "downtime.gif" #define EMPTY_ICON "empty.gif" #define ACTIVE_ICON "active.gif" #define ACTIVE_ICON_ALT "Active Mode" #define STANDBY_ICON "standby.gif" #define STANDBY_ICON_ALT "Standby Mode" #define HOST_DOWN_ICON "critical.png" #define HOST_DOWN_ICON_ALT "Host Down" #define HOST_UNREACHABLE_ICON "critical.png" #define HOST_UNREACHABLE_ICON_ALT "Host Unreachable" #define HOST_UP_ICON "recovery.png" #define HOST_UP_ICON_ALT "Host Up" #define HOST_NOTIFICATION_ICON "notify.gif" #define HOST_NOTIFICATION_ICON_ALT "Host Notification" #define SERVICE_EVENT_ICON "serviceevent.gif" #define SERVICE_EVENT_ICON_ALT "Service Event Handler" #define HOST_EVENT_ICON "hostevent.gif" #define HOST_EVENT_ICON_ALT "Host Event Handler" #define THERM_OK_IMAGE "thermok.png" #define THERM_WARNING_IMAGE "thermwarn.png" #define THERM_CRITICAL_IMAGE "thermcrit.png" #define CONFIGURATION_ICON "config.gif" #define NOTES_ICON "notes.gif" #define ACTION_ICON "action.gif" #define DETAIL_ICON "detail.gif" #define PARENT_TRAVERSAL_ICON "parentup.gif" #define TAC_DISABLED_ICON "tacdisabled.png" #define TAC_ENABLED_ICON "tacenabled.png" #define ZOOM1_ICON "zoom1.gif" #define ZOOM2_ICON "zoom2.gif" #define CONTEXT_HELP_ICON1 "contexthelp1.gif" #define CONTEXT_HELP_ICON2 "contexthelp2.gif" /************************** PLUGIN RETURN VALUES ****************************/ #define STATE_OK 0 #define STATE_WARNING 1 #define STATE_CRITICAL 2 #define STATE_UNKNOWN 3 /* changed from -1 on 02/24/2001 */ /********************* EXTENDED INFO CGI DISPLAY TYPES *********************/ #define DISPLAY_PROCESS_INFO 0 #define DISPLAY_HOST_INFO 1 #define DISPLAY_SERVICE_INFO 2 #define DISPLAY_COMMENTS 3 #define DISPLAY_PERFORMANCE 4 #define DISPLAY_HOSTGROUP_INFO 5 #define DISPLAY_DOWNTIME 6 #define DISPLAY_SCHEDULING_QUEUE 7 #define DISPLAY_SERVICEGROUP_INFO 8 /************************ COMMAND CGI COMMAND MODES *************************/ #define CMDMODE_NONE 0 #define CMDMODE_REQUEST 1 #define CMDMODE_COMMIT 2 /******************** HOST AND SERVICE NOTIFICATION TYPES ******************/ #define NOTIFICATION_ALL 0 /* all service and host notifications */ #define NOTIFICATION_SERVICE_ALL 1 /* all types of service notifications */ #define NOTIFICATION_HOST_ALL 2 /* all types of host notifications */ #define NOTIFICATION_SERVICE_WARNING 4 #define NOTIFICATION_SERVICE_UNKNOWN 8 #define NOTIFICATION_SERVICE_CRITICAL 16 #define NOTIFICATION_SERVICE_RECOVERY 32 #define NOTIFICATION_HOST_DOWN 64 #define NOTIFICATION_HOST_UNREACHABLE 128 #define NOTIFICATION_HOST_RECOVERY 256 #define NOTIFICATION_SERVICE_ACK 512 #define NOTIFICATION_HOST_ACK 1024 #define NOTIFICATION_SERVICE_FLAP 2048 #define NOTIFICATION_HOST_FLAP 4096 /********************** HOST AND SERVICE ALERT TYPES **********************/ #define HISTORY_ALL 0 /* all service and host alert */ #define HISTORY_SERVICE_ALL 1 /* all types of service alerts */ #define HISTORY_HOST_ALL 2 /* all types of host alerts */ #define HISTORY_SERVICE_WARNING 4 #define HISTORY_SERVICE_UNKNOWN 8 #define HISTORY_SERVICE_CRITICAL 16 #define HISTORY_SERVICE_RECOVERY 32 #define HISTORY_HOST_DOWN 64 #define HISTORY_HOST_UNREACHABLE 128 #define HISTORY_HOST_RECOVERY 256 /****************************** SORT TYPES *******************************/ #define SORT_NONE 0 #define SORT_ASCENDING 1 #define SORT_DESCENDING 2 /***************************** SORT OPTIONS ******************************/ #define SORT_NOTHING 0 #define SORT_HOSTNAME 1 #define SORT_SERVICENAME 2 #define SORT_SERVICESTATUS 3 #define SORT_LASTCHECKTIME 4 #define SORT_CURRENTATTEMPT 5 #define SORT_STATEDURATION 6 #define SORT_NEXTCHECKTIME 7 #define SORT_HOSTSTATUS 8 /****************** HOST AND SERVICE FILTER PROPERTIES *******************/ #define HOST_SCHEDULED_DOWNTIME 1 #define HOST_NO_SCHEDULED_DOWNTIME 2 #define HOST_STATE_ACKNOWLEDGED 4 #define HOST_STATE_UNACKNOWLEDGED 8 #define HOST_CHECKS_DISABLED 16 #define HOST_CHECKS_ENABLED 32 #define HOST_EVENT_HANDLER_DISABLED 64 #define HOST_EVENT_HANDLER_ENABLED 128 #define HOST_FLAP_DETECTION_DISABLED 256 #define HOST_FLAP_DETECTION_ENABLED 512 #define HOST_IS_FLAPPING 1024 #define HOST_IS_NOT_FLAPPING 2048 #define HOST_NOTIFICATIONS_DISABLED 4096 #define HOST_NOTIFICATIONS_ENABLED 8192 #define HOST_PASSIVE_CHECKS_DISABLED 16384 #define HOST_PASSIVE_CHECKS_ENABLED 32768 #define HOST_PASSIVE_CHECK 65536 #define HOST_ACTIVE_CHECK 131072 #define SERVICE_SCHEDULED_DOWNTIME 1 #define SERVICE_NO_SCHEDULED_DOWNTIME 2 #define SERVICE_STATE_ACKNOWLEDGED 4 #define SERVICE_STATE_UNACKNOWLEDGED 8 #define SERVICE_CHECKS_DISABLED 16 #define SERVICE_CHECKS_ENABLED 32 #define SERVICE_EVENT_HANDLER_DISABLED 64 #define SERVICE_EVENT_HANDLER_ENABLED 128 #define SERVICE_FLAP_DETECTION_ENABLED 256 #define SERVICE_FLAP_DETECTION_DISABLED 512 #define SERVICE_IS_FLAPPING 1024 #define SERVICE_IS_NOT_FLAPPING 2048 #define SERVICE_NOTIFICATIONS_DISABLED 4096 #define SERVICE_NOTIFICATIONS_ENABLED 8192 #define SERVICE_PASSIVE_CHECKS_DISABLED 16384 #define SERVICE_PASSIVE_CHECKS_ENABLED 32768 #define SERVICE_PASSIVE_CHECK 65536 #define SERVICE_ACTIVE_CHECK 131072 /****************************** SSI TYPES ********************************/ #define SSI_HEADER 0 #define SSI_FOOTER 1 /************************ CONTEXT-SENSITIVE HELP *************************/ #define CONTEXTHELP_STATUS_DETAIL "A1" #define CONTEXTHELP_STATUS_HGOVERVIEW "A2" #define CONTEXTHELP_STATUS_HGSUMMARY "A3" #define CONTEXTHELP_STATUS_HGGRID "A4" #define CONTEXTHELP_STATUS_SVCPROBLEMS "A5" #define CONTEXTHELP_STATUS_HOST_DETAIL "A6" #define CONTEXTHELP_STATUS_HOSTPROBLEMS "A7" #define CONTEXTHELP_STATUS_SGOVERVIEW "A8" #define CONTEXTHELP_STATUS_SGSUMMARY "A9" #define CONTEXTHELP_STATUS_SGGRID "A10" #define CONTEXTHELP_TAC "B1" #define CONTEXTHELP_MAP "C1" #define CONTEXTHELP_LOG "D1" #define CONTEXTHELP_HISTORY "E1" #define CONTEXTHELP_NOTIFICATIONS "F1" #define CONTEXTHELP_TRENDS_MENU1 "G1" #define CONTEXTHELP_TRENDS_MENU2 "G2" #define CONTEXTHELP_TRENDS_MENU3 "G3" #define CONTEXTHELP_TRENDS_MENU4 "G4" #define CONTEXTHELP_TRENDS_HOST "G5" #define CONTEXTHELP_TRENDS_SERVICE "G6" #define CONTEXTHELP_AVAIL_MENU1 "H1" #define CONTEXTHELP_AVAIL_MENU2 "H2" #define CONTEXTHELP_AVAIL_MENU3 "H3" #define CONTEXTHELP_AVAIL_MENU4 "H4" #define CONTEXTHELP_AVAIL_MENU5 "H5" #define CONTEXTHELP_AVAIL_HOSTGROUP "H6" #define CONTEXTHELP_AVAIL_HOST "H7" #define CONTEXTHELP_AVAIL_SERVICE "H8" #define CONTEXTHELP_AVAIL_SERVICEGROUP "H9" #define CONTEXTHELP_EXT_HOST "I1" #define CONTEXTHELP_EXT_SERVICE "I2" #define CONTEXTHELP_EXT_HOSTGROUP "I3" #define CONTEXTHELP_EXT_PROCESS "I4" #define CONTEXTHELP_EXT_PERFORMANCE "I5" #define CONTEXTHELP_EXT_COMMENTS "I6" #define CONTEXTHELP_EXT_DOWNTIME "I7" #define CONTEXTHELP_EXT_QUEUE "I8" #define CONTEXTHELP_EXT_SERVICEGROUP "I9" #define CONTEXTHELP_CMD_INPUT "J1" #define CONTEXTHELP_CMD_COMMIT "J2" #define CONTEXTHELP_OUTAGES "K1" #define CONTEXTHELP_CONFIG_MENU "L1" #define CONTEXTHELP_CONFIG_HOSTS "L2" #define CONTEXTHELP_CONFIG_HOSTDEPENDENCIES "L3" #define CONTEXTHELP_CONFIG_HOSTESCALATIONS "L4" #define CONTEXTHELP_CONFIG_HOSTGROUPS "L5" #define CONTEXTHELP_CONFIG_HOSTGROUPESCALATIONS "L6" #define CONTEXTHELP_CONFIG_SERVICES "L7" #define CONTEXTHELP_CONFIG_SERVICEDEPENDENCIES "L8" #define CONTEXTHELP_CONFIG_SERVICEESCALATIONS "L9" #define CONTEXTHELP_CONFIG_CONTACTS "L10" #define CONTEXTHELP_CONFIG_CONTACTGROUPS "L11" #define CONTEXTHELP_CONFIG_TIMEPERIODS "L12" #define CONTEXTHELP_CONFIG_COMMANDS "L13" #define CONTEXTHELP_CONFIG_HOSTEXTINFO "L14" #define CONTEXTHELP_CONFIG_SERVICEEXTINFO "L15" #define CONTEXTHELP_CONFIG_SERVICEGROUPS "L16" #define CONTEXTHELP_HISTOGRAM_MENU1 "M1" #define CONTEXTHELP_HISTOGRAM_MENU2 "M2" #define CONTEXTHELP_HISTOGRAM_MENU3 "M3" #define CONTEXTHELP_HISTOGRAM_MENU4 "M4" #define CONTEXTHELP_HISTOGRAM_HOST "M5" #define CONTEXTHELP_HISTOGRAM_SERVICE "M6" #define CONTEXTHELP_SUMMARY_MENU "N1" #define CONTEXTHELP_SUMMARY_RECENT_ALERTS "N2" #define CONTEXTHELP_SUMMARY_ALERT_TOTALS "N3" #define CONTEXTHELP_SUMMARY_HOSTGROUP_ALERT_TOTALS "N4" #define CONTEXTHELP_SUMMARY_HOST_ALERT_TOTALS "N5" #define CONTEXTHELP_SUMMARY_SERVICE_ALERT_TOTALS "N6" #define CONTEXTHELP_SUMMARY_ALERT_PRODUCERS "N7" #define CONTEXTHELP_SUMMARY_SERVICEGROUP_ALERT_TOTALS "N8" /************************** LIFO RETURN CODES ****************************/ #define LIFO_OK 0 #define LIFO_ERROR_MEMORY 1 #define LIFO_ERROR_FILE 2 #define LIFO_ERROR_DATA 3 /*************************** DATA STRUCTURES *****************************/ /* LIFO data structure */ typedef struct lifo_struct{ char *data; struct lifo_struct *next; }lifo; /* MMAPFILE structure - used for reading files via mmap() */ typedef struct mmapfile_struct{ char *path; int mode; int fd; unsigned long file_size; unsigned long current_position; unsigned long current_line; void *mmap_buf; }mmapfile; /******************************** FUNCTIONS *******************************/ void reset_cgi_vars(void); void free_cgi_vars(void); void free_memory(void); char * get_cgi_config_location(void); /* gets location of the CGI config file to read */ char * get_cmd_file_location(void); /* gets location of external command file to write to */ int read_cgi_config_file(char *); int read_main_config_file(char *); int read_all_object_configuration_data(char *,int); int read_all_status_data(char *,int); int hashfunc1(const char *name1, int hashslots); int hashfunc2(const char *name1, const char *name2, int hashslots); int compare_hashdata1(const char *,const char *); int compare_hashdata2(const char *,const char *,const char *,const char *); void strip(char *); /* strips newlines, carriage returns, and spaces from end of buffer */ void sanitize_plugin_output(char *); /* strips HTML and bad characters from plugin output */ void get_time_string(time_t *,char *,int,int); /* gets a date/time string */ void get_interval_time_string(int,char *,int); /* gets a time string for an interval of time */ void get_expire_time_string(time_t *,char *,int); /* gets a date/time string in the format used for Expire: tags*/ char * my_strtok(char *,char *); /* replacement for strtok() function - doesn't skip multiple tokens */ char * my_strsep (char **, const char *); char * url_encode(char *); /* encodes a string in proper URL format */ char * html_encode(char *); /* encodes a string in HTML format (for what the user sees) */ void get_time_breakdown(unsigned long,int *,int *,int *,int *); /* given total seconds, get days, hours, minutes, seconds */ void get_log_archive_to_use(int,char *,int); /* determines the name of the log archive to use */ void determine_log_rotation_times(int); int determine_archive_to_use_from_time(time_t); void print_extra_host_url(char *,char *); void print_extra_service_url(char *,char *,char *); void display_info_table(char *,int,authdata *); void display_nav_table(char *,int); void include_ssi_files(char *,int); /* include user-defined SSI footers/headers */ void include_ssi_file(char *); /* include user-defined SSI footer/header */ void cgi_config_file_error(char *); void main_config_file_error(char *); void object_data_error(void); void status_data_error(void); void display_context_help(char *); /* displays context-sensitive help window */ int read_file_into_lifo(char *); /* LIFO functions */ void free_lifo_memory(void); int push_lifo(char *); char *pop_lifo(void); mmapfile *mmap_fopen(char *); /* open a file read-only using mmap() */ int mmap_fclose(mmapfile *); char *mmap_fgets(mmapfile *); char *mmap_fgets_multiline(mmapfile *); #ifdef __cplusplus } #endif #endif nagios-2.6/include/comments.h0000664000076500007650000001153710353050230015616 0ustar nagiosnagios/***************************************************************************** * * COMMENTS.H - Header file for comment functions * * Last Modified: 12-15-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. * *****************************************************************************/ #ifndef _COMMENTS_H #define _COMMENTS_H #include "config.h" #include "common.h" #include "objects.h" #ifdef __cplusplus extern "C" { #endif /**************************** COMMENT SOURCES ******************************/ #define COMMENTSOURCE_INTERNAL 0 #define COMMENTSOURCE_EXTERNAL 1 /***************************** COMMENT TYPES *******************************/ #define HOST_COMMENT 1 #define SERVICE_COMMENT 2 /****************************** ENTRY TYPES ********************************/ #define USER_COMMENT 1 #define DOWNTIME_COMMENT 2 #define FLAPPING_COMMENT 3 #define ACKNOWLEDGEMENT_COMMENT 4 /*************************** CHAINED HASH LIMITS ***************************/ #define COMMENT_HASHSLOTS 1024 /**************************** DATA STRUCTURES ******************************/ /* COMMENT structure */ typedef struct comment_struct{ int comment_type; int entry_type; unsigned long comment_id; int source; int persistent; time_t entry_time; int expires; time_t expire_time; char *host_name; char *service_description; char *author; char *comment_data; struct comment_struct *next; struct comment_struct *nexthash; }comment; #ifdef NSCORE int initialize_comment_data(char *); /* initializes comment data */ int cleanup_comment_data(char *); /* cleans up comment data */ int add_new_comment(int,int,char *,char *,time_t,char *,char *,int,int,int,time_t,unsigned long *); /* adds a new host or service comment */ int add_new_host_comment(int,char *,time_t,char *,char *,int,int,int,time_t,unsigned long *); /* adds a new host comment */ int add_new_service_comment(int,char *,char *,time_t,char *,char *,int,int,int,time_t,unsigned long *); /* adds a new service comment */ int delete_comment(int,unsigned long); /* deletes a host or service comment */ int delete_host_comment(unsigned long); /* deletes a host comment */ int delete_service_comment(unsigned long); /* deletes a service comment */ int delete_all_comments(int,char *,char *); /* deletes all comments for a particular host or service */ int delete_all_host_comments(char *); /* deletes all comments for a specific host */ int delete_all_service_comments(char *,char *); /* deletes all comments for a specific service */ int check_for_expired_comment(unsigned long); /* expires a comment */ #endif comment *find_comment(unsigned long,int); /* finds a specific comment */ comment *find_service_comment(unsigned long); /* finds a specific service comment */ comment *find_host_comment(unsigned long); /* finds a specific host comment */ comment *get_first_comment_by_host(char *); comment *get_next_comment_by_host(char *,comment *); int number_of_host_comments(char *); /* returns the number of comments associated with a particular host */ int number_of_service_comments(char *, char *); /* returns the number of comments associated with a particular service */ int read_comment_data(char *); /* reads all host and service comments */ int add_comment(int,int,char *,char *,time_t,char *,char *,unsigned long,int,int,time_t,int); /* adds a comment (host or service) */ int add_host_comment(int,char *,time_t,char *,char *,unsigned long,int,int,time_t,int); /* adds a host comment */ int add_service_comment(int,char *,char *,time_t,char *,char *,unsigned long,int,int,time_t,int); /* adds a service comment */ int add_comment_to_hashlist(comment *); void free_comment_data(void); /* frees memory allocated to the comment list */ #ifdef __cplusplus } #endif #endif nagios-2.6/include/common.h0000664000076500007650000003344310532717361015277 0ustar nagiosnagios/************************************************************************ * * Nagios Common Header File * Written By: Ethan Galstad (nagios@nagios.org) * Last Modified: 12-01-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. ************************************************************************/ #define PROGRAM_VERSION "2.6" #define PROGRAM_MODIFICATION_DATE "11-27-2006" /* daemon is thread safe */ #ifdef NSCORE #ifndef _REENTRANT #define _REENTRANT #endif #ifndef _THREAD_SAFE #define _THREAD_SAFE #endif #endif /* Experimental performance tweaks - use with caution */ #undef USE_MEMORY_PERFORMANCE_TWEAKS /***************************** COMMANDS *********************************/ #define CMD_NONE 0 #define CMD_ADD_HOST_COMMENT 1 #define CMD_DEL_HOST_COMMENT 2 #define CMD_ADD_SVC_COMMENT 3 #define CMD_DEL_SVC_COMMENT 4 #define CMD_ENABLE_SVC_CHECK 5 #define CMD_DISABLE_SVC_CHECK 6 #define CMD_SCHEDULE_SVC_CHECK 7 #define CMD_DELAY_SVC_NOTIFICATION 9 #define CMD_DELAY_HOST_NOTIFICATION 10 #define CMD_DISABLE_NOTIFICATIONS 11 #define CMD_ENABLE_NOTIFICATIONS 12 #define CMD_RESTART_PROCESS 13 #define CMD_SHUTDOWN_PROCESS 14 #define CMD_ENABLE_HOST_SVC_CHECKS 15 #define CMD_DISABLE_HOST_SVC_CHECKS 16 #define CMD_SCHEDULE_HOST_SVC_CHECKS 17 #define CMD_DELAY_HOST_SVC_NOTIFICATIONS 19 /* currently unimplemented */ #define CMD_DEL_ALL_HOST_COMMENTS 20 #define CMD_DEL_ALL_SVC_COMMENTS 21 #define CMD_ENABLE_SVC_NOTIFICATIONS 22 #define CMD_DISABLE_SVC_NOTIFICATIONS 23 #define CMD_ENABLE_HOST_NOTIFICATIONS 24 #define CMD_DISABLE_HOST_NOTIFICATIONS 25 #define CMD_ENABLE_ALL_NOTIFICATIONS_BEYOND_HOST 26 #define CMD_DISABLE_ALL_NOTIFICATIONS_BEYOND_HOST 27 #define CMD_ENABLE_HOST_SVC_NOTIFICATIONS 28 #define CMD_DISABLE_HOST_SVC_NOTIFICATIONS 29 #define CMD_PROCESS_SERVICE_CHECK_RESULT 30 #define CMD_SAVE_STATE_INFORMATION 31 #define CMD_READ_STATE_INFORMATION 32 #define CMD_ACKNOWLEDGE_HOST_PROBLEM 33 #define CMD_ACKNOWLEDGE_SVC_PROBLEM 34 #define CMD_START_EXECUTING_SVC_CHECKS 35 #define CMD_STOP_EXECUTING_SVC_CHECKS 36 #define CMD_START_ACCEPTING_PASSIVE_SVC_CHECKS 37 #define CMD_STOP_ACCEPTING_PASSIVE_SVC_CHECKS 38 #define CMD_ENABLE_PASSIVE_SVC_CHECKS 39 #define CMD_DISABLE_PASSIVE_SVC_CHECKS 40 #define CMD_ENABLE_EVENT_HANDLERS 41 #define CMD_DISABLE_EVENT_HANDLERS 42 #define CMD_ENABLE_HOST_EVENT_HANDLER 43 #define CMD_DISABLE_HOST_EVENT_HANDLER 44 #define CMD_ENABLE_SVC_EVENT_HANDLER 45 #define CMD_DISABLE_SVC_EVENT_HANDLER 46 #define CMD_ENABLE_HOST_CHECK 47 #define CMD_DISABLE_HOST_CHECK 48 #define CMD_START_OBSESSING_OVER_SVC_CHECKS 49 #define CMD_STOP_OBSESSING_OVER_SVC_CHECKS 50 #define CMD_REMOVE_HOST_ACKNOWLEDGEMENT 51 #define CMD_REMOVE_SVC_ACKNOWLEDGEMENT 52 #define CMD_SCHEDULE_FORCED_HOST_SVC_CHECKS 53 #define CMD_SCHEDULE_FORCED_SVC_CHECK 54 #define CMD_SCHEDULE_HOST_DOWNTIME 55 #define CMD_SCHEDULE_SVC_DOWNTIME 56 #define CMD_ENABLE_HOST_FLAP_DETECTION 57 #define CMD_DISABLE_HOST_FLAP_DETECTION 58 #define CMD_ENABLE_SVC_FLAP_DETECTION 59 #define CMD_DISABLE_SVC_FLAP_DETECTION 60 #define CMD_ENABLE_FLAP_DETECTION 61 #define CMD_DISABLE_FLAP_DETECTION 62 #define CMD_ENABLE_HOSTGROUP_SVC_NOTIFICATIONS 63 #define CMD_DISABLE_HOSTGROUP_SVC_NOTIFICATIONS 64 #define CMD_ENABLE_HOSTGROUP_HOST_NOTIFICATIONS 65 #define CMD_DISABLE_HOSTGROUP_HOST_NOTIFICATIONS 66 #define CMD_ENABLE_HOSTGROUP_SVC_CHECKS 67 #define CMD_DISABLE_HOSTGROUP_SVC_CHECKS 68 #define CMD_CANCEL_HOST_DOWNTIME 69 /* not internally implemented */ #define CMD_CANCEL_SVC_DOWNTIME 70 /* not internally implemented */ #define CMD_CANCEL_ACTIVE_HOST_DOWNTIME 71 /* old - no longer used */ #define CMD_CANCEL_PENDING_HOST_DOWNTIME 72 /* old - no longer used */ #define CMD_CANCEL_ACTIVE_SVC_DOWNTIME 73 /* old - no longer used */ #define CMD_CANCEL_PENDING_SVC_DOWNTIME 74 /* old - no longer used */ #define CMD_CANCEL_ACTIVE_HOST_SVC_DOWNTIME 75 /* unimplemented */ #define CMD_CANCEL_PENDING_HOST_SVC_DOWNTIME 76 /* unimplemented */ #define CMD_FLUSH_PENDING_COMMANDS 77 #define CMD_DEL_HOST_DOWNTIME 78 #define CMD_DEL_SVC_DOWNTIME 79 #define CMD_ENABLE_FAILURE_PREDICTION 80 #define CMD_DISABLE_FAILURE_PREDICTION 81 #define CMD_ENABLE_PERFORMANCE_DATA 82 #define CMD_DISABLE_PERFORMANCE_DATA 83 #define CMD_SCHEDULE_HOSTGROUP_HOST_DOWNTIME 84 #define CMD_SCHEDULE_HOSTGROUP_SVC_DOWNTIME 85 #define CMD_SCHEDULE_HOST_SVC_DOWNTIME 86 #define CMD_PROCESS_HOST_CHECK_RESULT 87 #define CMD_START_EXECUTING_HOST_CHECKS 88 #define CMD_STOP_EXECUTING_HOST_CHECKS 89 #define CMD_START_ACCEPTING_PASSIVE_HOST_CHECKS 90 #define CMD_STOP_ACCEPTING_PASSIVE_HOST_CHECKS 91 #define CMD_ENABLE_PASSIVE_HOST_CHECKS 92 #define CMD_DISABLE_PASSIVE_HOST_CHECKS 93 #define CMD_START_OBSESSING_OVER_HOST_CHECKS 94 #define CMD_STOP_OBSESSING_OVER_HOST_CHECKS 95 #define CMD_SCHEDULE_HOST_CHECK 96 #define CMD_SCHEDULE_FORCED_HOST_CHECK 98 #define CMD_START_OBSESSING_OVER_SVC 99 #define CMD_STOP_OBSESSING_OVER_SVC 100 #define CMD_START_OBSESSING_OVER_HOST 101 #define CMD_STOP_OBSESSING_OVER_HOST 102 #define CMD_ENABLE_HOSTGROUP_HOST_CHECKS 103 #define CMD_DISABLE_HOSTGROUP_HOST_CHECKS 104 #define CMD_ENABLE_HOSTGROUP_PASSIVE_SVC_CHECKS 105 #define CMD_DISABLE_HOSTGROUP_PASSIVE_SVC_CHECKS 106 #define CMD_ENABLE_HOSTGROUP_PASSIVE_HOST_CHECKS 107 #define CMD_DISABLE_HOSTGROUP_PASSIVE_HOST_CHECKS 108 #define CMD_ENABLE_SERVICEGROUP_SVC_NOTIFICATIONS 109 #define CMD_DISABLE_SERVICEGROUP_SVC_NOTIFICATIONS 110 #define CMD_ENABLE_SERVICEGROUP_HOST_NOTIFICATIONS 111 #define CMD_DISABLE_SERVICEGROUP_HOST_NOTIFICATIONS 112 #define CMD_ENABLE_SERVICEGROUP_SVC_CHECKS 113 #define CMD_DISABLE_SERVICEGROUP_SVC_CHECKS 114 #define CMD_ENABLE_SERVICEGROUP_HOST_CHECKS 115 #define CMD_DISABLE_SERVICEGROUP_HOST_CHECKS 116 #define CMD_ENABLE_SERVICEGROUP_PASSIVE_SVC_CHECKS 117 #define CMD_DISABLE_SERVICEGROUP_PASSIVE_SVC_CHECKS 118 #define CMD_ENABLE_SERVICEGROUP_PASSIVE_HOST_CHECKS 119 #define CMD_DISABLE_SERVICEGROUP_PASSIVE_HOST_CHECKS 120 #define CMD_SCHEDULE_SERVICEGROUP_HOST_DOWNTIME 121 #define CMD_SCHEDULE_SERVICEGROUP_SVC_DOWNTIME 122 #define CMD_CHANGE_GLOBAL_HOST_EVENT_HANDLER 123 #define CMD_CHANGE_GLOBAL_SVC_EVENT_HANDLER 124 #define CMD_CHANGE_HOST_EVENT_HANDLER 125 #define CMD_CHANGE_SVC_EVENT_HANDLER 126 #define CMD_CHANGE_HOST_CHECK_COMMAND 127 #define CMD_CHANGE_SVC_CHECK_COMMAND 128 #define CMD_CHANGE_NORMAL_HOST_CHECK_INTERVAL 129 #define CMD_CHANGE_NORMAL_SVC_CHECK_INTERVAL 130 #define CMD_CHANGE_RETRY_SVC_CHECK_INTERVAL 131 #define CMD_CHANGE_MAX_HOST_CHECK_ATTEMPTS 132 #define CMD_CHANGE_MAX_SVC_CHECK_ATTEMPTS 133 #define CMD_SCHEDULE_AND_PROPAGATE_TRIGGERED_HOST_DOWNTIME 134 #define CMD_ENABLE_HOST_AND_CHILD_NOTIFICATIONS 135 #define CMD_DISABLE_HOST_AND_CHILD_NOTIFICATIONS 136 #define CMD_SCHEDULE_AND_PROPAGATE_HOST_DOWNTIME 137 #define CMD_ENABLE_SERVICE_FRESHNESS_CHECKS 138 #define CMD_DISABLE_SERVICE_FRESHNESS_CHECKS 139 #define CMD_ENABLE_HOST_FRESHNESS_CHECKS 140 #define CMD_DISABLE_HOST_FRESHNESS_CHECKS 141 #define CMD_SET_HOST_NOTIFICATION_NUMBER 142 #define CMD_SET_SVC_NOTIFICATION_NUMBER 143 /************************ SERVICE CHECK TYPES ****************************/ #define SERVICE_CHECK_ACTIVE 0 /* Nagios performed the service check */ #define SERVICE_CHECK_PASSIVE 1 /* the service check result was submitted by an external source */ /************************** HOST CHECK TYPES *****************************/ #define HOST_CHECK_ACTIVE 0 /* Nagios performed the host check */ #define HOST_CHECK_PASSIVE 1 /* the host check result was submitted by an external source */ /************************ SERVICE STATE TYPES ****************************/ #define SOFT_STATE 0 #define HARD_STATE 1 /************************* SCHEDULED DOWNTIME TYPES **********************/ #define SERVICE_DOWNTIME 1 /* service downtime */ #define HOST_DOWNTIME 2 /* host downtime */ #define ANY_DOWNTIME 3 /* host or service downtime */ /************************** ACKNOWLEDGEMENT TYPES ************************/ #define HOST_ACKNOWLEDGEMENT 0 #define SERVICE_ACKNOWLEDGEMENT 1 #define ACKNOWLEDGEMENT_NONE 0 #define ACKNOWLEDGEMENT_NORMAL 1 #define ACKNOWLEDGEMENT_STICKY 2 /**************************** DEPENDENCY TYPES ***************************/ #define NOTIFICATION_DEPENDENCY 1 #define EXECUTION_DEPENDENCY 2 /**************************** PROGRAM MODES ******************************/ #define STANDBY_MODE 0 #define ACTIVE_MODE 1 /************************** LOG ROTATION MODES ***************************/ #define LOG_ROTATION_NONE 0 #define LOG_ROTATION_HOURLY 1 #define LOG_ROTATION_DAILY 2 #define LOG_ROTATION_WEEKLY 3 #define LOG_ROTATION_MONTHLY 4 /***************************** LOG VERSIONS ******************************/ #define LOG_VERSION_1 "1.0" #define LOG_VERSION_2 "2.0" /************************* GENERAL DEFINITIONS **************************/ #define OK 0 #define ERROR -2 /* value was changed from -1 so as to not interfere with STATUS_UNKNOWN plugin result */ #ifndef TRUE #define TRUE 1 #elif (TRUE!=1) #define TRUE 1 #endif #ifndef FALSE #define FALSE 0 #elif (FALSE!=0) #define FALSE 0 #endif /****************** HOST CONFIG FILE READING OPTIONS ********************/ #define READ_HOSTS 1 #define READ_HOSTGROUPS 2 #define READ_CONTACTS 4 #define READ_CONTACTGROUPS 8 #define READ_SERVICES 16 #define READ_COMMANDS 32 #define READ_TIMEPERIODS 64 #define READ_SERVICEESCALATIONS 128 #define READ_HOSTGROUPESCALATIONS 256 /* no longer implemented */ #define READ_SERVICEDEPENDENCIES 512 #define READ_HOSTDEPENDENCIES 1024 #define READ_HOSTESCALATIONS 2048 #define READ_HOSTEXTINFO 4096 #define READ_SERVICEEXTINFO 8192 #define READ_SERVICEGROUPS 16384 #define READ_ALL_OBJECT_DATA READ_HOSTS | READ_HOSTGROUPS | READ_CONTACTS | READ_CONTACTGROUPS | READ_SERVICES | READ_COMMANDS | READ_TIMEPERIODS | READ_SERVICEESCALATIONS | READ_SERVICEDEPENDENCIES | READ_HOSTDEPENDENCIES | READ_HOSTESCALATIONS | READ_HOSTEXTINFO | READ_SERVICEEXTINFO | READ_SERVICEGROUPS /************************** DATE/TIME TYPES *****************************/ #define LONG_DATE_TIME 0 #define SHORT_DATE_TIME 1 #define SHORT_DATE 2 #define SHORT_TIME 3 #define HTTP_DATE_TIME 4 /* time formatted for use in HTTP headers */ /**************************** DATE FORMATS ******************************/ #define DATE_FORMAT_US 0 /* U.S. (MM-DD-YYYY HH:MM:SS) */ #define DATE_FORMAT_EURO 1 /* European (DD-MM-YYYY HH:MM:SS) */ #define DATE_FORMAT_ISO8601 2 /* ISO8601 (YYYY-MM-DD HH:MM:SS) */ #define DATE_FORMAT_STRICT_ISO8601 3 /* ISO8601 (YYYY-MM-DDTHH:MM:SS) */ /************************** MISC DEFINITIONS ****************************/ #define MAX_FILENAME_LENGTH 256 /* max length of path/filename that Nagios will process */ #define MAX_INPUT_BUFFER 1024 /* size in bytes of max. input buffer (for reading files) */ #define MAX_COMMAND_BUFFER 8192 /* max length of raw or processed command line */ #define MAX_DATETIME_LENGTH 48 /************************* MODIFIED ATTRIBUTES **************************/ #define MODATTR_NONE 0 #define MODATTR_NOTIFICATIONS_ENABLED 1 #define MODATTR_ACTIVE_CHECKS_ENABLED 2 #define MODATTR_PASSIVE_CHECKS_ENABLED 4 #define MODATTR_EVENT_HANDLER_ENABLED 8 #define MODATTR_FLAP_DETECTION_ENABLED 16 #define MODATTR_FAILURE_PREDICTION_ENABLED 32 #define MODATTR_PERFORMANCE_DATA_ENABLED 64 #define MODATTR_OBSESSIVE_HANDLER_ENABLED 128 #define MODATTR_EVENT_HANDLER_COMMAND 256 #define MODATTR_CHECK_COMMAND 512 #define MODATTR_NORMAL_CHECK_INTERVAL 1024 #define MODATTR_RETRY_CHECK_INTERVAL 2048 #define MODATTR_MAX_CHECK_ATTEMPTS 4096 #define MODATTR_FRESHNESS_CHECKS_ENABLED 8192 nagios-2.6/include/config.h.in0000664000076500007650000001301710432657342015655 0ustar nagiosnagios/************************************************************************ * * Nagios Config Header File * Written By: Ethan Galstad (nagios@nagios.org) * Last Modified: 05-16-2006 * * 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. ************************************************************************/ /***** NAGIOS STUFF *****/ #define DEFAULT_NAGIOS_USER nagios #define DEFAULT_NAGIOS_GROUP nagios /* Event broker integration */ #undef USE_EVENT_BROKER /* Embed a PERL interpreter into Nagios with optional cache for compiled code (contributed by Stephen Davies) */ #undef EMBEDDEDPERL #undef THREADEDPERL /* 0 = cache, 1 = do not cache */ #define DO_CLEAN "1" /* commands used by CGIs */ #undef TRACEROUTE_COMMAND #undef PING_COMMAND #undef PING_PACKETS_FIRST /* Debugging options */ /* function entry and exit */ #undef DEBUG0 /* general info messages */ #undef DEBUG1 /* warning messages */ #undef DEBUG2 /* service and host checks, other events */ #undef DEBUG3 /* service and host notifications */ #undef DEBUG4 /* SQL queries (defunct) */ #undef DEBUG5 /* I/O implementations */ #undef USE_XSDDEFAULT #undef USE_XCDDEFAULT #undef USE_XRDDEFAULT #undef USE_XODTEMPLATE #undef USE_XPDDEFAULT #undef USE_XDDDEFAULT /***** FUNCTION DEFINITIONS *****/ #undef HAVE_SETENV #undef HAVE_UNSETENV #undef HAVE_SOCKET #undef HAVE_STRDUP #undef HAVE_STRSTR #undef HAVE_STRTOUL #undef HAVE_INITGROUPS #undef HAVE_GETLOADAVG /***** MISC DEFINITIONS *****/ #undef USE_NANOSLEEP #undef STDC_HEADERS #undef HAVE_TM_ZONE #undef HAVE_TZNAME #undef USE_PROC #define SOCKET_SIZE_TYPE "" #define GETGROUPS_T "" #define RETSIGTYPE "" #ifndef RTLD_GLOBAL #define RTLD_GLOBAL 0 #endif #ifndef RTLD_NOW #define RTLD_NOW 0 #endif /***** HEADER FILES *****/ #include #include /* needed for the time_t structures we use later... */ /* this include must come before sys/resource.h or we can have problems on some OSes */ #undef TIME_WITH_SYS_TIME #undef HAVE_SYS_TIME_H #if TIME_WITH_SYS_TIME #include #include #else #if HAVE_SYS_TIME_H #include #else #include #endif #endif #undef HAVE_SYS_RESOURCE_H #ifdef HAVE_SYS_RESOURCE_H #include #endif #undef HAVE_LIMITS_H #ifdef HAVE_LIMITS_H #include #endif #undef HAVE_PWD_H #ifdef HAVE_PWD_H #include #endif #undef HAVE_GRP_H #ifdef HAVE_GRP_H #include #endif #undef HAVE_STRINGS_H #ifdef HAVE_STRINGS_H #include #endif #undef HAVE_STRING_H #ifdef HAVE_STRINGS_H #include #endif #undef HAVE_UNISTD_H #ifdef HAVE_UNISTD_H #include #endif #undef HAVE_SYSLOG_H #ifdef HAVE_SYSLOG_H #include #endif #undef HAVE_SIGNAL_H #ifdef HAVE_SIGNAL_H #include #endif #undef HAVE_SYS_STAT_H #ifdef HAVE_SYS_STAT_H #include #endif #undef HAVE_SYS_MMAN_H #ifdef HAVE_SYS_MMAN_H #include #endif #undef HAVE_FCNTL_H #ifdef HAVE_FCNTL_H #include #endif #undef HAVE_SYS_TYPES_H #ifdef HAVE_SYS_TYPES_H #include #endif #undef HAVE_SYS_WAIT_H #ifdef HAVE_SYS_WAIT_H #include #endif #undef HAVE_ERRNO_H #ifdef HAVE_ERRNO_H #include #endif #undef HAVE_SYS_TIMEB_H #if HAVE_SYS_TIMEB_H #include #endif #undef HAVE_SYS_IPC_H #ifdef HAVE_SYS_IPC_H #include #endif #undef HAVE_SYS_MSG_H #ifdef HAVE_SYS_MSG_H #include #endif #undef HAVE_MATH_H #ifdef HAVE_MATH_H #include #endif #undef HAVE_CTYPE_H #ifdef HAVE_CTYPE_H #include #endif #undef HAVE_DIRENT_H #ifdef HAVE_DIRENT_H #include #endif #undef HAVE_PTHREAD_H #ifdef HAVE_PTHREAD_H #include #endif #undef HAVE_REGEX_H #ifdef HAVE_REGEX_H #include #undef HAVE_SYS_SOCKET_H #ifdef HAVE_SYS_SOCKET_H #include #endif #undef HAVE_SOCKET #ifdef HAVE_SOCKET_H #include #endif #undef HAVE_NETINET_IN_H #ifdef HAVE_NETINET_IN_H #include #endif #undef HAVE_ARPA_INET_H #ifdef HAVE_ARPA_INET_H #include #endif #undef HAVE_NETDB_H #ifdef HAVE_NETDB_H #include #endif #undef HAVE_SYS_UN_H #ifdef HAVE_SYS_UN_H #include #endif #undef HAVE_SYS_POLL_H #ifdef HAVE_SYS_POLL_H #include #endif #undef HAVE_GETOPT_H #ifdef HAVE_GETOPT_H #include #endif #undef HAVE_LINUX_MODULE_H #ifdef HAVE_LINUX_MODULE_H #include #endif /* configure script should allow user to override ltdl choice, but this will do for now... */ #undef USE_LTDL #undef HAVE_LTDL_H #ifdef HAVE_LTDL_H #define USE_LTDL #endif #ifdef USE_LTDL #include #else #undef HAVE_DLFCN_H #ifdef HAVE_DLFCN_H #include #endif #endif /***** MARO DEFINITIONS *****/ /* this needs to come after all system include files, so we don't accidentally attempt to redefine it */ #ifndef WEXITSTATUS # define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8) #endif #ifndef WIFEXITED # define WIFEXITED(stat_val) (((stat_val) & 255) == 0) #endif #endif nagios-2.6/include/downtime.h0000664000076500007650000000667610341755747015655 0ustar nagiosnagios/***************************************************************************** * * DOWNTIME.H - Header file for scheduled downtime functions * * Copyright (c) 2001-2005 Ethan Galstad (nagios@nagios.org) * Last Modified: 11-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. * *****************************************************************************/ #ifndef _DOWNTIME_H #define _DOWNTIME_H #include "config.h" #include "common.h" #include "objects.h" #ifdef __cplusplus extern "C" { #endif /* SCHEDULED_DOWNTIME_ENTRY structure */ typedef struct scheduled_downtime_struct{ int type; char *host_name; char *service_description; time_t entry_time; time_t start_time; time_t end_time; int fixed; unsigned long triggered_by; unsigned long duration; unsigned long downtime_id; char *author; char *comment; #ifdef NSCORE unsigned long comment_id; int is_in_effect; int start_flex_downtime; int incremented_pending_downtime; #endif struct scheduled_downtime_struct *next; }scheduled_downtime; #ifdef NSCORE int initialize_downtime_data(char *); /* initializes scheduled downtime data */ int cleanup_downtime_data(char *); /* cleans up scheduled downtime data */ int add_new_downtime(int,char *,char *,time_t,char *,char *,time_t,time_t,int,unsigned long,unsigned long,unsigned long *); int add_new_host_downtime(char *,time_t,char *,char *,time_t,time_t,int,unsigned long,unsigned long,unsigned long *); int add_new_service_downtime(char *,char *,time_t,char *,char *,time_t,time_t,int,unsigned long,unsigned long,unsigned long *); int delete_host_downtime(unsigned long); int delete_service_downtime(unsigned long); int delete_downtime(int,unsigned long); int schedule_downtime(int,char *,char *,time_t,char *,char *,time_t,time_t,int,unsigned long,unsigned long,unsigned long *); int unschedule_downtime(int,unsigned long); int register_downtime(int,unsigned long); int handle_scheduled_downtime(scheduled_downtime *); int check_pending_flex_host_downtime(host *); int check_pending_flex_service_downtime(service *); int check_for_expired_downtime(void); #endif #ifdef NSCGI int read_downtime_data(char *); #endif int add_host_downtime(char *,time_t,char *,char *,time_t,time_t,int,unsigned long,unsigned long,unsigned long); int add_service_downtime(char *,char *,time_t,char *,char *,time_t,time_t,int,unsigned long,unsigned long,unsigned long); int add_downtime(int,char *,char *,time_t,char *,char *,time_t,time_t,int,unsigned long,unsigned long,unsigned long); scheduled_downtime *find_downtime(int,unsigned long); scheduled_downtime *find_host_downtime(unsigned long); scheduled_downtime *find_service_downtime(unsigned long); void free_downtime_data(void); /* frees memory allocated to scheduled downtime list */ #ifdef __cplusplus } #endif #endif nagios-2.6/include/epn_nagios.h0000664000076500007650000000157610157237705016135 0ustar nagiosnagios/************************************************************************ * * Embedded Perl Header File * Last Modified: 12-08-2004 * ************************************************************************/ /******** BEGIN EMBEDDED PERL INTERPRETER DECLARATIONS ********/ #include #include #include #undef ctime /* don't need perl's threaded version */ #undef printf /* can't use perl's printf until initialized */ /* In perl.h (or friends) there is a macro that defines sighandler as Perl_sighandler, so we must #undef it so we can use our sighandler() function */ #undef sighandler /* and we don't need perl's reentrant versions */ #undef localtime #undef getpwnam #undef getgrnam #undef strerror #ifdef aTHX EXTERN_C void xs_init(pTHX); #else EXTERN_C void xs_init(void); #endif /******** END EMBEDDED PERL INTERPRETER DECLARATIONS ********/ nagios-2.6/include/getcgi.h0000664000076500007650000000066010341755747015254 0ustar nagiosnagios/****************************************************** * * GETCGI.H - Nagios CGI Input Routine Include File * * Last Modified: 11-25-2005 * *****************************************************/ #ifdef __cplusplus extern "C" { #endif char **getcgivars(void); void free_cgivars(char **); void unescape_cgi_input(char *); void sanitize_cgi_input(char **); unsigned char hex_to_char(char *); #ifdef __cplusplus } #endif nagios-2.6/include/locations.h.in0000664000076500007650000000372210336571237016406 0ustar nagiosnagios/************************************************************************ * * Nagios Locations Header File * Written By: Ethan Galstad (nagios@nagios.org) * Last Modified: 03-24-2003 * * 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. ************************************************************************/ #define DEFAULT_TEMP_FILE "@localstatedir@/tempfile" #define DEFAULT_STATUS_FILE "@localstatedir@/status.dat" #define DEFAULT_LOG_FILE "@localstatedir@/nagios.log" #define DEFAULT_LOG_ARCHIVE_PATH "@localstatedir@/archives/" #define DEFAULT_COMMENT_FILE "@localstatedir@/comments.dat" #define DEFAULT_DOWNTIME_FILE "@localstatedir@/downtime.dat" #define DEFAULT_RETENTION_FILE "@localstatedir@/retention.dat" #define DEFAULT_COMMAND_FILE "@localstatedir@/rw/nagios.cmd" #define DEFAULT_CONFIG_FILE "@sysconfdir@/nagios.cfg" #define DEFAULT_PHYSICAL_HTML_PATH "@datadir@" #define DEFAULT_URL_HTML_PATH "@htmurl@" #define DEFAULT_PHYSICAL_CGIBIN_PATH "@sbindir@" #define DEFAULT_URL_CGIBIN_PATH "@cgiurl@" #define DEFAULT_CGI_CONFIG_FILE "@sysconfdir@/cgi.cfg" #define DEFAULT_LOCK_FILE "@lockfile@" #define DEFAULT_OBJECT_CACHE_FILE "@localstatedir@/objects.cache" #define DEFAULT_EVENT_BROKER_FILE "@localstatedir@/broker.socket" #define DEFAULT_P1_FILE "@bindir@/p1.pl" /**** EMBEDDED PERL ****/ #define DEFAULT_AUTH_FILE "" /**** EMBEDDED PERL - IS THIS USED? ****/ nagios-2.6/include/nagios.h.in0000664000076500007650000011671410520246622015671 0ustar nagiosnagios/************************************************************************ * * Nagios Main Header File * Written By: Ethan Galstad (nagios@nagios.org) * Last Modified: 10-26-2006 * * 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. ************************************************************************/ #ifndef _NAGIOS_H #define _NAGIOS_H #include "config.h" #include "common.h" #include "locations.h" #include "objects.h" #ifdef __cplusplus extern "C" { #endif #define MAX_COMMAND_ARGUMENTS 32 /* maximum number of $ARGx$ macros */ #define MAX_USER_MACROS 256 /* maximum number of $USERx$ macros */ #define MAX_STATE_LENGTH 32 /* length definitions used in macros */ #define MAX_STATETYPE_LENGTH 24 #define MAX_CHECKTYPE_LENGTH 8 #define MAX_NOTIFICATIONTYPE_LENGTH 32 #define MAX_NOTIFICATIONNUMBER_LENGTH 8 #define MAX_ATTEMPT_LENGTH 8 #define MAX_TOTALS_LENGTH 8 #define MAX_EXECUTIONTIME_LENGTH 10 #define MAX_LATENCY_LENGTH 10 #define MAX_DURATION_LENGTH 17 #define MAX_DOWNTIME_LENGTH 3 #define MAX_STATEID_LENGTH 2 #define MAX_PERCENTCHANGE_LENGTH 8 #define MACRO_ENV_VAR_PREFIX "NAGIOS_" #define MACRO_X_COUNT 99 /* size of macro_x[] array */ #define MACRO_HOSTNAME 0 #define MACRO_HOSTALIAS 1 #define MACRO_HOSTADDRESS 2 #define MACRO_SERVICEDESC 3 #define MACRO_SERVICESTATE 4 #define MACRO_SERVICESTATEID 5 #define MACRO_SERVICEATTEMPT 6 #define MACRO_LONGDATETIME 7 #define MACRO_SHORTDATETIME 8 #define MACRO_DATE 9 #define MACRO_TIME 10 #define MACRO_TIMET 11 #define MACRO_LASTHOSTCHECK 12 #define MACRO_LASTSERVICECHECK 13 #define MACRO_LASTHOSTSTATECHANGE 14 #define MACRO_LASTSERVICESTATECHANGE 15 #define MACRO_HOSTOUTPUT 16 #define MACRO_SERVICEOUTPUT 17 #define MACRO_HOSTPERFDATA 18 #define MACRO_SERVICEPERFDATA 19 #define MACRO_CONTACTNAME 20 #define MACRO_CONTACTALIAS 21 #define MACRO_CONTACTEMAIL 22 #define MACRO_CONTACTPAGER 23 #define MACRO_ADMINEMAIL 24 #define MACRO_ADMINPAGER 25 #define MACRO_HOSTSTATE 26 #define MACRO_HOSTSTATEID 27 #define MACRO_HOSTATTEMPT 28 #define MACRO_NOTIFICATIONTYPE 29 #define MACRO_NOTIFICATIONNUMBER 30 #define MACRO_HOSTEXECUTIONTIME 31 #define MACRO_SERVICEEXECUTIONTIME 32 #define MACRO_HOSTLATENCY 33 #define MACRO_SERVICELATENCY 34 #define MACRO_HOSTDURATION 35 #define MACRO_SERVICEDURATION 36 #define MACRO_HOSTDURATIONSEC 37 #define MACRO_SERVICEDURATIONSEC 38 #define MACRO_HOSTDOWNTIME 39 #define MACRO_SERVICEDOWNTIME 40 #define MACRO_HOSTSTATETYPE 41 #define MACRO_SERVICESTATETYPE 42 #define MACRO_HOSTPERCENTCHANGE 43 #define MACRO_SERVICEPERCENTCHANGE 44 #define MACRO_HOSTGROUPNAME 45 #define MACRO_HOSTGROUPALIAS 46 #define MACRO_SERVICEGROUPNAME 47 #define MACRO_SERVICEGROUPALIAS 48 #define MACRO_HOSTACKAUTHOR 49 #define MACRO_HOSTACKCOMMENT 50 #define MACRO_SERVICEACKAUTHOR 51 #define MACRO_SERVICEACKCOMMENT 52 #define MACRO_LASTSERVICEOK 53 #define MACRO_LASTSERVICEWARNING 54 #define MACRO_LASTSERVICEUNKNOWN 55 #define MACRO_LASTSERVICECRITICAL 56 #define MACRO_LASTHOSTUP 57 #define MACRO_LASTHOSTDOWN 58 #define MACRO_LASTHOSTUNREACHABLE 59 #define MACRO_SERVICECHECKCOMMAND 60 #define MACRO_HOSTCHECKCOMMAND 61 #define MACRO_MAINCONFIGFILE 62 #define MACRO_STATUSDATAFILE 63 #define MACRO_COMMENTDATAFILE 64 #define MACRO_DOWNTIMEDATAFILE 65 #define MACRO_RETENTIONDATAFILE 66 #define MACRO_OBJECTCACHEFILE 67 #define MACRO_TEMPFILE 68 #define MACRO_LOGFILE 69 #define MACRO_RESOURCEFILE 70 #define MACRO_COMMANDFILE 71 #define MACRO_HOSTPERFDATAFILE 72 #define MACRO_SERVICEPERFDATAFILE 73 #define MACRO_HOSTACTIONURL 74 #define MACRO_HOSTNOTESURL 75 #define MACRO_HOSTNOTES 76 #define MACRO_SERVICEACTIONURL 77 #define MACRO_SERVICENOTESURL 78 #define MACRO_SERVICENOTES 79 #define MACRO_TOTALHOSTSUP 80 #define MACRO_TOTALHOSTSDOWN 81 #define MACRO_TOTALHOSTSUNREACHABLE 82 #define MACRO_TOTALHOSTSDOWNUNHANDLED 83 #define MACRO_TOTALHOSTSUNREACHABLEUNHANDLED 84 #define MACRO_TOTALHOSTPROBLEMS 85 #define MACRO_TOTALHOSTPROBLEMSUNHANDLED 86 #define MACRO_TOTALSERVICESOK 87 #define MACRO_TOTALSERVICESWARNING 88 #define MACRO_TOTALSERVICESCRITICAL 89 #define MACRO_TOTALSERVICESUNKNOWN 90 #define MACRO_TOTALSERVICESWARNINGUNHANDLED 91 #define MACRO_TOTALSERVICESCRITICALUNHANDLED 92 #define MACRO_TOTALSERVICESUNKNOWNUNHANDLED 93 #define MACRO_TOTALSERVICEPROBLEMS 94 #define MACRO_TOTALSERVICEPROBLEMSUNHANDLED 95 #define MACRO_PROCESSSTARTTIME 96 #define MACRO_HOSTCHECKTYPE 97 #define MACRO_SERVICECHECKTYPE 98 #define DEFAULT_LOG_LEVEL 1 /* log all events to main log file */ #define DEFAULT_USE_SYSLOG 1 /* log events to syslog? 1=yes, 0=no */ #define DEFAULT_SYSLOG_LEVEL 2 /* log only severe events to syslog */ #define DEFAULT_NOTIFICATION_LOGGING 1 /* log notification events? 1=yes, 0=no */ #define DEFAULT_INTER_CHECK_DELAY 5.0 /* seconds between initial service check scheduling */ #define DEFAULT_INTERLEAVE_FACTOR 1 /* default interleave to use when scheduling checks */ #define DEFAULT_SLEEP_TIME 0.5 /* seconds between event run checks */ #define DEFAULT_INTERVAL_LENGTH 60 /* seconds per interval unit for check scheduling */ #define DEFAULT_RETRY_INTERVAL 30 /* services are retried in 30 seconds if they're not OK */ #define DEFAULT_COMMAND_CHECK_INTERVAL -1 /* interval to check for external commands (default = as often as possible) */ #define DEFAULT_SERVICE_REAPER_INTERVAL 10 /* interval in seconds to reap service check results */ #define DEFAULT_MAX_REAPER_TIME 30 /* maximum number of seconds to spend reaping service checks before we break out for a while */ #define DEFAULT_MAX_PARALLEL_SERVICE_CHECKS 0 /* maximum number of service checks we can have running at any given time (0=unlimited) */ #define DEFAULT_RETENTION_UPDATE_INTERVAL 60 /* minutes between auto-save of retention data */ #define DEFAULT_RETENTION_SCHEDULING_HORIZON 900 /* max seconds between program restarts that we will preserve scheduling information */ #define DEFAULT_STATUS_UPDATE_INTERVAL 60 /* seconds between aggregated status data updates */ #define DEFAULT_FRESHNESS_CHECK_INTERVAL 60 /* seconds between service result freshness checks */ #define DEFAULT_AUTO_RESCHEDULING_INTERVAL 30 /* seconds between host and service check rescheduling events */ #define DEFAULT_AUTO_RESCHEDULING_WINDOW 180 /* window of time (in seconds) for which we should reschedule host and service checks */ #define DEFAULT_NOTIFICATION_TIMEOUT 30 /* max time in seconds to wait for notification commands to complete */ #define DEFAULT_EVENT_HANDLER_TIMEOUT 30 /* max time in seconds to wait for event handler commands to complete */ #define DEFAULT_HOST_CHECK_TIMEOUT 30 /* max time in seconds to wait for host check commands to complete */ #define DEFAULT_SERVICE_CHECK_TIMEOUT 60 /* max time in seconds to wait for service check commands to complete */ #define DEFAULT_OCSP_TIMEOUT 15 /* max time in seconds to wait for obsessive compulsive processing commands to complete */ #define DEFAULT_OCHP_TIMEOUT 15 /* max time in seconds to wait for obsessive compulsive processing commands to complete */ #define DEFAULT_PERFDATA_TIMEOUT 5 /* max time in seconds to wait for performance data commands to complete */ #define DEFAULT_TIME_CHANGE_THRESHOLD 900 /* compensate for time changes of more than 15 minutes */ #define DEFAULT_LOG_HOST_RETRIES 0 /* don't log host retries */ #define DEFAULT_LOG_SERVICE_RETRIES 0 /* don't log service retries */ #define DEFAULT_LOG_EVENT_HANDLERS 1 /* log event handlers */ #define DEFAULT_LOG_INITIAL_STATES 0 /* don't log initial service and host states */ #define DEFAULT_LOG_EXTERNAL_COMMANDS 1 /* log external commands */ #define DEFAULT_LOG_PASSIVE_CHECKS 1 /* log passive service checks */ #define DEFAULT_AGGRESSIVE_HOST_CHECKING 0 /* don't use "aggressive" host checking */ #define DEFAULT_CHECK_EXTERNAL_COMMANDS 0 /* don't check for external commands */ #define DEFAULT_CHECK_ORPHANED_SERVICES 1 /* don't check for orphaned services */ #define DEFAULT_ENABLE_FLAP_DETECTION 0 /* don't enable flap detection */ #define DEFAULT_PROCESS_PERFORMANCE_DATA 0 /* don't process performance data */ #define DEFAULT_CHECK_SERVICE_FRESHNESS 1 /* check service result freshness */ #define DEFAULT_CHECK_HOST_FRESHNESS 0 /* don't check host result freshness */ #define DEFAULT_AUTO_RESCHEDULE_CHECKS 0 /* don't auto-reschedule host and service checks */ #define DEFAULT_LOW_SERVICE_FLAP_THRESHOLD 20.0 /* low threshold for detection of service flapping */ #define DEFAULT_HIGH_SERVICE_FLAP_THRESHOLD 30.0 /* high threshold for detection of service flapping */ #define DEFAULT_LOW_HOST_FLAP_THRESHOLD 20.0 /* low threshold for detection of host flapping */ #define DEFAULT_HIGH_HOST_FLAP_THRESHOLD 30.0 /* high threshold for detection of host flapping */ #define DEFAULT_HOST_CHECK_SPREAD 30 /* max minutes to schedule all initial host checks */ #define DEFAULT_SERVICE_CHECK_SPREAD 30 /* max minutes to schedule all initial service checks */ /******************* LOGGING TYPES ********************/ #define NSLOG_RUNTIME_ERROR 1 #define NSLOG_RUNTIME_WARNING 2 #define NSLOG_VERIFICATION_ERROR 4 #define NSLOG_VERIFICATION_WARNING 8 #define NSLOG_CONFIG_ERROR 16 #define NSLOG_CONFIG_WARNING 32 #define NSLOG_PROCESS_INFO 64 #define NSLOG_EVENT_HANDLER 128 /*#define NSLOG_NOTIFICATION 256*/ /* NOT USED ANYMORE - CAN BE REUSED */ #define NSLOG_EXTERNAL_COMMAND 512 #define NSLOG_HOST_UP 1024 #define NSLOG_HOST_DOWN 2048 #define NSLOG_HOST_UNREACHABLE 4096 #define NSLOG_SERVICE_OK 8192 #define NSLOG_SERVICE_UNKNOWN 16384 #define NSLOG_SERVICE_WARNING 32768 #define NSLOG_SERVICE_CRITICAL 65536 #define NSLOG_PASSIVE_CHECK 131072 #define NSLOG_INFO_MESSAGE 262144 #define NSLOG_HOST_NOTIFICATION 524288 #define NSLOG_SERVICE_NOTIFICATION 1048576 /******************** HOST STATUS *********************/ #define HOST_UP 0 #define HOST_DOWN 1 #define HOST_UNREACHABLE 2 /******************* STATE LOGGING TYPES **************/ #define INITIAL_STATES 1 #define CURRENT_STATES 2 /************ SERVICE DEPENDENCY VALUES ***************/ #define DEPENDENCIES_OK 0 #define DEPENDENCIES_FAILED 1 /*********** ROUTE CHECK PROPAGATION TYPES ************/ #define PROPAGATE_TO_PARENT_HOSTS 1 #define PROPAGATE_TO_CHILD_HOSTS 2 /****************** SERVICE STATES ********************/ #define STATE_OK 0 #define STATE_WARNING 1 #define STATE_CRITICAL 2 #define STATE_UNKNOWN 3 /* changed from -1 on 02/24/2001 */ /****************** FLAPPING TYPES ********************/ #define HOST_FLAPPING 0 #define SERVICE_FLAPPING 1 /**************** NOTIFICATION TYPES ******************/ #define HOST_NOTIFICATION 0 #define SERVICE_NOTIFICATION 1 /************* NOTIFICATION REASON TYPES ***************/ #define NOTIFICATION_NORMAL 0 #define NOTIFICATION_ACKNOWLEDGEMENT 1 #define NOTIFICATION_FLAPPINGSTART 2 #define NOTIFICATION_FLAPPINGSTOP 3 /**************** EVENT HANDLER TYPES *****************/ #define HOST_EVENTHANDLER 0 #define SERVICE_EVENTHANDLER 1 #define GLOBAL_HOST_EVENTHANDLER 2 #define GLOBAL_SERVICE_EVENTHANDLER 3 /***************** STATE CHANGE TYPES *****************/ #define HOST_STATECHANGE 0 #define SERVICE_STATECHANGE 1 /******************* EVENT TYPES **********************/ #define EVENT_SERVICE_CHECK 0 /* active service check */ #define EVENT_COMMAND_CHECK 1 /* external command check */ #define EVENT_LOG_ROTATION 2 /* log file rotation */ #define EVENT_PROGRAM_SHUTDOWN 3 /* program shutdown */ #define EVENT_PROGRAM_RESTART 4 /* program restart */ #define EVENT_SERVICE_REAPER 5 /* reaps results from service checks */ #define EVENT_ORPHAN_CHECK 6 /* checks for orphaned service checks */ #define EVENT_RETENTION_SAVE 7 /* save (dump) retention data */ #define EVENT_STATUS_SAVE 8 /* save (dump) status data */ #define EVENT_SCHEDULED_DOWNTIME 9 /* scheduled host or service downtime */ #define EVENT_SFRESHNESS_CHECK 10 /* checks service result "freshness" */ #define EVENT_EXPIRE_DOWNTIME 11 /* checks for (and removes) expired scheduled downtime */ #define EVENT_HOST_CHECK 12 /* active host check */ #define EVENT_HFRESHNESS_CHECK 13 /* checks host result "freshness" */ #define EVENT_RESCHEDULE_CHECKS 14 /* adjust scheduling of host and service checks */ #define EVENT_EXPIRE_COMMENT 15 /* removes expired comments */ #define EVENT_SLEEP 98 /* asynchronous sleep event that occurs when event queues are empty */ #define EVENT_USER_FUNCTION 99 /* USER-defined function (modules) */ /******* INTER-CHECK DELAY CALCULATION TYPES **********/ #define ICD_NONE 0 /* no inter-check delay */ #define ICD_DUMB 1 /* dumb delay of 1 second */ #define ICD_SMART 2 /* smart delay */ #define ICD_USER 3 /* user-specified delay */ /******* INTERLEAVE FACTOR CALCULATION TYPES **********/ #define ILF_USER 0 /* user-specified interleave factor */ #define ILF_SMART 1 /* smart interleave */ /************** SERVICE CHECK OPTIONS *****************/ #define CHECK_OPTION_NONE 0 /* no check options */ #define CHECK_OPTION_FORCE_EXECUTION 1 /* force execution of a service check (ignores disabled services, invalid timeperiods) */ /************ SCHEDULED DOWNTIME TYPES ****************/ #define ACTIVE_DOWNTIME 0 /* active downtime - currently in effect */ #define PENDING_DOWNTIME 1 /* pending downtime - scheduled for the future */ /************* MACRO CLEANING OPTIONS *****************/ #define STRIP_ILLEGAL_MACRO_CHARS 1 #define ESCAPE_MACRO_CHARS 2 #define URL_ENCODE_MACRO_CHARS 4 /****************** DATA STRUCTURES *******************/ /* TIMED_EVENT structure */ typedef struct timed_event_struct{ int event_type; time_t run_time; int recurring; unsigned long event_interval; int compensate_for_time_change; void *timing_func; void *event_data; void *event_args; struct timed_event_struct *next; }timed_event; /* NOTIFY_LIST structure */ typedef struct notify_list_struct{ contact *contact; struct notify_list_struct *next; }notification; /* SERVICE_MESSAGE structure */ typedef struct service_message_struct{ char host_name[MAX_HOSTNAME_LENGTH]; /* host name */ char description[MAX_SERVICEDESC_LENGTH]; /* service description */ int return_code; /* plugin return code */ int exited_ok; /* did the plugin check return okay? */ int check_type; /* was this an active or passive service check? */ int parallelized; /* was this check run in parallel? */ struct timeval start_time; /* time the service check was initiated */ struct timeval finish_time; /* time the service check was completed */ int early_timeout; /* did the service check timeout? */ char output[MAX_PLUGINOUTPUT_LENGTH]; /* plugin output */ }service_message; /* SCHED_INFO structure */ typedef struct sched_info_struct{ int total_services; int total_scheduled_services; int total_hosts; int total_scheduled_hosts; double average_services_per_host; double average_scheduled_services_per_host; unsigned long service_check_interval_total; unsigned long host_check_interval_total; double average_service_check_interval; double average_host_check_interval; double average_service_inter_check_delay; double average_host_inter_check_delay; double service_inter_check_delay; double host_inter_check_delay; int service_interleave_factor; int max_service_check_spread; int max_host_check_spread; time_t first_service_check; time_t last_service_check; time_t first_host_check; time_t last_host_check; }sched_info; /* PASSIVE_CHECK_RESULT structure */ typedef struct passive_check_result_struct{ char *host_name; char *svc_description; int return_code; char *output; time_t check_time; struct passive_check_result_struct *next; }passive_check_result; /* SCHEDULED_DOWNTIME_ENTRY structure */ typedef struct scheduled_downtime_entry_struct{ int type; void *object; time_t start_time; time_t end_time; int is_in_effect; int fixed; unsigned long duration; int comment_id; }scheduled_downtime_entry; /* CIRCULAR_BUFFER structure - used by worker threads */ typedef struct circular_buffer_struct{ void **buffer; int tail; int head; int items; unsigned long overflow; pthread_mutex_t buffer_lock; }circular_buffer; /* MMAPFILE structure - used for reading files via mmap() */ typedef struct mmapfile_struct{ char *path; int mode; int fd; unsigned long file_size; unsigned long current_position; unsigned long current_line; void *mmap_buf; }mmapfile; /* slots in circular buffers */ #define COMMAND_BUFFER_SLOTS 1024 #define SERVICE_BUFFER_SLOTS 1024 /* worker threads */ #define TOTAL_WORKER_THREADS 2 #define COMMAND_WORKER_THREAD 0 #define SERVICE_WORKER_THREAD 1 /******************** FUNCTIONS **********************/ /**** Configuration Functions ****/ int read_main_config_file(char *); /* reads the main config file (nagios.cfg) */ int read_resource_file(char *); /* processes macros in resource file */ int read_all_object_data(char *); /* reads all object config data */ /**** Setup Functions ****/ int pre_flight_check(void); /* try and verify the configuration data */ void init_timing_loop(void); /* setup the initial scheduling queue */ void setup_sighandler(void); /* trap signals */ void reset_sighandler(void); /* reset signals to default action */ int daemon_init(void); /* switches to daemon mode */ int drop_privileges(char *,char *); /* drops privileges before startup */ void display_scheduling_info(void); /* displays service check scheduling information */ /**** IPC Functions ****/ int read_svc_message(service_message *); /* reads a service check message from the message pipe */ int write_svc_message(service_message *); /* writes a service check message to the message pipe */ int open_command_file(void); /* creates the external command file as a named pipe (FIFO) and opens it for reading */ int close_command_file(void); /* closes and deletes the external command file (FIFO) */ /**** Monitoring/Event Handler Functions ****/ int schedule_new_event(int,int,time_t,int,unsigned long,void *,int,void *,void *); /* schedules a new timed event */ void reschedule_event(timed_event *,timed_event **); /* reschedules an event */ int deschedule_event(int,int,void *,void *); /* removes an event from the schedule */ void add_event(timed_event *,timed_event **); /* adds an event to the execution queue */ void remove_event(timed_event *,timed_event **); /* remove an event from the execution queue */ int event_execution_loop(void); /* main monitoring/event handler loop */ int handle_timed_event(timed_event *); /* top level handler for timed events */ void run_service_check(service *); /* parallelized service check routine */ void reap_service_checks(void); /* handles results from service checks */ int check_service_dependencies(service *,int); /* checks service dependencies */ int check_host_dependencies(host *,int); /* checks host dependencies */ void check_for_orphaned_services(void); /* checks for orphaned services */ void check_service_result_freshness(void); /* checks the "freshness" of service check results */ void check_host_result_freshness(void); /* checks the "freshness" of host check results */ void adjust_check_scheduling(void); /* auto-adjusts scheduling of host and service checks */ int my_system(char *,int,int *,double *,char *,int); /* executes a command via popen(), but also protects against timeouts */ void compensate_for_system_time_change(unsigned long,unsigned long); /* attempts to compensate for a change in the system time */ void adjust_timestamp_for_time_change(time_t,time_t,unsigned long,time_t *); /* adjusts a timestamp variable for a system time change */ void resort_event_list(timed_event **); /* resorts event list by event run time for system time changes */ /**** Flap Detection Functions ****/ void check_for_service_flapping(service *,int); /* determines whether or not a service is "flapping" between states */ void check_for_host_flapping(host *,int); /* determines whether or not a host is "flapping" between states */ void set_service_flap(service *,double,double,double); /* handles a service that is flapping */ void clear_service_flap(service *,double,double,double); /* handles a service that has stopped flapping */ void set_host_flap(host *,double,double,double); /* handles a host that is flapping */ void clear_host_flap(host *,double,double,double); /* handles a host that has stopped flapping */ void enable_flap_detection_routines(void); /* enables flap detection on a program-wide basis */ void disable_flap_detection_routines(void); /* disables flap detection on a program-wide basis */ void enable_host_flap_detection(host *); /* enables flap detection for a particular host */ void disable_host_flap_detection(host *); /* disables flap detection for a particular host */ void enable_service_flap_detection(service *); /* enables flap detection for a particular service */ void disable_service_flap_detection(service *); /* disables flap detection for a particular service */ /**** Route/Host Check Functions ****/ int verify_route_to_host(host *,int); /* on-demand check of whether a host is up, down, or unreachable */ int run_scheduled_host_check(host *); /* runs a scheduled host check */ int check_host(host *,int,int); /* checks if a host is up or down */ int run_host_check(host *,int); /* runs a host check */ int handle_host_state(host *); /* top level host state handler */ /**** Event Handler Functions ****/ int obsessive_compulsive_service_check_processor(service *); /* distributed monitoring craziness... */ int obsessive_compulsive_host_check_processor(host *); /* distributed monitoring craziness... */ int handle_service_event(service *); /* top level service event logic */ int run_service_event_handler(service *); /* runs the event handler for a specific service */ int run_global_service_event_handler(service *); /* runs the global service event handler */ int handle_host_event(host *); /* top level host event logic */ int run_host_event_handler(host *); /* runs the event handler for a specific host */ int run_global_host_event_handler(host *); /* runs the global host event handler */ /**** Notification Functions ****/ int check_service_notification_viability(service *,int); /* checks viability of notifying all contacts about a service */ int is_valid_escalation_for_service_notification(service *,serviceescalation *); /* checks if an escalation entry is valid for a particular service notification */ int should_service_notification_be_escalated(service *); /* checks if a service notification should be escalated */ int service_notification(service *,int,char *,char *); /* notify all contacts about a service (problem or recovery) */ int check_contact_service_notification_viability(contact *,service *,int); /* checks viability of notifying a contact about a service */ int notify_contact_of_service(contact *,service *,int,char *,char *,int); /* notify a single contact about a service */ int check_host_notification_viability(host *,int); /* checks viability of notifying all contacts about a host */ int is_valid_host_escalation_for_host_notification(host *,hostescalation *); /* checks if an escalation entry is valid for a particular host notification */ int should_host_notification_be_escalated(host *); /* checks if a host notification should be escalated */ int host_notification(host *,int,char *,char *); /* notify all contacts about a host (problem or recovery) */ int check_contact_host_notification_viability(contact *,host *,int); /* checks viability of notifying a contact about a host */ int notify_contact_of_host(contact *,host *,int,char *,char *,int); /* notify a single contact about a host */ int create_notification_list_from_host(host *,int *); /* given a host, create list of contacts to be notified (remove duplicates) */ int create_notification_list_from_service(service *,int *); /* given a service, create list of contacts to be notified (remove duplicates) */ int add_notification(contact *); /* adds a notification instance */ notification * find_notification(char *); /* finds a notification object */ time_t get_next_host_notification_time(host *,time_t); /* calculates nex acceptable re-notification time for a host */ time_t get_next_service_notification_time(service *,time_t); /* calculates nex acceptable re-notification time for a service */ /**** Logging Functions ****/ int write_to_logs_and_console(char *,unsigned long,int); /* writes a string to screen and logs */ int write_to_console(char *); /* writes a string to screen */ int write_to_all_logs(char *,unsigned long); /* writes a string to main log file and syslog facility */ int write_to_all_logs_with_timestamp(char *,unsigned long,time_t *); /* writes a string to main log file and syslog facility */ int write_to_log(char *,unsigned long,time_t *); /* write a string to the main log file */ int write_to_syslog(char *,unsigned long); /* write a string to the syslog facility */ int log_service_event(service *); /* logs a service event */ int log_host_event(host *); /* logs a host event */ int log_host_states(int,time_t *); /* logs initial/current host states */ int log_service_states(int,time_t *); /* logs initial/current service states */ int rotate_log_file(time_t); /* rotates the main log file */ int write_log_file_info(time_t *); /* records log file/version info */ /**** Cleanup Functions ****/ void cleanup(void); /* cleanup after ourselves (before quitting or restarting) */ void free_memory(void); /* free memory allocated to all linked lists in memory */ int reset_variables(void); /* reset all global variables */ void free_notification_list(void); /* frees all memory allocated to the notification list */ /**** Hash Functions ****/ int hashfunc1(const char *name1, int hashslots); int hashfunc2(const char *name1, const char *name2, int hashslots); int compare_hashdata1(const char *,const char *); int compare_hashdata2(const char *,const char *,const char *,const char *); /**** Miscellaneous Functions ****/ void sighandler(int); /* handles signals */ void service_check_sighandler(int); /* handles timeouts when executing service checks */ void my_system_sighandler(int); /* handles timeouts when executing commands via my_system() */ void file_lock_sighandler(int); /* handles timeouts while waiting for file locks */ void strip(char *); /* strips whitespace from string */ char *my_strtok(char *,char *); /* my replacement for strtok() function (doesn't skip consecutive tokens) */ char *my_strsep(char **,const char *); /* Solaris doesn't have strsep(), so I took this from the glibc source code */ char *get_url_encoded_string(char *); /* URL encode a string */ int contains_illegal_object_chars(char *); /* tests whether or not an object name (host, service, etc.) contains illegal characters */ int my_rename(char *,char *); /* renames a file - works across filesystems */ void get_raw_command_line(char *,char *,int,int); /* given a raw command line, determine the actual command to run */ int check_time_against_period(time_t,char *); /* check to see if a specific time is covered by a time period */ void get_next_valid_time(time_t, time_t *,char *); /* get the next valid time in a time period */ void get_datetime_string(time_t *,char *,int,int); /* get a date/time string for use in output */ time_t get_next_log_rotation_time(void); /* determine the next time to schedule a log rotation */ int init_embedded_perl(char **); /* initialized embedded perl interpreter */ int deinit_embedded_perl(void); /* cleans up embedded perl */ /**** Macro Functions ****/ int process_macros(char *,char *,int,int); /* replace macros with their actual values */ char *clean_macro_chars(char *,int); /* cleans macros characters before insertion into output string */ int grab_service_macros(service *); /* updates the service macro data */ int grab_host_macros(host *); /* updates the host macro data */ int grab_contact_macros(contact *); /* updates the contact macro data */ int grab_datetime_macros(void); /* updates date/time macros */ int grab_summary_macros(contact *); /* updates summary macros */ int grab_on_demand_macro(char *); /* fetches an on-demand macro */ int grab_on_demand_host_macro(host *,char *); /* fetches an on-demand host macro */ int grab_on_demand_service_macro(service *,char *); /* fetches an on-demand service macro */ int clear_argv_macros(void); /* clear all argv macros used in commands */ int clear_volatile_macros(void); /* clear all "volatile" macros that change between service/host checks */ int clear_nonvolatile_macros(void); /* clear all "nonvolatile" macros which remain relatively constant */ /**** External Command Functions ****/ void check_for_external_commands(void); /* checks for any external commands */ void process_external_command(int,time_t,char *); /* process an external command */ int process_host_command(int,time_t,char *); /* process an external host command */ int process_hostgroup_command(int,time_t,char *); /* process an external hostgroup command */ int process_service_command(int,time_t,char *); /* process an external service command */ int process_servicegroup_command(int,time_t,char *); /* process an external servicegroup command */ /**** External Command Implementations ****/ int cmd_add_comment(int,time_t,char *); /* add a service or host comment */ int cmd_delete_comment(int,char *); /* delete a service or host comment */ int cmd_delete_all_comments(int,char *); /* delete all comments associated with a host or service */ int cmd_delay_notification(int,char *); /* delay a service or host notification */ int cmd_schedule_service_check(int,char *,int); /* schedule an immediate or delayed service check */ int cmd_schedule_check(int,char *); /* schedule an immediate or delayed host check */ int cmd_schedule_host_service_checks(int,char *,int); /* schedule an immediate or delayed checks of all services on a host */ int cmd_signal_process(int,char *); /* schedules a program shutdown or restart */ int cmd_process_service_check_result(int,time_t,char *); /* processes a passive service check */ int cmd_process_host_check_result(int,time_t,char *); /* processes a passive host check */ int cmd_acknowledge_problem(int,char *); /* acknowledges a host or service problem */ int cmd_remove_acknowledgement(int,char *); /* removes a host or service acknowledgement */ int cmd_schedule_downtime(int,time_t,char *); /* schedules host or service downtime */ int cmd_delete_downtime(int,char *); /* cancels active/pending host or service scheduled downtime */ int cmd_change_command(int,char *); /* changes host/svc command */ int cmd_change_check_interval(int,char *); /* changes host/svc check interval */ int cmd_change_max_attempts(int,char *); /* changes host/svc max attempts */ int process_passive_service_check(time_t,char *,char *,int,char *); int process_passive_host_check(time_t,char *,int,char *); /**** Internal Command Implementations ****/ void disable_service_checks(service *); /* disables a service check */ void enable_service_checks(service *); /* enables a service check */ void schedule_service_check(service *,time_t,int); /* schedules an immediate or delayed service check */ void schedule_host_check(host *,time_t,int); /* schedules an immediate or delayed host check */ void enable_all_notifications(void); /* enables notifications on a program-wide basis */ void disable_all_notifications(void); /* disables notifications on a program-wide basis */ void enable_service_notifications(service *); /* enables service notifications */ void disable_service_notifications(service *); /* disables service notifications */ void enable_host_notifications(host *); /* enables host notifications */ void disable_host_notifications(host *); /* disables host notifications */ void enable_and_propagate_notifications(host *,int,int,int,int); /* enables notifications for all hosts and services beyond a given host */ void disable_and_propagate_notifications(host *,int,int,int,int); /* disables notifications for all hosts and services beyond a given host */ void schedule_and_propagate_downtime(host *,time_t,char *,char *,time_t,time_t,int,unsigned long,unsigned long); /* schedules downtime for all hosts beyond a given host */ void acknowledge_host_problem(host *,char *,char *,int,int,int); /* acknowledges a host problem */ void acknowledge_service_problem(service *,char *,char *,int,int,int); /* acknowledges a service problem */ void remove_host_acknowledgement(host *); /* removes a host acknowledgement */ void remove_service_acknowledgement(service *); /* removes a service acknowledgement */ void start_executing_service_checks(void); /* starts executing service checks */ void stop_executing_service_checks(void); /* stops executing service checks */ void start_accepting_passive_service_checks(void); /* starts accepting passive service check results */ void stop_accepting_passive_service_checks(void); /* stops accepting passive service check results */ void enable_passive_service_checks(service *); /* enables passive service checks for a particular service */ void disable_passive_service_checks(service *); /* disables passive service checks for a particular service */ void start_using_event_handlers(void); /* enables event handlers on a program-wide basis */ void stop_using_event_handlers(void); /* disables event handlers on a program-wide basis */ void enable_service_event_handler(service *); /* enables the event handler for a particular service */ void disable_service_event_handler(service *); /* disables the event handler for a particular service */ void enable_host_event_handler(host *); /* enables the event handler for a particular host */ void disable_host_event_handler(host *); /* disables the event handler for a particular host */ void enable_host_checks(host *); /* enables checks of a particular host */ void disable_host_checks(host *); /* disables checks of a particular host */ void start_obsessing_over_service_checks(void); /* start obsessing about service check results */ void stop_obsessing_over_service_checks(void); /* stop obsessing about service check results */ void start_obsessing_over_host_checks(void); /* start obsessing about host check results */ void stop_obsessing_over_host_checks(void); /* stop obsessing about host check results */ void enable_service_freshness_checks(void); /* enable service freshness checks */ void disable_service_freshness_checks(void); /* disable service freshness checks */ void enable_host_freshness_checks(void); /* enable host freshness checks */ void disable_host_freshness_checks(void); /* disable host freshness checks */ void process_passive_service_checks(void); /* processes passive service check results */ void enable_all_failure_prediction(void); /* enables failure prediction on a program-wide basis */ void disable_all_failure_prediction(void); /* disables failure prediction on a program-wide basis */ void enable_performance_data(void); /* enables processing of performance data on a program-wide basis */ void disable_performance_data(void); /* disables processing of performance data on a program-wide basis */ void start_executing_host_checks(void); /* starts executing host checks */ void stop_executing_host_checks(void); /* stops executing host checks */ void start_accepting_passive_host_checks(void); /* starts accepting passive host check results */ void stop_accepting_passive_host_checks(void); /* stops accepting passive host check results */ void enable_passive_host_checks(host *); /* enables passive host checks for a particular host */ void disable_passive_host_checks(host *); /* disables passive host checks for a particular host */ void start_obsessing_over_service(service *); /* start obsessing about specific service check results */ void stop_obsessing_over_service(service *); /* stop obsessing about specific service check results */ void start_obsessing_over_host(host *); /* start obsessing about specific host check results */ void stop_obsessing_over_host(host *); /* stop obsessing about specific host check results */ void set_host_notification_number(host *,int); /* sets current notification number for a specific host */ void set_service_notification_number(service *,int); /* sets current notification number for a specific service */ int init_service_result_worker_thread(void); int shutdown_service_result_worker_thread(void); void * service_result_worker_thread(void *); void cleanup_service_result_worker_thread(void *); int init_command_file_worker_thread(void); int shutdown_command_file_worker_thread(void); void * command_file_worker_thread(void *); void cleanup_command_file_worker_thread(void *); int submit_external_command(char *,int *); int submit_raw_external_command(char *,time_t *,int *); char *get_program_version(void); char *get_program_modification_date(void); mmapfile *mmap_fopen(char *); /* open a file read-only via mmap() */ int mmap_fclose(mmapfile *); char *mmap_fgets(mmapfile *); char *mmap_fgets_multiline(mmapfile *); int init_macrox_names(void); int add_macrox_name(int,char *); int free_macrox_names(void); int set_all_macro_environment_vars(int); int set_macrox_environment_vars(int); int set_argv_macro_environment_vars(int); int set_macro_environment_var(char *,char *,int); #ifdef __cplusplus } #endif #endif nagios-2.6/include/nebcallbacks.h0000664000076500007650000000635210512470706016407 0ustar nagiosnagios/***************************************************************************** * * NEBCALLBACKS.H - Include file for event broker modules * * Copyright (c) 2002-2006 Ethan Galstad (nagios@nagios.org) * Last Modified: 10-09-2006 * * 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. * *****************************************************************************/ #ifndef _NEBCALLBACKS_H #define _NEBCALLBACKS_H #include "config.h" #include "nebmodules.h" #ifdef __cplusplus extern "C" { #endif /***** CALLBACK TYPES *****/ #define NEBCALLBACK_NUMITEMS 31 /* total number of callback types we have */ #define NEBCALLBACK_RESERVED0 0 /* reserved for future use */ #define NEBCALLBACK_RESERVED1 1 #define NEBCALLBACK_RESERVED2 2 #define NEBCALLBACK_RESERVED3 3 #define NEBCALLBACK_RESERVED4 4 #define NEBCALLBACK_RAW_DATA 5 #define NEBCALLBACK_NEB_DATA 6 #define NEBCALLBACK_PROCESS_DATA 7 #define NEBCALLBACK_TIMED_EVENT_DATA 8 #define NEBCALLBACK_LOG_DATA 9 #define NEBCALLBACK_SYSTEM_COMMAND_DATA 10 #define NEBCALLBACK_EVENT_HANDLER_DATA 11 #define NEBCALLBACK_NOTIFICATION_DATA 12 #define NEBCALLBACK_SERVICE_CHECK_DATA 13 #define NEBCALLBACK_HOST_CHECK_DATA 14 #define NEBCALLBACK_COMMENT_DATA 15 #define NEBCALLBACK_DOWNTIME_DATA 16 #define NEBCALLBACK_FLAPPING_DATA 17 #define NEBCALLBACK_PROGRAM_STATUS_DATA 18 #define NEBCALLBACK_HOST_STATUS_DATA 19 #define NEBCALLBACK_SERVICE_STATUS_DATA 20 #define NEBCALLBACK_ADAPTIVE_PROGRAM_DATA 21 #define NEBCALLBACK_ADAPTIVE_HOST_DATA 22 #define NEBCALLBACK_ADAPTIVE_SERVICE_DATA 23 #define NEBCALLBACK_EXTERNAL_COMMAND_DATA 24 #define NEBCALLBACK_AGGREGATED_STATUS_DATA 25 #define NEBCALLBACK_RETENTION_DATA 26 #define NEBCALLBACK_CONTACT_NOTIFICATION_DATA 27 #define NEBCALLBACK_CONTACT_NOTIFICATION_METHOD_DATA 28 #define NEBCALLBACK_ACKNOWLEDGEMENT_DATA 29 #define NEBCALLBACK_STATE_CHANGE_DATA 30 /***** CALLBACK FUNCTIONS *****/ int neb_register_callback(int, void *, int, int (*callback_func)(int,void *)); int neb_deregister_callback(int, int (*callback_func)(int,void *)); int neb_deregister_module_callbacks(nebmodule *); #ifdef __cplusplus } #endif #endif nagios-2.6/include/neberrors.h0000664000076500007650000000376410341755747016023 0ustar nagiosnagios/***************************************************************************** * * NEBERRORS.H - Event broker errors * * Copyright (c) 2003-2005 Ethan Galstad (nagios@nagios.org) * Last Modified: 11-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. * *****************************************************************************/ #ifndef _NEBERRORS_H #define _NEBERRORS_H /***** GENERIC DEFINES *****/ #define NEB_OK 0 #define NEB_ERROR -1 #define NEB_TRUE 1 #define NEB_FALSE 0 /***** GENERIC ERRORS *****/ #define NEBERROR_NOMEM 100 /* memory could not be allocated */ /***** CALLBACK ERRORS *****/ #define NEBERROR_NOCALLBACKFUNC 200 /* no callback function was specified */ #define NEBERROR_NOCALLBACKLIST 201 /* callback list not initialized */ #define NEBERROR_CALLBACKBOUNDS 202 /* callback type was out of bounds */ #define NEBERROR_CALLBACKNOTFOUND 203 /* the callback could not be found */ #define NEBERROR_NOMODULEHANDLE 204 /* no module handle specified */ #define NEBERROR_BADMODULEHANDLE 205 /* bad module handle */ /***** MODULE ERRORS *****/ #define NEBERROR_NOMODULE 300 /* no module was specified */ /***** MODULE INFO ERRORS *****/ #define NEBERROR_MODINFOBOUNDS 400 /* module info index was out of bounds */ #endif nagios-2.6/include/nebmods.h0000664000076500007650000000350110341755747015436 0ustar nagiosnagios/***************************************************************************** * * NEBMODS.H - Include file for event broker modules * * Copyright (c) 2002-2005 Ethan Galstad (nagios@nagios.org) * Last Modified: 11-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. * *****************************************************************************/ #ifndef _NEBMODS_H #define _NEBMODS_H #include "config.h" #include "nebcallbacks.h" #include "nebmodules.h" #ifdef __cplusplus extern "C" { #endif /***** MODULE STRUCTURES *****/ /* NEB module callback list struct */ typedef struct nebcallback_struct{ void *callback_func; void *module_handle; int priority; struct nebcallback_struct *next; }nebcallback; /***** MODULE FUNCTIONS *****/ int neb_init_modules(void); int neb_deinit_modules(void); int neb_load_all_modules(void); int neb_load_module(nebmodule *); int neb_free_module_list(void); int neb_unload_all_modules(int,int); int neb_unload_module(nebmodule *,int,int); int neb_add_module(char *,char *,int); /***** CALLBACK FUNCTIONS *****/ int neb_init_callback_list(void); int neb_free_callback_list(void); int neb_make_callbacks(int,void *); #ifdef __cplusplus } #endif #endif nagios-2.6/include/nebmodules.h0000664000076500007650000000562110353050230016123 0ustar nagiosnagios/***************************************************************************** * * NEBMODULES.H - Include file for event broker modules * * Copyright (c) 2002-2005 Ethan Galstad (nagios@nagios.org) * Last Modified: 12-17-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. * *****************************************************************************/ #ifndef _NEBMODULES_H #define _NEBMODULES_H #ifdef __cplusplus extern "C" { #endif /***** MODULE VERSION INFORMATION *****/ #define NEB_API_VERSION(x) int __neb_api_version = x; #define CURRENT_NEB_API_VERSION 2 /***** MODULE INFORMATION *****/ #define NEBMODULE_MODINFO_NUMITEMS 6 #define NEBMODULE_MODINFO_TITLE 0 #define NEBMODULE_MODINFO_AUTHOR 1 #define NEBMODULE_MODINFO_COPYRIGHT 2 #define NEBMODULE_MODINFO_VERSION 3 #define NEBMODULE_MODINFO_LICENSE 4 #define NEBMODULE_MODINFO_DESC 5 /***** MODULE LOAD/UNLOAD OPTIONS *****/ #define NEBMODULE_NORMAL_LOAD 0 /* module is being loaded normally */ #define NEBMODULE_REQUEST_UNLOAD 0 /* request module to unload (but don't force it) */ #define NEBMODULE_FORCE_UNLOAD 1 /* force module to unload */ /***** MODULES UNLOAD REASONS *****/ #define NEBMODULE_NEB_SHUTDOWN 1 /* event broker is shutting down */ #define NEBMODULE_NEB_RESTART 2 /* event broker is restarting */ #define NEBMODULE_ERROR_NO_INIT 3 /* _module_init() function was not found in module */ #define NEBMODULE_ERROR_BAD_INIT 4 /* _module_init() function returned a bad code */ #define NEBMODULE_ERROR_API_VERSION 5 /* module version is incompatible with current api */ /***** MODULE STRUCTURES *****/ /* NEB module structure */ typedef struct nebmodule_struct{ char *filename; char *args; char *info[NEBMODULE_MODINFO_NUMITEMS]; int should_be_loaded; int is_currently_loaded; #ifdef USE_LTDL lt_dlhandle module_handle; lt_ptr init_func; lt_ptr deinit_func; #else void *module_handle; void *init_func; void *deinit_func; #endif #ifdef HAVE_PTHREAD_H pthread_t thread_id; #endif struct nebmodule_struct *next; }nebmodule; /***** MODULE FUNCTIONS *****/ int neb_set_module_info(void *,int,char *); #ifdef __cplusplus } #endif #endif nagios-2.6/include/nebstructs.h0000664000076500007650000003055510353050230016166 0ustar nagiosnagios/***************************************************************************** * * NEBSTRUCTS.H - Event broker includes for Nagios * * Copyright (c) 2003-2005 Ethan Galstad (nagios@nagios.org) * Last Modified: 12-17-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. * *****************************************************************************/ #ifndef _NEBSTRUCTS_H #define _NEBSTRUCTS_H #include "config.h" #include "objects.h" #include "nagios.h" #ifdef __cplusplus extern "C" { #endif /****** STRUCTURES *************************/ /* process data structure */ typedef struct nebstruct_process_struct{ int type; int flags; int attr; struct timeval timestamp; }nebstruct_process_data; /* timed event data structure */ typedef struct nebstruct_timed_event_struct{ int type; int flags; int attr; struct timeval timestamp; int event_type; int recurring; time_t run_time; void *event_data; }nebstruct_timed_event_data; /* log data structure */ typedef struct nebstruct_log_struct{ int type; int flags; int attr; struct timeval timestamp; time_t entry_time; int data_type; char *data; }nebstruct_log_data; /* system command structure */ typedef struct nebstruct_system_command_struct{ int type; int flags; int attr; struct timeval timestamp; struct timeval start_time; struct timeval end_time; int timeout; char *command_line; int early_timeout; double execution_time; int return_code; char *output; }nebstruct_system_command_data; /* event handler structure */ typedef struct nebstruct_event_handler_struct{ int type; int flags; int attr; struct timeval timestamp; int eventhandler_type; char *host_name; char *service_description; int state_type; int state; int timeout; char *command_name; char *command_args; char *command_line; struct timeval start_time; struct timeval end_time; int early_timeout; double execution_time; int return_code; char *output; }nebstruct_event_handler_data; /* host check structure */ typedef struct nebstruct_host_check_struct{ int type; int flags; int attr; struct timeval timestamp; char *host_name; int current_attempt; int check_type; int max_attempts; int state_type; int state; int timeout; char *command_name; char *command_args; char *command_line; struct timeval start_time; struct timeval end_time; int early_timeout; double execution_time; double latency; int return_code; char *output; char *perf_data; }nebstruct_host_check_data; /* service check structure */ typedef struct nebstruct_service_check_struct{ int type; int flags; int attr; struct timeval timestamp; char *host_name; char *service_description; int check_type; int current_attempt; int max_attempts; int state_type; int state; int timeout; char *command_name; char *command_args; char *command_line; struct timeval start_time; struct timeval end_time; int early_timeout; double execution_time; double latency; int return_code; char *output; char *perf_data; }nebstruct_service_check_data; /* comment data structure */ typedef struct nebstruct_comment_struct{ int type; int flags; int attr; struct timeval timestamp; int comment_type; char *host_name; char *service_description; time_t entry_time; char *author_name; char *comment_data; int persistent; int source; int entry_type; int expires; time_t expire_time; unsigned long comment_id; }nebstruct_comment_data; /* downtime data structure */ typedef struct nebstruct_downtime_struct{ int type; int flags; int attr; struct timeval timestamp; int downtime_type; char *host_name; char *service_description; time_t entry_time; char *author_name; char *comment_data; time_t start_time; time_t end_time; int fixed; unsigned long duration; unsigned long triggered_by; unsigned long downtime_id; }nebstruct_downtime_data; /* flapping data structure */ typedef struct nebstruct_flapping_struct{ int type; int flags; int attr; struct timeval timestamp; int flapping_type; char *host_name; char *service_description; double percent_change; double high_threshold; double low_threshold; unsigned long comment_id; }nebstruct_flapping_data; /* program status structure */ typedef struct nebstruct_program_status_struct{ int type; int flags; int attr; struct timeval timestamp; time_t program_start; int pid; int daemon_mode; time_t last_command_check; time_t last_log_rotation; int notifications_enabled; int active_service_checks_enabled; int passive_service_checks_enabled; int active_host_checks_enabled; int passive_host_checks_enabled; int event_handlers_enabled; int flap_detection_enabled; int failure_prediction_enabled; int process_performance_data; int obsess_over_hosts; int obsess_over_services; unsigned long modified_host_attributes; unsigned long modified_service_attributes; char *global_host_event_handler; char *global_service_event_handler; }nebstruct_program_status_data; /* host status structure */ typedef struct nebstruct_host_status_struct{ int type; int flags; int attr; struct timeval timestamp; void *object_ptr; }nebstruct_host_status_data; /* service status structure */ typedef struct nebstruct_service_status_struct{ int type; int flags; int attr; struct timeval timestamp; void *object_ptr; }nebstruct_service_status_data; /* notification data structure */ typedef struct nebstruct_notification_struct{ int type; int flags; int attr; struct timeval timestamp; int notification_type; struct timeval start_time; struct timeval end_time; char *host_name; char *service_description; int reason_type; int state; char *output; char *ack_author; char *ack_data; int escalated; int contacts_notified; }nebstruct_notification_data; /* contact notification data structure */ typedef struct nebstruct_contact_notification_struct{ int type; int flags; int attr; struct timeval timestamp; int notification_type; struct timeval start_time; struct timeval end_time; char *host_name; char *service_description; char *contact_name; int reason_type; int state; char *output; char *ack_author; char *ack_data; int escalated; }nebstruct_contact_notification_data; /* contact notification method data structure */ typedef struct nebstruct_contact_notification_method_struct{ int type; int flags; int attr; struct timeval timestamp; int notification_type; struct timeval start_time; struct timeval end_time; char *host_name; char *service_description; char *contact_name; char *command_name; char *command_args; int reason_type; int state; char *output; char *ack_author; char *ack_data; int escalated; }nebstruct_contact_notification_method_data; /* adaptive program data structure */ typedef struct nebstruct_adaptive_program_data_struct{ int type; int flags; int attr; struct timeval timestamp; int command_type; unsigned long modified_host_attribute; unsigned long modified_host_attributes; unsigned long modified_service_attribute; unsigned long modified_service_attributes; char *global_host_event_handler; char *global_service_event_handler; }nebstruct_adaptive_program_data; /* adaptive host data structure */ typedef struct nebstruct_adaptive_host_data_struct{ int type; int flags; int attr; struct timeval timestamp; int command_type; unsigned long modified_attribute; unsigned long modified_attributes; void *object_ptr; }nebstruct_adaptive_host_data; /* adaptive service data structure */ typedef struct nebstruct_adaptive_service_data_struct{ int type; int flags; int attr; struct timeval timestamp; int command_type; unsigned long modified_attribute; unsigned long modified_attributes; void *object_ptr; }nebstruct_adaptive_service_data; /* external command data structure */ typedef struct nebstruct_external_command_struct{ int type; int flags; int attr; struct timeval timestamp; int command_type; time_t entry_time; char *command_string; char *command_args; }nebstruct_external_command_data; /* aggregated status data structure */ typedef struct nebstruct_aggregated_status_struct{ int type; int flags; int attr; struct timeval timestamp; }nebstruct_aggregated_status_data; /* retention data structure */ typedef struct nebstruct_retention_struct{ int type; int flags; int attr; struct timeval timestamp; }nebstruct_retention_data; /* acknowledgement structure */ typedef struct nebstruct_acknowledgement_struct{ int type; int flags; int attr; struct timeval timestamp; int acknowledgement_type; char *host_name; char *service_description; int state; char *author_name; char *comment_data; int is_sticky; int persistent_comment; int notify_contacts; }nebstruct_acknowledgement_data; /* state change structure */ typedef struct nebstruct_statechange_struct{ int type; int flags; int attr; struct timeval timestamp; int statechange_type; char *host_name; char *service_description; int state; int state_type; int current_attempt; int max_attempts; char *output; }nebstruct_statechange_data; #ifdef __cplusplus } #endif #endif nagios-2.6/include/objects.h0000664000076500007650000006005510410076177015435 0ustar nagiosnagios/***************************************************************************** * * OBJECTS.H - Header file for object addition/search functions * * Copyright (c) 1999-2006 Ethan Galstad (nagios@nagios.org) * Last Modified: 03-21-2006 * * 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. * *****************************************************************************/ #ifndef _OBJECTS_H #define _OBJECTS_H #include "config.h" #include "common.h" #ifdef __cplusplus extern "C" { #endif /*************** CURRENT OBJECT REVISION **************/ #define CURRENT_OBJECT_STRUCTURE_VERSION 2 /***************** OBJECT SIZE LIMITS *****************/ #define MAX_HOSTNAME_LENGTH 64 /* max. host name length */ #define MAX_SERVICEDESC_LENGTH 64 /* max. service description length */ #define MAX_PLUGINOUTPUT_LENGTH 332 /* max. length of plugin output */ #define MAX_STATE_HISTORY_ENTRIES 21 /* max number of old states to keep track of for flap detection */ #define MAX_CONTACT_ADDRESSES 6 /* max number of custom addresses a contact can have */ /***************** CHAINED HASH LIMITS ****************/ #define SERVICE_HASHSLOTS 1024 #define HOST_HASHSLOTS 1024 #define COMMAND_HASHSLOTS 256 #define TIMEPERIOD_HASHSLOTS 64 #define CONTACT_HASHSLOTS 128 #define CONTACTGROUP_HASHSLOTS 64 #define HOSTGROUP_HASHSLOTS 128 #define SERVICEGROUP_HASHSLOTS 128 #define HOSTEXTINFO_HASHSLOTS 1024 #define SERVICEEXTINFO_HASHSLOTS 1024 #define HOSTDEPENDENCY_HASHSLOTS 1024 #define SERVICEDEPENDENCY_HASHSLOTS 1024 #define HOSTESCALATION_HASHSLOTS 1024 #define SERVICEESCALATION_HASHSLOTS 1024 /****************** DATA STRUCTURES *******************/ /* TIMERANGE structure */ typedef struct timerange_struct{ unsigned long range_start; unsigned long range_end; struct timerange_struct *next; }timerange; /* TIMEPERIOD structure */ typedef struct timeperiod_struct{ char *name; char *alias; timerange *days[7]; struct timeperiod_struct *next; struct timeperiod_struct *nexthash; }timeperiod; /* CONTACTGROUPMEMBER structure */ typedef struct contactgroupmember_struct{ char *contact_name; struct contactgroupmember_struct *next; }contactgroupmember; /* CONTACTGROUP structure */ typedef struct contactgroup_struct{ char *group_name; char *alias; contactgroupmember *members; struct contactgroup_struct *next; struct contactgroup_struct *nexthash; }contactgroup; /* CONTACTGROUPSMEMBER structure */ typedef struct contactgroupsmember_struct{ char *group_name; struct contactgroupsmember_struct *next; }contactgroupsmember; /* HOSTSMEMBER structure */ typedef struct hostsmember_struct{ char *host_name; struct hostsmember_struct *next; }hostsmember; /* HOST structure */ typedef struct host_struct{ char *name; char *alias; char *address; hostsmember *parent_hosts; char *host_check_command; int check_interval; int max_attempts; char *event_handler; contactgroupsmember *contact_groups; int notification_interval; int notify_on_down; int notify_on_unreachable; int notify_on_recovery; int notify_on_flapping; char *notification_period; char *check_period; int flap_detection_enabled; double low_flap_threshold; double high_flap_threshold; int stalk_on_up; int stalk_on_down; int stalk_on_unreachable; int check_freshness; int freshness_threshold; int process_performance_data; int checks_enabled; int accept_passive_host_checks; int event_handler_enabled; int retain_status_information; int retain_nonstatus_information; int failure_prediction_enabled; char *failure_prediction_options; int obsess_over_host; #ifdef NSCORE int problem_has_been_acknowledged; int acknowledgement_type; int check_type; int current_state; int last_state; int last_hard_state; char *plugin_output; char *perf_data; int state_type; int current_attempt; double latency; double execution_time; int check_options; int notifications_enabled; time_t last_host_notification; time_t next_host_notification; time_t next_check; int should_be_scheduled; time_t last_check; time_t last_state_change; time_t last_hard_state_change; time_t last_time_up; time_t last_time_down; time_t last_time_unreachable; int has_been_checked; int is_being_freshened; int notified_on_down; int notified_on_unreachable; int current_notification_number; int no_more_notifications; int check_flapping_recovery_notification; int scheduled_downtime_depth; int pending_flex_downtime; int state_history[MAX_STATE_HISTORY_ENTRIES]; /* flap detection */ int state_history_index; time_t last_state_history_update; int is_flapping; unsigned long flapping_comment_id; double percent_state_change; int total_services; unsigned long total_service_check_interval; unsigned long modified_attributes; int circular_path_checked; int contains_circular_path; #endif struct host_struct *next; struct host_struct *nexthash; }host; /* HOSTGROUPMEMBER structure */ typedef struct hostgroupmember_struct{ char *host_name; struct hostgroupmember_struct *next; }hostgroupmember; /* HOSTGROUP structure */ typedef struct hostgroup_struct{ char *group_name; char *alias; hostgroupmember *members; struct hostgroup_struct *next; struct hostgroup_struct *nexthash; }hostgroup; /* SERVICEGROUPMEMBER structure */ typedef struct servicegroupmember_struct{ char *host_name; char *service_description; struct servicegroupmember_struct *next; }servicegroupmember; /* SERVICEGROUP structure */ typedef struct servicegroup_struct{ char *group_name; char *alias; servicegroupmember *members; struct servicegroup_struct *next; struct servicegroup_struct *nexthash; }servicegroup; /* COMMANDSMEMBER structure */ typedef struct commandsmember_struct{ char *command; struct commandsmember_struct *next; }commandsmember; /* CONTACT structure */ typedef struct contact_struct{ char *name; char *alias; char *email; char *pager; char *address[MAX_CONTACT_ADDRESSES]; commandsmember *host_notification_commands; commandsmember *service_notification_commands; int notify_on_service_unknown; int notify_on_service_warning; int notify_on_service_critical; int notify_on_service_recovery; int notify_on_service_flapping; int notify_on_host_down; int notify_on_host_unreachable; int notify_on_host_recovery; int notify_on_host_flapping; char *host_notification_period; char *service_notification_period; struct contact_struct *next; struct contact_struct *nexthash; }contact; /* SERVICE structure */ typedef struct service_struct{ char *host_name; char *description; char *service_check_command; char *event_handler; int check_interval; int retry_interval; int max_attempts; int parallelize; contactgroupsmember *contact_groups; int notification_interval; int notify_on_unknown; int notify_on_warning; int notify_on_critical; int notify_on_recovery; int notify_on_flapping; int stalk_on_ok; int stalk_on_warning; int stalk_on_unknown; int stalk_on_critical; int is_volatile; char *notification_period; char *check_period; int flap_detection_enabled; double low_flap_threshold; double high_flap_threshold; int process_performance_data; int check_freshness; int freshness_threshold; int accept_passive_service_checks; int event_handler_enabled; int checks_enabled; int retain_status_information; int retain_nonstatus_information; int notifications_enabled; int obsess_over_service; int failure_prediction_enabled; char *failure_prediction_options; #ifdef NSCORE int problem_has_been_acknowledged; int acknowledgement_type; int host_problem_at_last_check; #ifdef REMOVED_041403 int no_recovery_notification; #endif int check_type; int current_state; int last_state; int last_hard_state; char *plugin_output; char *perf_data; int state_type; time_t next_check; int should_be_scheduled; time_t last_check; int current_attempt; time_t last_notification; time_t next_notification; int no_more_notifications; int check_flapping_recovery_notification; time_t last_state_change; time_t last_hard_state_change; time_t last_time_ok; time_t last_time_warning; time_t last_time_unknown; time_t last_time_critical; int has_been_checked; int is_being_freshened; int notified_on_unknown; int notified_on_warning; int notified_on_critical; int current_notification_number; double latency; double execution_time; int is_executing; int check_options; int scheduled_downtime_depth; int pending_flex_downtime; int state_history[MAX_STATE_HISTORY_ENTRIES]; /* flap detection */ int state_history_index; int is_flapping; unsigned long flapping_comment_id; double percent_state_change; unsigned long modified_attributes; #endif struct service_struct *next; struct service_struct *nexthash; }service; /* COMMAND structure */ typedef struct command_struct{ char *name; char *command_line; struct command_struct *next; struct command_struct *nexthash; }command; /* SERVICE ESCALATION structure */ typedef struct serviceescalation_struct{ char *host_name; char *description; int first_notification; int last_notification; int notification_interval; char *escalation_period; int escalate_on_recovery; int escalate_on_warning; int escalate_on_unknown; int escalate_on_critical; contactgroupsmember *contact_groups; struct serviceescalation_struct *next; struct serviceescalation_struct *nexthash; }serviceescalation; /* SERVICE DEPENDENCY structure */ typedef struct servicedependency_struct{ int dependency_type; char *dependent_host_name; char *dependent_service_description; char *host_name; char *service_description; int inherits_parent; int fail_on_ok; int fail_on_warning; int fail_on_unknown; int fail_on_critical; int fail_on_pending; #ifdef NSCORE int circular_path_checked; int contains_circular_path; #endif struct servicedependency_struct *next; struct servicedependency_struct *nexthash; }servicedependency; /* HOST ESCALATION structure */ typedef struct hostescalation_struct{ char *host_name; int first_notification; int last_notification; int notification_interval; char *escalation_period; int escalate_on_recovery; int escalate_on_down; int escalate_on_unreachable; contactgroupsmember *contact_groups; struct hostescalation_struct *next; struct hostescalation_struct *nexthash; }hostescalation; /* HOST DEPENDENCY structure */ typedef struct hostdependency_struct{ int dependency_type; char *dependent_host_name; char *host_name; int inherits_parent; int fail_on_up; int fail_on_down; int fail_on_unreachable; int fail_on_pending; #ifdef NSCORE int circular_path_checked; int contains_circular_path; #endif struct hostdependency_struct *next; struct hostdependency_struct *nexthash; }hostdependency; /* EXTENDED HOST INFO structure */ typedef struct hostextinfo_struct{ char *host_name; char *notes; char *notes_url; char *action_url; char *icon_image; char *vrml_image; char *statusmap_image; char *icon_image_alt; int have_2d_coords; int x_2d; int y_2d; int have_3d_coords; double x_3d; double y_3d; double z_3d; int should_be_drawn; struct hostextinfo_struct *next; struct hostextinfo_struct *nexthash; }hostextinfo; /* EXTENDED SERVICE INFO structure */ typedef struct serviceextinfo_struct{ char *host_name; char *description; char *notes; char *notes_url; char *action_url; char *icon_image; char *icon_image_alt; struct serviceextinfo_struct *next; struct serviceextinfo_struct *nexthash; }serviceextinfo; /****************** HASH STRUCTURES ********************/ typedef struct host_cursor_struct{ int host_hashchain_iterator; host *current_host_pointer; }host_cursor; /********************* FUNCTIONS **********************/ /**** DEBUG functions ****/ /* RMO: 9/25/01 Send debug output to stdout. Does nothing if 'level' is not enabled by a corresponding 'DEBUGn' define. Accepts format string (fmt) and variable-length arg list (as printf does). Prints to stdout and, if NSCGI environment, surrounded with HTML comment delimiters to be viewed through browser's 'view source' option. Use as: dbg_print((level,fmt,...)); [NOTE double parens] The macro def below causes dbg_print(()) calls to vaporize if none of the DEBUGn levels are defined. */ #if defined(DEBUG0) || defined(DEBUG1) || defined(DEBUG2) || defined(DEBUG3) || defined(DEBUG4) || defined(DEBUG5) || defined(DEBUG6) || defined(DEBUG7) || defined(DEBUG8) || defined(DEBUG9) || defined(DEBUG10) || defined(DEBUG11) #define dbg_print(args) dbg_print_x args #else #define dbg_print(args) #endif /**** Top-level input functions ****/ int read_object_config_data(char *,int,int); /* reads all external configuration data of specific types */ /**** Object Creation Functions ****/ contact *add_contact(char *,char *,char *,char *,char **,char *,char *,int,int,int,int,int,int,int,int,int); /* adds a contact definition */ commandsmember *add_service_notification_command_to_contact(contact *,char *); /* adds a service notification command to a contact definition */ commandsmember *add_host_notification_command_to_contact(contact *,char *); /* adds a host notification command to a contact definition */ host *add_host(char *,char *,char *,char *,int,int,int,int,int,int,int,char *,int,char *,int,int,char *,int,int,double,double,int,int,int,int,int,char *,int,int,int,int,int); /* adds a host definition */ hostsmember *add_parent_host_to_host(host *,char *); /* adds a parent host to a host definition */ contactgroupsmember *add_contactgroup_to_host(host *,char *); /* adds a contactgroup to a host definition */ timeperiod *add_timeperiod(char *,char *); /* adds a timeperiod definition */ timerange *add_timerange_to_timeperiod(timeperiod *,int,unsigned long,unsigned long); /* adds a timerange to a timeperiod definition */ hostgroup *add_hostgroup(char *,char *); /* adds a hostgroup definition */ hostgroupmember *add_host_to_hostgroup(hostgroup *, char *); /* adds a host to a hostgroup definition */ servicegroup *add_servicegroup(char *,char *); /* adds a servicegroup definition */ servicegroupmember *add_service_to_servicegroup(servicegroup *,char *,char *); /* adds a service to a servicegroup definition */ contactgroup *add_contactgroup(char *,char *); /* adds a contactgroup definition */ contactgroupmember *add_contact_to_contactgroup(contactgroup *,char *); /* adds a contact to a contact group definition */ command *add_command(char *,char *); /* adds a command definition */ service *add_service(char *,char *,char *,int,int,int,int,int,int,char *,int,int,int,int,int,int,int,char *,int,char *,int,int,double,double,int,int,int,int,int,int,char *,int,int,int,int,int); /* adds a service definition */ contactgroupsmember *add_contactgroup_to_service(service *,char *); /* adds a contact group to a service definition */ serviceescalation *add_serviceescalation(char *,char *,int,int,int,char *,int,int,int,int); /* adds a service escalation definition */ contactgroupsmember *add_contactgroup_to_serviceescalation(serviceescalation *,char *); /* adds a contact group to a service escalation definition */ servicedependency *add_service_dependency(char *,char *,char *,char *,int,int,int,int,int,int,int); /* adds a service dependency definition */ hostdependency *add_host_dependency(char *,char *,int,int,int,int,int,int); /* adds a host dependency definition */ hostescalation *add_hostescalation(char *,int,int,int,char *,int,int,int); /* adds a host escalation definition */ contactgroupsmember *add_contactgroup_to_hostescalation(hostescalation *,char *); /* adds a contact group to a host escalation definition */ hostextinfo *add_hostextinfo(char *,char *,char *,char *,char *,char *,char *,char *,int,int,double,double,double,int,int); /* adds an extended host info definition */ serviceextinfo *add_serviceextinfo(char *,char *,char *,char *,char *,char *,char *); /* add an extended service info definition */ /**** Object Hash Functions ****/ int add_host_to_hashlist(host *); int add_service_to_hashlist(service *); int add_command_to_hashlist(command *); int add_timeperiod_to_hashlist(timeperiod *); int add_contact_to_hashlist(contact *); int add_contactgroup_to_hashlist(contactgroup *); int add_hostgroup_to_hashlist(hostgroup *); int add_servicegroup_to_hashlist(servicegroup *); int add_hostdependency_to_hashlist(hostdependency *); int add_servicedependency_to_hashlist(servicedependency *); int add_hostescalation_to_hashlist(hostescalation *); int add_serviceescalation_to_hashlist(serviceescalation *); int add_hostextinfo_to_hashlist(hostextinfo *); int add_serviceextinfo_to_hashlist(serviceextinfo *); /**** Object Search Functions ****/ timeperiod * find_timeperiod(char *); /* finds a timeperiod object */ host * find_host(char *); /* finds a host object */ hostgroup * find_hostgroup(char *); /* finds a hostgroup object */ servicegroup * find_servicegroup(char *); /* finds a servicegroup object */ contact * find_contact(char *); /* finds a contact object */ contactgroup * find_contactgroup(char *); /* finds a contactgroup object */ contactgroupmember *find_contactgroupmember(char *,contactgroup *); /* finds a contactgroup member object */ command * find_command(char *); /* finds a command object */ service * find_service(char *,char *); /* finds a service object */ hostextinfo *find_hostextinfo(char *); /* find an extended host info object */ serviceextinfo *find_serviceextinfo(char *,char *); /* find an extended service info object */ /**** Object Traversal Functions ****/ void move_first_service(void); /* sets up the static memory area for get_next_service */ service *get_next_service(void); /* returns the next service, NULL at the end of the list */ int find_all_services_by_host(char *); /* sets up the static memory area for get_next_service_by_host */ service *get_next_service_by_host(void); /* returns the next service for the host, NULL at the end of the list */ void move_first_host(void); /* sets up the static memory area for get_next_host */ host *get_next_host(void); /* returns the next host, NULL at the end of the list */ void *get_host_cursor(void); /* allocate memory for the host cursor */ host *get_next_host_cursor(void *v_cursor); /* return the next host, NULL at the end of the list */ void free_host_cursor(void *cursor); /* free allocated cursor memory */ void *get_next_N(void **hashchain, int hashslots, int *iterator, void *current, void *next); hostescalation *get_first_hostescalation_by_host(char *); hostescalation *get_next_hostescalation_by_host(char *,hostescalation *); serviceescalation *get_first_serviceescalation_by_service(char *,char *); serviceescalation *get_next_serviceescalation_by_service(char *,char *,serviceescalation *); hostdependency *get_first_hostdependency_by_dependent_host(char *); hostdependency *get_next_hostdependency_by_dependent_host(char *,hostdependency *); servicedependency *get_first_servicedependency_by_dependent_service(char *,char *); servicedependency *get_next_servicedependency_by_dependent_service(char *,char *,servicedependency *); /**** Object Query Functions ****/ int is_host_immediate_child_of_host(host *,host *); /* checks if a host is an immediate child of another host */ int is_host_primary_immediate_child_of_host(host *,host *); /* checks if a host is an immediate child (and primary child) of another host */ int is_host_immediate_parent_of_host(host *,host *); /* checks if a host is an immediate child of another host */ int is_host_member_of_hostgroup(hostgroup *,host *); /* tests whether or not a host is a member of a specific hostgroup */ int is_host_member_of_servicegroup(servicegroup *,host *); /* tests whether or not a service is a member of a specific servicegroup */ int is_service_member_of_servicegroup(servicegroup *,service *); /* tests whether or not a service is a member of a specific servicegroup */ int is_contact_member_of_contactgroup(contactgroup *, contact *); /* tests whether or not a contact is a member of a specific contact group */ int is_contact_for_hostgroup(hostgroup *,contact *); /* tests whether or not a contact is a member of a specific hostgroup */ int is_contact_for_servicegroup(servicegroup *,contact *); /* tests whether or not a contact is a member of a specific servicegroup */ int is_contact_for_host(host *,contact *); /* tests whether or not a contact is a contact member for a specific host */ int is_escalated_contact_for_host(host *,contact *); /* checks whether or not a contact is an escalated contact for a specific host */ int is_contact_for_service(service *,contact *); /* tests whether or not a contact is a contact member for a specific service */ int is_escalated_contact_for_service(service *,contact *); /* checks whether or not a contact is an escalated contact for a specific service */ int is_host_immediate_parent_of_host(host *,host *); /* tests whether or not a host is an immediate parent of another host */ int number_of_immediate_child_hosts(host *); /* counts the number of immediate child hosts for a particular host */ int number_of_total_child_hosts(host *); /* counts the number of total child hosts for a particular host */ int number_of_immediate_parent_hosts(host *); /* counts the number of immediate parents hosts for a particular host */ int number_of_total_parent_hosts(host *); /* counts the number of total parents hosts for a particular host */ #ifdef NSCORE int check_for_circular_path(host *,host *); /* checks if a circular path exists for a given host */ int check_for_circular_servicedependency(servicedependency *,servicedependency *,int); /* checks if a circular dependency exists for a given service */ int check_for_circular_hostdependency(hostdependency *,hostdependency *,int); /* checks if a circular dependency exists for a given host */ #endif /**** Object Cleanup Functions ****/ int free_object_data(void); /* frees all allocated memory for the object definitions */ int free_extended_data(void); /* frees memory allocated to the extended host/service information */ #ifdef __cplusplus } #endif #endif nagios-2.6/include/perfdata.h0000664000076500007650000000272510341755747015604 0ustar nagiosnagios/***************************************************************************** * * PERFDATA.H - Include file for performance data routines * * Copyright (c) 2001-2005 Ethan Galstad (nagios@nagios.org) * Last Modified: 11-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. * *****************************************************************************/ #ifndef _PERFDATA_H #define _PERFDATA_H #include "objects.h" #ifdef __cplusplus extern "C" { #endif int initialize_performance_data(char *); /* initializes performance data */ int cleanup_performance_data(char *); /* cleans up performance data */ int update_host_performance_data(host *); /* updates host performance data */ int update_service_performance_data(service *); /* updates service performance data */ #ifdef __cplusplus } #endif #endif nagios-2.6/include/snprintf.h.in0000664000076500007650000000007107717034222016245 0ustar nagiosnagios/* -*- C -*- */ #undef HAVE_SNPRINTF #undef NEED_VA_LIST nagios-2.6/include/sretention.h0000664000076500007650000000232110341755747016200 0ustar nagiosnagios/***************************************************************************** * * SRETENTION.H - Header for state retention routines * * Copyright (c) 1999-2005 Ethan Galstad (nagios@nagios.org) * Last Modified: 11-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. * *****************************************************************************/ #ifdef __cplusplus extern "C" { #endif int save_state_information(char *,int); /* saves all host and state information */ int read_initial_state_information(char *); /* reads in initial host and state information */ #ifdef __cplusplus } #endif nagios-2.6/include/statusdata.h0000664000076500007650000001347210341755747016174 0ustar nagiosnagios/***************************************************************************** * * STATUSDATA.H - Header for external status data routines * * Copyright (c) 2000-2005 Ethan Galstad (nagios@nagios.org) * Last Modified: 11-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. * *****************************************************************************/ #ifndef _STATUSDATA_H #define _STATUSDATA_H #ifdef NSCORE #include "objects.h" #endif #ifdef __cplusplus extern "C" { #endif #ifdef NSCGI #define READ_PROGRAM_STATUS 1 #define READ_HOST_STATUS 2 #define READ_SERVICE_STATUS 4 #define READ_ALL_STATUS_DATA READ_PROGRAM_STATUS | READ_HOST_STATUS | READ_SERVICE_STATUS /*************************** CHAINED HASH LIMITS ***************************/ #define SERVICESTATUS_HASHSLOTS 1024 #define HOSTSTATUS_HASHSLOTS 1024 /**************************** DATA STRUCTURES ******************************/ /* HOST STATUS structure */ typedef struct hoststatus_struct{ char *host_name; char *plugin_output; char *perf_data; int status; time_t last_update; int has_been_checked; int should_be_scheduled; int current_attempt; int max_attempts; time_t last_check; time_t next_check; int check_type; time_t last_state_change; time_t last_hard_state_change; int last_hard_state; time_t last_time_up; time_t last_time_down; time_t last_time_unreachable; int state_type; time_t last_notification; time_t next_notification; int no_more_notifications; int notifications_enabled; int problem_has_been_acknowledged; int acknowledgement_type; int current_notification_number; int accept_passive_host_checks; int event_handler_enabled; int checks_enabled; int flap_detection_enabled; int is_flapping; double percent_state_change; double latency; double execution_time; int scheduled_downtime_depth; int failure_prediction_enabled; int process_performance_data; int obsess_over_host; struct hoststatus_struct *next; struct hoststatus_struct *nexthash; }hoststatus; /* SERVICE STATUS structure */ typedef struct servicestatus_struct{ char *host_name; char *description; char *plugin_output; char *perf_data; int max_attempts; int current_attempt; int status; time_t last_update; int has_been_checked; int should_be_scheduled; time_t last_check; time_t next_check; int check_type; int checks_enabled; time_t last_state_change; time_t last_hard_state_change; int last_hard_state; time_t last_time_ok; time_t last_time_warning; time_t last_time_unknown; time_t last_time_critical; int state_type; time_t last_notification; time_t next_notification; int no_more_notifications; int notifications_enabled; int problem_has_been_acknowledged; int acknowledgement_type; int current_notification_number; int accept_passive_service_checks; int event_handler_enabled; int flap_detection_enabled; int is_flapping; double percent_state_change; double latency; double execution_time; int scheduled_downtime_depth; int failure_prediction_enabled; int process_performance_data; int obsess_over_service; struct servicestatus_struct *next; struct servicestatus_struct *nexthash; }servicestatus; /*************************** SERVICE STATES ***************************/ #define SERVICE_PENDING 1 #define SERVICE_OK 2 #define SERVICE_WARNING 4 #define SERVICE_UNKNOWN 8 #define SERVICE_CRITICAL 16 /**************************** HOST STATES ****************************/ #define HOST_PENDING 1 #define HOST_UP 2 #define HOST_DOWN 4 #define HOST_UNREACHABLE 8 /**************************** FUNCTIONS ******************************/ int read_status_data(char *,int); /* reads all status data */ int add_host_status(hoststatus *); /* adds a host status entry to the list in memory */ int add_service_status(servicestatus *); /* adds a service status entry to the list in memory */ int add_hoststatus_to_hashlist(hoststatus *); int add_servicestatus_to_hashlist(servicestatus *); servicestatus *find_servicestatus(char *,char *); /* finds status information for a specific service */ hoststatus *find_hoststatus(char *); /* finds status information for a specific host */ int get_servicestatus_count(char *,int); /* gets total number of services of a certain type for a specific host */ void free_status_data(void); /* free all memory allocated to status data */ #endif #ifdef NSCORE int initialize_status_data(char *); /* initializes status data at program start */ int update_all_status_data(void); /* updates all status data */ int cleanup_status_data(char *,int); /* cleans up status data at program termination */ int update_program_status(int); /* updates program status data */ int update_host_status(host *,int); /* updates host status data */ int update_service_status(service *,int); /* updates service status data */ #endif #ifdef __cplusplus } #endif #endif nagios-2.6/module/0000775000076500007650000000000010532717611013467 5ustar nagiosnagiosnagios-2.6/module/Makefile.in0000664000076500007650000000144110342004500015515 0ustar nagiosnagios################################### # Makefile for NEB examples # # Last Modified: 08-15-2003 ################################### # Source code directories SRC_INCLUDE=../include CC=@CC@ CFLAGS=@CFLAGS@ @DEFS@ @MOD_CFLAGS@ LDFLAGS=@LDFLAGS@ @MOD_LDFLAGS@ LIBS=@LIBS@ prefix=@prefix@ exec_prefix=@exec_prefix@ BINDIR=@bindir@ INSTALL=@INSTALL@ INSTALL_OPTS=@INSTALL_OPTS@ COMMAND_OPTS=@COMMAND_OPTS@ STRIP=@STRIP@ CP=@CP@ all: helloworld.o mod1.o: mod1.c $(CC) $(CFLAGS) -o mod1.o mod1.c $(LDFLAGS) $(LIBS) mod2.o: mod2.c $(CC) $(CFLAGS) -o mod2.o mod2.c $(LDFLAGS) $(LIBS) helloworld.o: helloworld.c $(CC) $(CFLAGS) -o helloworld.o helloworld.c $(LDFLAGS) $(LIBS) clean: rm -f helloworld.o rm -f core *.o rm -f *~ *.*~ distclean: clean rm -f Makefile devclean: distclean install: nagios-2.6/module/helloworld.c0000664000076500007650000001023510274004242015777 0ustar nagiosnagios/***************************************************************************** * * HELLOWORLD.C - Example of a simple NEB module * * Copyright (c) 2003-2005 Ethan Galstad (http://www.nagios.org) * * Last Modified: 08-02-2005 * * Description: * * This is an example of a very basic module. It does nothing useful other * than logging some messages to the main Nagios log file when it is initialized * (loaded), when it is closed (unloaded), and when aggregated status updates * occur. I would not call that too useful, but hopefully it will serve as a * very basic example of how to write a NEB module... * * Instructions: * * Compile with the following command: * * gcc -shared -o helloworld.o helloworld.c * *****************************************************************************/ /* include (minimum required) event broker header files */ #include "../include/nebmodules.h" #include "../include/nebcallbacks.h" /* include other event broker header files that we need for our work */ #include "../include/nebstructs.h" #include "../include/broker.h" /* include some Nagios stuff as well */ #include "../include/config.h" #include "../include/common.h" #include "../include/nagios.h" /* specify event broker API version (required) */ NEB_API_VERSION(CURRENT_NEB_API_VERSION); void *helloworld_module_handle=NULL; void helloworld_reminder_message(char *); int helloworld_handle_data(int,void *); /* this function gets called when the module is loaded by the event broker */ int nebmodule_init(int flags, char *args, nebmodule *handle){ char temp_buffer[1024]; time_t current_time; unsigned long interval; /* save our handle */ helloworld_module_handle=handle; /* log module info to the Nagios log file */ write_to_all_logs("helloworld: Copyright (c) 2003-2005 Ethan Galstad (nagios@nagios.org)",NSLOG_INFO_MESSAGE); /* log a message to the Nagios log file */ snprintf(temp_buffer,sizeof(temp_buffer)-1,"helloworld: Hello world!\n"); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_all_logs(temp_buffer,NSLOG_INFO_MESSAGE); /* log a reminder message every 15 minutes (how's that for annoying? :-)) */ time(¤t_time); interval=900; schedule_new_event(EVENT_USER_FUNCTION,TRUE,current_time+interval,TRUE,interval,NULL,TRUE,helloworld_reminder_message,"How about you?"); /* register to be notified of certain events... */ neb_register_callback(NEBCALLBACK_AGGREGATED_STATUS_DATA,helloworld_module_handle,0,helloworld_handle_data); return 0; } /* this function gets called when the module is unloaded by the event broker */ int nebmodule_deinit(int flags, int reason){ char temp_buffer[1024]; /* deregister for all events we previously registered for... */ neb_deregister_callback(NEBCALLBACK_AGGREGATED_STATUS_DATA,helloworld_handle_data); /* log a message to the Nagios log file */ snprintf(temp_buffer,sizeof(temp_buffer)-1,"helloworld: Goodbye world!\n"); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_all_logs(temp_buffer,NSLOG_INFO_MESSAGE); return 0; } /* gets called every X minutes by an event in the scheduling queue */ void helloworld_reminder_message(char *message){ char temp_buffer[1024]; /* log a message to the Nagios log file */ snprintf(temp_buffer,sizeof(temp_buffer)-1,"helloworld: I'm still here! %s",message); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_all_logs(temp_buffer,NSLOG_INFO_MESSAGE); return; } /* handle data from Nagios daemon */ int helloworld_handle_data(int event_type, void *data){ nebstruct_aggregated_status_data *agsdata=NULL; char temp_buffer[1024]; /* what type of event/data do we have? */ switch(event_type){ case NEBCALLBACK_AGGREGATED_STATUS_DATA: /* an aggregated status data dump just started or ended... */ if((agsdata=(nebstruct_aggregated_status_data *)data)){ /* log a message to the Nagios log file */ snprintf(temp_buffer,sizeof(temp_buffer)-1,"helloworld: An aggregated status update just %s.",(agsdata->type==NEBTYPE_AGGREGATEDSTATUS_STARTDUMP)?"started":"finished"); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_all_logs(temp_buffer,NSLOG_INFO_MESSAGE); } break; default: break; } return 0; } nagios-2.6/sample-config/0000775000076500007650000000000010532717611014726 5ustar nagiosnagiosnagios-2.6/sample-config/cgi.cfg.in0000664000076500007650000002247610530732161016564 0ustar nagiosnagios################################################################# # # CGI.CFG - Sample CGI Configuration File for Nagios @VERSION@ # # Last Modified: 11-21-2006 # ################################################################# # MAIN CONFIGURATION FILE # This tells the CGIs where to find your main configuration file. # The CGIs will read the main and host config files for any other # data they might need. main_config_file=@sysconfdir@/nagios.cfg # PHYSICAL HTML PATH # This is the path where the HTML files for Nagios reside. This # value is used to locate the logo images needed by the statusmap # and statuswrl CGIs. physical_html_path=@datadir@ # URL HTML PATH # This is the path portion of the URL that corresponds to the # physical location of the Nagios HTML files (as defined above). # This value is used by the CGIs to locate the online documentation # and graphics. If you access the Nagios pages with an URL like # http://www.myhost.com/nagios, this value should be '/nagios' # (without the quotes). url_html_path=@htmurl@ # CONTEXT-SENSITIVE HELP # This option determines whether or not a context-sensitive # help icon will be displayed for most of the CGIs. # Values: 0 = disables context-sensitive help # 1 = enables context-sensitive help show_context_help=0 # NAGIOS PROCESS CHECK COMMAND # This is the full path and filename of the program used to check # the status of the Nagios process. It is used only by the CGIs # and is completely optional. However, if you don't use it, you'll # see warning messages in the CGIs about the Nagios process # not running and you won't be able to execute any commands from # the web interface. The program should follow the same rules # as plugins; the return codes are the same as for the plugins, # it should have timeout protection, it should output something # to STDIO, etc. # # Note: The command line for the check_nagios plugin below may # have to be tweaked a bit, as different versions of the plugin # use different command line arguments/syntaxes. #nagios_check_command=@libexecdir@/check_nagios @localstatedir@/status.dat 5 '@bindir@/nagios' # AUTHENTICATION USAGE # This option controls whether or not the CGIs will use any # authentication when displaying host and service information, as # well as committing commands to Nagios for processing. # # Read the HTML documentation to learn how the authorization works! # # NOTE: It is a really *bad* idea to disable authorization, unless # you plan on removing the command CGI (cmd.cgi)! Failure to do # so will leave you wide open to kiddies messing with Nagios and # possibly hitting you with a denial of service attack by filling up # your drive by continuously writing to your command file! # # Setting this value to 0 will cause the CGIs to *not* use # authentication (bad idea), while any other value will make them # use the authentication functions (the default). use_authentication=1 # DEFAULT USER # Setting this variable will define a default user name that can # access pages without authentication. This allows people within a # secure domain (i.e., behind a firewall) to see the current status # without authenticating. You may want to use this to avoid basic # authentication if you are not using a secure server since basic # authentication transmits passwords in the clear. # # Important: Do not define a default username unless you are # running a secure web server and are sure that everyone who has # access to the CGIs has been authenticated in some manner! If you # define this variable, anyone who has not authenticated to the web # server will inherit all rights you assign to this user! #default_user_name=guest # SYSTEM/PROCESS INFORMATION ACCESS # This option is a comma-delimited list of all usernames that # have access to viewing the Nagios process information as # provided by the Extended Information CGI (extinfo.cgi). By # default, *no one* has access to this unless you choose to # not use authorization. You may use an asterisk (*) to # authorize any user who has authenticated to the web server. #authorized_for_system_information=nagiosadmin,theboss,jdoe # CONFIGURATION INFORMATION ACCESS # This option is a comma-delimited list of all usernames that # can view ALL configuration information (hosts, commands, etc). # By default, users can only view configuration information # for the hosts and services they are contacts for. You may use # an asterisk (*) to authorize any user who has authenticated # to the web server. #authorized_for_configuration_information=nagiosadmin,jdoe # SYSTEM/PROCESS COMMAND ACCESS # This option is a comma-delimited list of all usernames that # can issue shutdown and restart commands to Nagios via the # command CGI (cmd.cgi). Users in this list can also change # the program mode to active or standby. By default, *no one* # has access to this unless you choose to not use authorization. # You may use an asterisk (*) to authorize any user who has # authenticated to the web server. #authorized_for_system_commands=nagiosadmin # GLOBAL HOST/SERVICE VIEW ACCESS # These two options are comma-delimited lists of all usernames that # can view information for all hosts and services that are being # monitored. By default, users can only view information # for hosts or services that they are contacts for (unless you # you choose to not use authorization). You may use an asterisk (*) # to authorize any user who has authenticated to the web server. #authorized_for_all_services=nagiosadmin,guest #authorized_for_all_hosts=nagiosadmin,guest # GLOBAL HOST/SERVICE COMMAND ACCESS # These two options are comma-delimited lists of all usernames that # can issue host or service related commands via the command # CGI (cmd.cgi) for all hosts and services that are being monitored. # By default, users can only issue commands for hosts or services # that they are contacts for (unless you you choose to not use # authorization). You may use an asterisk (*) to authorize any # user who has authenticated to the web server. #authorized_for_all_service_commands=nagiosadmin #authorized_for_all_host_commands=nagiosadmin # STATUSMAP BACKGROUND IMAGE # This option allows you to specify an image to be used as a # background in the statusmap CGI. It is assumed that the image # resides in the HTML images path (i.e. /usr/local/nagios/share/images). # This path is automatically determined by appending "/images" # to the path specified by the 'physical_html_path' directive. # Note: The image file may be in GIF, PNG, JPEG, or GD2 format. # However, I recommend that you convert your image to GD2 format # (uncompressed), as this will cause less CPU load when the CGI # generates the image. #statusmap_background_image=smbackground.gd2 # DEFAULT STATUSMAP LAYOUT METHOD # This option allows you to specify the default layout method # the statusmap CGI should use for drawing hosts. If you do # not use this option, the default is to use user-defined # coordinates. Valid options are as follows: # 0 = User-defined coordinates # 1 = Depth layers # 2 = Collapsed tree # 3 = Balanced tree # 4 = Circular # 5 = Circular (Marked Up) default_statusmap_layout=5 # DEFAULT STATUSWRL LAYOUT METHOD # This option allows you to specify the default layout method # the statuswrl (VRML) CGI should use for drawing hosts. If you # do not use this option, the default is to use user-defined # coordinates. Valid options are as follows: # 0 = User-defined coordinates # 2 = Collapsed tree # 3 = Balanced tree # 4 = Circular default_statuswrl_layout=4 # STATUSWRL INCLUDE # This option allows you to include your own objects in the # generated VRML world. It is assumed that the file # resides in the HTML path (i.e. /usr/local/nagios/share). #statuswrl_include=myworld.wrl # PING SYNTAX # This option determines what syntax should be used when # attempting to ping a host from the WAP interface (using # the statuswml CGI. You must include the full path to # the ping binary, along with all required options. The # $HOSTADDRESS$ macro is substituted with the address of # the host before the command is executed. # Please note that the syntax for the ping binary is # notorious for being different on virtually ever *NIX # OS and distribution, so you may have to tweak this to # work on your system. ping_syntax=/bin/ping -n -U -c 5 $HOSTADDRESS$ # REFRESH RATE # This option allows you to specify the refresh rate in seconds # of various CGIs (status, statusmap, extinfo, and outages). refresh_rate=90 # SOUND OPTIONS # These options allow you to specify an optional audio file # that should be played in your browser window when there are # problems on the network. The audio files are used only in # the status CGI. Only the sound for the most critical problem # will be played. Order of importance (higher to lower) is as # follows: unreachable hosts, down hosts, critical services, # warning services, and unknown services. If there are no # visible problems, the sound file optionally specified by # 'normal_sound' variable will be played. # # # = # # Note: All audio files must be placed in the /media subdirectory # under the HTML path (i.e. /usr/local/nagios/share/media/). #host_unreachable_sound=hostdown.wav #host_down_sound=hostdown.wav #service_critical_sound=critical.wav #service_warning_sound=warning.wav #service_unknown_sound=warning.wav #normal_sound=noproblem.wav nagios-2.6/sample-config/README0000664000076500007650000000172710140505667015616 0ustar nagiosnagios========================= SAMPLE CONFIG FILE README ========================= This directory contains *sample* configuration files for Nagios. You should read the HTML documentation for information on customizing these config files to suit your needs. A description of the sample config files and subdirectories contained here follows: CONTENTS: --------- cgi.cfg - This is a sample CGI config file nagios.cfg - This is a sample main config file resource.cfg - This is a sample resource config file, used for definining custom macros, storing sensitive data, etc. httpd.conf - This file contains sample snippets that you'll need to include in your Apache web server config file if you want to use the web interface. template-object/ - This directory contains sample object config files. You'll need to define object config files like these before you can actually start to monitor anything. nagios-2.6/sample-config/template-object/0000775000076500007650000000000010532717611020005 5ustar nagiosnagiosnagios-2.6/sample-config/template-object/README0000664000076500007650000000207610530732162020666 0ustar nagiosnagios================================ SAMPLE OBJECT CONFIG FILE README ================================ This directory contains sample object definition config files for use with the TEMPLATE-BASED object configuration file format. This is now the only type of file format supported by Nagios "out of the box". Sample config files have a .cfg extension. Ignore any files with a .in extension, as they are templates used to generate the sample config files. Please note that you can keep all of your object definitions in a single file if you wish. You may also split them up into multiple config files, as is done here. Read the HTML docs for information on how to include multiple object config files. FILE DESCRIPTIONS: ------------------ localhost.cfg - This is a minimalistic object config file that should be easier for new users to understand. It contains all types of object definitions you need to get started (hosts, services, etc..) commands.cfg - This file contains sample command definitions for host and service checks, notifications, etc. nagios-2.6/sample-config/template-object/commands.cfg.in0000664000076500007650000002062110530732162022671 0ustar nagiosnagios################################################################################ # Sample command definitions for Nagios @VERSION@ # # Read the documentation for more information on this configuration file. I've # provided some comments here, but things may not be so clear without further # explanation, so make sure to read the HTML documentation! # # Last Modified: 11-21-2006 # ################################################################################ ################################################################################ # COMMAND DEFINITIONS # # SYNTAX: # # define command{ # template # name # command_name # command_line # } # # WHERE: # # = object name of another command definition that should be # used as a template for this definition (optional) # = object name of command definition, referenced by other # command definitions that use it as a template (optional) # = name of the command, as recognized/used by Nagios # = command line # ################################################################################ ################################################################################ # # SAMPLE SERVICE CHECK COMMANDS # # These are some example service check commands. They may or may not work on # your system, as they must be modified for your plugins. See the HTML # documentation on the plugins for examples of how to configure command definitions. # ################################################################################ ################################################################################ # NOTE: The following 'check_local_...' functions are designed to monitor # various metrics on the host that Nagios is running on (i.e. this one). ################################################################################ # 'check_local_disk' command definition define command{ command_name check_local_disk command_line $USER1$/check_disk -w $ARG1$ -c $ARG2$ -p $ARG3$ } # 'check_local_load' command definition define command{ command_name check_local_load command_line $USER1$/check_load -w $ARG1$ -c $ARG2$ } # 'check_local_procs' command definition define command{ command_name check_local_procs command_line $USER1$/check_procs -w $ARG1$ -c $ARG2$ -s $ARG3$ } # 'check_local_users' command definition define command{ command_name check_local_users command_line $USER1$/check_users -w $ARG1$ -c $ARG2$ } ################################################################################ # NOTE: The following 'check_...' commands are used to monitor services on # both local and remote hosts. ################################################################################ # 'check_dns' command definition define command{ command_name check_dns command_line $USER1$/check_dns -H www.yahoo.com -s $HOSTADDRESS$ } # 'check_ftp' command definition define command{ command_name check_ftp command_line $USER1$/check_ftp -H $HOSTADDRESS$ } # 'check_hpjd' command definition define command{ command_name check_hpjd command_line $USER1$/check_hpjd -H $HOSTADDRESS$ -C public } # 'check_http' command definition define command{ command_name check_http command_line $USER1$/check_http -H $HOSTADDRESS$ } # 'check_nntp' command definition define command{ command_name check_nntp command_line $USER1$/check_nntp -H $HOSTADDRESS$ } # 'check_ping' command definition define command{ command_name check_ping command_line $USER1$/check_ping -H $HOSTADDRESS$ -w $ARG1$ -c $ARG2$ -p 5 } # 'check_pop' command definition define command{ command_name check_pop command_line $USER1$/check_pop -H $HOSTADDRESS$ } # 'check_smtp' command definition define command{ command_name check_smtp command_line $USER1$/check_smtp -H $HOSTADDRESS$ } # 'check_tcp' command definition define command{ command_name check_tcp command_line $USER1$/check_tcp -H $HOSTADDRESS$ -p $ARG1$ } # 'check_telnet' command definition define command{ command_name check_telnet command_line $USER1$/check_tcp -H $HOSTADDRESS$ -p 23 } # 'check_udp' command definition define command{ command_name check_udp command_line $USER1$/check_udp -H $HOSTADDRESS$ -p $ARG1$ } ################################################################################ # # SAMPLE HOST CHECK COMMANDS # ################################################################################ # This command checks to see if a host is "alive" by pinging it # The check must result in a 100% packet loss or 5 second (5000ms) round trip # average time to produce a critical error. # Note: Only one ICMP echo packet is sent (determined by the '-p 1' argument) # 'check-host-alive' command definition define command{ command_name check-host-alive command_line $USER1$/check_ping -H $HOSTADDRESS$ -w 3000.0,80% -c 5000.0,100% -p 1 } ################################################################################ # # SAMPLE NOTIFICATION COMMANDS # # These are some example notification commands. They may or may not work on # your system without modification. As an example, some systems will require # you to use "/usr/bin/mailx" instead of "/usr/bin/mail" in the commands below. # ################################################################################ # 'host-notify-by-email' command definition define command{ command_name host-notify-by-email command_line /usr/bin/printf "%b" "***** Nagios @VERSION@ *****\n\nNotification Type: $NOTIFICATIONTYPE$\nHost: $HOSTNAME$\nState: $HOSTSTATE$\nAddress: $HOSTADDRESS$\nInfo: $HOSTOUTPUT$\n\nDate/Time: $LONGDATETIME$\n" | @MAIL_PROG@ -s "Host $HOSTSTATE$ alert for $HOSTNAME$!" $CONTACTEMAIL$ } # 'host-notify-by-epager' command definition define command{ command_name host-notify-by-epager command_line /usr/bin/printf "%b" "Host '$HOSTALIAS$' is $HOSTSTATE$\nInfo: $HOSTOUTPUT$\nTime: $LONGDATETIME$" | @MAIL_PROG@ -s "$NOTIFICATIONTYPE$ alert - Host $HOSTNAME$ is $HOSTSTATE$" $CONTACTPAGER$ } # 'notify-by-email' command definition define command{ command_name notify-by-email command_line /usr/bin/printf "%b" "***** Nagios @VERSION@ *****\n\nNotification Type: $NOTIFICATIONTYPE$\n\nService: $SERVICEDESC$\nHost: $HOSTALIAS$\nAddress: $HOSTADDRESS$\nState: $SERVICESTATE$\n\nDate/Time: $LONGDATETIME$\n\nAdditional Info:\n\n$SERVICEOUTPUT$" | @MAIL_PROG@ -s "** $NOTIFICATIONTYPE$ alert - $HOSTALIAS$/$SERVICEDESC$ is $SERVICESTATE$ **" $CONTACTEMAIL$ } # 'notify-by-epager' command definition define command{ command_name notify-by-epager command_line /usr/bin/printf "%b" "Service: $SERVICEDESC$\nHost: $HOSTNAME$\nAddress: $HOSTADDRESS$\nState: $SERVICESTATE$\nInfo: $SERVICEOUTPUT$\nDate: $LONGDATETIME$" | @MAIL_PROG@ -s "$NOTIFICATIONTYPE$: $HOSTALIAS$/$SERVICEDESC$ is $SERVICESTATE$" $CONTACTPAGER$ } ################################################################################ # # SAMPLE PERFORMANCE DATA COMMANDS # # These are sample performance data commands that can be used to send performance # data output to two text files (one for hosts, another for services). If you # plan on simply writing performance data out to a file, consider using the # host_perfdata_file and service_perfdata_file options in the main config file. # ################################################################################ # 'process-host-perfdata' command definition define command{ command_name process-host-perfdata command_line /usr/bin/printf "%b" "$LASTHOSTCHECK$\t$HOSTNAME$\t$HOSTSTATE$\t$HOSTATTEMPT$\t$HOSTSTATETYPE$\t$HOSTEXECUTIONTIME$\t$HOSTOUTPUT$\t$HOSTPERFDATA$\n" >> @localstatedir@/host-perfdata.out } # 'process-service-perfdata' command definition define command{ command_name process-service-perfdata command_line /usr/bin/printf "%b" "$LASTSERVICECHECK$\t$HOSTNAME$\t$SERVICEDESC$\t$SERVICESTATE$\t$SERVICEATTEMPT$\t$SERVICESTATETYPE$\t$SERVICEEXECUTIONTIME$\t$SERVICELATENCY$\t$SERVICEOUTPUT$\t$SERVICEPERFDATA$\n" >> @localstatedir@/service-perfdata.out } nagios-2.6/sample-config/template-object/localhost.cfg.in0000664000076500007650000003032110532717361023064 0ustar nagiosnagios############################################################################### # LOCALHOST.CFG - SAMPLE OBJECT CONFIG FILE FOR MONITORING THIS MACHINE # # Last Modified: 11-27-2006 # # NOTE: This config file is intended to servce as an *extremely* simple # example of how you can create your object configuration file(s). # ############################################################################### ############################################################################### ############################################################################### # # TIME PERIODS # ############################################################################### ############################################################################### # This defines a timeperiod where all times are valid for checks, # notifications, etc. The classic "24x7" support nightmare. :-) define timeperiod{ timeperiod_name 24x7 alias 24 Hours A Day, 7 Days A Week sunday 00:00-24:00 monday 00:00-24:00 tuesday 00:00-24:00 wednesday 00:00-24:00 thursday 00:00-24:00 friday 00:00-24:00 saturday 00:00-24:00 } # 'workhours' timeperiod definition define timeperiod{ timeperiod_name workhours alias "Normal" Working Hours monday 09:00-17:00 tuesday 09:00-17:00 wednesday 09:00-17:00 thursday 09:00-17:00 friday 09:00-17:00 } # 'nonworkhours' timeperiod definition define timeperiod{ timeperiod_name nonworkhours alias Non-Work Hours sunday 00:00-24:00 monday 00:00-09:00,17:00-24:00 tuesday 00:00-09:00,17:00-24:00 wednesday 00:00-09:00,17:00-24:00 thursday 00:00-09:00,17:00-24:00 friday 00:00-09:00,17:00-24:00 saturday 00:00-24:00 } # 'none' timeperiod definition define timeperiod{ timeperiod_name none alias No Time Is A Good Time } ############################################################################### ############################################################################### # # COMMANDS # ############################################################################### ############################################################################### # NOTE: Sample command definitions can now be found in the sample commands.cfg # file ############################################################################### ############################################################################### # # CONTACTS # ############################################################################### ############################################################################### # In this simple config file, a single contact will receive all alerts. # This assumes that you have an account (or email alias) called # "@nagios_user@-admin" on the local host. define contact{ contact_name @nagios_user@-admin alias Nagios Admin service_notification_period 24x7 host_notification_period 24x7 service_notification_options w,u,c,r host_notification_options d,r service_notification_commands notify-by-email host_notification_commands host-notify-by-email email @nagios_user@-admin@localhost } ############################################################################### ############################################################################### # # CONTACT GROUPS # ############################################################################### ############################################################################### # We only have one contact in this simple configuration file, so there is # no need to create more than one contact group. define contactgroup{ contactgroup_name admins alias Nagios Administrators members @nagios_user@-admin } ############################################################################### ############################################################################### # # HOSTS # ############################################################################### ############################################################################### # Generic host definition template - This is NOT a real host, just a template! define host{ name generic-host ; The name of this host template notifications_enabled 1 ; Host notifications are enabled event_handler_enabled 1 ; Host event handler is enabled flap_detection_enabled 1 ; Flap detection is enabled failure_prediction_enabled 1 ; Failure prediction is enabled process_perf_data 1 ; Process performance data retain_status_information 1 ; Retain status information across program restarts retain_nonstatus_information 1 ; Retain non-status information across program restarts notification_period 24x7 ; Send host notifications at any time register 0 ; DONT REGISTER THIS DEFINITION - ITS NOT A REAL HOST, JUST A TEMPLATE! } # Linux host definition template - This is NOT a real host, just a template! define host{ name linux-server ; The name of this host template use generic-host ; This template inherits other values from the generic-host template check_period 24x7 ; By default, Linux hosts are checked round the clock max_check_attempts 10 ; Check each Linux host 10 times (max) check_command check-host-alive ; Default command to check Linux hosts notification_period workhours ; Linux admins hate to be woken up, so we only notify during the day ; Note that the notification_period variable is being overridden from ; the value that is inherited from the generic-host template! notification_interval 120 ; Resend notification every 2 hours notification_options d,u,r ; Only send notifications for specific host states contact_groups admins ; Notifications get sent to the admins by default register 0 ; DONT REGISTER THIS DEFINITION - ITS NOT A REAL HOST, JUST A TEMPLATE! } # Since this is a simple configuration file, we only monitor one host - the # local host (this machine). define host{ use linux-server ; Name of host template to use ; This host definition will inherit all variables that are defined ; in (or inherited by) the linux-server host template definition. host_name localhost alias localhost address 127.0.0.1 } ############################################################################### ############################################################################### # # HOST GROUPS # ############################################################################### ############################################################################### # We only have one host in our simple config file, so there is no need to # create more than one hostgroup. define hostgroup{ hostgroup_name test alias Test Servers members localhost } ############################################################################### ############################################################################### # # SERVICES # ############################################################################### ############################################################################### # Generic service definition template - This is NOT a real service, just a template! define service{ name generic-service ; The 'name' of this service template active_checks_enabled 1 ; Active service checks are enabled passive_checks_enabled 1 ; Passive service checks are enabled/accepted parallelize_check 1 ; Active service checks should be parallelized (disabling this can lead to major performance problems) obsess_over_service 1 ; We should obsess over this service (if necessary) check_freshness 0 ; Default is to NOT check service 'freshness' notifications_enabled 1 ; Service notifications are enabled event_handler_enabled 1 ; Service event handler is enabled flap_detection_enabled 1 ; Flap detection is enabled failure_prediction_enabled 1 ; Failure prediction is enabled process_perf_data 1 ; Process performance data retain_status_information 1 ; Retain status information across program restarts retain_nonstatus_information 1 ; Retain non-status information across program restarts is_volatile 0 ; The service is not volatile register 0 ; DONT REGISTER THIS DEFINITION - ITS NOT A REAL SERVICE, JUST A TEMPLATE! } # Local service definition template - This is NOT a real service, just a template! define service{ name local-service ; The name of this service template use generic-service ; Inherit default values from the generic-service definition check_period 24x7 ; The service can be checked at any time of the day max_check_attempts 4 ; Re-check the service up to 4 times in order to determine its final (hard) state normal_check_interval 5 ; Check the service every 5 minutes under normal conditions retry_check_interval 1 ; Re-check the service every minute until a hard state can be determined contact_groups admins ; Notifications get sent out to everyone in the 'admins' group notification_options w,u,c,r ; Send notifications about warning, unknown, critical, and recovery events notification_interval 60 ; Re-notify about service problems every hour notification_period 24x7 ; Notifications can be sent out at any time register 0 ; DONT REGISTER THIS DEFINITION - ITS NOT A REAL SERVICE, JUST A TEMPLATE! } # Define a service to "ping" the local machine define service{ use local-service ; Name of service template to use host_name localhost service_description PING check_command check_ping!100.0,20%!500.0,60% } # Define a service to check the disk space of the root partition # on the local machine. Warning if < 20% free, critical if # < 10% free space on partition. define service{ use local-service ; Name of service template to use host_name localhost service_description Root Partition check_command check_local_disk!20%!10%!/ } # Define a service to check the number of currently logged in # users on the local machine. Warning if > 20 users, critical # if > 50 users. define service{ use local-service ; Name of service template to use host_name localhost service_description Current Users check_command check_local_users!20!50 } # Define a service to check the number of currently running procs # on the local machine. Warning if > 250 processes, critical if # > 400 users. define service{ use local-service ; Name of service template to use host_name localhost service_description Total Processes check_command check_local_procs!250!400!RSZDT } # Define a service to check the load on the local machine. define service{ use local-service ; Name of service template to use host_name localhost service_description Current Load check_command check_local_load!5.0,4.0,3.0!10.0,6.0,4.0 } nagios-2.6/sample-config/httpd.conf.in0000664000076500007650000000164410342163030017317 0ustar nagiosnagios# SAMPLE CONFIG SNIPPETS FOR APACHE WEB SERVER # Last Modified: 11-26-2005 # # This file contains examples of entries that need # to be incorporated into your Apache web server # configuration file. Customize the paths, etc. as # needed to fit your system. ScriptAlias @cgiurl@ "@sbindir@" # SSLRequireSSL Options ExecCGI AllowOverride None Order allow,deny Allow from all # Order deny,allow # Deny from all # Allow from 127.0.0.1 AuthName "Nagios Access" AuthType Basic AuthUserFile @sysconfdir@/htpasswd.users Require valid-user Alias @htmurl@ "@datadir@" # SSLRequireSSL Options None AllowOverride None Order allow,deny Allow from all # Order deny,allow # Deny from all # Allow from 127.0.0.1 AuthName "Nagios Access" AuthType Basic AuthUserFile @sysconfdir@/htpasswd.users Require valid-user nagios-2.6/sample-config/nagios.cfg.in0000664000076500007650000007304710530732161017302 0ustar nagiosnagios############################################################################## # # NAGIOS.CFG - Sample Main Config File for Nagios @VERSION@ # # Read the documentation for more information on this configuration # file. I've provided some comments here, but things may not be so # clear without further explanation. # # Last Modified: 11-21-2006 # ############################################################################## # LOG FILE # This is the main log file where service and host events are logged # for historical purposes. This should be the first option specified # in the config file!!! log_file=@localstatedir@/nagios.log # OBJECT CONFIGURATION FILE(S) # This is the configuration file in which you define hosts, host # groups, contacts, contact groups, services, etc. I guess it would # be better called an object definition file, but for historical # reasons it isn't. You can split object definitions into several # different config files by using multiple cfg_file statements here. # Nagios will read and process all the config files you define. # This can be very useful if you want to keep command definitions # separate from host and contact definitions... # Command definitions cfg_file=@sysconfdir@/commands.cfg # Host and service definitions for monitoring this machine cfg_file=@sysconfdir@/localhost.cfg # You can split other types of object definitions across several # config files if you wish (as done here), or keep them all in a # single config file. #cfg_file=@sysconfdir@/contactgroups.cfg #cfg_file=@sysconfdir@/contacts.cfg #cfg_file=@sysconfdir@/dependencies.cfg #cfg_file=@sysconfdir@/escalations.cfg #cfg_file=@sysconfdir@/hostgroups.cfg #cfg_file=@sysconfdir@/hosts.cfg #cfg_file=@sysconfdir@/services.cfg #cfg_file=@sysconfdir@/timeperiods.cfg # Extended host/service info definitions are now stored along with # other object definitions: #cfg_file=@sysconfdir@/hostextinfo.cfg #cfg_file=@sysconfdir@/serviceextinfo.cfg # You can also tell Nagios to process all config files (with a .cfg # extension) in a particular directory by using the cfg_dir # directive as shown below: #cfg_dir=@sysconfdir@/servers #cfg_dir=@sysconfdir@/printers #cfg_dir=@sysconfdir@/switches #cfg_dir=@sysconfdir@/routers # OBJECT CACHE FILE # This option determines where object definitions are cached when # Nagios starts/restarts. The CGIs read object definitions from # this cache file (rather than looking at the object config files # directly) in order to prevent inconsistencies that can occur # when the config files are modified after Nagios starts. object_cache_file=@localstatedir@/objects.cache # RESOURCE FILE # This is an optional resource file that contains $USERx$ macro # definitions. Multiple resource files can be specified by using # multiple resource_file definitions. The CGIs will not attempt to # read the contents of resource files, so information that is # considered to be sensitive (usernames, passwords, etc) can be # defined as macros in this file and restrictive permissions (600) # can be placed on this file. resource_file=@sysconfdir@/resource.cfg # STATUS FILE # This is where the current status of all monitored services and # hosts is stored. Its contents are read and processed by the CGIs. # The contents of the status file are deleted every time Nagios # restarts. status_file=@localstatedir@/status.dat # NAGIOS USER # This determines the effective user that Nagios should run as. # You can either supply a username or a UID. nagios_user=@nagios_user@ # NAGIOS GROUP # This determines the effective group that Nagios should run as. # You can either supply a group name or a GID. nagios_group=@nagios_grp@ # EXTERNAL COMMAND OPTION # This option allows you to specify whether or not Nagios should check # for external commands (in the command file defined below). By default # Nagios will *not* check for external commands, just to be on the # cautious side. If you want to be able to use the CGI command interface # you will have to enable this. Setting this value to 0 disables command # checking (the default), other values enable it. check_external_commands=0 # EXTERNAL COMMAND CHECK INTERVAL # This is the interval at which Nagios should check for external commands. # This value works of the interval_length you specify later. If you leave # that at its default value of 60 (seconds), a value of 1 here will cause # Nagios to check for external commands every minute. If you specify a # number followed by an "s" (i.e. 15s), this will be interpreted to mean # actual seconds rather than a multiple of the interval_length variable. # Note: In addition to reading the external command file at regularly # scheduled intervals, Nagios will also check for external commands after # event handlers are executed. # NOTE: Setting this value to -1 causes Nagios to check the external # command file as often as possible. #command_check_interval=15s command_check_interval=-1 # EXTERNAL COMMAND FILE # This is the file that Nagios checks for external command requests. # It is also where the command CGI will write commands that are submitted # by users, so it must be writeable by the user that the web server # is running as (usually 'nobody'). Permissions should be set at the # directory level instead of on the file, as the file is deleted every # time its contents are processed. command_file=@localstatedir@/rw/nagios.cmd # COMMENT FILE # This is the file that Nagios will use for storing host and service # comments. comment_file=@localstatedir@/comments.dat # DOWNTIME FILE # This is the file that Nagios will use for storing host and service # downtime data. downtime_file=@localstatedir@/downtime.dat # LOCK FILE # This is the lockfile that Nagios will use to store its PID number # in when it is running in daemon mode. lock_file=@lockfile@ # TEMP FILE # This is a temporary file that is used as scratch space when Nagios # updates the status log, cleans the comment file, etc. This file # is created, used, and deleted throughout the time that Nagios is # running. temp_file=@localstatedir@/nagios.tmp # EVENT BROKER OPTIONS # Controls what (if any) data gets sent to the event broker. # Values: 0 = Broker nothing # -1 = Broker everything # = See documentation event_broker_options=-1 # EVENT BROKER MODULE(S) # This directive is used to specify an event broker module that should # by loaded by Nagios at startup. Use multiple directives if you want # to load more than one module. Arguments that should be passed to # the module at startup are seperated from the module path by a space. # # Example: # # broker_module= [moduleargs] #broker_module=/somewhere/module1.o #broker_module=/somewhere/module2.o arg1 arg2=3 debug=0 # LOG ROTATION METHOD # This is the log rotation method that Nagios should use to rotate # the main log file. Values are as follows.. # n = None - don't rotate the log # h = Hourly rotation (top of the hour) # d = Daily rotation (midnight every day) # w = Weekly rotation (midnight on Saturday evening) # m = Monthly rotation (midnight last day of month) log_rotation_method=d # LOG ARCHIVE PATH # This is the directory where archived (rotated) log files should be # placed (assuming you've chosen to do log rotation). log_archive_path=@localstatedir@/archives # LOGGING OPTIONS # If you want messages logged to the syslog facility, as well as the # NetAlarm log file set this option to 1. If not, set it to 0. use_syslog=1 # NOTIFICATION LOGGING OPTION # If you don't want notifications to be logged, set this value to 0. # If notifications should be logged, set the value to 1. log_notifications=1 # SERVICE RETRY LOGGING OPTION # If you don't want service check retries to be logged, set this value # to 0. If retries should be logged, set the value to 1. log_service_retries=1 # HOST RETRY LOGGING OPTION # If you don't want host check retries to be logged, set this value to # 0. If retries should be logged, set the value to 1. log_host_retries=1 # EVENT HANDLER LOGGING OPTION # If you don't want host and service event handlers to be logged, set # this value to 0. If event handlers should be logged, set the value # to 1. log_event_handlers=1 # INITIAL STATES LOGGING OPTION # If you want Nagios to log all initial host and service states to # the main log file (the first time the service or host is checked) # you can enable this option by setting this value to 1. If you # are not using an external application that does long term state # statistics reporting, you do not need to enable this option. In # this case, set the value to 0. log_initial_states=0 # EXTERNAL COMMANDS LOGGING OPTION # If you don't want Nagios to log external commands, set this value # to 0. If external commands should be logged, set this value to 1. # Note: This option does not include logging of passive service # checks - see the option below for controlling whether or not # passive checks are logged. log_external_commands=1 # PASSIVE CHECKS LOGGING OPTION # If you don't want Nagios to log passive host and service checks, set # this value to 0. If passive checks should be logged, set # this value to 1. log_passive_checks=1 # GLOBAL HOST AND SERVICE EVENT HANDLERS # These options allow you to specify a host and service event handler # command that is to be run for every host or service state change. # The global event handler is executed immediately prior to the event # handler that you have optionally specified in each host or # service definition. The command argument is the short name of a # command definition that you define in your host configuration file. # Read the HTML docs for more information. #global_host_event_handler=somecommand #global_service_event_handler=somecommand # SERVICE INTER-CHECK DELAY METHOD # This is the method that Nagios should use when initially # "spreading out" service checks when it starts monitoring. The # default is to use smart delay calculation, which will try to # space all service checks out evenly to minimize CPU load. # Using the dumb setting will cause all checks to be scheduled # at the same time (with no delay between them)! This is not a # good thing for production, but is useful when testing the # parallelization functionality. # n = None - don't use any delay between checks # d = Use a "dumb" delay of 1 second between checks # s = Use "smart" inter-check delay calculation # x.xx = Use an inter-check delay of x.xx seconds service_inter_check_delay_method=s # MAXIMUM SERVICE CHECK SPREAD # This variable determines the timeframe (in minutes) from the # program start time that an initial check of all services should # be completed. Default is 30 minutes. max_service_check_spread=30 # SERVICE CHECK INTERLEAVE FACTOR # This variable determines how service checks are interleaved. # Interleaving the service checks allows for a more even # distribution of service checks and reduced load on remote # hosts. Setting this value to 1 is equivalent to how versions # of Nagios previous to 0.0.5 did service checks. Set this # value to s (smart) for automatic calculation of the interleave # factor unless you have a specific reason to change it. # s = Use "smart" interleave factor calculation # x = Use an interleave factor of x, where x is a # number greater than or equal to 1. service_interleave_factor=s # HOST INTER-CHECK DELAY METHOD # This is the method that Nagios should use when initially # "spreading out" host checks when it starts monitoring. The # default is to use smart delay calculation, which will try to # space all host checks out evenly to minimize CPU load. # Using the dumb setting will cause all checks to be scheduled # at the same time (with no delay between them)! # n = None - don't use any delay between checks # d = Use a "dumb" delay of 1 second between checks # s = Use "smart" inter-check delay calculation # x.xx = Use an inter-check delay of x.xx seconds host_inter_check_delay_method=s # MAXIMUM HOST CHECK SPREAD # This variable determines the timeframe (in minutes) from the # program start time that an initial check of all hosts should # be completed. Default is 30 minutes. max_host_check_spread=30 # MAXIMUM CONCURRENT SERVICE CHECKS # This option allows you to specify the maximum number of # service checks that can be run in parallel at any given time. # Specifying a value of 1 for this variable essentially prevents # any service checks from being parallelized. A value of 0 # will not restrict the number of concurrent checks that are # being executed. max_concurrent_checks=0 # SERVICE CHECK REAPER FREQUENCY # This is the frequency (in seconds!) that Nagios will process # the results of services that have been checked. service_reaper_frequency=10 # AUTO-RESCHEDULING OPTION # This option determines whether or not Nagios will attempt to # automatically reschedule active host and service checks to # "smooth" them out over time. This can help balance the load on # the monitoring server. # WARNING: THIS IS AN EXPERIMENTAL FEATURE - IT CAN DEGRADE # PERFORMANCE, RATHER THAN INCREASE IT, IF USED IMPROPERLY auto_reschedule_checks=0 # AUTO-RESCHEDULING INTERVAL # This option determines how often (in seconds) Nagios will # attempt to automatically reschedule checks. This option only # has an effect if the auto_reschedule_checks option is enabled. # Default is 30 seconds. # WARNING: THIS IS AN EXPERIMENTAL FEATURE - IT CAN DEGRADE # PERFORMANCE, RATHER THAN INCREASE IT, IF USED IMPROPERLY auto_rescheduling_interval=30 # AUTO-RESCHEDULING WINDOW # This option determines the "window" of time (in seconds) that # Nagios will look at when automatically rescheduling checks. # Only host and service checks that occur in the next X seconds # (determined by this variable) will be rescheduled. This option # only has an effect if the auto_reschedule_checks option is # enabled. Default is 180 seconds (3 minutes). # WARNING: THIS IS AN EXPERIMENTAL FEATURE - IT CAN DEGRADE # PERFORMANCE, RATHER THAN INCREASE IT, IF USED IMPROPERLY auto_rescheduling_window=180 # SLEEP TIME # This is the number of seconds to sleep between checking for system # events and service checks that need to be run. sleep_time=0.25 # TIMEOUT VALUES # These options control how much time Nagios will allow various # types of commands to execute before killing them off. Options # are available for controlling maximum time allotted for # service checks, host checks, event handlers, notifications, the # ocsp command, and performance data commands. All values are in # seconds. service_check_timeout=60 host_check_timeout=30 event_handler_timeout=30 notification_timeout=30 ocsp_timeout=5 perfdata_timeout=5 # RETAIN STATE INFORMATION # This setting determines whether or not Nagios will save state # information for services and hosts before it shuts down. Upon # startup Nagios will reload all saved service and host state # information before starting to monitor. This is useful for # maintaining long-term data on state statistics, etc, but will # slow Nagios down a bit when it (re)starts. Since its only # a one-time penalty, I think its well worth the additional # startup delay. retain_state_information=1 # STATE RETENTION FILE # This is the file that Nagios should use to store host and # service state information before it shuts down. The state # information in this file is also read immediately prior to # starting to monitor the network when Nagios is restarted. # This file is used only if the preserve_state_information # variable is set to 1. state_retention_file=@localstatedir@/retention.dat # RETENTION DATA UPDATE INTERVAL # This setting determines how often (in minutes) that Nagios # will automatically save retention data during normal operation. # If you set this value to 0, Nagios will not save retention # data at regular interval, but it will still save retention # data before shutting down or restarting. If you have disabled # state retention, this option has no effect. retention_update_interval=60 # USE RETAINED PROGRAM STATE # This setting determines whether or not Nagios will set # program status variables based on the values saved in the # retention file. If you want to use retained program status # information, set this value to 1. If not, set this value # to 0. use_retained_program_state=1 # USE RETAINED SCHEDULING INFO # This setting determines whether or not Nagios will retain # the scheduling info (next check time) for hosts and services # based on the values saved in the retention file. If you # If you want to use retained scheduling info, set this # value to 1. If not, set this value to 0. use_retained_scheduling_info=0 # INTERVAL LENGTH # This is the seconds per unit interval as used in the # host/contact/service configuration files. Setting this to 60 means # that each interval is one minute long (60 seconds). Other settings # have not been tested much, so your mileage is likely to vary... interval_length=60 # AGGRESSIVE HOST CHECKING OPTION # If you don't want to turn on aggressive host checking features, set # this value to 0 (the default). Otherwise set this value to 1 to # enable the aggressive check option. Read the docs for more info # on what aggressive host check is or check out the source code in # base/checks.c use_aggressive_host_checking=0 # SERVICE CHECK EXECUTION OPTION # This determines whether or not Nagios will actively execute # service checks when it initially starts. If this option is # disabled, checks are not actively made, but Nagios can still # receive and process passive check results that come in. Unless # you're implementing redundant hosts or have a special need for # disabling the execution of service checks, leave this enabled! # Values: 1 = enable checks, 0 = disable checks execute_service_checks=1 # PASSIVE SERVICE CHECK ACCEPTANCE OPTION # This determines whether or not Nagios will accept passive # service checks results when it initially (re)starts. # Values: 1 = accept passive checks, 0 = reject passive checks accept_passive_service_checks=1 # HOST CHECK EXECUTION OPTION # This determines whether or not Nagios will actively execute # host checks when it initially starts. If this option is # disabled, checks are not actively made, but Nagios can still # receive and process passive check results that come in. Unless # you're implementing redundant hosts or have a special need for # disabling the execution of host checks, leave this enabled! # Values: 1 = enable checks, 0 = disable checks execute_host_checks=1 # PASSIVE HOST CHECK ACCEPTANCE OPTION # This determines whether or not Nagios will accept passive # host checks results when it initially (re)starts. # Values: 1 = accept passive checks, 0 = reject passive checks accept_passive_host_checks=1 # NOTIFICATIONS OPTION # This determines whether or not Nagios will sent out any host or # service notifications when it is initially (re)started. # Values: 1 = enable notifications, 0 = disable notifications enable_notifications=1 # EVENT HANDLER USE OPTION # This determines whether or not Nagios will run any host or # service event handlers when it is initially (re)started. Unless # you're implementing redundant hosts, leave this option enabled. # Values: 1 = enable event handlers, 0 = disable event handlers enable_event_handlers=1 # PROCESS PERFORMANCE DATA OPTION # This determines whether or not Nagios will process performance # data returned from service and host checks. If this option is # enabled, host performance data will be processed using the # host_perfdata_command (defined below) and service performance # data will be processed using the service_perfdata_command (also # defined below). Read the HTML docs for more information on # performance data. # Values: 1 = process performance data, 0 = do not process performance data process_performance_data=0 # HOST AND SERVICE PERFORMANCE DATA PROCESSING COMMANDS # These commands are run after every host and service check is # performed. These commands are executed only if the # enable_performance_data option (above) is set to 1. The command # argument is the short name of a command definition that you # define in your host configuration file. Read the HTML docs for # more information on performance data. #host_perfdata_command=process-host-perfdata #service_perfdata_command=process-service-perfdata # HOST AND SERVICE PERFORMANCE DATA FILES # These files are used to store host and service performance data. # Performance data is only written to these files if the # enable_performance_data option (above) is set to 1. #host_perfdata_file=/tmp/host-perfdata #service_perfdata_file=/tmp/service-perfdata # HOST AND SERVICE PERFORMANCE DATA FILE TEMPLATES # These options determine what data is written (and how) to the # performance data files. The templates may contain macros, special # characters (\t for tab, \r for carriage return, \n for newline) # and plain text. A newline is automatically added after each write # to the performance data file. Some examples of what you can do are # shown below. #host_perfdata_file_template=[HOSTPERFDATA]\t$TIMET$\t$HOSTNAME$\t$HOSTEXECUTIONTIME$\t$HOSTOUTPUT$\t$HOSTPERFDATA$ #service_perfdata_file_template=[SERVICEPERFDATA]\t$TIMET$\t$HOSTNAME$\t$SERVICEDESC$\t$SERVICEEXECUTIONTIME$\t$SERVICELATENCY$\t$SERVICEOUTPUT$\t$SERVICEPERFDATA$ # HOST AND SERVICE PERFORMANCE DATA FILE MODES # This option determines whether or not the host and service # performance data files are opened in write ("w") or append ("a") # mode. Unless you are the files are named pipes, you will probably # want to use the default mode of append ("a"). #host_perfdata_file_mode=a #service_perfdata_file_mode=a # HOST AND SERVICE PERFORMANCE DATA FILE PROCESSING INTERVAL # These options determine how often (in seconds) the host and service # performance data files are processed using the commands defined # below. A value of 0 indicates the files should not be periodically # processed. #host_perfdata_file_processing_interval=0 #service_perfdata_file_processing_interval=0 # HOST AND SERVICE PERFORMANCE DATA FILE PROCESSING COMMANDS # These commands are used to periodically process the host and # service performance data files. The interval at which the # processing occurs is determined by the options above. #host_perfdata_file_processing_command=process-host-perfdata-file #service_perfdata_file_processing_command=process-service-perfdata-file # OBSESS OVER SERVICE CHECKS OPTION # This determines whether or not Nagios will obsess over service # checks and run the ocsp_command defined below. Unless you're # planning on implementing distributed monitoring, do not enable # this option. Read the HTML docs for more information on # implementing distributed monitoring. # Values: 1 = obsess over services, 0 = do not obsess (default) obsess_over_services=0 # OBSESSIVE COMPULSIVE SERVICE PROCESSOR COMMAND # This is the command that is run for every service check that is # processed by Nagios. This command is executed only if the # obsess_over_service option (above) is set to 1. The command # argument is the short name of a command definition that you # define in your host configuration file. Read the HTML docs for # more information on implementing distributed monitoring. #ocsp_command=somecommand # ORPHANED SERVICE CHECK OPTION # This determines whether or not Nagios will periodically # check for orphaned services. Since service checks are not # rescheduled until the results of their previous execution # instance are processed, there exists a possibility that some # checks may never get rescheduled. This seems to be a rare # problem and should not happen under normal circumstances. # If you have problems with service checks never getting # rescheduled, you might want to try enabling this option. # Values: 1 = enable checks, 0 = disable checks check_for_orphaned_services=1 # SERVICE FRESHNESS CHECK OPTION # This option determines whether or not Nagios will periodically # check the "freshness" of service results. Enabling this option # is useful for ensuring passive checks are received in a timely # manner. # Values: 1 = enabled freshness checking, 0 = disable freshness checking check_service_freshness=1 # SERVICE FRESHNESS CHECK INTERVAL # This setting determines how often (in seconds) Nagios will # check the "freshness" of service check results. If you have # disabled service freshness checking, this option has no effect. service_freshness_check_interval=60 # HOST FRESHNESS CHECK OPTION # This option determines whether or not Nagios will periodically # check the "freshness" of host results. Enabling this option # is useful for ensuring passive checks are received in a timely # manner. # Values: 1 = enabled freshness checking, 0 = disable freshness checking check_host_freshness=0 # HOST FRESHNESS CHECK INTERVAL # This setting determines how often (in seconds) Nagios will # check the "freshness" of host check results. If you have # disabled host freshness checking, this option has no effect. host_freshness_check_interval=60 # AGGREGATED STATUS UPDATES # This option determines whether or not Nagios will # aggregate updates of host, service, and program status # data. Normally, status data is updated immediately when # a change occurs. This can result in high CPU loads if # you are monitoring a lot of services. If you want Nagios # to only refresh status data every few seconds, disable # this option. # Values: 1 = enable aggregate updates, 0 = disable aggregate updates aggregate_status_updates=1 # AGGREGATED STATUS UPDATE INTERVAL # Combined with the aggregate_status_updates option, # this option determines the frequency (in seconds!) that # Nagios will periodically dump program, host, and # service status data. If you are not using aggregated # status data updates, this option has no effect. status_update_interval=15 # FLAP DETECTION OPTION # This option determines whether or not Nagios will try # and detect hosts and services that are "flapping". # Flapping occurs when a host or service changes between # states too frequently. When Nagios detects that a # host or service is flapping, it will temporarily suppress # notifications for that host/service until it stops # flapping. Flap detection is very experimental, so read # the HTML documentation before enabling this feature! # Values: 1 = enable flap detection # 0 = disable flap detection (default) enable_flap_detection=0 # FLAP DETECTION THRESHOLDS FOR HOSTS AND SERVICES # Read the HTML documentation on flap detection for # an explanation of what this option does. This option # has no effect if flap detection is disabled. low_service_flap_threshold=5.0 high_service_flap_threshold=20.0 low_host_flap_threshold=5.0 high_host_flap_threshold=20.0 # DATE FORMAT OPTION # This option determines how short dates are displayed. Valid options # include: # us (MM-DD-YYYY HH:MM:SS) # euro (DD-MM-YYYY HH:MM:SS) # iso8601 (YYYY-MM-DD HH:MM:SS) # strict-iso8601 (YYYY-MM-DDTHH:MM:SS) # date_format=us # P1.PL FILE LOCATION # This value determines where the p1.pl perl script (used by the # embedded Perl interpreter) is located. If you didn't compile # Nagios with embedded Perl support, this option has no effect. p1_file=@bindir@/p1.pl # ILLEGAL OBJECT NAME CHARACTERS # This option allows you to specify illegal characters that cannot # be used in host names, service descriptions, or names of other # object types. illegal_object_name_chars=`~!$%^&*|'"<>?,()= # ILLEGAL MACRO OUTPUT CHARACTERS # This option allows you to specify illegal characters that are # stripped from macros before being used in notifications, event # handlers, etc. This DOES NOT affect macros used in service or # host check commands. # The following macros are stripped of the characters you specify: # $HOSTOUTPUT$ # $HOSTPERFDATA$ # $HOSTACKAUTHOR$ # $HOSTACKCOMMENT$ # $SERVICEOUTPUT$ # $SERVICEPERFDATA$ # $SERVICEACKAUTHOR$ # $SERVICEACKCOMMENT$ illegal_macro_output_chars=`~$&|'"<> # REGULAR EXPRESSION MATCHING # This option controls whether or not regular expression matching # takes place in the object config files. Regular expression # matching is used to match host, hostgroup, service, and service # group names/descriptions in some fields of various object types. # Values: 1 = enable regexp matching, 0 = disable regexp matching use_regexp_matching=0 # "TRUE" REGULAR EXPRESSION MATCHING # This option controls whether or not "true" regular expression # matching takes place in the object config files. This option # only has an effect if regular expression matching is enabled # (see above). If this option is DISABLED, regular expression # matching only occurs if a string contains wildcard characters # (* and ?). If the option is ENABLED, regexp matching occurs # all the time (which can be annoying). # Values: 1 = enable true matching, 0 = disable true matching use_true_regexp_matching=0 # ADMINISTRATOR EMAIL ADDRESS # The email address of the administrator of *this* machine (the one # doing the monitoring). Nagios never uses this value itself, but # you can access this value by using the $ADMINEMAIL$ macro in your # notification commands. admin_email=@nagios_user@ # ADMINISTRATOR PAGER NUMBER/ADDRESS # The pager number/address for the administrator of *this* machine. # Nagios never uses this value itself, but you can access this # value by using the $ADMINPAGER$ macro in your notification # commands. admin_pager=page@nagios_user@ # DAEMON CORE DUMP OPTION # This option determines whether or not Nagios is allowed to create # a core dump when it runs as a daemon. Note that it is generally # considered bad form to allow this, but it may be useful for # debugging purposes. # Values: 1 - Allow core dumps # 0 - Do not allow core dumps (default) daemon_dumps_core=0 nagios-2.6/sample-config/resource.cfg.in0000664000076500007650000000244607730205777017664 0ustar nagiosnagios########################################################################### # # RESOURCE.CFG - Sample Resource File for Nagios @VERSION@ # # Last Modified: 09-10-2003 # # You can define $USERx$ macros in this file, which can in turn be used # in command definitions in your host config file(s). $USERx$ macros are # useful for storing sensitive information such as usernames, passwords, # etc. They are also handy for specifying the path to plugins and # event handlers - if you decide to move the plugins or event handlers to # a different directory in the future, you can just update one or two # $USERx$ macros, instead of modifying a lot of command definitions. # # The CGIs will not attempt to read the contents of resource files, so # you can set restrictive permissions (600 or 660) on them. # # Nagios supports up to 32 $USERx$ macros ($USER1$ through $USER32$) # # Resource files may also be used to store configuration directives for # external data sources like MySQL... # ########################################################################### # Sets $USER1$ to be the path to the plugins $USER1$=@libexecdir@ # Sets $USER2$ to be the path to event handlers #$USER2$=@libexecdir@/eventhandlers # Store some usernames and passwords (hidden from the CGIs) #$USER3$=someuser #$USER4$=somepassword nagios-2.6/xdata/0000775000076500007650000000000010532717616013310 5ustar nagiosnagiosnagios-2.6/xdata/Makefile.in0000664000076500007650000000030307645164372015357 0ustar nagiosnagios############################ # Makefile for Nagios # # Last Modified: 04-08-2003 ############################ clean: rm -f *.o rm -f *~ distclean: clean rm -f Makefile devclean: distclean nagios-2.6/xdata/xcddefault.c0000664000076500007650000004134110433670166015600 0ustar nagiosnagios/***************************************************************************** * * XCDDEFAULT.C - Default external comment data routines for Nagios * * Copyright (c) 2000-2006 Ethan Galstad (nagios@nagios.org) * Last Modified: 05-20-2006 * * 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/locations.h" #include "../include/comments.h" #ifdef NSCORE #include "../include/objects.h" #include "../include/nagios.h" #endif #ifdef NSCGI #include "../include/cgiutils.h" #endif /**** IMPLEMENTATION SPECIFIC HEADER FILES ****/ #include "xcddefault.h" char xcddefault_comment_file[MAX_FILENAME_LENGTH]=""; char xcddefault_temp_file[MAX_FILENAME_LENGTH]=""; #ifdef NSCORE unsigned long current_comment_id=0; extern comment *comment_list; extern char *macro_x[MACRO_X_COUNT]; #endif /******************************************************************/ /***************** COMMON CONFIG INITIALIZATION ******************/ /******************************************************************/ /* grab configuration information from appropriate config file(s) */ int xcddefault_grab_config_info(char *config_file){ char *input=NULL; mmapfile *thefile; #ifdef NSCGI char *input2=NULL; mmapfile *thefile2; char *temp_buffer; #endif /*** CORE PASSES IN MAIN CONFIG FILE, CGIS PASS IN CGI CONFIG FILE! ***/ /* initialize the location of the comment and temp */ strncpy(xcddefault_comment_file,DEFAULT_COMMENT_FILE,sizeof(xcddefault_comment_file)-1); strncpy(xcddefault_temp_file,DEFAULT_TEMP_FILE,sizeof(xcddefault_temp_file)-1); xcddefault_comment_file[sizeof(xcddefault_comment_file)-1]='\x0'; xcddefault_temp_file[sizeof(xcddefault_temp_file)-1]='\x0'; /* open the config file for reading */ if((thefile=mmap_fopen(config_file))==NULL) return ERROR; /* read in all lines from the config file */ while(1){ /* free memory */ free(input); /* read the next line */ if((input=mmap_fgets(thefile))==NULL) break; strip(input); /* skip blank lines and comments */ if(input[0]=='#' || input[0]=='\x0') continue; #ifdef NSCGI /* CGI needs to find and read contents of main config file, since it was passed the name of the CGI config file */ if(strstr(input,"main_config_file")==input){ temp_buffer=strtok(input,"="); temp_buffer=strtok(NULL,"\n"); if(temp_buffer==NULL) continue; if((thefile2=mmap_fopen(temp_buffer))==NULL) continue; /* read in all lines from the main config file */ while(1){ /* free memory */ free(input2); /* read the next line */ if((input2=mmap_fgets(thefile2))==NULL) break; strip(input2); /* skip blank lines and comments */ if(input2[0]=='#' || input2[0]=='\x0') continue; xcddefault_grab_config_directives(input2); } /* free memory and close the file */ free(input2); mmap_fclose(thefile2); } #endif #ifdef NSCORE /* core read variables directly from the main config file */ xcddefault_grab_config_directives(input); #endif } /* free memory and close the file */ free(input); mmap_fclose(thefile); /* we didn't find the comment file */ if(!strcmp(xcddefault_comment_file,"")) return ERROR; /* we didn't find the temp file */ if(!strcmp(xcddefault_temp_file,"")) return ERROR; #ifdef NSCORE /* save the comment data file macro */ if(macro_x[MACRO_COMMENTDATAFILE]!=NULL) free(macro_x[MACRO_COMMENTDATAFILE]); macro_x[MACRO_COMMENTDATAFILE]=(char *)strdup(xcddefault_comment_file); if(macro_x[MACRO_COMMENTDATAFILE]!=NULL) strip(macro_x[MACRO_COMMENTDATAFILE]); #endif return OK; } void xcddefault_grab_config_directives(char *input_buffer){ char *temp_buffer; /* comment file definition */ if((strstr(input_buffer,"comment_file")==input_buffer) || (strstr(input_buffer,"xcddefault_comment_file")==input_buffer)){ temp_buffer=strtok(input_buffer,"="); temp_buffer=strtok(NULL,"\n"); if(temp_buffer==NULL) return; strncpy(xcddefault_comment_file,temp_buffer,sizeof(xcddefault_comment_file)-1); xcddefault_comment_file[sizeof(xcddefault_comment_file)-1]='\x0'; } /* status log definition */ if((strstr(input_buffer,"temp_file")==input_buffer) || (strstr(input_buffer,"xcddefault_temp_file")==input_buffer)){ temp_buffer=strtok(input_buffer,"="); temp_buffer=strtok(NULL,"\n"); if(temp_buffer==NULL) return; strncpy(xcddefault_temp_file,temp_buffer,sizeof(xcddefault_temp_file)-1); xcddefault_temp_file[sizeof(xcddefault_temp_file)-1]='\x0'; } return; } #ifdef NSCORE /******************************************************************/ /************ COMMENT INITIALIZATION/CLEANUP FUNCTIONS ************/ /******************************************************************/ /* initialize comment data */ int xcddefault_initialize_comment_data(char *main_config_file){ /* grab configuration information */ if(xcddefault_grab_config_info(main_config_file)==ERROR) return ERROR; /* create comment file if necessary */ xcddefault_create_comment_file(); /* read comment data */ xcddefault_read_comment_data(main_config_file); /* clean up the old comment data */ xcddefault_validate_comment_data(); return OK; } /* creates an empty comment data file if one doesn't already exist */ int xcddefault_create_comment_file(void){ struct stat statbuf; /* bail out if file already exists */ if(!stat(xcddefault_comment_file,&statbuf)) return OK; /* create an empty file */ xcddefault_save_comment_data(); return OK; } /* removes invalid and old comments from the comment file */ int xcddefault_validate_comment_data(void){ comment *temp_comment; comment *next_comment; int update_file=FALSE; int save=TRUE; /* remove stale comments */ for(temp_comment=comment_list;temp_comment!=NULL;temp_comment=next_comment){ next_comment=temp_comment->next; save=TRUE; /* delete comments with invalid host names */ if(find_host(temp_comment->host_name)==NULL) save=FALSE; /* delete comments with invalid service descriptions */ if(temp_comment->comment_type==SERVICE_COMMENT && find_service(temp_comment->host_name,temp_comment->service_description)==NULL) save=FALSE; /* delete non-persistent comments */ if(temp_comment->persistent==FALSE) save=FALSE; /* delete the comment */ if(save==FALSE){ update_file=TRUE; delete_comment(temp_comment->comment_type,temp_comment->comment_id); } } /* update comment file */ if(update_file==TRUE) xcddefault_save_comment_data(); /* reset the current comment counter */ current_comment_id=0; /* find the new starting index for comment id */ for(temp_comment=comment_list;temp_comment!=NULL;temp_comment=temp_comment->next){ if(temp_comment->comment_id>current_comment_id) current_comment_id=temp_comment->comment_id; } return OK; } /* removes invalid and old comments from the comment file */ int xcddefault_cleanup_comment_data(char *main_config_file){ /* we don't need to do any cleanup... */ return OK; } /******************************************************************/ /***************** DEFAULT DATA OUTPUT FUNCTIONS ******************/ /******************************************************************/ /* adds a new host comment */ int xcddefault_add_new_host_comment(int entry_type, char *host_name, time_t entry_time, char *author_name, char *comment_data, int persistent, int source, int expires, time_t expire_time, unsigned long *comment_id){ /* find the next valid comment id */ do{ current_comment_id++; if(current_comment_id==0) current_comment_id++; }while(find_host_comment(current_comment_id)!=NULL); /* add comment to list in memory */ add_host_comment(entry_type,host_name,entry_time,author_name,comment_data,current_comment_id,persistent,expires,expire_time,source); /* update comment file */ xcddefault_save_comment_data(); /* return the id for the comment we are about to add (this happens in the main code) */ if(comment_id!=NULL) *comment_id=current_comment_id; return OK; } /* adds a new service comment */ int xcddefault_add_new_service_comment(int entry_type, char *host_name, char *svc_description, time_t entry_time, char *author_name, char *comment_data, int persistent, int source, int expires, time_t expire_time, unsigned long *comment_id){ /* find the next valid comment id */ do{ current_comment_id++; if(current_comment_id==0) current_comment_id++; }while(find_service_comment(current_comment_id)!=NULL); /* add comment to list in memory */ add_service_comment(entry_type,host_name,svc_description,entry_time,author_name,comment_data,current_comment_id,persistent,expires,expire_time,source); /* update comment file */ xcddefault_save_comment_data(); /* return the id for the comment we are about to add (this happens in the main code) */ if(comment_id!=NULL) *comment_id=current_comment_id; return OK; } /******************************************************************/ /**************** COMMENT DELETION FUNCTIONS **********************/ /******************************************************************/ /* deletes a host comment */ int xcddefault_delete_host_comment(unsigned long comment_id){ /* update comment file */ xcddefault_save_comment_data(); return OK; } /* deletes a service comment */ int xcddefault_delete_service_comment(unsigned long comment_id){ /* update comment file */ xcddefault_save_comment_data(); return OK; } /* deletes all comments for a particular host */ int xcddefault_delete_all_host_comments(char *host_name){ /* update comment file */ xcddefault_save_comment_data(); return OK; } /* deletes all comments for a particular service */ int xcddefault_delete_all_service_comments(char *host_name, char *svc_description){ /* update comment file */ xcddefault_save_comment_data(); return OK; } /******************************************************************/ /****************** COMMENT OUTPUT FUNCTIONS **********************/ /******************************************************************/ /* writes comment data to file */ int xcddefault_save_comment_data(void){ char temp_file[MAX_FILENAME_LENGTH]; time_t current_time; comment *temp_comment; int fd=0; FILE *fp=NULL; /* open a safe temp file for output */ snprintf(temp_file,sizeof(temp_file)-1,"%sXXXXXX",xcddefault_temp_file); temp_file[sizeof(temp_file)-1]='\x0'; if((fd=mkstemp(temp_file))==-1) return ERROR; fp=fdopen(fd,"w"); if(fp==NULL){ close(fd); unlink(temp_file); return ERROR; } /* write header */ fprintf(fp,"########################################\n"); fprintf(fp,"# NAGIOS COMMENT FILE\n"); fprintf(fp,"#\n"); fprintf(fp,"# THIS FILE IS AUTOMATICALLY GENERATED\n"); fprintf(fp,"# BY NAGIOS. DO NOT MODIFY THIS FILE!\n"); fprintf(fp,"########################################\n\n"); time(¤t_time); /* write file info */ fprintf(fp,"info {\n"); fprintf(fp,"\tcreated=%lu\n",current_time); fprintf(fp,"\tversion=%s\n",PROGRAM_VERSION); fprintf(fp,"\t}\n\n"); /* save all comments */ for(temp_comment=comment_list;temp_comment!=NULL;temp_comment=temp_comment->next){ if(temp_comment->comment_type==HOST_COMMENT) fprintf(fp,"hostcomment {\n"); else fprintf(fp,"servicecomment {\n"); fprintf(fp,"\thost_name=%s\n",temp_comment->host_name); if(temp_comment->comment_type==SERVICE_COMMENT) fprintf(fp,"\tservice_description=%s\n",temp_comment->service_description); fprintf(fp,"\tentry_type=%d\n",temp_comment->entry_type); fprintf(fp,"\tcomment_id=%lu\n",temp_comment->comment_id); fprintf(fp,"\tsource=%d\n",temp_comment->source); fprintf(fp,"\tpersistent=%d\n",temp_comment->persistent); fprintf(fp,"\tentry_time=%lu\n",temp_comment->entry_time); fprintf(fp,"\texpires=%d\n",temp_comment->expires); fprintf(fp,"\texpire_time=%lu\n",temp_comment->expire_time); fprintf(fp,"\tauthor=%s\n",temp_comment->author); fprintf(fp,"\tcomment_data=%s\n",temp_comment->comment_data); fprintf(fp,"\t}\n\n"); } /* reset file permissions */ fchmod(fd,S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH); /* close the temp file */ fclose(fp); /* move the temp file to the comment file (overwrite the old comment file) */ if(my_rename(temp_file,xcddefault_comment_file)) return ERROR; return OK; } #endif /******************************************************************/ /****************** COMMENT INPUT FUNCTIONS ***********************/ /******************************************************************/ /* read the comment file */ int xcddefault_read_comment_data(char *main_config_file){ #ifdef BAD_MMAP char *input=NULL; mmapfile *thefile; #else char input[2048]=""; FILE *fp=NULL; #endif int data_type=XCDDEFAULT_NO_DATA; char *var; char *val; int result; unsigned long comment_id=0; int persistent=FALSE; int expires=FALSE; time_t expire_time=0L; int entry_type=USER_COMMENT; int source=COMMENTSOURCE_INTERNAL; time_t entry_time=0L; char *host_name=NULL; char *service_description=NULL; char *author=NULL; char *comment_data=NULL; /* grab configuration data */ result=xcddefault_grab_config_info(main_config_file); if(result==ERROR) return ERROR; /* open the comment file for reading */ #ifdef BAD_MMAP if((thefile=mmap_fopen(xcddefault_comment_file))==NULL) return ERROR; #else if((fp=fopen(xcddefault_comment_file,"r"))==NULL) return ERROR; #endif /* read all lines in the comment file */ while(1){ #ifdef BAD_MMAP /* free memory */ free(input); /* read the next line */ if((input=mmap_fgets(thefile))==NULL) break; #else strcpy(input,""); if(fgets(input,sizeof(input),fp)==NULL) break; #endif strip(input); /* skip blank lines and comments */ if(input[0]=='#' || input[0]=='\x0') continue; else if(!strcmp(input,"info {")) data_type=XCDDEFAULT_INFO_DATA; else if(!strcmp(input,"hostcomment {")) data_type=XCDDEFAULT_HOST_DATA; else if(!strcmp(input,"servicecomment {")) data_type=XCDDEFAULT_SERVICE_DATA; else if(!strcmp(input,"}")){ switch(data_type){ case XCDDEFAULT_INFO_DATA: break; case XCDDEFAULT_HOST_DATA: case XCDDEFAULT_SERVICE_DATA: add_comment((data_type==XCDDEFAULT_HOST_DATA)?HOST_COMMENT:SERVICE_COMMENT,entry_type,host_name,service_description,entry_time,author,comment_data,comment_id,persistent,expires,expire_time,source); break; default: break; } data_type=XCDDEFAULT_NO_DATA; /* free temp memory */ free(host_name); free(service_description); free(author); free(comment_data); /* reset defaults */ host_name=NULL; service_description=NULL; author=NULL; comment_data=NULL; entry_type=USER_COMMENT; comment_id=0; source=COMMENTSOURCE_INTERNAL; persistent=FALSE; entry_time=0L; expires=FALSE; expire_time=0L; } else if(data_type!=XCDDEFAULT_NO_DATA){ var=strtok(input,"="); val=strtok(NULL,"\n"); if(val==NULL) continue; switch(data_type){ case XCDDEFAULT_INFO_DATA: break; case XCDDEFAULT_HOST_DATA: case XCDDEFAULT_SERVICE_DATA: if(!strcmp(var,"host_name")) host_name=strdup(val); else if(!strcmp(var,"service_description")) service_description=strdup(val); else if(!strcmp(var,"entry_type")) entry_type=atoi(val); else if(!strcmp(var,"comment_id")) comment_id=strtoul(val,NULL,10); else if(!strcmp(var,"source")) source=atoi(val); else if(!strcmp(var,"persistent")) persistent=(atoi(val)>0)?TRUE:FALSE; else if(!strcmp(var,"entry_time")) entry_time=strtoul(val,NULL,10); else if(!strcmp(var,"expires")) expires=(atoi(val)>0)?TRUE:FALSE; else if(!strcmp(var,"expire_time")) expire_time=strtoul(val,NULL,10); else if(!strcmp(var,"author")) author=strdup(val); else if(!strcmp(var,"comment_data")) comment_data=strdup(val); break; default: break; } } } /* free memory and close the file */ #ifdef BAD_MMAP free(input); mmap_fclose(thefile); #else fclose(fp); #endif return OK; } nagios-2.6/xdata/xcddefault.h0000664000076500007650000000361510336571237015610 0ustar nagiosnagios/***************************************************************************** * * XCDDEFAULT.H - Header file for default comment data routines * * Copyright (c) 2000-2003 Ethan Galstad (nagios@nagios.org) * Last Modified: 08-26-2003 * * 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. * *****************************************************************************/ #define XCDDEFAULT_NO_DATA 0 #define XCDDEFAULT_INFO_DATA 1 #define XCDDEFAULT_HOST_DATA 2 #define XCDDEFAULT_SERVICE_DATA 3 #ifdef NSCORE int xcddefault_initialize_comment_data(char *); int xcddefault_create_comment_file(void); int xcddefault_validate_comment_data(void); int xcddefault_cleanup_comment_data(char *); int xcddefault_save_comment_data(void); int xcddefault_add_new_host_comment(int,char *,time_t,char *,char *,int,int,int,time_t,unsigned long *); int xcddefault_add_new_service_comment(int,char *,char *,time_t,char *,char *,int,int,int,time_t,unsigned long *); int xcddefault_delete_host_comment(unsigned long); int xcddefault_delete_service_comment(unsigned long); int xcddefault_delete_all_host_comments(char *); int xcddefault_delete_all_service_comments(char *,char *); #endif int xcddefault_grab_config_info(char *); void xcddefault_grab_config_directives(char *); int xcddefault_read_comment_data(char *); nagios-2.6/xdata/xdddefault.c0000664000076500007650000004321210433670166015600 0ustar nagiosnagios/***************************************************************************** * * XDDDEFAULT.C - Default scheduled downtime data routines for Nagios * * Copyright (c) 2001-2006 Ethan Galstad (nagios@nagios.org) * Last Modified: 05-20-2006 * * 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/locations.h" #include "../include/downtime.h" #ifdef NSCORE #include "../include/objects.h" #include "../include/nagios.h" #endif #ifdef NSCGI #include "../include/cgiutils.h" #endif /**** IMPLEMENTATION SPECIFIC HEADER FILES ****/ #include "xdddefault.h" char xdddefault_downtime_file[MAX_FILENAME_LENGTH]=""; char xdddefault_temp_file[MAX_FILENAME_LENGTH]=""; #ifdef NSCORE unsigned long current_downtime_id=0; extern scheduled_downtime *scheduled_downtime_list; extern char *macro_x[MACRO_X_COUNT]; #endif /******************************************************************/ /***************** COMMON CONFIG INITIALIZATION ******************/ /******************************************************************/ /* grab configuration information from appropriate config file(s) */ int xdddefault_grab_config_info(char *config_file){ char *input=NULL; mmapfile *thefile; #ifdef NSCGI char *input2=NULL; mmapfile *thefile2; char *temp_buffer; #endif /*** CORE PASSES IN MAIN CONFIG FILE, CGIS PASS IN CGI CONFIG FILE! ***/ /* initialize the location of the downtime and temp files */ strncpy(xdddefault_downtime_file,DEFAULT_DOWNTIME_FILE,sizeof(xdddefault_downtime_file)-1); strncpy(xdddefault_temp_file,DEFAULT_TEMP_FILE,sizeof(xdddefault_temp_file)-1); xdddefault_downtime_file[sizeof(xdddefault_downtime_file)-1]='\x0'; xdddefault_temp_file[sizeof(xdddefault_temp_file)-1]='\x0'; /* open the config file for reading */ if((thefile=mmap_fopen(config_file))==NULL) return ERROR; /* read in all lines from the config file */ while(1){ /* free memory */ free(input); /* read the next line */ if((input=mmap_fgets(thefile))==NULL) break; strip(input); /* skip blank lines and comments */ if(input[0]=='#' || input[0]=='\x0') continue; #ifdef NSCGI /* CGI needs to find and read contents of main config file, since it was passed the name of the CGI config file */ if(strstr(input,"main_config_file")==input){ temp_buffer=strtok(input,"="); temp_buffer=strtok(NULL,"\n"); if(temp_buffer==NULL) continue; if((thefile2=mmap_fopen(temp_buffer))==NULL) continue; /* read in all lines from the main config file */ while(1){ /* free memory */ free(input2); /* read the next line */ if((input2=mmap_fgets(thefile2))==NULL) break; strip(input2); /* skip blank lines and comments */ if(input2[0]=='#' || input2[0]=='\x0') continue; xdddefault_grab_config_directives(input2); } /* close the file */ mmap_fclose(thefile2); } #endif #ifdef NSCORE /* core read variables directly from the main config file */ xdddefault_grab_config_directives(input); #endif } /* close the file */ mmap_fclose(thefile); /* we didn't find the downtime file */ if(!strcmp(xdddefault_downtime_file,"")) return ERROR; /* we didn't find the temp file */ if(!strcmp(xdddefault_temp_file,"")) return ERROR; #ifdef NSCORE /* save the downtime data file macro */ if(macro_x[MACRO_DOWNTIMEDATAFILE]!=NULL) free(macro_x[MACRO_DOWNTIMEDATAFILE]); macro_x[MACRO_DOWNTIMEDATAFILE]=(char *)strdup(xdddefault_downtime_file); if(macro_x[MACRO_DOWNTIMEDATAFILE]!=NULL) strip(macro_x[MACRO_DOWNTIMEDATAFILE]); #endif return OK; } void xdddefault_grab_config_directives(char *input_buffer){ char *temp_buffer; /* downtime file definition */ if((strstr(input_buffer,"downtime_file")==input_buffer) || (strstr(input_buffer,"xdddefault_downtime_file")==input_buffer)){ temp_buffer=strtok(input_buffer,"="); temp_buffer=strtok(NULL,"\n"); if(temp_buffer==NULL) return; strncpy(xdddefault_downtime_file,temp_buffer,sizeof(xdddefault_downtime_file)-1); xdddefault_downtime_file[sizeof(xdddefault_downtime_file)-1]='\x0'; } /* temp file definition */ if((strstr(input_buffer,"temp_file")==input_buffer) || (strstr(input_buffer,"xdddefault_temp_file")==input_buffer)){ temp_buffer=strtok(input_buffer,"="); temp_buffer=strtok(NULL,"\n"); if(temp_buffer==NULL) return; strncpy(xdddefault_temp_file,temp_buffer,sizeof(xdddefault_temp_file)-1); xdddefault_temp_file[sizeof(xdddefault_temp_file)-1]='\x0'; } return; } #ifdef NSCORE /******************************************************************/ /*********** DOWNTIME INITIALIZATION/CLEANUP FUNCTIONS ************/ /******************************************************************/ /* initialize downtime data */ int xdddefault_initialize_downtime_data(char *main_config_file){ /* grab configuration information */ if(xdddefault_grab_config_info(main_config_file)==ERROR) return ERROR; /* create downtime file if necessary */ xdddefault_create_downtime_file(); /* read downtime data into memory */ xdddefault_read_downtime_data(main_config_file); /* clean up the old downtime data */ xdddefault_validate_downtime_data(); return OK; } /* creates an empty downtime data file if one doesn't already exist */ int xdddefault_create_downtime_file(void){ struct stat statbuf; /* bail out if file already exists */ if(!stat(xdddefault_downtime_file,&statbuf)) return OK; /* create an empty file */ xdddefault_save_downtime_data(); return OK; } /* removes invalid and old downtime entries from the downtime file */ int xdddefault_validate_downtime_data(void){ scheduled_downtime *temp_downtime; scheduled_downtime *next_downtime; int update_file=FALSE; int save=TRUE; /* remove stale downtimes */ for(temp_downtime=scheduled_downtime_list;temp_downtime!=NULL;temp_downtime=next_downtime){ next_downtime=temp_downtime->next; save=TRUE; /* delete downtimes with invalid host names */ if(find_host(temp_downtime->host_name)==NULL) save=FALSE; /* delete downtimes with invalid service descriptions */ if(temp_downtime->type==SERVICE_DOWNTIME && find_service(temp_downtime->host_name,temp_downtime->service_description)==NULL) save=FALSE; /* delete downtimes that have expired */ if(temp_downtime->end_timetype,temp_downtime->downtime_id); } } /* remove triggered downtimes without valid parents */ for(temp_downtime=scheduled_downtime_list;temp_downtime!=NULL;temp_downtime=next_downtime){ next_downtime=temp_downtime->next; save=TRUE; if(temp_downtime->triggered_by==0) continue; if(find_host_downtime(temp_downtime->triggered_by)==NULL && find_service_downtime(temp_downtime->triggered_by)==NULL) save=FALSE; /* delete the downtime */ if(save==FALSE){ update_file=TRUE; delete_downtime(temp_downtime->type,temp_downtime->downtime_id); } } /* update downtime file */ if(update_file==TRUE) xdddefault_save_downtime_data(); /* reset the current downtime counter */ current_downtime_id=0; /* find the new starting index for downtime id */ for(temp_downtime=scheduled_downtime_list;temp_downtime!=NULL;temp_downtime=temp_downtime->next){ if(temp_downtime->downtime_id>current_downtime_id) current_downtime_id=temp_downtime->downtime_id; } return OK; } /* removes invalid and old downtime entries from the downtime file */ int xdddefault_cleanup_downtime_data(char *main_config_file){ /* we don't need to do any cleanup... */ return OK; } /******************************************************************/ /************************ SAVE FUNCTIONS **************************/ /******************************************************************/ /* adds a new scheduled host downtime entry */ int xdddefault_add_new_host_downtime(char *host_name, time_t entry_time, char *author, char *comment, time_t start_time, time_t end_time, int fixed, unsigned long triggered_by, unsigned long duration, unsigned long *downtime_id){ /* find the next valid downtime id */ do{ current_downtime_id++; if(current_downtime_id==0) current_downtime_id++; }while(find_host_downtime(current_downtime_id)!=NULL); /* add downtime to list in memory */ add_host_downtime(host_name,entry_time,author,comment,start_time,end_time,fixed,triggered_by,duration,current_downtime_id); /* update downtime file */ xdddefault_save_downtime_data(); /* return the id for the downtime we are about to add (this happens in the main code) */ if(downtime_id!=NULL) *downtime_id=current_downtime_id; return OK; } /* adds a new scheduled service downtime entry */ int xdddefault_add_new_service_downtime(char *host_name, char *service_description, time_t entry_time, char *author, char *comment, time_t start_time, time_t end_time, int fixed, unsigned long triggered_by, unsigned long duration, unsigned long *downtime_id){ /* find the next valid downtime id */ do{ current_downtime_id++; if(current_downtime_id==0) current_downtime_id++; }while(find_service_downtime(current_downtime_id)!=NULL); /* add downtime to list in memory */ add_service_downtime(host_name,service_description,entry_time,author,comment,start_time,end_time,fixed,triggered_by,duration,current_downtime_id); /* update downtime file */ xdddefault_save_downtime_data(); /* return the id for the downtime we are about to add (this happens in the main code) */ if(downtime_id!=NULL) *downtime_id=current_downtime_id; return OK; } /******************************************************************/ /********************** DELETION FUNCTIONS ************************/ /******************************************************************/ /* deletes a scheduled host downtime entry */ int xdddefault_delete_host_downtime(unsigned long downtime_id){ int result; result=xdddefault_delete_downtime(HOST_DOWNTIME,downtime_id); return result; } /* deletes a scheduled service downtime entry */ int xdddefault_delete_service_downtime(unsigned long downtime_id){ int result; result=xdddefault_delete_downtime(SERVICE_DOWNTIME,downtime_id); return result; } /* deletes a scheduled host or service downtime entry */ int xdddefault_delete_downtime(int type, unsigned long downtime_id){ /* rewrite the downtime file (downtime was already removed from memory) */ xdddefault_save_downtime_data(); return OK; } /******************************************************************/ /****************** DOWNTIME OUTPUT FUNCTIONS *********************/ /******************************************************************/ /* writes downtime data to file */ int xdddefault_save_downtime_data(void){ char temp_file[MAX_FILENAME_LENGTH]; time_t current_time; scheduled_downtime *temp_downtime; int fd=0; FILE *fp=NULL; /* open a safe temp file for output */ snprintf(temp_file,sizeof(temp_file)-1,"%sXXXXXX",xdddefault_temp_file); temp_file[sizeof(temp_file)-1]='\x0'; if((fd=mkstemp(temp_file))==-1) return ERROR; fp=fdopen(fd,"w"); if(fp==NULL){ close(fd); unlink(temp_file); return ERROR; } /* write header */ fprintf(fp,"########################################\n"); fprintf(fp,"# NAGIOS DOWNTIME FILE\n"); fprintf(fp,"#\n"); fprintf(fp,"# THIS FILE IS AUTOMATICALLY GENERATED\n"); fprintf(fp,"# BY NAGIOS. DO NOT MODIFY THIS FILE!\n"); fprintf(fp,"########################################\n\n"); time(¤t_time); /* write file info */ fprintf(fp,"info {\n"); fprintf(fp,"\tcreated=%lu\n",current_time); fprintf(fp,"\tversion=%s\n",PROGRAM_VERSION); fprintf(fp,"\t}\n\n"); /* save all downtime */ for(temp_downtime=scheduled_downtime_list;temp_downtime!=NULL;temp_downtime=temp_downtime->next){ if(temp_downtime->type==HOST_DOWNTIME) fprintf(fp,"hostdowntime {\n"); else fprintf(fp,"servicedowntime {\n"); fprintf(fp,"\thost_name=%s\n",temp_downtime->host_name); if(temp_downtime->type==SERVICE_DOWNTIME) fprintf(fp,"\tservice_description=%s\n",temp_downtime->service_description); fprintf(fp,"\tdowntime_id=%lu\n",temp_downtime->downtime_id); fprintf(fp,"\tentry_time=%lu\n",temp_downtime->entry_time); fprintf(fp,"\tstart_time=%lu\n",temp_downtime->start_time); fprintf(fp,"\tend_time=%lu\n",temp_downtime->end_time); fprintf(fp,"\ttriggered_by=%lu\n",temp_downtime->triggered_by); fprintf(fp,"\tfixed=%d\n",temp_downtime->fixed); fprintf(fp,"\tduration=%lu\n",temp_downtime->duration); fprintf(fp,"\tauthor=%s\n",temp_downtime->author); fprintf(fp,"\tcomment=%s\n",temp_downtime->comment); fprintf(fp,"\t}\n\n"); } /* reset file permissions */ fchmod(fd,S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH); /* close the temp file */ fclose(fp); /* move the temp file to the downtime file (overwrite the old downtime file) */ if(my_rename(temp_file,xdddefault_downtime_file)) return ERROR; return OK; } #endif /******************************************************************/ /****************** DOWNTIME INPUT FUNCTIONS **********************/ /******************************************************************/ /* read the downtime file */ int xdddefault_read_downtime_data(char *main_config_file){ #ifdef BAD_MMAP char *input=NULL; mmapfile *thefile; #else char input[2048]=""; FILE *fp=NULL; #endif int data_type=XDDDEFAULT_NO_DATA; char *var; char *val; unsigned long downtime_id=0; time_t entry_time=0L; time_t start_time=0L; time_t end_time=0L; int fixed=FALSE; unsigned long triggered_by=0; unsigned long duration=0L; char *host_name=NULL; char *service_description=NULL; char *comment=NULL; char *author=NULL; #ifdef NSCGI /* grab configuration information */ if(xdddefault_grab_config_info(main_config_file)==ERROR) return ERROR; #endif /* open the downtime file */ #ifdef BAD_MMAP if((thefile=mmap_fopen(xdddefault_downtime_file))==NULL) return ERROR; #else if((fp=fopen(xdddefault_downtime_file,"r"))==NULL) return ERROR; #endif while(1){ #ifdef BAD_MMAP /* free memory */ free(input); /* get the next line */ if((input=mmap_fgets(thefile))==NULL) break; #else strcpy(input,""); if(fgets(input,sizeof(input),fp)==NULL) break; #endif strip(input); /* skip blank lines and comments */ if(input[0]=='#' || input[0]=='\x0') continue; else if(!strcmp(input,"info {")) data_type=XDDDEFAULT_INFO_DATA; else if(!strcmp(input,"hostdowntime {")) data_type=XDDDEFAULT_HOST_DATA; else if(!strcmp(input,"servicedowntime {")) data_type=XDDDEFAULT_SERVICE_DATA; else if(!strcmp(input,"}")){ switch(data_type){ case XDDDEFAULT_INFO_DATA: break; case XDDDEFAULT_HOST_DATA: case XDDDEFAULT_SERVICE_DATA: /* add the downtime */ if(data_type==XDDDEFAULT_HOST_DATA) add_host_downtime(host_name,entry_time,author,comment,start_time,end_time,fixed,triggered_by,duration,downtime_id); else add_service_downtime(host_name,service_description,entry_time,author,comment,start_time,end_time,fixed,triggered_by,duration,downtime_id); #ifdef NSCORE /* must register the downtime with Nagios so it can schedule it, add comments, etc. */ register_downtime((data_type==XDDDEFAULT_HOST_DATA)?HOST_DOWNTIME:SERVICE_DOWNTIME,downtime_id); #endif break; default: break; } data_type=XDDDEFAULT_NO_DATA; /* free temp memory */ free(host_name); free(service_description); free(author); free(comment); /* reset defaults */ host_name=NULL; service_description=NULL; author=NULL; comment=NULL; downtime_id=0; entry_time=0L; start_time=0L; end_time=0L; fixed=FALSE; triggered_by=0; duration=0L; } else if(data_type!=XDDDEFAULT_NO_DATA){ var=strtok(input,"="); val=strtok(NULL,"\n"); if(val==NULL) continue; switch(data_type){ case XDDDEFAULT_INFO_DATA: break; case XDDDEFAULT_HOST_DATA: case XDDDEFAULT_SERVICE_DATA: if(!strcmp(var,"host_name")) host_name=strdup(val); else if(!strcmp(var,"service_description")) service_description=strdup(val); else if(!strcmp(var,"downtime_id")) downtime_id=strtoul(val,NULL,10); else if(!strcmp(var,"entry_time")) entry_time=strtoul(val,NULL,10); else if(!strcmp(var,"start_time")) start_time=strtoul(val,NULL,10); else if(!strcmp(var,"end_time")) end_time=strtoul(val,NULL,10); else if(!strcmp(var,"fixed")) fixed=(atoi(val)>0)?TRUE:FALSE; else if(!strcmp(var,"triggered_by")) triggered_by=strtoul(val,NULL,10); else if(!strcmp(var,"duration")) duration=strtoul(val,NULL,10); else if(!strcmp(var,"author")) author=strdup(val); else if(!strcmp(var,"comment")) comment=strdup(val); break; default: break; } } } /* free memory and close the file */ #ifdef BAD_MMAP free(input); mmap_fclose(thefile); #else fclose(fp); #endif return OK; } nagios-2.6/xdata/xdddefault.h0000664000076500007650000000363010336571237015606 0ustar nagiosnagios/***************************************************************************** * * XDDDEFAULT.H - Header file for default scheduled downtime data routines * * Copyright (c) 2001-2003 Ethan Galstad (nagios@nagios.org) * Last Modified: 07-20-2003 * * 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. * *****************************************************************************/ #define XDDDEFAULT_NO_DATA 0 #define XDDDEFAULT_INFO_DATA 1 #define XDDDEFAULT_HOST_DATA 2 #define XDDDEFAULT_SERVICE_DATA 3 #ifdef NSCORE int xdddefault_initialize_downtime_data(char *); int xdddefault_create_downtime_file(void); int xdddefault_validate_downtime_data(void); int xdddefault_cleanup_downtime_data(char *); int xdddefault_save_downtime_data(void); int xdddefault_add_new_host_downtime(char *,time_t,char *,char *,time_t,time_t,int,unsigned long,unsigned long,unsigned long *); int xdddefault_add_new_service_downtime(char *,char *,time_t,char *,char *,time_t,time_t,int,unsigned long,unsigned long,unsigned long *); int xdddefault_delete_host_downtime(unsigned long); int xdddefault_delete_service_downtime(unsigned long); int xdddefault_delete_downtime(int,unsigned long); #endif int xdddefault_grab_config_info(char *); void xdddefault_grab_config_directives(char *); int xdddefault_read_downtime_data(char *); nagios-2.6/xdata/xodtemplate.c0000664000076500007650000144345010454524170016007 0ustar nagiosnagios /***************************************************************************** * * XODTEMPLATE.C - Template-based object configuration data input routines * * Copyright (c) 2001-2006 Ethan Galstad (nagios@nagios.org) * Last Modified: 07-10-2006 * * Description: * * Routines for parsing and resolving template-based object definitions. * Basic steps involved in this in the daemon are as follows: * * 1) Read * 2) Resolve * 3) Duplicate * 4) Recombobulate * 5) Cache * 7) Register * 8) Cleanup * * The steps involved for the CGIs differ a bit, since they read the cached * definitions which are already resolved, recombobulated and duplicated. In * otherwords, they've already been "flattened"... * * 1) Read * 2) Register * 3) Cleanup * * * 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/locations.h" /**** CORE OR CGI SPECIFIC HEADER FILES ****/ #ifdef NSCORE #include "../include/nagios.h" #endif #ifdef NSCGI #include "../include/cgiutils.h" #endif /**** DATA INPUT-SPECIFIC HEADER FILES ****/ #include "xodtemplate.h" #ifdef NSCORE extern int use_regexp_matches; extern int use_true_regexp_matching; extern char *macro_x[MACRO_X_COUNT]; #endif xodtemplate_timeperiod *xodtemplate_timeperiod_list=NULL; xodtemplate_command *xodtemplate_command_list=NULL; xodtemplate_contactgroup *xodtemplate_contactgroup_list=NULL; xodtemplate_hostgroup *xodtemplate_hostgroup_list=NULL; xodtemplate_servicegroup *xodtemplate_servicegroup_list=NULL; xodtemplate_servicedependency *xodtemplate_servicedependency_list=NULL; xodtemplate_serviceescalation *xodtemplate_serviceescalation_list=NULL; xodtemplate_contact *xodtemplate_contact_list=NULL; xodtemplate_host *xodtemplate_host_list=NULL; xodtemplate_service *xodtemplate_service_list=NULL; xodtemplate_hostdependency *xodtemplate_hostdependency_list=NULL; xodtemplate_hostescalation *xodtemplate_hostescalation_list=NULL; xodtemplate_hostextinfo *xodtemplate_hostextinfo_list=NULL; xodtemplate_serviceextinfo *xodtemplate_serviceextinfo_list=NULL; void *xodtemplate_current_object=NULL; int xodtemplate_current_object_type=XODTEMPLATE_NONE; int xodtemplate_current_config_file=0; char **xodtemplate_config_files; char xodtemplate_cache_file[MAX_FILENAME_LENGTH]; /******************************************************************/ /************* TOP-LEVEL CONFIG DATA INPUT FUNCTION ***************/ /******************************************************************/ /* process all config files - both core and CGIs pass in name of main config file */ int xodtemplate_read_config_data(char *main_config_file,int options,int cache){ #ifdef NSCORE char config_file[MAX_FILENAME_LENGTH]; char *input=NULL; char *temp_ptr; #endif mmapfile *thefile; int result=OK; #ifdef DEBUG0 printf("xodtemplate_read_config_data() start\n"); #endif /* get variables from main config file */ xodtemplate_grab_config_info(main_config_file); /* open the main config file for reading (we need to find all the config files to read) */ if((thefile=mmap_fopen(main_config_file))==NULL){ #ifdef DEBUG1 printf("Error: Cannot open main configuration file '%s' for reading!\n",main_config_file); #endif return ERROR; } /* initialize variables */ xodtemplate_timeperiod_list=NULL; xodtemplate_command_list=NULL; xodtemplate_contactgroup_list=NULL; xodtemplate_hostgroup_list=NULL; xodtemplate_servicegroup_list=NULL; xodtemplate_servicedependency_list=NULL; xodtemplate_serviceescalation_list=NULL; xodtemplate_contact_list=NULL; xodtemplate_host_list=NULL; xodtemplate_service_list=NULL; xodtemplate_hostdependency_list=NULL; xodtemplate_hostescalation_list=NULL; xodtemplate_hostextinfo_list=NULL; xodtemplate_serviceextinfo_list=NULL; xodtemplate_current_object=NULL; xodtemplate_current_object_type=XODTEMPLATE_NONE; /* allocate memory for 256 config files (increased dynamically) */ xodtemplate_current_config_file=0; xodtemplate_config_files=(char **)malloc(256*sizeof(char **)); if(xodtemplate_config_files==NULL){ #ifdef DEBUG1 printf("Error: Cannot allocate memory for config file names!\n"); #endif return ERROR; } #ifdef NSCORE /* daemon reads all config files/dirs specified in the main config file */ /* read in all lines from the main config file */ while(1){ /* free memory */ free(input); /* get the next line */ if((input=mmap_fgets(thefile))==NULL) break; /* strip input */ strip(input); /* skip blank lines and comments */ if(input[0]=='#' || input[0]==';' || input[0]=='\x0') continue; temp_ptr=strtok(input,"="); if(temp_ptr==NULL) continue; /* process a single config file */ if(strstr(temp_ptr,"xodtemplate_config_file")==temp_ptr || strstr(temp_ptr,"cfg_file")==temp_ptr){ /* get the config file name */ temp_ptr=strtok(NULL,"\n"); if(temp_ptr==NULL) continue; strncpy(config_file,temp_ptr,sizeof(config_file)-1); config_file[sizeof(config_file)-1]='\x0'; /* process the config file... */ result=xodtemplate_process_config_file(config_file,options); /* if there was an error processing the config file, break out of loop */ if(result==ERROR) break; } /* process all files in a config directory */ else if(strstr(temp_ptr,"xodtemplate_config_dir")==temp_ptr || strstr(temp_ptr,"cfg_dir")==temp_ptr){ /* get the config directory name */ temp_ptr=strtok(NULL,"\n"); if(temp_ptr==NULL) continue; strncpy(config_file,temp_ptr,sizeof(config_file)-1); config_file[sizeof(config_file)-1]='\x0'; /* strip trailing / if necessary */ if(config_file[strlen(config_file)-1]=='/') config_file[strlen(config_file)-1]='\x0'; /* process the config directory... */ result=xodtemplate_process_config_dir(config_file,options); /* if there was an error processing the config file, break out of loop */ if(result==ERROR) break; } } /* free memory and close the file */ free(input); mmap_fclose(thefile); #endif #ifdef NSCGI /* CGIs process only one file - the cached objects file */ result=xodtemplate_process_config_file(xodtemplate_cache_file,options); #endif #ifdef NSCORE /* resolve objects definitions */ if(result==OK) result=xodtemplate_resolve_objects(); /* do the meat and potatoes stuff... */ if(result==OK) result=xodtemplate_recombobulate_contactgroups(); if(result==OK) result=xodtemplate_recombobulate_hostgroups(); if(result==OK) result=xodtemplate_duplicate_services(); if(result==OK) result=xodtemplate_recombobulate_servicegroups(); if(result==OK) result=xodtemplate_duplicate_objects(); /* sort objects */ if(result==OK) result=xodtemplate_sort_objects(); /* cache object definitions */ if(result==OK && cache==TRUE) xodtemplate_cache_objects(xodtemplate_cache_file); #endif /* register objects */ if(result==OK) result=xodtemplate_register_objects(); /* cleanup */ xodtemplate_free_memory(); #ifdef DEBUG0 printf("xodtemplate_read_config_data() end\n"); #endif return result; } /* grab config variable from main config file */ int xodtemplate_grab_config_info(char *main_config_file){ char *input=NULL; char *temp_ptr; mmapfile *thefile; #ifdef DEBUG0 printf("xodtemplate_grab_config_info() start\n"); #endif /* default location of cached object file */ snprintf(xodtemplate_cache_file,sizeof(xodtemplate_cache_file)-1,"%s",DEFAULT_OBJECT_CACHE_FILE); xodtemplate_cache_file[sizeof(xodtemplate_cache_file)-1]='\x0'; /* open the main config file for reading */ if((thefile=mmap_fopen(main_config_file))==NULL) return ERROR; /* read in all lines from the main config file */ while(1){ /* free memory */ free(input); /* read the next line */ if((input=mmap_fgets(thefile))==NULL) break; /* strip input */ strip(input); /* skip blank lines and comments */ if(input[0]=='#' || input[0]==';' || input[0]=='\x0') continue; temp_ptr=strtok(input,"="); if(temp_ptr==NULL) continue; /* cached object file definition (overrides default location) */ if(strstr(temp_ptr,"object_cache_file")==temp_ptr){ /* get the config file name */ temp_ptr=strtok(NULL,"\n"); if(temp_ptr==NULL) continue; strncpy(xodtemplate_cache_file,temp_ptr,sizeof(xodtemplate_cache_file)-1); xodtemplate_cache_file[sizeof(xodtemplate_cache_file)-1]='\x0'; } } /* close the file */ mmap_fclose(thefile); #ifdef NSCORE /* save the object cache file macro */ if(macro_x[MACRO_OBJECTCACHEFILE]!=NULL) free(macro_x[MACRO_OBJECTCACHEFILE]); macro_x[MACRO_OBJECTCACHEFILE]=(char *)strdup(xodtemplate_cache_file); if(macro_x[MACRO_OBJECTCACHEFILE]!=NULL) strip(macro_x[MACRO_OBJECTCACHEFILE]); #endif #ifdef DEBUG0 printf("xodtemplate_grab_config_info() end\n"); #endif return OK; } /* process all files in a specific config directory */ int xodtemplate_process_config_dir(char *dirname, int options){ char file[MAX_FILENAME_LENGTH]; DIR *dirp; struct dirent *dirfile; int result=OK; int x; char link_buffer[MAX_FILENAME_LENGTH]; char linked_to_buffer[MAX_FILENAME_LENGTH]; struct stat stat_buf; ssize_t readlink_count; #ifdef NSCORE char temp_buffer[MAX_INPUT_BUFFER]; #endif #ifdef DEBUG0 printf("xodtemplate_process_config_dir() start\n"); #endif /* open the directory for reading */ dirp=opendir(dirname); if(dirp==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not open config directory '%s' for reading.\n",dirname); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return ERROR; } /* process all files in the directory... */ while((dirfile=readdir(dirp))!=NULL){ /* create /path/to/file */ snprintf(file,sizeof(file),"%s/%s",dirname,dirfile->d_name); file[sizeof(file)-1]='\x0'; /* process this if it's a non-hidden config file... */ x=strlen(dirfile->d_name); if(x>4 && dirfile->d_name[0]!='.' && !strcmp(dirfile->d_name+(x-4),".cfg")){ #ifdef _DIRENT_HAVE_D_TYPE /* only process normal files and symlinks */ if(dirfile->d_type==DT_UNKNOWN){ x=stat(file,&stat_buf); if(x==0){ if(!S_ISREG(stat_buf.st_mode) && !S_ISLNK(stat_buf.st_mode)) continue; } } else{ if(dirfile->d_type!=DT_REG && dirfile->d_type!=DT_LNK) continue; } #endif /* process the config file */ result=xodtemplate_process_config_file(file,options); /* break out if we encountered an error */ if(result==ERROR) break; } #ifdef _DIRENT_HAVE_D_TYPE /* recurse into subdirectories... */ if(dirfile->d_type==DT_UNKNOWN || dirfile->d_type==DT_DIR || dirfile->d_type==DT_LNK){ if(dirfile->d_type==DT_UNKNOWN){ x=stat(file,&stat_buf); if(x==0){ if(!S_ISDIR(stat_buf.st_mode) && !S_ISLNK(stat_buf.st_mode)) continue; } else continue; } /* ignore current, parent and hidden directory entries */ if(dirfile->d_name[0]=='.') continue; /* check that a symlink points to a dir */ if(dirfile->d_type==DT_LNK || (dirfile->d_type==DT_UNKNOWN && S_ISLNK(stat_buf.st_mode))){ readlink_count=readlink(file,link_buffer,MAX_FILENAME_LENGTH); /* Handle special case with maxxed out buffer */ if(readlink_count==MAX_FILENAME_LENGTH){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Cannot follow symlink '%s' - Too big!\n",file); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return ERROR; } /* Check if reading symlink failed */ if(readlink_count==-1){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Cannot read symlink '%s': %s!\n",file, strerror(errno)); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return ERROR; } /* terminate string */ link_buffer[readlink_count]='\x0'; /* create new symlink buffer name */ if(link_buffer[0]=='/'){ /* full path */ snprintf(linked_to_buffer,sizeof(linked_to_buffer)-1,"%s",link_buffer); linked_to_buffer[sizeof(linked_to_buffer)-1]='\x0'; } else{ /* relative path */ snprintf(linked_to_buffer,sizeof(linked_to_buffer)-1,"%s/%s",dirname,link_buffer); linked_to_buffer[sizeof(linked_to_buffer)-1]='\x0'; } /* * At this point, we know it's a symlink - * now check for whether it points to a * directory or not */ x=stat(linked_to_buffer,&stat_buf); if(x!=0){ /* non-existent symlink - bomb out */ if(errno==ENOENT){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: symlink '%s' points to non-existent '%s'!\n",file,link_buffer); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return ERROR; } #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Cannot stat symlinked from '%s' to %s!\n",file,link_buffer); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return ERROR; } if(!S_ISDIR(stat_buf.st_mode)){ /* Not a symlink to a dir - skip */ continue; } /* Otherwise, we may proceed! */ } /* process the config directory */ result=xodtemplate_process_config_dir(file,options); /* break out if we encountered an error */ if(result==ERROR) break; } #endif } closedir(dirp); #ifdef DEBUG0 printf("xodtemplate_process_config_dir() end\n"); #endif return result; } /* process data in a specific config file */ int xodtemplate_process_config_file(char *filename, int options){ mmapfile *thefile; char *input=NULL; register int in_definition=FALSE; register int current_line=0; int result=OK; register int x; register int y; char *ptr; #ifdef NSCORE char temp_buffer[MAX_INPUT_BUFFER]; #endif #ifdef DEBUG0 printf("xodtemplate_process_config_file() start\n"); #endif /* save config file name */ xodtemplate_config_files[xodtemplate_current_config_file++]=strdup(filename); /* reallocate memory for config files */ if(!(xodtemplate_current_config_file%256)){ xodtemplate_config_files=(char **)realloc(xodtemplate_config_files,(xodtemplate_current_config_file+256)*sizeof(char **)); if(xodtemplate_config_files==NULL){ #ifdef DEBUG1 printf("Error: Cannot re-allocate memory for config file names!\n"); #endif return ERROR; } } /* open the config file for reading */ if((thefile=mmap_fopen(filename))==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Cannot open config file '%s' for reading: %s\n",filename,strerror(errno)); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return ERROR; } /* read in all lines from the config file */ while(1){ /* free memory */ free(input); /* read the next line */ if((input=mmap_fgets(thefile))==NULL) break; current_line++; /* skip empty lines */ if(input[0]=='#' || input[0]==';' || input[0]=='\r' || input[0]=='\n') continue; /* grab data before comment delimiter - faster than a strtok() and strncpy()... */ for(x=0;input[x]!='\x0';x++) if(input[x]==';') break; input[x]='\x0'; /* strip input */ strip(input); /* skip blank lines */ if(input[0]=='\x0') continue; /* this is the start of an object definition */ if(strstr(input,"define")==input){ /* get the type of object we're defining... */ for(x=6;input[x]!='\x0';x++) if(input[x]!=' ' && input[x]!='\t') break; for(y=0;input[x]!='\x0';x++){ if(input[x]==' ' || input[x]=='\t' || input[x]=='{') break; else input[y++]=input[x]; } input[y]='\x0'; /* make sure an object type is specified... */ if(input[0]=='\x0'){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: No object type specified in file '%s' on line %d.\n",filename,current_line); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif result=ERROR; break; } /* check validity of object type */ if(strcmp(input,"timeperiod") && strcmp(input,"command") && strcmp(input,"contact") && strcmp(input,"contactgroup") && strcmp(input,"host") && strcmp(input,"hostgroup") && strcmp(input,"servicegroup") && strcmp(input,"service") && strcmp(input,"servicedependency") && strcmp(input,"serviceescalation") && strcmp(input,"hostgroupescalation") && strcmp(input,"hostdependency") && strcmp(input,"hostescalation") && strcmp(input,"hostextinfo") && strcmp(input,"serviceextinfo")){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Invalid object definition type '%s' in file '%s' on line %d.\n",input,filename,current_line); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif result=ERROR; break; } /* we're already in an object definition... */ if(in_definition==TRUE){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Unexpected start of object definition in file '%s' on line %d. Make sure you close preceding objects before starting a new one.\n",filename,current_line); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif result=ERROR; break; } /* start a new definition */ if(xodtemplate_begin_object_definition(input,options,xodtemplate_current_config_file,current_line)==ERROR){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not add object definition in file '%s' on line %d.\n",filename,current_line); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif result=ERROR; break; } in_definition=TRUE; } /* this is the close of an object definition */ else if(!strcmp(input,"}") && in_definition==TRUE){ in_definition=FALSE; /* close out current definition */ if(xodtemplate_end_object_definition(options)==ERROR){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not complete object definition in file '%s' on line %d.\n",filename,current_line); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif result=ERROR; break; } } /* we're currently inside an object definition */ else if(in_definition==TRUE){ /* this is the close of an object definition */ if(!strcmp(input,"}")){ in_definition=FALSE; /* close out current definition */ if(xodtemplate_end_object_definition(options)==ERROR){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not complete object definition in file '%s' on line %d.\n",filename,current_line); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif result=ERROR; break; } } /* this is a directive inside an object definition */ else{ /* add directive to object definition */ if(xodtemplate_add_object_property(input,options)==ERROR){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not add object property in file '%s' on line %d.\n",filename,current_line); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif result=ERROR; break; } } } /* include another file */ else if(strstr(input,"include_file=")==input){ ptr=strtok(input,"="); ptr=strtok(NULL,"\n"); if(ptr!=NULL){ result=xodtemplate_process_config_file(ptr,options); if(result==ERROR) break; } } /* include a directory */ else if(strstr(input,"include_dir")==input){ ptr=strtok(input,"="); ptr=strtok(NULL,"\n"); if(ptr!=NULL){ result=xodtemplate_process_config_dir(ptr,options); if(result==ERROR) break; } } /* unexpected token or statement */ else{ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Unexpected token or statement in file '%s' on line %d.\n",filename,current_line); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif result=ERROR; break; } } /* free memory and close file */ free(input); mmap_fclose(thefile); /* whoops - EOF while we were in the middle of an object definition... */ if(in_definition==TRUE && result==OK){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Unexpected EOF in file '%s' on line %d - check for a missing closing bracket.\n",filename,current_line); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif result=ERROR; } #ifdef DEBUG0 printf("xodtemplate_process_config_file() end\n"); #endif return result; } /******************************************************************/ /***************** OBJECT DEFINITION FUNCTIONS ********************/ /******************************************************************/ /* starts a new object definition */ int xodtemplate_begin_object_definition(char *input, int options, int config_file, int start_line){ int result=OK; xodtemplate_timeperiod *new_timeperiod; xodtemplate_command *new_command; xodtemplate_contactgroup *new_contactgroup; xodtemplate_hostgroup *new_hostgroup; xodtemplate_servicegroup *new_servicegroup; xodtemplate_servicedependency *new_servicedependency; xodtemplate_serviceescalation *new_serviceescalation; xodtemplate_contact *new_contact; xodtemplate_host *new_host; xodtemplate_service *new_service; xodtemplate_hostdependency *new_hostdependency; xodtemplate_hostescalation *new_hostescalation; xodtemplate_hostextinfo *new_hostextinfo; xodtemplate_serviceextinfo *new_serviceextinfo; int x; #ifdef DEBUG0 printf("xodtemplate_begin_object_definition() start\n"); #endif if(!strcmp(input,"service")) xodtemplate_current_object_type=XODTEMPLATE_SERVICE; else if(!strcmp(input,"host")) xodtemplate_current_object_type=XODTEMPLATE_HOST; else if(!strcmp(input,"command")) xodtemplate_current_object_type=XODTEMPLATE_COMMAND; else if(!strcmp(input,"contact")) xodtemplate_current_object_type=XODTEMPLATE_CONTACT; else if(!strcmp(input,"contactgroup")) xodtemplate_current_object_type=XODTEMPLATE_CONTACTGROUP; else if(!strcmp(input,"hostgroup")) xodtemplate_current_object_type=XODTEMPLATE_HOSTGROUP; else if(!strcmp(input,"servicegroup")) xodtemplate_current_object_type=XODTEMPLATE_SERVICEGROUP; else if(!strcmp(input,"timeperiod")) xodtemplate_current_object_type=XODTEMPLATE_TIMEPERIOD; else if(!strcmp(input,"servicedependency")) xodtemplate_current_object_type=XODTEMPLATE_SERVICEDEPENDENCY; else if(!strcmp(input,"serviceescalation")) xodtemplate_current_object_type=XODTEMPLATE_SERVICEESCALATION; else if(!strcmp(input,"hostdependency")) xodtemplate_current_object_type=XODTEMPLATE_HOSTDEPENDENCY; else if(!strcmp(input,"hostescalation")) xodtemplate_current_object_type=XODTEMPLATE_HOSTESCALATION; else if(!strcmp(input,"hostextinfo")) xodtemplate_current_object_type=XODTEMPLATE_HOSTEXTINFO; else if(!strcmp(input,"serviceextinfo")) xodtemplate_current_object_type=XODTEMPLATE_SERVICEEXTINFO; else return ERROR; /* check to see if we should process this type of object */ switch(xodtemplate_current_object_type){ case XODTEMPLATE_TIMEPERIOD: if(!(options & READ_TIMEPERIODS)) return OK; break; case XODTEMPLATE_COMMAND: if(!(options & READ_COMMANDS)) return OK; break; case XODTEMPLATE_CONTACT: if(!(options & READ_CONTACTS)) return OK; break; case XODTEMPLATE_CONTACTGROUP: if(!(options & READ_CONTACTGROUPS)) return OK; break; case XODTEMPLATE_HOST: if(!(options & READ_HOSTS)) return OK; break; case XODTEMPLATE_HOSTGROUP: if(!(options & READ_HOSTGROUPS)) return OK; break; case XODTEMPLATE_SERVICEGROUP: if(!(options & READ_SERVICEGROUPS)) return OK; break; case XODTEMPLATE_SERVICE: if(!(options & READ_SERVICES)) return OK; break; case XODTEMPLATE_SERVICEDEPENDENCY: if(!(options & READ_SERVICEDEPENDENCIES)) return OK; break; case XODTEMPLATE_SERVICEESCALATION: if(!(options & READ_SERVICEESCALATIONS)) return OK; break; case XODTEMPLATE_HOSTDEPENDENCY: if(!(options & READ_HOSTDEPENDENCIES)) return OK; break; case XODTEMPLATE_HOSTESCALATION: if(!(options & READ_HOSTESCALATIONS)) return OK; break; case XODTEMPLATE_HOSTEXTINFO: if(!(options & READ_HOSTEXTINFO)) return OK; break; case XODTEMPLATE_SERVICEEXTINFO: if(!(options & READ_SERVICEEXTINFO)) return OK; break; default: return ERROR; break; } /* add a new (blank) object */ switch(xodtemplate_current_object_type){ case XODTEMPLATE_TIMEPERIOD: /* allocate memory */ new_timeperiod=(xodtemplate_timeperiod *)malloc(sizeof(xodtemplate_timeperiod)); if(new_timeperiod==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for timeperiod definition\n"); #endif return ERROR; } new_timeperiod->template=NULL; new_timeperiod->name=NULL; new_timeperiod->timeperiod_name=NULL; new_timeperiod->alias=NULL; for(x=0;x<7;x++) new_timeperiod->timeranges[x]=NULL; new_timeperiod->has_been_resolved=FALSE; new_timeperiod->register_object=TRUE; new_timeperiod->_config_file=config_file; new_timeperiod->_start_line=start_line; /* add new timeperiod to head of list in memory */ new_timeperiod->next=xodtemplate_timeperiod_list; xodtemplate_timeperiod_list=new_timeperiod; /* update current object pointer */ xodtemplate_current_object=xodtemplate_timeperiod_list; break; case XODTEMPLATE_COMMAND: /* allocate memory */ new_command=(xodtemplate_command *)malloc(sizeof(xodtemplate_command)); if(new_command==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for command definition\n"); #endif return ERROR; } new_command->template=NULL; new_command->name=NULL; new_command->command_name=NULL; new_command->command_line=NULL; new_command->has_been_resolved=FALSE; new_command->register_object=TRUE; new_command->_config_file=config_file; new_command->_start_line=start_line; /* add new command to head of list in memory */ new_command->next=xodtemplate_command_list; xodtemplate_command_list=new_command; /* update current object pointer */ xodtemplate_current_object=xodtemplate_command_list; break; case XODTEMPLATE_CONTACTGROUP: /* allocate memory */ new_contactgroup=(xodtemplate_contactgroup *)malloc(sizeof(xodtemplate_contactgroup)); if(new_contactgroup==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for contactgroup definition\n"); #endif return ERROR; } new_contactgroup->template=NULL; new_contactgroup->name=NULL; new_contactgroup->contactgroup_name=NULL; new_contactgroup->alias=NULL; new_contactgroup->members=NULL; new_contactgroup->has_been_resolved=FALSE; new_contactgroup->register_object=TRUE; new_contactgroup->_config_file=config_file; new_contactgroup->_start_line=start_line; /* add new contactgroup to head of list in memory */ new_contactgroup->next=xodtemplate_contactgroup_list; xodtemplate_contactgroup_list=new_contactgroup; /* update current object pointer */ xodtemplate_current_object=xodtemplate_contactgroup_list; break; case XODTEMPLATE_HOSTGROUP: /* allocate memory */ new_hostgroup=(xodtemplate_hostgroup *)malloc(sizeof(xodtemplate_hostgroup)); if(new_hostgroup==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for hostgroup definition\n"); #endif return ERROR; } new_hostgroup->template=NULL; new_hostgroup->name=NULL; new_hostgroup->hostgroup_name=NULL; new_hostgroup->alias=NULL; new_hostgroup->members=NULL; new_hostgroup->has_been_resolved=FALSE; new_hostgroup->register_object=TRUE; new_hostgroup->_config_file=config_file; new_hostgroup->_start_line=start_line; /* add new hostgroup to head of list in memory */ new_hostgroup->next=xodtemplate_hostgroup_list; xodtemplate_hostgroup_list=new_hostgroup; /* update current object pointer */ xodtemplate_current_object=xodtemplate_hostgroup_list; break; case XODTEMPLATE_SERVICEGROUP: /* allocate memory */ new_servicegroup=(xodtemplate_servicegroup *)malloc(sizeof(xodtemplate_servicegroup)); if(new_servicegroup==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for servicegroup definition\n"); #endif return ERROR; } new_servicegroup->template=NULL; new_servicegroup->name=NULL; new_servicegroup->servicegroup_name=NULL; new_servicegroup->alias=NULL; new_servicegroup->members=NULL; new_servicegroup->has_been_resolved=FALSE; new_servicegroup->register_object=TRUE; new_servicegroup->_config_file=config_file; new_servicegroup->_start_line=start_line; /* add new servicegroup to head of list in memory */ new_servicegroup->next=xodtemplate_servicegroup_list; xodtemplate_servicegroup_list=new_servicegroup; /* update current object pointer */ xodtemplate_current_object=xodtemplate_servicegroup_list; break; case XODTEMPLATE_SERVICEDEPENDENCY: /* allocate memory */ new_servicedependency=(xodtemplate_servicedependency *)malloc(sizeof(xodtemplate_servicedependency)); if(new_servicedependency==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for servicedependency definition\n"); #endif return ERROR; } new_servicedependency->template=NULL; new_servicedependency->name=NULL; new_servicedependency->servicegroup_name=NULL; new_servicedependency->hostgroup_name=NULL; new_servicedependency->host_name=NULL; new_servicedependency->service_description=NULL; new_servicedependency->dependent_servicegroup_name=NULL; new_servicedependency->dependent_hostgroup_name=NULL; new_servicedependency->dependent_host_name=NULL; new_servicedependency->dependent_service_description=NULL; new_servicedependency->inherits_parent=FALSE; new_servicedependency->fail_execute_on_ok=FALSE; new_servicedependency->fail_execute_on_unknown=FALSE; new_servicedependency->fail_execute_on_warning=FALSE; new_servicedependency->fail_execute_on_critical=FALSE; new_servicedependency->fail_execute_on_pending=FALSE; new_servicedependency->fail_notify_on_ok=FALSE; new_servicedependency->fail_notify_on_unknown=FALSE; new_servicedependency->fail_notify_on_warning=FALSE; new_servicedependency->fail_notify_on_critical=FALSE; new_servicedependency->fail_notify_on_pending=FALSE; new_servicedependency->have_inherits_parent=FALSE; new_servicedependency->have_execution_dependency_options=FALSE; new_servicedependency->have_notification_dependency_options=FALSE; new_servicedependency->has_been_resolved=FALSE; new_servicedependency->register_object=TRUE; new_servicedependency->_config_file=config_file; new_servicedependency->_start_line=start_line; /* add new servicedependency to head of list in memory */ new_servicedependency->next=xodtemplate_servicedependency_list; xodtemplate_servicedependency_list=new_servicedependency; /* update current object pointer */ xodtemplate_current_object=xodtemplate_servicedependency_list; break; case XODTEMPLATE_SERVICEESCALATION: /* allocate memory */ new_serviceescalation=(xodtemplate_serviceescalation *)malloc(sizeof(xodtemplate_serviceescalation)); if(new_serviceescalation==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for serviceescalation definition\n"); #endif return ERROR; } new_serviceescalation->template=NULL; new_serviceescalation->name=NULL; new_serviceescalation->servicegroup_name=NULL; new_serviceescalation->hostgroup_name=NULL; new_serviceescalation->host_name=NULL; new_serviceescalation->service_description=NULL; new_serviceescalation->escalation_period=NULL; new_serviceescalation->contact_groups=NULL; new_serviceescalation->first_notification=-2; new_serviceescalation->last_notification=-2; new_serviceescalation->notification_interval=-2; new_serviceescalation->escalate_on_warning=FALSE; new_serviceescalation->escalate_on_unknown=FALSE; new_serviceescalation->escalate_on_critical=FALSE; new_serviceescalation->escalate_on_recovery=FALSE; new_serviceescalation->have_first_notification=FALSE; new_serviceescalation->have_last_notification=FALSE; new_serviceescalation->have_notification_interval=FALSE; new_serviceescalation->have_escalation_options=FALSE; new_serviceescalation->has_been_resolved=FALSE; new_serviceescalation->register_object=TRUE; new_serviceescalation->_config_file=config_file; new_serviceescalation->_start_line=start_line; /* add new serviceescalation to head of list in memory */ new_serviceescalation->next=xodtemplate_serviceescalation_list; xodtemplate_serviceescalation_list=new_serviceescalation; /* update current object pointer */ xodtemplate_current_object=xodtemplate_serviceescalation_list; break; case XODTEMPLATE_CONTACT: /* allocate memory */ new_contact=(xodtemplate_contact *)malloc(sizeof(xodtemplate_contact)); if(new_contact==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for contact definition\n"); #endif return ERROR; } new_contact->template=NULL; new_contact->name=NULL; new_contact->contact_name=NULL; new_contact->alias=NULL; new_contact->contactgroups=NULL; new_contact->email=NULL; new_contact->pager=NULL; for(x=0;xaddress[x]=NULL; new_contact->host_notification_period=NULL; new_contact->host_notification_commands=NULL; new_contact->service_notification_period=NULL; new_contact->service_notification_commands=NULL; new_contact->notify_on_host_down=FALSE; new_contact->notify_on_host_unreachable=FALSE; new_contact->notify_on_host_recovery=FALSE; new_contact->notify_on_host_flapping=FALSE; new_contact->notify_on_service_unknown=FALSE; new_contact->notify_on_service_warning=FALSE; new_contact->notify_on_service_critical=FALSE; new_contact->notify_on_service_recovery=FALSE; new_contact->notify_on_service_flapping=FALSE; new_contact->have_host_notification_options=FALSE; new_contact->have_service_notification_options=FALSE; new_contact->has_been_resolved=FALSE; new_contact->register_object=TRUE; new_contact->_config_file=config_file; new_contact->_start_line=start_line; /* add new contact to head of list in memory */ new_contact->next=xodtemplate_contact_list; xodtemplate_contact_list=new_contact; /* update current object pointer */ xodtemplate_current_object=xodtemplate_contact_list; break; case XODTEMPLATE_HOST: /* allocate memory */ new_host=(xodtemplate_host *)malloc(sizeof(xodtemplate_host)); if(new_host==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for host definition\n"); #endif return ERROR; } new_host->template=NULL; new_host->name=NULL; new_host->host_name=NULL; new_host->alias=NULL; new_host->address=NULL; new_host->parents=NULL; new_host->hostgroups=NULL; new_host->check_command=NULL; new_host->check_period=NULL; new_host->event_handler=NULL; new_host->contact_groups=NULL; new_host->notification_period=NULL; new_host->check_interval=0; new_host->have_check_interval=FALSE; new_host->active_checks_enabled=TRUE; new_host->have_active_checks_enabled=FALSE; new_host->passive_checks_enabled=TRUE; new_host->have_passive_checks_enabled=FALSE; new_host->obsess_over_host=TRUE; new_host->have_obsess_over_host=FALSE; new_host->max_check_attempts=-2; new_host->have_max_check_attempts=FALSE; new_host->event_handler_enabled=TRUE; new_host->have_event_handler_enabled=FALSE; new_host->check_freshness=FALSE; new_host->have_check_freshness=FALSE; new_host->freshness_threshold=0; new_host->have_freshness_threshold=0; new_host->flap_detection_enabled=TRUE; new_host->have_flap_detection_enabled=FALSE; new_host->low_flap_threshold=0.0; new_host->have_low_flap_threshold=FALSE; new_host->high_flap_threshold=0.0; new_host->have_high_flap_threshold=FALSE; new_host->notify_on_down=FALSE; new_host->notify_on_unreachable=FALSE; new_host->notify_on_recovery=FALSE; new_host->notify_on_flapping=FALSE; new_host->have_notification_options=FALSE; new_host->notifications_enabled=TRUE; new_host->have_notifications_enabled=FALSE; new_host->notification_interval=-2; new_host->have_notification_interval=FALSE; new_host->stalk_on_up=FALSE; new_host->stalk_on_down=FALSE; new_host->stalk_on_unreachable=FALSE; new_host->have_stalking_options=FALSE; new_host->process_perf_data=TRUE; new_host->have_process_perf_data=FALSE; new_host->failure_prediction_enabled=TRUE; new_host->have_failure_prediction_enabled=FALSE; new_host->failure_prediction_options=NULL; new_host->retain_status_information=TRUE; new_host->have_retain_status_information=FALSE; new_host->retain_nonstatus_information=TRUE; new_host->have_retain_nonstatus_information=FALSE; new_host->has_been_resolved=FALSE; new_host->register_object=TRUE; new_host->_config_file=config_file; new_host->_start_line=start_line; /* add new host to head of list in memory */ new_host->next=xodtemplate_host_list; xodtemplate_host_list=new_host; /* update current object pointer */ xodtemplate_current_object=xodtemplate_host_list; break; case XODTEMPLATE_SERVICE: /* allocate memory */ new_service=(xodtemplate_service *)malloc(sizeof(xodtemplate_service)); if(new_service==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for service definition\n"); #endif return ERROR; } new_service->template=NULL; new_service->name=NULL; new_service->hostgroup_name=NULL; new_service->host_name=NULL; new_service->service_description=NULL; new_service->servicegroups=NULL; new_service->check_command=NULL; new_service->check_period=NULL; new_service->event_handler=NULL; new_service->notification_period=NULL; new_service->contact_groups=NULL; new_service->max_check_attempts=-2; new_service->have_max_check_attempts=FALSE; new_service->normal_check_interval=-2; new_service->have_normal_check_interval=FALSE; new_service->retry_check_interval=-2; new_service->have_retry_check_interval=FALSE; new_service->active_checks_enabled=TRUE; new_service->have_active_checks_enabled=FALSE; new_service->passive_checks_enabled=TRUE; new_service->have_passive_checks_enabled=FALSE; new_service->parallelize_check=TRUE; new_service->have_parallelize_check=FALSE; new_service->is_volatile=FALSE; new_service->have_is_volatile=FALSE; new_service->obsess_over_service=TRUE; new_service->have_obsess_over_service=FALSE; new_service->event_handler_enabled=TRUE; new_service->have_event_handler_enabled=FALSE; new_service->check_freshness=FALSE; new_service->have_check_freshness=FALSE; new_service->freshness_threshold=0; new_service->have_freshness_threshold=FALSE; new_service->flap_detection_enabled=TRUE; new_service->have_flap_detection_enabled=FALSE; new_service->low_flap_threshold=0.0; new_service->have_low_flap_threshold=FALSE; new_service->high_flap_threshold=0.0; new_service->have_high_flap_threshold=FALSE; new_service->notify_on_unknown=FALSE; new_service->notify_on_warning=FALSE; new_service->notify_on_critical=FALSE; new_service->notify_on_recovery=FALSE; new_service->notify_on_flapping=FALSE; new_service->have_notification_options=FALSE; new_service->notifications_enabled=TRUE; new_service->have_notifications_enabled=FALSE; new_service->notification_interval=-2; new_service->have_notification_interval=FALSE; new_service->stalk_on_ok=FALSE; new_service->stalk_on_unknown=FALSE; new_service->stalk_on_warning=FALSE; new_service->stalk_on_critical=FALSE; new_service->have_stalking_options=FALSE; new_service->process_perf_data=TRUE; new_service->have_process_perf_data=FALSE; new_service->failure_prediction_enabled=TRUE; new_service->have_failure_prediction_enabled=FALSE; new_service->failure_prediction_options=NULL; new_service->retain_status_information=TRUE; new_service->have_retain_status_information=FALSE; new_service->retain_nonstatus_information=TRUE; new_service->have_retain_nonstatus_information=FALSE; new_service->has_been_resolved=FALSE; new_service->register_object=TRUE; new_service->_config_file=config_file; new_service->_start_line=start_line; /* add new service to head of list in memory */ new_service->next=xodtemplate_service_list; xodtemplate_service_list=new_service; /* update current object pointer */ xodtemplate_current_object=new_service; break; case XODTEMPLATE_HOSTDEPENDENCY: /* allocate memory */ new_hostdependency=(xodtemplate_hostdependency *)malloc(sizeof(xodtemplate_hostdependency)); if(new_hostdependency==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for hostdependency definition\n"); #endif return ERROR; } new_hostdependency->template=NULL; new_hostdependency->name=NULL; new_hostdependency->hostgroup_name=NULL; new_hostdependency->dependent_hostgroup_name=NULL; new_hostdependency->host_name=NULL; new_hostdependency->dependent_host_name=NULL; new_hostdependency->inherits_parent=FALSE; new_hostdependency->fail_notify_on_up=FALSE; new_hostdependency->fail_notify_on_down=FALSE; new_hostdependency->fail_notify_on_unreachable=FALSE; new_hostdependency->fail_notify_on_pending=FALSE; new_hostdependency->fail_execute_on_up=FALSE; new_hostdependency->fail_execute_on_down=FALSE; new_hostdependency->fail_execute_on_unreachable=FALSE; new_hostdependency->fail_execute_on_pending=FALSE; new_hostdependency->have_inherits_parent=FALSE; new_hostdependency->have_notification_dependency_options=FALSE; new_hostdependency->have_execution_dependency_options=FALSE; new_hostdependency->has_been_resolved=FALSE; new_hostdependency->register_object=TRUE; new_hostdependency->_config_file=config_file; new_hostdependency->_start_line=start_line; /* add new hostdependency to head of list in memory */ new_hostdependency->next=xodtemplate_hostdependency_list; xodtemplate_hostdependency_list=new_hostdependency; /* update current object pointer */ xodtemplate_current_object=xodtemplate_hostdependency_list; break; case XODTEMPLATE_HOSTESCALATION: /* allocate memory */ new_hostescalation=(xodtemplate_hostescalation *)malloc(sizeof(xodtemplate_hostescalation)); if(new_hostescalation==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for hostescalation definition\n"); #endif return ERROR; } new_hostescalation->template=NULL; new_hostescalation->name=NULL; new_hostescalation->hostgroup_name=NULL; new_hostescalation->host_name=NULL; new_hostescalation->escalation_period=NULL; new_hostescalation->contact_groups=NULL; new_hostescalation->first_notification=-2; new_hostescalation->last_notification=-2; new_hostescalation->notification_interval=-2; new_hostescalation->escalate_on_down=FALSE; new_hostescalation->escalate_on_unreachable=FALSE; new_hostescalation->escalate_on_recovery=FALSE; new_hostescalation->have_first_notification=FALSE; new_hostescalation->have_last_notification=FALSE; new_hostescalation->have_notification_interval=FALSE; new_hostescalation->have_escalation_options=FALSE; new_hostescalation->has_been_resolved=FALSE; new_hostescalation->register_object=TRUE; new_hostescalation->_config_file=config_file; new_hostescalation->_start_line=start_line; /* add new hostescalation to head of list in memory */ new_hostescalation->next=xodtemplate_hostescalation_list; xodtemplate_hostescalation_list=new_hostescalation; /* update current object pointer */ xodtemplate_current_object=xodtemplate_hostescalation_list; break; case XODTEMPLATE_HOSTEXTINFO: /* allocate memory */ new_hostextinfo=(xodtemplate_hostextinfo *)malloc(sizeof(xodtemplate_hostextinfo)); if(new_hostextinfo==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for extended host info\n"); #endif return ERROR; } new_hostextinfo->template=NULL; new_hostextinfo->name=NULL; new_hostextinfo->host_name=NULL; new_hostextinfo->hostgroup_name=NULL; new_hostextinfo->notes=NULL; new_hostextinfo->notes_url=NULL; new_hostextinfo->action_url=NULL; new_hostextinfo->icon_image=NULL; new_hostextinfo->icon_image_alt=NULL; new_hostextinfo->vrml_image=NULL; new_hostextinfo->statusmap_image=NULL; new_hostextinfo->x_2d=-1; new_hostextinfo->y_2d=-1; new_hostextinfo->x_3d=0.0; new_hostextinfo->y_3d=0.0; new_hostextinfo->z_3d=0.0; new_hostextinfo->have_2d_coords=FALSE; new_hostextinfo->have_3d_coords=FALSE; new_hostextinfo->has_been_resolved=FALSE; new_hostextinfo->register_object=TRUE; new_hostextinfo->_config_file=config_file; new_hostextinfo->_start_line=start_line; /* add new extended host info to head of list in memory */ new_hostextinfo->next=xodtemplate_hostextinfo_list; xodtemplate_hostextinfo_list=new_hostextinfo; /* update current object pointer */ xodtemplate_current_object=xodtemplate_hostextinfo_list; break; case XODTEMPLATE_SERVICEEXTINFO: /* allocate memory */ new_serviceextinfo=(xodtemplate_serviceextinfo *)malloc(sizeof(xodtemplate_serviceextinfo)); if(new_serviceextinfo==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for extended service info\n"); #endif return ERROR; } new_serviceextinfo->template=NULL; new_serviceextinfo->name=NULL; new_serviceextinfo->host_name=NULL; new_serviceextinfo->hostgroup_name=NULL; new_serviceextinfo->service_description=NULL; new_serviceextinfo->notes=NULL; new_serviceextinfo->notes_url=NULL; new_serviceextinfo->action_url=NULL; new_serviceextinfo->icon_image=NULL; new_serviceextinfo->icon_image_alt=NULL; new_serviceextinfo->has_been_resolved=FALSE; new_serviceextinfo->register_object=TRUE; new_serviceextinfo->_config_file=config_file; new_serviceextinfo->_start_line=start_line; /* add new extended service info to head of list in memory */ new_serviceextinfo->next=xodtemplate_serviceextinfo_list; xodtemplate_serviceextinfo_list=new_serviceextinfo; /* update current object pointer */ xodtemplate_current_object=xodtemplate_serviceextinfo_list; break; default: return ERROR; break; } #ifdef DEBUG0 printf("xodtemplate_begin_object_definition() end\n"); #endif return result; } /* adds a property to an object definition */ int xodtemplate_add_object_property(char *input, int options){ int result=OK; char *variable=NULL; char *value=NULL; char *temp_ptr; xodtemplate_timeperiod *temp_timeperiod; xodtemplate_command *temp_command; xodtemplate_contactgroup *temp_contactgroup; xodtemplate_hostgroup *temp_hostgroup; xodtemplate_servicegroup *temp_servicegroup; xodtemplate_servicedependency *temp_servicedependency; xodtemplate_serviceescalation *temp_serviceescalation; xodtemplate_contact *temp_contact; xodtemplate_host *temp_host; xodtemplate_service *temp_service; xodtemplate_hostdependency *temp_hostdependency; xodtemplate_hostescalation *temp_hostescalation; xodtemplate_hostextinfo *temp_hostextinfo; xodtemplate_serviceextinfo *temp_serviceextinfo; register int x; register int y; register int len; #ifdef NSCORE char temp_buffer[MAX_XODTEMPLATE_INPUT_BUFFER]; #endif #ifdef DEBUG0 printf("xodtemplate_add_object_property() start\n"); #endif /* check to see if we should process this type of object */ switch(xodtemplate_current_object_type){ case XODTEMPLATE_TIMEPERIOD: if(!(options & READ_TIMEPERIODS)) return OK; break; case XODTEMPLATE_COMMAND: if(!(options & READ_COMMANDS)) return OK; break; case XODTEMPLATE_CONTACT: if(!(options & READ_CONTACTS)) return OK; break; case XODTEMPLATE_CONTACTGROUP: if(!(options & READ_CONTACTGROUPS)) return OK; break; case XODTEMPLATE_HOST: if(!(options & READ_HOSTS)) return OK; break; case XODTEMPLATE_HOSTGROUP: if(!(options & READ_HOSTGROUPS)) return OK; break; case XODTEMPLATE_SERVICEGROUP: if(!(options & READ_SERVICEGROUPS)) return OK; break; case XODTEMPLATE_SERVICE: if(!(options & READ_SERVICES)) return OK; break; case XODTEMPLATE_SERVICEDEPENDENCY: if(!(options & READ_SERVICEDEPENDENCIES)) return OK; break; case XODTEMPLATE_SERVICEESCALATION: if(!(options & READ_SERVICEESCALATIONS)) return OK; break; case XODTEMPLATE_HOSTDEPENDENCY: if(!(options & READ_HOSTDEPENDENCIES)) return OK; break; case XODTEMPLATE_HOSTESCALATION: if(!(options & READ_HOSTESCALATIONS)) return OK; break; case XODTEMPLATE_HOSTEXTINFO: if(!(options & READ_HOSTEXTINFO)) return OK; break; case XODTEMPLATE_SERVICEEXTINFO: if(!(options & READ_SERVICEEXTINFO)) return OK; break; default: return ERROR; break; } /* allocate memory */ len=strlen(input); if((variable=(char *)malloc(len+1))==NULL) return ERROR; if((value=(char *)malloc(len+1))==NULL){ free(variable); return ERROR; } /* get variable name */ strcpy(variable,input); for(x=0,y=0;input[x]!='\x0';x++){ if(input[x]==' ' || input[x]=='\t') break; y++; } variable[y]='\x0'; /* get variable value */ /* skip leading whitespace */ for(;input[x]!='\x0';x++){ if(input[x]!=' ' && input[x]!='\t') break; } if(x>=len){ #ifdef DEBUG1 printf("Error: NULL variable value in object definition.\n"); #endif return ERROR; } strcpy(value,input+x); /* printf("RAW VARIABLE: '%s'\n",variable); printf("RAW VALUE: '%s'\n",value); */ #ifdef RUN_SLOW_AS_HELL strip(variable); #endif strip(value); /* printf("STRIPPED VARIABLE: '%s'\n",variable); printf("STRIPPED VALUE: '%s'\n\n",value); */ switch(xodtemplate_current_object_type){ case XODTEMPLATE_TIMEPERIOD: temp_timeperiod=(xodtemplate_timeperiod *)xodtemplate_current_object; if(!strcmp(variable,"use")){ temp_timeperiod->template=strdup(value); if(temp_timeperiod->template==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for timeperiod template.\n"); #endif return ERROR; } } else if(!strcmp(variable,"name")){ #ifdef NSCORE /* check for duplicates */ if(xodtemplate_find_timeperiod(value)!=NULL){ snprintf(temp_buffer,sizeof(temp_buffer)-1,"Warning: Duplicate definition found for timeperiod '%s' (config file '%s', starting on line %d)\n",value,xodtemplate_config_file_name(temp_timeperiod->_config_file),temp_timeperiod->_start_line); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_WARNING,TRUE); } #endif temp_timeperiod->name=strdup(value); if(temp_timeperiod->name==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for timeperiod name.\n"); #endif return ERROR; } } else if(!strcmp(variable,"timeperiod_name")){ temp_timeperiod->timeperiod_name=strdup(value); if(temp_timeperiod->timeperiod_name==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for timeperiod name.\n"); #endif return ERROR; } } else if(!strcmp(variable,"alias")){ temp_timeperiod->alias=strdup(value); if(temp_timeperiod->alias==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for timeperiod alias.\n"); #endif return ERROR; } } else if(!strcmp(variable,"monday") || !strcmp(variable,"tuesday") || !strcmp(variable,"wednesday") || !strcmp(variable,"thursday") || !strcmp(variable,"friday") || !strcmp(variable,"saturday") || !strcmp(variable,"sunday")){ if(!strcmp(variable,"monday")) x=1; else if(!strcmp(variable,"tuesday")) x=2; else if(!strcmp(variable,"wednesday")) x=3; else if(!strcmp(variable,"thursday")) x=4; else if(!strcmp(variable,"friday")) x=5; else if(!strcmp(variable,"saturday")) x=6; else x=0; temp_timeperiod->timeranges[x]=strdup(value); if(temp_timeperiod->timeranges[x]==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for timeperiod timerange.\n"); #endif return ERROR; } } else if(!strcmp(variable,"register")) temp_timeperiod->register_object=(atoi(value)>0)?TRUE:FALSE; else{ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Invalid timeperiod object directive '%s'.\n",variable); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return ERROR; } break; case XODTEMPLATE_COMMAND: temp_command=(xodtemplate_command *)xodtemplate_current_object; if(!strcmp(variable,"use")){ temp_command->template=strdup(value); if(temp_command->template==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for command template.\n"); #endif return ERROR; } } else if(!strcmp(variable,"name")){ #ifdef NSCORE /* check for duplicates */ if(xodtemplate_find_command(value)!=NULL){ snprintf(temp_buffer,sizeof(temp_buffer)-1,"Warning: Duplicate definition found for command '%s' (config file '%s', starting on line %d)\n",value,xodtemplate_config_file_name(temp_command->_config_file),temp_command->_start_line); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_WARNING,TRUE); } #endif temp_command->name=strdup(value); if(temp_command->name==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for command name.\n"); #endif return ERROR; } } else if(!strcmp(variable,"command_name")){ temp_command->command_name=strdup(value); if(temp_command->command_name==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for command name.\n"); #endif return ERROR; } } else if(!strcmp(variable,"command_line")){ temp_command->command_line=strdup(value); if(temp_command->command_line==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for command line.\n"); #endif return ERROR; } } else if(!strcmp(variable,"register")) temp_command->register_object=(atoi(value)>0)?TRUE:FALSE; else{ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Invalid command object directive '%s'.\n",variable); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return ERROR; } break; case XODTEMPLATE_CONTACTGROUP: temp_contactgroup=(xodtemplate_contactgroup *)xodtemplate_current_object; if(!strcmp(variable,"use")){ temp_contactgroup->template=strdup(value); if(temp_contactgroup->template==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for contactgroup template.\n"); #endif return ERROR; } } else if(!strcmp(variable,"name")){ #ifdef NSCORE /* check for duplicates */ if(xodtemplate_find_contactgroup(value)!=NULL){ snprintf(temp_buffer,sizeof(temp_buffer)-1,"Warning: Duplicate definition found for contactgroup '%s' (config file '%s', starting on line %d)\n",value,xodtemplate_config_file_name(temp_contactgroup->_config_file),temp_contactgroup->_start_line); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_WARNING,TRUE); } #endif temp_contactgroup->name=strdup(value); if(temp_contactgroup->name==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for contactgroup name.\n"); #endif return ERROR; } } else if(!strcmp(variable,"contactgroup_name")){ temp_contactgroup->contactgroup_name=strdup(value); if(temp_contactgroup->contactgroup_name==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for contactgroup name.\n"); #endif return ERROR; } } else if(!strcmp(variable,"alias")){ temp_contactgroup->alias=strdup(value); if(temp_contactgroup->alias==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for contactgroup alias.\n"); #endif return ERROR; } } else if(!strcmp(variable,"members")){ temp_contactgroup->members=strdup(value); if(temp_contactgroup->members==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for contactgroup members.\n"); #endif return ERROR; } } else if(!strcmp(variable,"register")) temp_contactgroup->register_object=(atoi(value)>0)?TRUE:FALSE; else{ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Invalid contactgroup object directive '%s'.\n",variable); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return ERROR; } break; case XODTEMPLATE_HOSTGROUP: temp_hostgroup=(xodtemplate_hostgroup *)xodtemplate_current_object; if(!strcmp(variable,"use")){ temp_hostgroup->template=strdup(value); if(temp_hostgroup->template==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for hostgroup template.\n"); #endif return ERROR; } } else if(!strcmp(variable,"name")){ #ifdef NSCORE /* check for duplicates */ if(xodtemplate_find_hostgroup(value)!=NULL){ snprintf(temp_buffer,sizeof(temp_buffer)-1,"Warning: Duplicate definition found for hostgroup '%s' (config file '%s', starting on line %d)\n",value,xodtemplate_config_file_name(temp_hostgroup->_config_file),temp_hostgroup->_start_line); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_WARNING,TRUE); } #endif temp_hostgroup->name=strdup(value); if(temp_hostgroup->name==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for hostgroup name.\n"); #endif return ERROR; } } else if(!strcmp(variable,"hostgroup_name")){ temp_hostgroup->hostgroup_name=strdup(value); if(temp_hostgroup->hostgroup_name==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for hostgroup name.\n"); #endif return ERROR; } } else if(!strcmp(variable,"alias")){ temp_hostgroup->alias=strdup(value); if(temp_hostgroup->alias==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for hostgroup alias.\n"); #endif return ERROR; } } else if(!strcmp(variable,"members")){ if(temp_hostgroup->members==NULL) temp_hostgroup->members=strdup(value); else{ temp_hostgroup->members=(char *)realloc(temp_hostgroup->members,strlen(temp_hostgroup->members)+strlen(value)+2); if(temp_hostgroup->members!=NULL){ strcat(temp_hostgroup->members,","); strcat(temp_hostgroup->members,value); } } if(temp_hostgroup->members==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for hostgroup members.\n"); #endif return ERROR; } } else if(!strcmp(variable,"register")) temp_hostgroup->register_object=(atoi(value)>0)?TRUE:FALSE; else{ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Invalid hostgroup object directive '%s'.\n",variable); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return ERROR; } break; case XODTEMPLATE_SERVICEGROUP: temp_servicegroup=(xodtemplate_servicegroup *)xodtemplate_current_object; if(!strcmp(variable,"use")){ temp_servicegroup->template=strdup(value); if(temp_servicegroup->template==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for servicegroup template.\n"); #endif return ERROR; } } else if(!strcmp(variable,"name")){ #ifdef NSCORE /* check for duplicates */ if(xodtemplate_find_servicegroup(value)!=NULL){ snprintf(temp_buffer,sizeof(temp_buffer)-1,"Warning: Duplicate definition found for servicegroup '%s' (config file '%s', starting on line %d)\n",value,xodtemplate_config_file_name(temp_servicegroup->_config_file),temp_servicegroup->_start_line); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_WARNING,TRUE); } #endif temp_servicegroup->name=strdup(value); if(temp_servicegroup->name==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for servicegroup name.\n"); #endif return ERROR; } } else if(!strcmp(variable,"servicegroup_name")){ temp_servicegroup->servicegroup_name=strdup(value); if(temp_servicegroup->servicegroup_name==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for servicegroup name.\n"); #endif return ERROR; } } else if(!strcmp(variable,"alias")){ temp_servicegroup->alias=strdup(value); if(temp_servicegroup->alias==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for servicegroup alias.\n"); #endif return ERROR; } } else if(!strcmp(variable,"members")){ if(temp_servicegroup->members==NULL) temp_servicegroup->members=strdup(value); else{ temp_servicegroup->members=(char *)realloc(temp_servicegroup->members,strlen(temp_servicegroup->members)+strlen(value)+2); if(temp_servicegroup->members!=NULL){ strcat(temp_servicegroup->members,","); strcat(temp_servicegroup->members,value); } } if(temp_servicegroup->members==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for servicegroup members.\n"); #endif return ERROR; } } else if(!strcmp(variable,"register")) temp_servicegroup->register_object=(atoi(value)>0)?TRUE:FALSE; else{ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Invalid servicegroup object directive '%s'.\n",variable); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return ERROR; } break; case XODTEMPLATE_SERVICEDEPENDENCY: temp_servicedependency=(xodtemplate_servicedependency *)xodtemplate_current_object; if(!strcmp(variable,"use")){ temp_servicedependency->template=strdup(value); if(temp_servicedependency->template==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for servicedependency template.\n"); #endif return ERROR; } } else if(!strcmp(variable,"name")){ #ifdef NSCORE /* check for duplicates */ if(xodtemplate_find_servicedependency(value)!=NULL){ snprintf(temp_buffer,sizeof(temp_buffer)-1,"Warning: Duplicate definition found for service dependency '%s' (config file '%s', starting on line %d)\n",value,xodtemplate_config_file_name(temp_servicedependency->_config_file),temp_servicedependency->_start_line); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_WARNING,TRUE); } #endif temp_servicedependency->name=strdup(value); if(temp_servicedependency->name==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for servicedependency name.\n"); #endif return ERROR; } } else if(!strcmp(variable,"servicegroup") || !strcmp(variable,"servicegroups") || !strcmp(variable,"servicegroup_name")){ temp_servicedependency->servicegroup_name=strdup(value); if(temp_servicedependency->servicegroup_name==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for servicedependency servicegroup.\n"); #endif return ERROR; } } else if(!strcmp(variable,"hostgroup") || !strcmp(variable,"hostgroups") || !strcmp(variable,"hostgroup_name")){ temp_servicedependency->hostgroup_name=strdup(value); if(temp_servicedependency->hostgroup_name==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for servicedependency hostgroup.\n"); #endif return ERROR; } } else if(!strcmp(variable,"host") || !strcmp(variable,"host_name") || !strcmp(variable,"master_host") || !strcmp(variable,"master_host_name")){ temp_servicedependency->host_name=strdup(value); if(temp_servicedependency->host_name==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for servicedependency host.\n"); #endif return ERROR; } } else if(!strcmp(variable,"description") || !strcmp(variable,"service_description") || !strcmp(variable,"master_description") || !strcmp(variable,"master_service_description")){ temp_servicedependency->service_description=strdup(value); if(temp_servicedependency->service_description==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for servicedependency service_description.\n"); #endif return ERROR; } } else if(!strcmp(variable,"dependent_servicegroup") || !strcmp(variable,"dependent_servicegroups") || !strcmp(variable,"dependent_servicegroup_name")){ temp_servicedependency->dependent_servicegroup_name=strdup(value); if(temp_servicedependency->dependent_servicegroup_name==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for servicedependency dependent servicegroup.\n"); #endif return ERROR; } } else if(!strcmp(variable,"dependent_hostgroup") || !strcmp(variable,"dependent_hostgroups") || !strcmp(variable,"dependent_hostgroup_name")){ temp_servicedependency->dependent_hostgroup_name=strdup(value); if(temp_servicedependency->dependent_hostgroup_name==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for servicedependency dependent hostgroup.\n"); #endif return ERROR; } } else if(!strcmp(variable,"dependent_host") || !strcmp(variable,"dependent_host_name")){ temp_servicedependency->dependent_host_name=strdup(value); if(temp_servicedependency->dependent_host_name==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for servicedependency dependent host.\n"); #endif return ERROR; } } else if(!strcmp(variable,"dependent_description") || !strcmp(variable,"dependent_service_description")){ temp_servicedependency->dependent_service_description=strdup(value); if(temp_servicedependency->dependent_service_description==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for servicedependency dependent service_description.\n"); #endif return ERROR; } } else if(!strcmp(variable,"inherits_parent")){ temp_servicedependency->inherits_parent=(atoi(value)>0)?TRUE:FALSE; temp_servicedependency->have_inherits_parent=TRUE; } else if(!strcmp(variable,"execution_failure_options") || !strcmp(variable,"execution_failure_criteria")){ for(temp_ptr=strtok(value,", ");temp_ptr;temp_ptr=strtok(NULL,", ")){ if(!strcmp(temp_ptr,"o") || !strcmp(temp_ptr,"ok")) temp_servicedependency->fail_execute_on_ok=TRUE; else if(!strcmp(temp_ptr,"u") || !strcmp(temp_ptr,"unknown")) temp_servicedependency->fail_execute_on_unknown=TRUE; else if(!strcmp(temp_ptr,"w") || !strcmp(temp_ptr,"warning")) temp_servicedependency->fail_execute_on_warning=TRUE; else if(!strcmp(temp_ptr,"c") || !strcmp(temp_ptr,"critical")) temp_servicedependency->fail_execute_on_critical=TRUE; else if(!strcmp(temp_ptr,"p") || !strcmp(temp_ptr,"pending")) temp_servicedependency->fail_execute_on_pending=TRUE; else if(!strcmp(temp_ptr,"n") || !strcmp(temp_ptr,"none")){ temp_servicedependency->fail_execute_on_ok=FALSE; temp_servicedependency->fail_execute_on_unknown=FALSE; temp_servicedependency->fail_execute_on_warning=FALSE; temp_servicedependency->fail_execute_on_critical=FALSE; } else{ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Invalid execution dependency option '%s' in servicedependency definition.\n",temp_ptr); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return ERROR; } } temp_servicedependency->have_execution_dependency_options=TRUE; } else if(!strcmp(variable,"notification_failure_options") || !strcmp(variable,"notification_failure_criteria")){ for(temp_ptr=strtok(value,", ");temp_ptr;temp_ptr=strtok(NULL,", ")){ if(!strcmp(temp_ptr,"o") || !strcmp(temp_ptr,"ok")) temp_servicedependency->fail_notify_on_ok=TRUE; else if(!strcmp(temp_ptr,"u") || !strcmp(temp_ptr,"unknown")) temp_servicedependency->fail_notify_on_unknown=TRUE; else if(!strcmp(temp_ptr,"w") || !strcmp(temp_ptr,"warning")) temp_servicedependency->fail_notify_on_warning=TRUE; else if(!strcmp(temp_ptr,"c") || !strcmp(temp_ptr,"critical")) temp_servicedependency->fail_notify_on_critical=TRUE; else if(!strcmp(temp_ptr,"p") || !strcmp(temp_ptr,"pending")) temp_servicedependency->fail_notify_on_pending=TRUE; else if(!strcmp(temp_ptr,"n") || !strcmp(temp_ptr,"none")){ temp_servicedependency->fail_notify_on_ok=FALSE; temp_servicedependency->fail_notify_on_unknown=FALSE; temp_servicedependency->fail_notify_on_warning=FALSE; temp_servicedependency->fail_notify_on_critical=FALSE; temp_servicedependency->fail_notify_on_pending=FALSE; } else{ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Invalid notification dependency option '%s' in servicedependency definition.\n",temp_ptr); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return ERROR; } } temp_servicedependency->have_notification_dependency_options=TRUE; } else if(!strcmp(variable,"register")) temp_servicedependency->register_object=(atoi(value)>0)?TRUE:FALSE; else{ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Invalid servicedependency object directive '%s'.\n",variable); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return ERROR; } break; case XODTEMPLATE_SERVICEESCALATION: temp_serviceescalation=(xodtemplate_serviceescalation *)xodtemplate_current_object; if(!strcmp(variable,"use")){ temp_serviceescalation->template=strdup(value); if(temp_serviceescalation->template==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for serviceescalation template.\n"); #endif return ERROR; } } else if(!strcmp(variable,"name")){ #ifdef NSCORE /* check for duplicates */ if(xodtemplate_find_serviceescalation(value)!=NULL){ snprintf(temp_buffer,sizeof(temp_buffer)-1,"Warning: Duplicate definition found for service escalation '%s' (config file '%s', starting on line %d)\n",value,xodtemplate_config_file_name(temp_serviceescalation->_config_file),temp_serviceescalation->_start_line); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_WARNING,TRUE); } #endif temp_serviceescalation->name=strdup(value); if(temp_serviceescalation->name==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for serviceescalation name.\n"); #endif return ERROR; } } else if(!strcmp(variable,"servicegroup") || !strcmp(variable,"servicegroups") || !strcmp(variable,"servicegroup_name")){ temp_serviceescalation->servicegroup_name=strdup(value); if(temp_serviceescalation->servicegroup_name==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for serviceescalation servicegroup.\n"); #endif return ERROR; } } else if(!strcmp(variable,"hostgroup") || !strcmp(variable,"hostgroups") || !strcmp(variable,"hostgroup_name")){ temp_serviceescalation->hostgroup_name=strdup(value); if(temp_serviceescalation->hostgroup_name==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for serviceescalation hostgroup.\n"); #endif return ERROR; } } else if(!strcmp(variable,"host") || !strcmp(variable,"host_name")){ temp_serviceescalation->host_name=strdup(value); if(temp_serviceescalation->host_name==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for serviceescalation host.\n"); #endif return ERROR; } } else if(!strcmp(variable,"description") || !strcmp(variable,"service_description")){ temp_serviceescalation->service_description=strdup(value); if(temp_serviceescalation->service_description==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for serviceescalation service_description.\n"); #endif return ERROR; } } else if(!strcmp(variable,"contact_groups")){ temp_serviceescalation->contact_groups=strdup(value); if(temp_serviceescalation->contact_groups==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for serviceescalation contact_groups.\n"); #endif return ERROR; } } else if(!strcmp(variable,"first_notification")){ temp_serviceescalation->first_notification=atoi(value); temp_serviceescalation->have_first_notification=TRUE; } else if(!strcmp(variable,"last_notification")){ temp_serviceescalation->last_notification=atoi(value); temp_serviceescalation->have_last_notification=TRUE; } else if(!strcmp(variable,"notification_interval")){ temp_serviceescalation->notification_interval=atoi(value); temp_serviceescalation->have_notification_interval=TRUE; } else if(!strcmp(variable,"escalation_period")){ temp_serviceescalation->escalation_period=strdup(value); if(temp_serviceescalation->escalation_period==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for serviceescalation escalation_period.\n"); #endif return ERROR; } } else if(!strcmp(variable,"escalation_options")){ for(temp_ptr=strtok(value,", ");temp_ptr;temp_ptr=strtok(NULL,", ")){ if(!strcmp(temp_ptr,"w") || !strcmp(temp_ptr,"warning")) temp_serviceescalation->escalate_on_warning=TRUE; else if(!strcmp(temp_ptr,"u") || !strcmp(temp_ptr,"unknown")) temp_serviceescalation->escalate_on_unknown=TRUE; else if(!strcmp(temp_ptr,"c") || !strcmp(temp_ptr,"critical")) temp_serviceescalation->escalate_on_critical=TRUE; else if(!strcmp(temp_ptr,"r") || !strcmp(temp_ptr,"recovery")) temp_serviceescalation->escalate_on_recovery=TRUE; else if(!strcmp(temp_ptr,"n") || !strcmp(temp_ptr,"none")){ temp_serviceescalation->escalate_on_warning=FALSE; temp_serviceescalation->escalate_on_unknown=FALSE; temp_serviceescalation->escalate_on_critical=FALSE; temp_serviceescalation->escalate_on_recovery=FALSE; } else{ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Invalid escalation option '%s' in serviceescalation definition.\n",temp_ptr); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return ERROR; } } temp_serviceescalation->have_escalation_options=TRUE; } else if(!strcmp(variable,"register")) temp_serviceescalation->register_object=(atoi(value)>0)?TRUE:FALSE; else{ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Invalid serviceescalation object directive '%s'.\n",variable); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return ERROR; } break; case XODTEMPLATE_CONTACT: temp_contact=(xodtemplate_contact *)xodtemplate_current_object; if(!strcmp(variable,"use")){ temp_contact->template=strdup(value); if(temp_contact->template==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for contact template.\n"); #endif return ERROR; } } else if(!strcmp(variable,"name")){ #ifdef NSCORE /* check for duplicates */ if(xodtemplate_find_contact(value)!=NULL){ snprintf(temp_buffer,sizeof(temp_buffer)-1,"Warning: Duplicate definition found for contact '%s' (config file '%s', starting on line %d)\n",value,xodtemplate_config_file_name(temp_contact->_config_file),temp_contact->_start_line); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_WARNING,TRUE); } #endif temp_contact->name=strdup(value); if(temp_contact->name==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for contact name.\n"); #endif return ERROR; } } else if(!strcmp(variable,"contact_name")){ temp_contact->contact_name=strdup(value); if(temp_contact->contact_name==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for contact name.\n"); #endif return ERROR; } } else if(!strcmp(variable,"alias")){ temp_contact->alias=strdup(value); if(temp_contact->alias==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for contact alias.\n"); #endif return ERROR; } } else if(!strcmp(variable,"contactgroups")){ temp_contact->contactgroups=strdup(value); if(temp_contact->contactgroups==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for contact contactgroups.\n"); #endif return ERROR; } } else if(!strcmp(variable,"email")){ temp_contact->email=strdup(value); if(temp_contact->email==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for contact email.\n"); #endif return ERROR; } } else if(!strcmp(variable,"pager")){ temp_contact->pager=strdup(value); if(temp_contact->pager==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for contact pager.\n"); #endif return ERROR; } } else if(strstr(variable,"address")==variable){ x=atoi(variable+7); if(x<1 || x>MAX_XODTEMPLATE_CONTACT_ADDRESSES){ #ifdef DEBUG1 printf("Error: Invalid contact address id '%d'.\n",x); #endif return ERROR; } temp_contact->address[x-1]=strdup(value); if(temp_contact->address[x-1]==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for contact address #%d.\n",x); #endif return ERROR; } } else if(!strcmp(variable,"host_notification_period")){ temp_contact->host_notification_period=strdup(value); if(temp_contact->host_notification_period==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for contact host_notification_period.\n"); #endif return ERROR; } } else if(!strcmp(variable,"host_notification_commands")){ temp_contact->host_notification_commands=strdup(value); if(temp_contact->host_notification_commands==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for contact host_notification_commands.\n"); #endif return ERROR; } } else if(!strcmp(variable,"service_notification_period")){ temp_contact->service_notification_period=strdup(value); if(temp_contact->service_notification_period==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for contact service_notification_period.\n"); #endif return ERROR; } } else if(!strcmp(variable,"service_notification_commands")){ temp_contact->service_notification_commands=strdup(value); if(temp_contact->service_notification_commands==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for contact service_notification_commands.\n"); #endif return ERROR; } } else if(!strcmp(variable,"host_notification_period")){ temp_contact->host_notification_period=strdup(value); if(temp_contact->host_notification_period==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for contact host_notification_period.\n"); #endif return ERROR; } } else if(!strcmp(variable,"service_notification_period")){ temp_contact->service_notification_period=strdup(value); if(temp_contact->service_notification_period==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for contact service_notification_period.\n"); #endif return ERROR; } } else if(!strcmp(variable,"host_notification_options")){ for(temp_ptr=strtok(value,", ");temp_ptr;temp_ptr=strtok(NULL,", ")){ if(!strcmp(temp_ptr,"d") || !strcmp(temp_ptr,"down")) temp_contact->notify_on_host_down=TRUE; else if(!strcmp(temp_ptr,"u") || !strcmp(temp_ptr,"unreachable")) temp_contact->notify_on_host_unreachable=TRUE; else if(!strcmp(temp_ptr,"r") || !strcmp(temp_ptr,"recovery")) temp_contact->notify_on_host_recovery=TRUE; else if(!strcmp(temp_ptr,"f") || !strcmp(temp_ptr,"flapping")) temp_contact->notify_on_host_flapping=TRUE; else if(!strcmp(temp_ptr,"n") || !strcmp(temp_ptr,"none")){ temp_contact->notify_on_host_down=FALSE; temp_contact->notify_on_host_unreachable=FALSE; temp_contact->notify_on_host_recovery=FALSE; temp_contact->notify_on_host_flapping=FALSE; } else{ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Invalid host notification option '%s' in contact definition.\n",temp_ptr); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return ERROR; } } temp_contact->have_host_notification_options=TRUE; } else if(!strcmp(variable,"service_notification_options")){ for(temp_ptr=strtok(value,", ");temp_ptr;temp_ptr=strtok(NULL,", ")){ if(!strcmp(temp_ptr,"u") || !strcmp(temp_ptr,"unknown")) temp_contact->notify_on_service_unknown=TRUE; else if(!strcmp(temp_ptr,"w") || !strcmp(temp_ptr,"warning")) temp_contact->notify_on_service_warning=TRUE; else if(!strcmp(temp_ptr,"c") || !strcmp(temp_ptr,"critical")) temp_contact->notify_on_service_critical=TRUE; else if(!strcmp(temp_ptr,"r") || !strcmp(temp_ptr,"recovery")) temp_contact->notify_on_service_recovery=TRUE; else if(!strcmp(temp_ptr,"f") || !strcmp(temp_ptr,"flapping")) temp_contact->notify_on_service_flapping=TRUE; else if(!strcmp(temp_ptr,"n") || !strcmp(temp_ptr,"none")){ temp_contact->notify_on_service_unknown=FALSE; temp_contact->notify_on_service_warning=FALSE; temp_contact->notify_on_service_critical=FALSE; temp_contact->notify_on_service_recovery=FALSE; temp_contact->notify_on_service_flapping=FALSE; } else{ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Invalid service notification option '%s' in contact definition.\n",temp_ptr); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return ERROR; } } temp_contact->have_service_notification_options=TRUE; } else if(!strcmp(variable,"register")) temp_contact->register_object=(atoi(value)>0)?TRUE:FALSE; else{ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Invalid contact object directive '%s'.\n",variable); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return ERROR; } break; case XODTEMPLATE_HOST: temp_host=(xodtemplate_host *)xodtemplate_current_object; if(!strcmp(variable,"use")){ temp_host->template=strdup(value); if(temp_host->template==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for host template.\n"); #endif return ERROR; } } else if(!strcmp(variable,"name")){ #ifdef NSCORE /* check for duplicates */ if(xodtemplate_find_host(value)!=NULL){ snprintf(temp_buffer,sizeof(temp_buffer)-1,"Warning: Duplicate definition found for host '%s' (config file '%s', starting on line %d)\n",value,xodtemplate_config_file_name(temp_host->_config_file),temp_host->_start_line); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_WARNING,TRUE); } #endif temp_host->name=strdup(value); if(temp_host->name==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for host name.\n"); #endif return ERROR; } } else if(!strcmp(variable,"host_name")){ temp_host->host_name=strdup(value); if(temp_host->host_name==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for host name.\n"); #endif return ERROR; } } else if(!strcmp(variable,"alias")){ temp_host->alias=strdup(value); if(temp_host->alias==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for host alias.\n"); #endif return ERROR; } } else if(!strcmp(variable,"address")){ temp_host->address=strdup(value); if(temp_host->address==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for host address.\n"); #endif return ERROR; } } else if(!strcmp(variable,"parents")){ temp_host->parents=strdup(value); if(temp_host->parents==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for host parents.\n"); #endif return ERROR; } } else if(!strcmp(variable,"hostgroups")){ temp_host->hostgroups=strdup(value); if(temp_host->hostgroups==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for host hostgroups.\n"); #endif return ERROR; } } else if(!strcmp(variable,"contact_groups")){ temp_host->contact_groups=strdup(value); if(temp_host->contact_groups==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for host contact_groups.\n"); #endif return ERROR; } } else if(!strcmp(variable,"notification_period")){ temp_host->notification_period=strdup(value); if(temp_host->notification_period==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for host notification_period.\n"); #endif return ERROR; } } else if(!strcmp(variable,"check_command")){ temp_host->check_command=strdup(value); if(temp_host->check_command==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for host check_command.\n"); #endif return ERROR; } } else if(!strcmp(variable,"check_period")){ temp_host->check_period=strdup(value); if(temp_host->check_period==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for host check_period.\n"); #endif return ERROR; } } else if(!strcmp(variable,"event_handler")){ temp_host->event_handler=strdup(value); if(temp_host->event_handler==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for host event_handler.\n"); #endif return ERROR; } } else if(!strcmp(variable,"failure_prediction_options")){ temp_host->failure_prediction_options=strdup(value); if(temp_host->failure_prediction_options==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for host failure_prediction_options.\n"); #endif return ERROR; } } else if(!strcmp(variable,"check_interval") || !strcmp(variable,"normal_check_interval")){ temp_host->check_interval=atoi(value); temp_host->have_check_interval=TRUE; } else if(!strcmp(variable,"max_check_attempts")){ temp_host->max_check_attempts=atoi(value); temp_host->have_max_check_attempts=TRUE; } else if(!strcmp(variable,"checks_enabled") || !strcmp(variable,"active_checks_enabled")){ temp_host->active_checks_enabled=(atoi(value)>0)?TRUE:FALSE; temp_host->have_active_checks_enabled=TRUE; } else if(!strcmp(variable,"passive_checks_enabled")){ temp_host->passive_checks_enabled=(atoi(value)>0)?TRUE:FALSE; temp_host->have_passive_checks_enabled=TRUE; } else if(!strcmp(variable,"event_handler_enabled")){ temp_host->event_handler_enabled=(atoi(value)>0)?TRUE:FALSE; temp_host->have_event_handler_enabled=TRUE; } else if(!strcmp(variable,"check_freshness")){ temp_host->check_freshness=(atoi(value)>0)?TRUE:FALSE; temp_host->have_check_freshness=TRUE; } else if(!strcmp(variable,"freshness_threshold")){ temp_host->freshness_threshold=atoi(value); temp_host->have_freshness_threshold=TRUE; } else if(!strcmp(variable,"low_flap_threshold")){ temp_host->low_flap_threshold=strtod(value,NULL); temp_host->have_low_flap_threshold=TRUE; } else if(!strcmp(variable,"high_flap_threshold")){ temp_host->high_flap_threshold=strtod(value,NULL); temp_host->have_high_flap_threshold=TRUE; } else if(!strcmp(variable,"flap_detection_enabled")){ temp_host->flap_detection_enabled=(atoi(value)>0)?TRUE:FALSE; temp_host->have_flap_detection_enabled=TRUE; } else if(!strcmp(variable,"notification_options")){ for(temp_ptr=strtok(value,", ");temp_ptr;temp_ptr=strtok(NULL,", ")){ if(!strcmp(temp_ptr,"d") || !strcmp(temp_ptr,"down")) temp_host->notify_on_down=TRUE; else if(!strcmp(temp_ptr,"u") || !strcmp(temp_ptr,"unreachable")) temp_host->notify_on_unreachable=TRUE; else if(!strcmp(temp_ptr,"r") || !strcmp(temp_ptr,"recovery")) temp_host->notify_on_recovery=TRUE; else if(!strcmp(temp_ptr,"f") || !strcmp(temp_ptr,"flapping")) temp_host->notify_on_flapping=TRUE; else if(!strcmp(temp_ptr,"n") || !strcmp(temp_ptr,"none")){ temp_host->notify_on_down=FALSE; temp_host->notify_on_unreachable=FALSE; temp_host->notify_on_recovery=FALSE; temp_host->notify_on_flapping=FALSE; } else{ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Invalid notification option '%s' in host definition.\n",temp_ptr); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return ERROR; } } temp_host->have_notification_options=TRUE; } else if(!strcmp(variable,"notifications_enabled")){ temp_host->notifications_enabled=(atoi(value)>0)?TRUE:FALSE; temp_host->have_notifications_enabled=TRUE; } else if(!strcmp(variable,"notification_interval")){ temp_host->notification_interval=atoi(value); temp_host->have_notification_interval=TRUE; } else if(!strcmp(variable,"stalking_options")){ for(temp_ptr=strtok(value,", ");temp_ptr;temp_ptr=strtok(NULL,", ")){ if(!strcmp(temp_ptr,"o") || !strcmp(temp_ptr,"up")) temp_host->stalk_on_up=TRUE; else if(!strcmp(temp_ptr,"d") || !strcmp(temp_ptr,"down")) temp_host->stalk_on_down=TRUE; else if(!strcmp(temp_ptr,"u") || !strcmp(temp_ptr,"unreachable")) temp_host->stalk_on_unreachable=TRUE; else if(!strcmp(temp_ptr,"n") || !strcmp(temp_ptr,"none")){ temp_host->stalk_on_up=FALSE; temp_host->stalk_on_down=FALSE; temp_host->stalk_on_unreachable=FALSE; } else{ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Invalid stalking option '%s' in host definition.\n",temp_ptr); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return ERROR; } } temp_host->have_stalking_options=TRUE; } else if(!strcmp(variable,"process_perf_data")){ temp_host->process_perf_data=(atoi(value)>0)?TRUE:FALSE; temp_host->have_process_perf_data=TRUE; } else if(!strcmp(variable,"failure_prediction_enabled")){ temp_host->failure_prediction_enabled=(atoi(value)>0)?TRUE:FALSE; temp_host->have_failure_prediction_enabled=TRUE; } else if(!strcmp(variable,"obsess_over_host")){ temp_host->obsess_over_host=(atoi(value)>0)?TRUE:FALSE; temp_host->have_obsess_over_host=TRUE; } else if(!strcmp(variable,"retain_status_information")){ temp_host->retain_status_information=(atoi(value)>0)?TRUE:FALSE; temp_host->have_retain_status_information=TRUE; } else if(!strcmp(variable,"retain_nonstatus_information")){ temp_host->retain_nonstatus_information=(atoi(value)>0)?TRUE:FALSE; temp_host->have_retain_nonstatus_information=TRUE; } else if(!strcmp(variable,"register")) temp_host->register_object=(atoi(value)>0)?TRUE:FALSE; else{ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Invalid host object directive '%s'.\n",variable); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return ERROR; } break; case XODTEMPLATE_SERVICE: temp_service=(xodtemplate_service *)xodtemplate_current_object; if(!strcmp(variable,"use")){ temp_service->template=strdup(value); if(temp_service->template==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for service template.\n"); #endif return ERROR; } } else if(!strcmp(variable,"name")){ #ifdef NSCORE /* check for duplicates */ if(xodtemplate_find_service(value)!=NULL){ snprintf(temp_buffer,sizeof(temp_buffer)-1,"Warning: Duplicate definition found for service '%s' (config file '%s', starting on line %d)\n",value,xodtemplate_config_file_name(temp_service->_config_file),temp_service->_start_line); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_WARNING,TRUE); } #endif temp_service->name=strdup(value); if(temp_service->name==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for service name.\n"); #endif return ERROR; } } else if(!strcmp(variable,"hostgroup") || !strcmp(variable,"hostgroups") || !strcmp(variable,"hostgroup_name")){ temp_service->hostgroup_name=strdup(value); if(temp_service->hostgroup_name==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for service hostgroup.\n"); #endif return ERROR; } } else if(!strcmp(variable,"host") || !strcmp(variable,"hosts") || !strcmp(variable,"host_name")){ temp_service->host_name=strdup(value); if(temp_service->host_name==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for service host.\n"); #endif return ERROR; } } else if(!strcmp(variable,"service_description") || !strcmp(variable,"description")){ temp_service->service_description=strdup(value); if(temp_service->service_description==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for service service_description.\n"); #endif return ERROR; } } else if(!strcmp(variable,"servicegroups")){ temp_service->servicegroups=strdup(value); if(temp_service->servicegroups==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for service servicegroups.\n"); #endif return ERROR; } } else if(!strcmp(variable,"check_command")){ temp_service->check_command=strdup(value); if(temp_service->check_command==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for service check_command.\n"); #endif return ERROR; } } else if(!strcmp(variable,"check_period")){ temp_service->check_period=strdup(value); if(temp_service->check_period==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for service check_period.\n"); #endif return ERROR; } } else if(!strcmp(variable,"event_handler")){ temp_service->event_handler=strdup(value); if(temp_service->event_handler==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for service event_handler.\n"); #endif return ERROR; } } else if(!strcmp(variable,"notification_period")){ temp_service->notification_period=strdup(value); if(temp_service->notification_period==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for service notification_period.\n"); #endif return ERROR; } } else if(!strcmp(variable,"contact_groups")){ temp_service->contact_groups=strdup(value); if(temp_service->contact_groups==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for service contact_groups.\n"); #endif return ERROR; } } else if(!strcmp(variable,"failure_prediction_options")){ temp_service->failure_prediction_options=strdup(value); if(temp_service->failure_prediction_options==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for service failure_prediction_options.\n"); #endif return ERROR; } } else if(!strcmp(variable,"max_check_attempts")){ temp_service->max_check_attempts=atoi(value); temp_service->have_max_check_attempts=TRUE; } else if(!strcmp(variable,"normal_check_interval")){ temp_service->normal_check_interval=atoi(value); temp_service->have_normal_check_interval=TRUE; } else if(!strcmp(variable,"retry_check_interval")){ temp_service->retry_check_interval=atoi(value); temp_service->have_retry_check_interval=TRUE; } else if(!strcmp(variable,"active_checks_enabled")){ temp_service->active_checks_enabled=(atoi(value)>0)?TRUE:FALSE; temp_service->have_active_checks_enabled=TRUE; } else if(!strcmp(variable,"passive_checks_enabled")){ temp_service->passive_checks_enabled=(atoi(value)>0)?TRUE:FALSE; temp_service->have_passive_checks_enabled=TRUE; } else if(!strcmp(variable,"parallelize_check")){ temp_service->parallelize_check=atoi(value); temp_service->have_parallelize_check=TRUE; } else if(!strcmp(variable,"is_volatile")){ temp_service->is_volatile=(atoi(value)>0)?TRUE:FALSE; temp_service->have_is_volatile=TRUE; } else if(!strcmp(variable,"obsess_over_service")){ temp_service->obsess_over_service=(atoi(value)>0)?TRUE:FALSE; temp_service->have_obsess_over_service=TRUE; } else if(!strcmp(variable,"event_handler_enabled")){ temp_service->event_handler_enabled=(atoi(value)>0)?TRUE:FALSE; temp_service->have_event_handler_enabled=TRUE; } else if(!strcmp(variable,"check_freshness")){ temp_service->check_freshness=(atoi(value)>0)?TRUE:FALSE; temp_service->have_check_freshness=TRUE; } else if(!strcmp(variable,"freshness_threshold")){ temp_service->freshness_threshold=atoi(value); temp_service->have_freshness_threshold=TRUE; } else if(!strcmp(variable,"low_flap_threshold")){ temp_service->low_flap_threshold=strtod(value,NULL); temp_service->have_low_flap_threshold=TRUE; } else if(!strcmp(variable,"high_flap_threshold")){ temp_service->high_flap_threshold=strtod(value,NULL); temp_service->have_high_flap_threshold=TRUE; } else if(!strcmp(variable,"flap_detection_enabled")){ temp_service->flap_detection_enabled=(atoi(value)>0)?TRUE:FALSE; temp_service->have_flap_detection_enabled=TRUE; } else if(!strcmp(variable,"notification_options")){ for(temp_ptr=strtok(value,", ");temp_ptr;temp_ptr=strtok(NULL,", ")){ if(!strcmp(temp_ptr,"u") || !strcmp(temp_ptr,"unknown")) temp_service->notify_on_unknown=TRUE; else if(!strcmp(temp_ptr,"w") || !strcmp(temp_ptr,"warning")) temp_service->notify_on_warning=TRUE; else if(!strcmp(temp_ptr,"c") || !strcmp(temp_ptr,"critical")) temp_service->notify_on_critical=TRUE; else if(!strcmp(temp_ptr,"r") || !strcmp(temp_ptr,"recovery")) temp_service->notify_on_recovery=TRUE; else if(!strcmp(temp_ptr,"f") || !strcmp(temp_ptr,"flapping")) temp_service->notify_on_flapping=TRUE; else if(!strcmp(temp_ptr,"n") || !strcmp(temp_ptr,"none")){ temp_service->notify_on_unknown=FALSE; temp_service->notify_on_warning=FALSE; temp_service->notify_on_critical=FALSE; temp_service->notify_on_recovery=FALSE; temp_service->notify_on_flapping=FALSE; } else{ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Invalid notification option '%s' in service definition.\n",temp_ptr); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return ERROR; } } temp_service->have_notification_options=TRUE; } else if(!strcmp(variable,"notifications_enabled")){ temp_service->notifications_enabled=(atoi(value)>0)?TRUE:FALSE; temp_service->have_notifications_enabled=TRUE; } else if(!strcmp(variable,"notification_interval")){ temp_service->notification_interval=atoi(value); temp_service->have_notification_interval=TRUE; } else if(!strcmp(variable,"stalking_options")){ for(temp_ptr=strtok(value,", ");temp_ptr;temp_ptr=strtok(NULL,", ")){ if(!strcmp(temp_ptr,"o") || !strcmp(temp_ptr,"ok")) temp_service->stalk_on_ok=TRUE; else if(!strcmp(temp_ptr,"w") || !strcmp(temp_ptr,"warning")) temp_service->stalk_on_warning=TRUE; else if(!strcmp(temp_ptr,"u") || !strcmp(temp_ptr,"unknown")) temp_service->stalk_on_unknown=TRUE; else if(!strcmp(temp_ptr,"c") || !strcmp(temp_ptr,"critical")) temp_service->stalk_on_critical=TRUE; else if(!strcmp(temp_ptr,"n") || !strcmp(temp_ptr,"none")){ temp_service->stalk_on_ok=FALSE; temp_service->stalk_on_warning=FALSE; temp_service->stalk_on_unknown=FALSE; temp_service->stalk_on_critical=FALSE; } else{ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Invalid stalking option '%s' in service definition.\n",temp_ptr); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return ERROR; } } temp_service->have_stalking_options=TRUE; } else if(!strcmp(variable,"process_perf_data")){ temp_service->process_perf_data=(atoi(value)>0)?TRUE:FALSE; temp_service->have_process_perf_data=TRUE; } else if(!strcmp(variable,"failure_prediction_enabled")){ temp_service->failure_prediction_enabled=(atoi(value)>0)?TRUE:FALSE; temp_service->have_failure_prediction_enabled=TRUE; } else if(!strcmp(variable,"retain_status_information")){ temp_service->retain_status_information=(atoi(value)>0)?TRUE:FALSE; temp_service->have_retain_status_information=TRUE; } else if(!strcmp(variable,"retain_nonstatus_information")){ temp_service->retain_nonstatus_information=(atoi(value)>0)?TRUE:FALSE; temp_service->have_retain_nonstatus_information=TRUE; } else if(!strcmp(variable,"register")) temp_service->register_object=(atoi(value)>0)?TRUE:FALSE; else{ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Invalid service object directive '%s'.\n",variable); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return ERROR; } break; case XODTEMPLATE_HOSTDEPENDENCY: temp_hostdependency=(xodtemplate_hostdependency *)xodtemplate_current_object; if(!strcmp(variable,"use")){ temp_hostdependency->template=strdup(value); if(temp_hostdependency->template==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for hostdependency template.\n"); #endif return ERROR; } } else if(!strcmp(variable,"name")){ #ifdef NSCORE /* check for duplicates */ if(xodtemplate_find_hostdependency(value)!=NULL){ snprintf(temp_buffer,sizeof(temp_buffer)-1,"Warning: Duplicate definition found for host dependency '%s' (config file '%s', starting on line %d)\n",value,xodtemplate_config_file_name(temp_hostdependency->_config_file),temp_hostdependency->_start_line); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_WARNING,TRUE); } #endif temp_hostdependency->name=strdup(value); if(temp_hostdependency->name==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for hostdependency name.\n"); #endif return ERROR; } } else if(!strcmp(variable,"hostgroup") || !strcmp(variable,"hostgroups") || !strcmp(variable,"hostgroup_name")){ temp_hostdependency->hostgroup_name=strdup(value); if(temp_hostdependency->hostgroup_name==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for hostdependency hostgroup.\n"); #endif return ERROR; } } else if(!strcmp(variable,"host") || !strcmp(variable,"host_name") || !strcmp(variable,"master_host") || !strcmp(variable,"master_host_name")){ temp_hostdependency->host_name=strdup(value); if(temp_hostdependency->host_name==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for hostdependency host.\n"); #endif return ERROR; } } else if(!strcmp(variable,"dependent_hostgroup") || !strcmp(variable,"dependent_hostgroups") || !strcmp(variable,"dependent_hostgroup_name")){ temp_hostdependency->dependent_hostgroup_name=strdup(value); if(temp_hostdependency->dependent_hostgroup_name==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for hostdependency dependent hostgroup.\n"); #endif return ERROR; } } else if(!strcmp(variable,"dependent_host") || !strcmp(variable,"dependent_host_name")){ temp_hostdependency->dependent_host_name=strdup(value); if(temp_hostdependency->dependent_host_name==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for hostdependency dependent host.\n"); #endif return ERROR; } } else if(!strcmp(variable,"inherits_parent")){ temp_hostdependency->inherits_parent=(atoi(value)>0)?TRUE:FALSE; temp_hostdependency->have_inherits_parent=TRUE; } else if(!strcmp(variable,"notification_failure_options") || !strcmp(variable,"notification_failure_criteria")){ for(temp_ptr=strtok(value,", ");temp_ptr;temp_ptr=strtok(NULL,", ")){ if(!strcmp(temp_ptr,"o") || !strcmp(temp_ptr,"up")) temp_hostdependency->fail_notify_on_up=TRUE; else if(!strcmp(temp_ptr,"d") || !strcmp(temp_ptr,"down")) temp_hostdependency->fail_notify_on_down=TRUE; else if(!strcmp(temp_ptr,"u") || !strcmp(temp_ptr,"unreachable")) temp_hostdependency->fail_notify_on_unreachable=TRUE; else if(!strcmp(temp_ptr,"p") || !strcmp(temp_ptr,"pending")) temp_hostdependency->fail_notify_on_pending=TRUE; else if(!strcmp(temp_ptr,"n") || !strcmp(temp_ptr,"none")){ temp_hostdependency->fail_notify_on_up=FALSE; temp_hostdependency->fail_notify_on_down=FALSE; temp_hostdependency->fail_notify_on_unreachable=FALSE; temp_hostdependency->fail_notify_on_pending=FALSE; } else{ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Invalid notification dependency option '%s' in hostdependency definition.\n",temp_ptr); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return ERROR; } } temp_hostdependency->have_notification_dependency_options=TRUE; } else if(!strcmp(variable,"execution_failure_options") || !strcmp(variable,"execution_failure_criteria")){ for(temp_ptr=strtok(value,", ");temp_ptr;temp_ptr=strtok(NULL,", ")){ if(!strcmp(temp_ptr,"o") || !strcmp(temp_ptr,"up")) temp_hostdependency->fail_execute_on_up=TRUE; else if(!strcmp(temp_ptr,"d") || !strcmp(temp_ptr,"down")) temp_hostdependency->fail_execute_on_down=TRUE; else if(!strcmp(temp_ptr,"u") || !strcmp(temp_ptr,"unreachable")) temp_hostdependency->fail_execute_on_unreachable=TRUE; else if(!strcmp(temp_ptr,"p") || !strcmp(temp_ptr,"pending")) temp_hostdependency->fail_execute_on_pending=TRUE; else if(!strcmp(temp_ptr,"n") || !strcmp(temp_ptr,"none")){ temp_hostdependency->fail_execute_on_up=FALSE; temp_hostdependency->fail_execute_on_down=FALSE; temp_hostdependency->fail_execute_on_unreachable=FALSE; temp_hostdependency->fail_execute_on_pending=FALSE; } else{ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Invalid execution dependency option '%s' in hostdependency definition.\n",temp_ptr); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return ERROR; } } temp_hostdependency->have_execution_dependency_options=TRUE; } else if(!strcmp(variable,"register")) temp_hostdependency->register_object=(atoi(value)>0)?TRUE:FALSE; else{ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Invalid hostdependency object directive '%s'.\n",variable); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return ERROR; } break; case XODTEMPLATE_HOSTESCALATION: temp_hostescalation=(xodtemplate_hostescalation *)xodtemplate_current_object; if(!strcmp(variable,"use")){ temp_hostescalation->template=strdup(value); if(temp_hostescalation->template==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for hostescalation template.\n"); #endif return ERROR; } } else if(!strcmp(variable,"name")){ #ifdef NSCORE /* check for duplicates */ if(xodtemplate_find_hostescalation(value)!=NULL){ snprintf(temp_buffer,sizeof(temp_buffer)-1,"Warning: Duplicate definition found for host escalation '%s' (config file '%s', starting on line %d)\n",value,xodtemplate_config_file_name(temp_hostescalation->_config_file),temp_hostescalation->_start_line); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_WARNING,TRUE); } #endif temp_hostescalation->name=strdup(value); if(temp_hostescalation->name==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for hostescalation name.\n"); #endif return ERROR; } } else if(!strcmp(variable,"hostgroup") || !strcmp(variable,"hostgroups") || !strcmp(variable,"hostgroup_name")){ temp_hostescalation->hostgroup_name=strdup(value); if(temp_hostescalation->hostgroup_name==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for hostescalation hostgroup.\n"); #endif return ERROR; } } else if(!strcmp(variable,"host") || !strcmp(variable,"host_name")){ temp_hostescalation->host_name=strdup(value); if(temp_hostescalation->host_name==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for hostescalation host.\n"); #endif return ERROR; } } else if(!strcmp(variable,"contact_groups")){ temp_hostescalation->contact_groups=strdup(value); if(temp_hostescalation->contact_groups==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for hostescalation contact_groups.\n"); #endif return ERROR; } } else if(!strcmp(variable,"first_notification")){ temp_hostescalation->first_notification=atoi(value); temp_hostescalation->have_first_notification=TRUE; } else if(!strcmp(variable,"last_notification")){ temp_hostescalation->last_notification=atoi(value); temp_hostescalation->have_last_notification=TRUE; } else if(!strcmp(variable,"notification_interval")){ temp_hostescalation->notification_interval=atoi(value); temp_hostescalation->have_notification_interval=TRUE; } else if(!strcmp(variable,"escalation_period")){ temp_hostescalation->escalation_period=strdup(value); if(temp_hostescalation->escalation_period==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for hostescalation escalation_period.\n"); #endif return ERROR; } } else if(!strcmp(variable,"escalation_options")){ for(temp_ptr=strtok(value,", ");temp_ptr;temp_ptr=strtok(NULL,", ")){ if(!strcmp(temp_ptr,"d") || !strcmp(temp_ptr,"down")) temp_hostescalation->escalate_on_down=TRUE; else if(!strcmp(temp_ptr,"u") || !strcmp(temp_ptr,"unreachable")) temp_hostescalation->escalate_on_unreachable=TRUE; else if(!strcmp(temp_ptr,"r") || !strcmp(temp_ptr,"recovery")) temp_hostescalation->escalate_on_recovery=TRUE; else if(!strcmp(temp_ptr,"n") || !strcmp(temp_ptr,"none")){ temp_hostescalation->escalate_on_down=FALSE; temp_hostescalation->escalate_on_unreachable=FALSE; temp_hostescalation->escalate_on_recovery=FALSE; } else{ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Invalid escalation option '%s' in hostescalation definition.\n",temp_ptr); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return ERROR; } } temp_hostescalation->have_escalation_options=TRUE; } else if(!strcmp(variable,"register")) temp_hostescalation->register_object=(atoi(value)>0)?TRUE:FALSE; else{ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Invalid hostescalation object directive '%s'.\n",variable); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return ERROR; } break; case XODTEMPLATE_HOSTEXTINFO: temp_hostextinfo=xodtemplate_hostextinfo_list; if(!strcmp(variable,"use")){ temp_hostextinfo->template=strdup(value); if(temp_hostextinfo->template==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for extended host info template.\n"); #endif return ERROR; } } else if(!strcmp(variable,"name")){ #ifdef NSCORE /* check for duplicates */ if(xodtemplate_find_hostextinfo(value)!=NULL){ snprintf(temp_buffer,sizeof(temp_buffer)-1,"Warning: Duplicate definition found for extended host info '%s' (config file '%s', starting on line %d)\n",value,xodtemplate_config_file_name(temp_hostextinfo->_config_file),temp_hostextinfo->_start_line); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_WARNING,TRUE); } #endif temp_hostextinfo->name=strdup(value); if(temp_hostextinfo->name==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for extended host info name.\n"); #endif return ERROR; } } else if(!strcmp(variable,"host_name")){ temp_hostextinfo->host_name=(char *)malloc(strlen(value)+1); if(temp_hostextinfo->host_name==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for extended host info host_name.\n"); #endif return ERROR; } strcpy(temp_hostextinfo->host_name,value); } else if(!strcmp(variable,"hostgroup") || !strcmp(variable,"hostgroup_name")){ temp_hostextinfo->hostgroup_name=strdup(value); if(temp_hostextinfo->hostgroup_name==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for extended host info hostgroup_name.\n"); #endif return ERROR; } } else if(!strcmp(variable,"notes")){ temp_hostextinfo->notes=strdup(value); if(temp_hostextinfo->notes==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for extended host info notes.\n"); #endif return ERROR; } } else if(!strcmp(variable,"notes_url")){ temp_hostextinfo->notes_url=strdup(value); if(temp_hostextinfo->notes_url==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for extended host info notes_url.\n"); #endif return ERROR; } } else if(!strcmp(variable,"action_url")){ temp_hostextinfo->action_url=strdup(value); if(temp_hostextinfo->action_url==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for extended host info action_url.\n"); #endif return ERROR; } } else if(!strcmp(variable,"icon_image")){ temp_hostextinfo->icon_image=strdup(value); if(temp_hostextinfo->icon_image==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for extended host info icon_image.\n"); #endif return ERROR; } } else if(!strcmp(variable,"icon_image_alt")){ temp_hostextinfo->icon_image_alt=strdup(value); if(temp_hostextinfo->icon_image_alt==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for extended host info icon_image_alt.\n"); #endif return ERROR; } } else if(!strcmp(variable,"vrml_image")){ temp_hostextinfo->vrml_image=strdup(value); if(temp_hostextinfo->vrml_image==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for extended host info vrml_image.\n"); #endif return ERROR; } } else if(!strcmp(variable,"gd2_image")|| !strcmp(variable,"statusmap_image")){ temp_hostextinfo->statusmap_image=strdup(value); if(temp_hostextinfo->statusmap_image==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for extended host info statusmap_image.\n"); #endif return ERROR; } } else if(!strcmp(variable,"2d_coords")){ temp_ptr=strtok(value,", "); if(temp_ptr==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Invalid 2d_coords value '%s' in extended host info definition.\n",temp_ptr); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return ERROR; } temp_hostextinfo->x_2d=atoi(temp_ptr); temp_ptr=strtok(NULL,", "); if(temp_ptr==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Invalid 2d_coords value '%s' in extended host info definition.\n",temp_ptr); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return ERROR; } temp_hostextinfo->y_2d=atoi(temp_ptr); temp_hostextinfo->have_2d_coords=TRUE; } else if(!strcmp(variable,"3d_coords")){ temp_ptr=strtok(value,", "); if(temp_ptr==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Invalid 3d_coords value '%s' in extended host info definition.\n",temp_ptr); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return ERROR; } temp_hostextinfo->x_3d=strtod(temp_ptr,NULL); temp_ptr=strtok(NULL,", "); if(temp_ptr==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Invalid 3d_coords value '%s' in extended host info definition.\n",temp_ptr); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return ERROR; } temp_hostextinfo->y_3d=strtod(temp_ptr,NULL); temp_ptr=strtok(NULL,", "); if(temp_ptr==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Invalid 3d_coords value '%s' in extended host info definition.\n",temp_ptr); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return ERROR; } temp_hostextinfo->z_3d=strtod(temp_ptr,NULL); temp_hostextinfo->have_3d_coords=TRUE; } else if(!strcmp(variable,"register")) temp_hostextinfo->register_object=(atoi(value)>0)?TRUE:FALSE; else{ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Invalid hostextinfo object directive '%s'.\n",variable); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return ERROR; } break; case XODTEMPLATE_SERVICEEXTINFO: temp_serviceextinfo=xodtemplate_serviceextinfo_list; if(!strcmp(variable,"use")){ temp_serviceextinfo->template=strdup(value); if(temp_serviceextinfo->template==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for extended service info template.\n"); #endif return ERROR; } } else if(!strcmp(variable,"name")){ #ifdef NSCORE /* check for duplicates */ if(xodtemplate_find_serviceextinfo(value)!=NULL){ snprintf(temp_buffer,sizeof(temp_buffer)-1,"Warning: Duplicate definition found for extended service info '%s' (config file '%s', starting on line %d)\n",value,xodtemplate_config_file_name(temp_serviceextinfo->_config_file),temp_serviceextinfo->_start_line); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_WARNING,TRUE); } #endif temp_serviceextinfo->name=strdup(value); if(temp_serviceextinfo->name==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for extended service info name.\n"); #endif return ERROR; } } else if(!strcmp(variable,"host_name")){ temp_serviceextinfo->host_name=strdup(value); if(temp_serviceextinfo->host_name==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for extended service info host_name.\n"); #endif return ERROR; } } else if(!strcmp(variable,"hostgroup") || !strcmp(variable,"hostgroup_name")){ temp_serviceextinfo->hostgroup_name=strdup(value); if(temp_serviceextinfo->hostgroup_name==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for extended service info hostgroup_name.\n"); #endif return ERROR; } } else if(!strcmp(variable,"service_description")){ temp_serviceextinfo->service_description=strdup(value); if(temp_serviceextinfo->service_description==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for extended service info service_description.\n"); #endif return ERROR; } } else if(!strcmp(variable,"notes")){ temp_serviceextinfo->notes=strdup(value); if(temp_serviceextinfo->notes==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for extended service info notes.\n"); #endif return ERROR; } } else if(!strcmp(variable,"notes_url")){ temp_serviceextinfo->notes_url=strdup(value); if(temp_serviceextinfo->notes_url==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for extended service info notes_url.\n"); #endif return ERROR; } } else if(!strcmp(variable,"action_url")){ temp_serviceextinfo->action_url=strdup(value); if(temp_serviceextinfo->action_url==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for extended service info action_url.\n"); #endif return ERROR; } } else if(!strcmp(variable,"icon_image")){ temp_serviceextinfo->icon_image=strdup(value); if(temp_serviceextinfo->icon_image==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for extended service info icon_image.\n"); #endif return ERROR; } } else if(!strcmp(variable,"icon_image_alt")){ temp_serviceextinfo->icon_image_alt=strdup(value); if(temp_serviceextinfo->icon_image_alt==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for extended service info icon_image_alt.\n"); #endif return ERROR; } } else if(!strcmp(variable,"register")) temp_serviceextinfo->register_object=(atoi(value)>0)?TRUE:FALSE; else{ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Invalid serviceextinfo object directive '%s'.\n",variable); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return ERROR; } break; default: return ERROR; break; } /* free memory */ free(variable); free(value); #ifdef DEBUG0 printf("xodtemplate_add_object_property() end\n"); #endif return result; } /* completes an object definition */ int xodtemplate_end_object_definition(int options){ int result=OK; #ifdef DEBUG0 printf("xodtemplate_end_object_definition() start\n"); #endif xodtemplate_current_object=NULL; xodtemplate_current_object_type=XODTEMPLATE_NONE; #ifdef DEBUG0 printf("xodtemplate_end_object_definition() end\n"); #endif return result; } /******************************************************************/ /***************** OBJECT DUPLICATION FUNCTIONS *******************/ /******************************************************************/ #ifdef NSCORE /* duplicates service definitions */ int xodtemplate_duplicate_services(void){ int result=OK; xodtemplate_service *temp_service; xodtemplate_hostlist *temp_hostlist; xodtemplate_hostlist *this_hostlist; char *host_name=""; int first_item; #ifdef NSCORE char temp_buffer[MAX_XODTEMPLATE_INPUT_BUFFER]; #endif #ifdef DEBUG0 printf("xodtemplate_duplicate_services() start\n"); #endif /****** DUPLICATE SERVICE DEFINITIONS WITH ONE OR MORE HOSTGROUP AND/OR HOST NAMES ******/ for(temp_service=xodtemplate_service_list;temp_service!=NULL;temp_service=temp_service->next){ /* skip service definitions without enough data */ if(temp_service->hostgroup_name==NULL && temp_service->host_name==NULL) continue; /* skip services that shouldn't be registered */ if(temp_service->register_object==FALSE) continue; /* get list of hosts */ temp_hostlist=xodtemplate_expand_hostgroups_and_hosts(temp_service->hostgroup_name,temp_service->host_name); if(temp_hostlist==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not expand hostgroups and/or hosts specified in service (config file '%s', starting on line %d)\n",xodtemplate_config_file_name(temp_service->_config_file),temp_service->_start_line); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return ERROR; } /* add a copy of the service for every host in the hostgroup/host name list */ first_item=TRUE; for(this_hostlist=temp_hostlist;this_hostlist!=NULL;this_hostlist=this_hostlist->next){ /* if this is the first duplication, use the existing entry */ if(first_item==TRUE){ free(temp_service->host_name); temp_service->host_name=strdup(this_hostlist->host_name); if(temp_service->host_name==NULL){ xodtemplate_free_hostlist(temp_hostlist); return ERROR; } first_item=FALSE; continue; } /* duplicate service definition */ result=xodtemplate_duplicate_service(temp_service,this_hostlist->host_name); /* exit on error */ if(result==ERROR){ free(host_name); return ERROR; } } /* free memory we used for host list */ xodtemplate_free_hostlist(temp_hostlist); } #ifdef DEBUG0 printf("xodtemplate_duplicate_services() end\n"); #endif return OK; } /* duplicates object definitions */ int xodtemplate_duplicate_objects(void){ int result=OK; xodtemplate_hostescalation *temp_hostescalation; xodtemplate_serviceescalation *temp_serviceescalation; xodtemplate_hostdependency *temp_hostdependency; xodtemplate_servicedependency *temp_servicedependency; xodtemplate_hostlist *temp_hostlist; xodtemplate_hostlist *this_hostlist; xodtemplate_servicelist *temp_servicelist; xodtemplate_servicelist *this_servicelist; xodtemplate_hostlist *master_hostlist; xodtemplate_hostlist *dependent_hostlist; xodtemplate_hostextinfo *temp_hostextinfo; xodtemplate_serviceextinfo *temp_serviceextinfo; char *host_name=""; int first_item; #ifdef NSCORE char temp_buffer[MAX_XODTEMPLATE_INPUT_BUFFER]; #endif #ifdef DEBUG0 printf("xodtemplate_duplicate_objects() start\n"); #endif /*************************************/ /* SERVICES ARE DUPLICATED ELSEWHERE */ /*************************************/ /****** DUPLICATE HOST ESCALATION DEFINITIONS WITH ONE OR MORE HOSTGROUP AND/OR HOST NAMES ******/ for(temp_hostescalation=xodtemplate_hostescalation_list;temp_hostescalation!=NULL;temp_hostescalation=temp_hostescalation->next){ /* skip host escalation definitions without enough data */ if(temp_hostescalation->hostgroup_name==NULL && temp_hostescalation->host_name==NULL) continue; /* get list of hosts */ temp_hostlist=xodtemplate_expand_hostgroups_and_hosts(temp_hostescalation->hostgroup_name,temp_hostescalation->host_name); if(temp_hostlist==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not expand hostgroups and/or hosts specified in host escalation (config file '%s', starting on line %d)\n",xodtemplate_config_file_name(temp_hostescalation->_config_file),temp_hostescalation->_start_line); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return ERROR; } /* add a copy of the hostescalation for every host in the hostgroup/host name list */ first_item=TRUE; for(this_hostlist=temp_hostlist;this_hostlist!=NULL;this_hostlist=this_hostlist->next){ /* if this is the first duplication, use the existing entry */ if(first_item==TRUE){ free(temp_hostescalation->host_name); temp_hostescalation->host_name=strdup(this_hostlist->host_name); if(temp_hostescalation->host_name==NULL){ xodtemplate_free_hostlist(temp_hostlist); return ERROR; } first_item=FALSE; continue; } /* duplicate hostescalation definition */ result=xodtemplate_duplicate_hostescalation(temp_hostescalation,this_hostlist->host_name); /* exit on error */ if(result==ERROR){ free(host_name); return ERROR; } } /* free memory we used for host list */ xodtemplate_free_hostlist(temp_hostlist); } /****** DUPLICATE SERVICE ESCALATION DEFINITIONS WITH ONE OR MORE HOSTGROUP AND/OR HOST NAMES ******/ for(temp_serviceescalation=xodtemplate_serviceescalation_list;temp_serviceescalation!=NULL;temp_serviceescalation=temp_serviceescalation->next){ /* skip service escalation definitions without enough data */ if(temp_serviceescalation->hostgroup_name==NULL && temp_serviceescalation->host_name==NULL) continue; /* get list of hosts */ temp_hostlist=xodtemplate_expand_hostgroups_and_hosts(temp_serviceescalation->hostgroup_name,temp_serviceescalation->host_name); if(temp_hostlist==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not expand hostgroups and/or hosts specified in service escalation (config file '%s', starting on line %d)\n",xodtemplate_config_file_name(temp_serviceescalation->_config_file),temp_serviceescalation->_start_line); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return ERROR; } /* duplicate service escalation entries */ first_item=TRUE; for(this_hostlist=temp_hostlist;this_hostlist!=NULL;this_hostlist=this_hostlist->next){ /* if this is the first duplication,use the existing entry */ if(first_item==TRUE){ free(temp_serviceescalation->host_name); temp_serviceescalation->host_name=strdup(this_hostlist->host_name); if(temp_serviceescalation->host_name==NULL){ xodtemplate_free_hostlist(temp_hostlist); return ERROR; } first_item=FALSE; continue; } /* duplicate service escalation definition */ result=xodtemplate_duplicate_serviceescalation(temp_serviceescalation,this_hostlist->host_name,NULL); /* exit on error */ if(result==ERROR){ xodtemplate_free_hostlist(temp_hostlist); return ERROR; } } /* free memory we used for host list */ xodtemplate_free_hostlist(temp_hostlist); } /****** DUPLICATE SERVICE ESCALATION DEFINITIONS WITH MULTIPLE DESCRIPTIONS ******/ /* THIS MUST BE DONE AFTER DUPLICATING FOR MULTIPLE HOST NAMES (SEE ABOVE) */ for(temp_serviceescalation=xodtemplate_serviceescalation_list;temp_serviceescalation!=NULL;temp_serviceescalation=temp_serviceescalation->next){ /* skip serviceescalations without enough data */ if(temp_serviceescalation->service_description==NULL || temp_serviceescalation->host_name==NULL) continue; /* get list of services */ temp_servicelist=xodtemplate_expand_servicegroups_and_services(NULL,temp_serviceescalation->host_name,temp_serviceescalation->service_description); if(temp_servicelist==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not expand services specified in service escalation (config file '%s', starting on line %d)\n",xodtemplate_config_file_name(temp_serviceescalation->_config_file),temp_serviceescalation->_start_line); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return ERROR; } /* duplicate service escalation entries */ first_item=TRUE; for(this_servicelist=temp_servicelist;this_servicelist!=NULL;this_servicelist=this_servicelist->next){ /* if this is the first duplication, use the existing entry */ if(first_item==TRUE){ free(temp_serviceescalation->service_description); temp_serviceescalation->service_description=strdup(this_servicelist->service_description); if(temp_serviceescalation->service_description==NULL){ xodtemplate_free_servicelist(temp_servicelist); return ERROR; } first_item=FALSE; continue; } /* duplicate service escalation definition */ result=xodtemplate_duplicate_serviceescalation(temp_serviceescalation,temp_serviceescalation->host_name,this_servicelist->service_description); /* exit on error */ if(result==ERROR){ xodtemplate_free_servicelist(temp_servicelist); return ERROR; } } /* free memory we used for service list */ xodtemplate_free_servicelist(temp_servicelist); } /****** DUPLICATE SERVICE ESCALATION DEFINITIONS WITH SERVICEGROUPS ******/ /* THIS MUST BE DONE AFTER DUPLICATING FOR MULTIPLE HOST NAMES (SEE ABOVE) */ for(temp_serviceescalation=xodtemplate_serviceescalation_list;temp_serviceescalation!=NULL;temp_serviceescalation=temp_serviceescalation->next){ /* skip serviceescalations without enough data */ if(temp_serviceescalation->servicegroup_name==NULL) continue; /* get list of services */ temp_servicelist=xodtemplate_expand_servicegroups_and_services(temp_serviceescalation->servicegroup_name,NULL,NULL); if(temp_servicelist==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not expand servicegroups specified in service escalation (config file '%s', starting on line %d)\n",xodtemplate_config_file_name(temp_serviceescalation->_config_file),temp_serviceescalation->_start_line); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return ERROR; } /* duplicate service escalation entries */ first_item=TRUE; for(this_servicelist=temp_servicelist;this_servicelist!=NULL;this_servicelist=this_servicelist->next){ /* if this is the first duplication, use the existing entry if possible */ if(first_item==TRUE && temp_serviceescalation->host_name==NULL && temp_serviceescalation->service_description==NULL){ free(temp_serviceescalation->host_name); temp_serviceescalation->host_name=strdup(this_servicelist->host_name); free(temp_serviceescalation->service_description); temp_serviceescalation->service_description=strdup(this_servicelist->service_description); if(temp_serviceescalation->service_description==NULL){ xodtemplate_free_servicelist(temp_servicelist); return ERROR; } first_item=FALSE; continue; } /* duplicate service escalation definition */ result=xodtemplate_duplicate_serviceescalation(temp_serviceescalation,this_servicelist->host_name,this_servicelist->service_description); /* exit on error */ if(result==ERROR){ xodtemplate_free_servicelist(temp_servicelist); return ERROR; } } /* free memory we used for service list */ xodtemplate_free_servicelist(temp_servicelist); } /****** DUPLICATE HOST DEPENDENCY DEFINITIONS WITH MULTIPLE HOSTGROUP AND/OR HOST NAMES (MASTER AND DEPENDENT) ******/ for(temp_hostdependency=xodtemplate_hostdependency_list;temp_hostdependency!=NULL;temp_hostdependency=temp_hostdependency->next){ /* skip host dependencies without enough data */ if(temp_hostdependency->hostgroup_name==NULL && temp_hostdependency->dependent_hostgroup_name==NULL && temp_hostdependency->host_name==NULL && temp_hostdependency->dependent_host_name==NULL) continue; /* get list of master host names */ master_hostlist=xodtemplate_expand_hostgroups_and_hosts(temp_hostdependency->hostgroup_name,temp_hostdependency->host_name); if(master_hostlist==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not expand master hostgroups and/or hosts specified in host dependency (config file '%s', starting on line %d)\n",xodtemplate_config_file_name(temp_hostdependency->_config_file),temp_hostdependency->_start_line); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return ERROR; } /* get list of dependent host names */ dependent_hostlist=xodtemplate_expand_hostgroups_and_hosts(temp_hostdependency->dependent_hostgroup_name,temp_hostdependency->dependent_host_name); if(dependent_hostlist==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not expand dependent hostgroups and/or hosts specified in host dependency (config file '%s', starting on line %d)\n",xodtemplate_config_file_name(temp_hostdependency->_config_file),temp_hostdependency->_start_line); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return ERROR; } /* duplicate the dependency definitions */ first_item=TRUE; for(temp_hostlist=master_hostlist;temp_hostlist!=NULL;temp_hostlist=temp_hostlist->next){ for(this_hostlist=dependent_hostlist;this_hostlist!=NULL;this_hostlist=this_hostlist->next){ /* existing definition gets first names */ if(first_item==TRUE){ free(temp_hostdependency->host_name); free(temp_hostdependency->dependent_host_name); temp_hostdependency->host_name=strdup(temp_hostlist->host_name); temp_hostdependency->dependent_host_name=strdup(this_hostlist->host_name); first_item=FALSE; continue; } else result=xodtemplate_duplicate_hostdependency(temp_hostdependency,temp_hostlist->host_name,this_hostlist->host_name); /* exit on error */ if(result==ERROR) return ERROR; } } /* free memory used to store host lists */ xodtemplate_free_hostlist(master_hostlist); xodtemplate_free_hostlist(dependent_hostlist); } /****** DUPLICATE SERVICE DEPENDENCY DEFINITIONS WITH MULTIPLE HOSTGROUP AND/OR HOST NAMES (MASTER AND DEPENDENT) ******/ for(temp_servicedependency=xodtemplate_servicedependency_list;temp_servicedependency!=NULL;temp_servicedependency=temp_servicedependency->next){ /* skip service dependencies without enough data */ if(temp_servicedependency->hostgroup_name==NULL && temp_servicedependency->dependent_hostgroup_name==NULL && temp_servicedependency->host_name==NULL && temp_servicedependency->dependent_host_name==NULL) continue; /* get list of master host names */ master_hostlist=xodtemplate_expand_hostgroups_and_hosts(temp_servicedependency->hostgroup_name,temp_servicedependency->host_name); if(master_hostlist==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not expand master hostgroups and/or hosts specified in service dependency (config file '%s', starting on line %d)\n",xodtemplate_config_file_name(temp_servicedependency->_config_file),temp_servicedependency->_start_line); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return ERROR; } /* get list of dependent host names */ dependent_hostlist=xodtemplate_expand_hostgroups_and_hosts(temp_servicedependency->dependent_hostgroup_name,temp_servicedependency->dependent_host_name); if(dependent_hostlist==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not expand dependent hostgroups and/or hosts specified in service dependency (config file '%s', starting on line %d)\n",xodtemplate_config_file_name(temp_servicedependency->_config_file),temp_servicedependency->_start_line); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return ERROR; } /* duplicate the dependency definitions */ first_item=TRUE; for(temp_hostlist=master_hostlist;temp_hostlist!=NULL;temp_hostlist=temp_hostlist->next){ for(this_hostlist=dependent_hostlist;this_hostlist!=NULL;this_hostlist=this_hostlist->next){ /* existing definition gets first names */ if(first_item==TRUE){ free(temp_servicedependency->host_name); free(temp_servicedependency->dependent_host_name); temp_servicedependency->host_name=strdup(temp_hostlist->host_name); temp_servicedependency->dependent_host_name=strdup(this_hostlist->host_name); first_item=FALSE; continue; } else result=xodtemplate_duplicate_servicedependency(temp_servicedependency,temp_hostlist->host_name,temp_servicedependency->service_description,this_hostlist->host_name,temp_servicedependency->dependent_service_description); /* exit on error */ if(result==ERROR) return ERROR; } } /* free memory used to store host lists */ xodtemplate_free_hostlist(master_hostlist); xodtemplate_free_hostlist(dependent_hostlist); } /****** DUPLICATE SERVICE DEPENDENCY DEFINITIONS WITH MULTIPLE MASTER DESCRIPTIONS ******/ /* THIS MUST BE DONE AFTER DUPLICATING FOR MULTIPLE HOST NAMES (SEE ABOVE) */ for(temp_servicedependency=xodtemplate_servicedependency_list;temp_servicedependency!=NULL;temp_servicedependency=temp_servicedependency->next){ /* skip servicedependencies without enough data */ if(temp_servicedependency->service_description==NULL || temp_servicedependency->host_name==NULL) continue; /* get list of services */ temp_servicelist=xodtemplate_expand_servicegroups_and_services(temp_servicedependency->servicegroup_name,temp_servicedependency->host_name,temp_servicedependency->service_description); if(temp_servicelist==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not expand services specified in service dependency (config file '%s', starting on line %d)\n",xodtemplate_config_file_name(temp_servicedependency->_config_file),temp_servicedependency->_start_line); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return ERROR; } /* duplicate service escalation entries */ first_item=TRUE; for(this_servicelist=temp_servicelist;this_servicelist!=NULL;this_servicelist=this_servicelist->next){ /* if this is the first duplication, use the existing entry */ if(first_item==TRUE){ free(temp_servicedependency->service_description); temp_servicedependency->service_description=strdup(this_servicelist->service_description); if(temp_servicedependency->service_description==NULL){ xodtemplate_free_servicelist(temp_servicelist); return ERROR; } first_item=FALSE; continue; } /* duplicate service escalation definition */ result=xodtemplate_duplicate_servicedependency(temp_servicedependency,temp_servicedependency->host_name,this_servicelist->service_description,temp_servicedependency->dependent_host_name,temp_servicedependency->dependent_service_description); /* exit on error */ if(result==ERROR){ xodtemplate_free_servicelist(temp_servicelist); return ERROR; } } /* free memory we used for service list */ xodtemplate_free_servicelist(temp_servicelist); } /****** DUPLICATE SERVICE DEPENDENCY DEFINITIONS WITH MULTIPLE DEPENDENCY DESCRIPTIONS ******/ /* THIS MUST BE DONE AFTER DUPLICATING FOR MULTIPLE HOST NAMES (SEE ABOVE) */ for(temp_servicedependency=xodtemplate_servicedependency_list;temp_servicedependency!=NULL;temp_servicedependency=temp_servicedependency->next){ /* skip servicedependencies without enough data */ if(temp_servicedependency->dependent_service_description==NULL || temp_servicedependency->dependent_host_name==NULL) continue; /* get list of services */ temp_servicelist=xodtemplate_expand_servicegroups_and_services(temp_servicedependency->dependent_servicegroup_name,temp_servicedependency->dependent_host_name,temp_servicedependency->dependent_service_description); if(temp_servicelist==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not expand services specified in service dependency (config file '%s', starting on line %d)\n",xodtemplate_config_file_name(temp_servicedependency->_config_file),temp_servicedependency->_start_line); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return ERROR; } /* duplicate service escalation entries */ first_item=TRUE; for(this_servicelist=temp_servicelist;this_servicelist!=NULL;this_servicelist=this_servicelist->next){ /* if this is the first duplication, use the existing entry */ if(first_item==TRUE){ free(temp_servicedependency->dependent_service_description); temp_servicedependency->dependent_service_description=strdup(this_servicelist->service_description); if(temp_servicedependency->dependent_service_description==NULL){ xodtemplate_free_servicelist(temp_servicelist); return ERROR; } first_item=FALSE; continue; } /* duplicate service escalation definition */ result=xodtemplate_duplicate_servicedependency(temp_servicedependency,temp_servicedependency->host_name,temp_servicedependency->service_description,temp_servicedependency->dependent_host_name,this_servicelist->service_description); /* exit on error */ if(result==ERROR){ xodtemplate_free_servicelist(temp_servicelist); return ERROR; } } /* free memory we used for service list */ xodtemplate_free_servicelist(temp_servicelist); } /****** DUPLICATE HOSTEXTINFO DEFINITIONS WITH ONE OR MORE HOSTGROUP AND/OR HOST NAMES ******/ for(temp_hostextinfo=xodtemplate_hostextinfo_list;temp_hostextinfo!=NULL;temp_hostextinfo=temp_hostextinfo->next){ /* skip definitions without enough data */ if(temp_hostextinfo->hostgroup_name==NULL && temp_hostextinfo->host_name==NULL) continue; /* get list of hosts */ temp_hostlist=xodtemplate_expand_hostgroups_and_hosts(temp_hostextinfo->hostgroup_name,temp_hostextinfo->host_name); if(temp_hostlist==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not expand hostgroups and/or hosts specified in extended host info (config file '%s', starting on line %d)\n",xodtemplate_config_file_name(temp_hostextinfo->_config_file),temp_hostextinfo->_start_line); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return ERROR; } /* add a copy of the definition for every host in the hostgroup/host name list */ first_item=TRUE; for(this_hostlist=temp_hostlist;this_hostlist!=NULL;this_hostlist=this_hostlist->next){ /* if this is the first duplication, use the existing entry */ if(first_item==TRUE){ free(temp_hostextinfo->host_name); temp_hostextinfo->host_name=strdup(this_hostlist->host_name); if(temp_hostextinfo->host_name==NULL){ xodtemplate_free_hostlist(temp_hostlist); return ERROR; } first_item=FALSE; continue; } /* duplicate hostextinfo definition */ result=xodtemplate_duplicate_hostextinfo(temp_hostextinfo,this_hostlist->host_name); /* exit on error */ if(result==ERROR){ xodtemplate_free_hostlist(temp_hostlist); return ERROR; } } /* free memory we used for host list */ xodtemplate_free_hostlist(temp_hostlist); } /****** DUPLICATE SERVICEEXTINFO DEFINITIONS WITH ONE OR MORE HOSTGROUP AND/OR HOST NAMES ******/ for(temp_serviceextinfo=xodtemplate_serviceextinfo_list;temp_serviceextinfo!=NULL;temp_serviceextinfo=temp_serviceextinfo->next){ /* skip definitions without enough data */ if(temp_serviceextinfo->hostgroup_name==NULL && temp_serviceextinfo->host_name==NULL) continue; /* get list of hosts */ temp_hostlist=xodtemplate_expand_hostgroups_and_hosts(temp_serviceextinfo->hostgroup_name,temp_serviceextinfo->host_name); if(temp_hostlist==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not expand hostgroups and/or hosts specified in extended service info (config file '%s', starting on line %d)\n",xodtemplate_config_file_name(temp_serviceextinfo->_config_file),temp_serviceextinfo->_start_line); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return ERROR; } /* add a copy of the definition for every host in the hostgroup/host name list */ first_item=TRUE; for(this_hostlist=temp_hostlist;this_hostlist!=NULL;this_hostlist=this_hostlist->next){ /* existing definition gets first host name */ if(first_item==TRUE){ free(temp_serviceextinfo->host_name); temp_serviceextinfo->host_name=strdup(this_hostlist->host_name); if(temp_serviceextinfo->host_name==NULL){ xodtemplate_free_hostlist(temp_hostlist); return ERROR; } first_item=FALSE; continue; } /* duplicate serviceextinfo definition */ result=xodtemplate_duplicate_serviceextinfo(temp_serviceextinfo,this_hostlist->host_name); /* exit on error */ if(result==ERROR){ xodtemplate_free_hostlist(temp_hostlist); return ERROR; } } /* free memory we used for host list */ xodtemplate_free_hostlist(temp_hostlist); } #ifdef DEBUG0 printf("xodtemplate_duplicate_objects() end\n"); #endif return OK; } /* duplicates a service definition (with a new host name) */ int xodtemplate_duplicate_service(xodtemplate_service *temp_service, char *host_name){ xodtemplate_service *new_service; #ifdef DEBUG0 printf("xodtemplate_duplicate_service() start\n"); #endif /* allocate memory for a new service definition */ new_service=(xodtemplate_service *)malloc(sizeof(xodtemplate_service)); if(new_service==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for duplicate definition of service.\n"); #endif return ERROR; } /* defaults */ new_service->template=NULL; new_service->name=NULL; new_service->hostgroup_name=NULL; new_service->host_name=NULL; new_service->service_description=NULL; new_service->servicegroups=NULL; new_service->check_command=NULL; new_service->check_period=NULL; new_service->event_handler=NULL; new_service->notification_period=NULL; new_service->contact_groups=NULL; new_service->failure_prediction_options=NULL; /* make sure hostgroup member in new service definition is NULL */ new_service->hostgroup_name=NULL; new_service->max_check_attempts=temp_service->max_check_attempts; new_service->have_max_check_attempts=temp_service->have_max_check_attempts; new_service->normal_check_interval=temp_service->normal_check_interval; new_service->have_normal_check_interval=temp_service->have_normal_check_interval; new_service->retry_check_interval=temp_service->retry_check_interval; new_service->have_retry_check_interval=temp_service->have_retry_check_interval; new_service->active_checks_enabled=temp_service->active_checks_enabled; new_service->have_active_checks_enabled=temp_service->have_active_checks_enabled; new_service->passive_checks_enabled=temp_service->passive_checks_enabled; new_service->have_passive_checks_enabled=temp_service->have_passive_checks_enabled; new_service->parallelize_check=temp_service->parallelize_check; new_service->have_parallelize_check=temp_service->have_parallelize_check; new_service->is_volatile=temp_service->is_volatile; new_service->have_is_volatile=temp_service->have_is_volatile; new_service->obsess_over_service=temp_service->obsess_over_service; new_service->have_obsess_over_service=temp_service->have_obsess_over_service; new_service->event_handler_enabled=temp_service->event_handler_enabled; new_service->have_event_handler_enabled=temp_service->have_event_handler_enabled; new_service->check_freshness=temp_service->check_freshness; new_service->have_check_freshness=temp_service->have_check_freshness; new_service->freshness_threshold=temp_service->freshness_threshold; new_service->have_freshness_threshold=temp_service->have_freshness_threshold; new_service->flap_detection_enabled=temp_service->flap_detection_enabled; new_service->have_flap_detection_enabled=temp_service->have_flap_detection_enabled; new_service->low_flap_threshold=temp_service->low_flap_threshold; new_service->have_low_flap_threshold=temp_service->have_low_flap_threshold; new_service->high_flap_threshold=temp_service->high_flap_threshold; new_service->have_high_flap_threshold=temp_service->have_high_flap_threshold; new_service->notify_on_unknown=temp_service->notify_on_unknown; new_service->notify_on_warning=temp_service->notify_on_warning; new_service->notify_on_critical=temp_service->notify_on_critical; new_service->notify_on_recovery=temp_service->notify_on_recovery; new_service->notify_on_flapping=temp_service->notify_on_flapping; new_service->have_notification_options=temp_service->have_notification_options; new_service->notifications_enabled=temp_service->notifications_enabled; new_service->have_notifications_enabled=temp_service->have_notifications_enabled; new_service->notification_interval=temp_service->notification_interval; new_service->have_notification_interval=temp_service->have_notification_interval; new_service->stalk_on_ok=temp_service->stalk_on_ok; new_service->stalk_on_unknown=temp_service->stalk_on_unknown; new_service->stalk_on_warning=temp_service->stalk_on_warning; new_service->stalk_on_critical=temp_service->stalk_on_critical; new_service->have_stalking_options=temp_service->have_stalking_options; new_service->process_perf_data=temp_service->process_perf_data; new_service->have_process_perf_data=temp_service->have_process_perf_data; new_service->failure_prediction_enabled=temp_service->failure_prediction_enabled; new_service->have_failure_prediction_enabled=temp_service->have_failure_prediction_enabled; new_service->retain_status_information=temp_service->retain_status_information; new_service->have_retain_status_information=temp_service->have_retain_status_information; new_service->retain_nonstatus_information=temp_service->retain_nonstatus_information; new_service->have_retain_nonstatus_information=temp_service->have_retain_nonstatus_information; new_service->has_been_resolved=temp_service->has_been_resolved; new_service->register_object=temp_service->register_object; new_service->_config_file=temp_service->_config_file; new_service->_start_line=temp_service->_start_line; /* allocate memory for and copy string members of service definition (host name provided, DO NOT duplicate hostgroup member!)*/ if(temp_service->host_name!=NULL){ new_service->host_name=strdup(host_name); if(new_service->host_name==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for duplicate definition of service.\n"); #endif free(new_service); return ERROR; } } if(temp_service->template!=NULL){ new_service->template=strdup(temp_service->template); if(new_service->template==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for duplicate definition of service.\n"); #endif free(new_service->host_name); free(new_service); return ERROR; } } if(temp_service->name!=NULL){ new_service->name=strdup(temp_service->name); if(new_service->name==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for duplicate definition of service.\n"); #endif free(new_service->host_name); free(new_service->template); free(new_service); return ERROR; } } if(temp_service->service_description!=NULL){ new_service->service_description=strdup(temp_service->service_description); if(new_service->service_description==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for duplicate definition of service.\n"); #endif free(new_service->host_name); free(new_service->template); free(new_service->name); free(new_service); return ERROR; } } if(temp_service->servicegroups!=NULL){ new_service->servicegroups=strdup(temp_service->servicegroups); if(new_service->servicegroups==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for duplicate definition of service.\n"); #endif free(new_service->host_name); free(new_service->template); free(new_service->name); free(new_service->service_description); free(new_service); return ERROR; } } if(temp_service->check_command!=NULL){ new_service->check_command=strdup(temp_service->check_command); if(new_service->check_command==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for duplicate definition of service.\n"); #endif free(new_service->host_name); free(new_service->template); free(new_service->name); free(new_service->service_description); free(new_service->servicegroups); free(new_service); return ERROR; } } if(temp_service->check_period!=NULL){ new_service->check_period=strdup(temp_service->check_period); if(new_service->check_period==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for duplicate definition of service.\n"); #endif free(new_service->host_name); free(new_service->template); free(new_service->name); free(new_service->service_description); free(new_service->check_command); free(new_service->servicegroups); free(new_service); return ERROR; } } if(temp_service->event_handler!=NULL){ new_service->event_handler=strdup(temp_service->event_handler); if(new_service->event_handler==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for duplicate definition of service.\n"); #endif free(new_service->host_name); free(new_service->template); free(new_service->name); free(new_service->service_description); free(new_service->servicegroups); free(new_service->check_command); free(new_service->check_period); free(new_service->servicegroups); free(new_service); return ERROR; } } if(temp_service->notification_period!=NULL){ new_service->notification_period=strdup(temp_service->notification_period); if(new_service->notification_period==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for duplicate definition of service.\n"); #endif free(new_service->host_name); free(new_service->template); free(new_service->name); free(new_service->service_description); free(new_service->servicegroups); free(new_service->check_command); free(new_service->check_period); free(new_service->event_handler); free(new_service); return ERROR; } } if(temp_service->contact_groups!=NULL){ new_service->contact_groups=strdup(temp_service->contact_groups); if(new_service->contact_groups==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for duplicate definition of service.\n"); #endif free(new_service->host_name); free(new_service->template); free(new_service->name); free(new_service->service_description); free(new_service->servicegroups); free(new_service->check_command); free(new_service->check_period); free(new_service->event_handler); free(new_service->notification_period); free(new_service); return ERROR; } } if(temp_service->failure_prediction_options!=NULL){ new_service->failure_prediction_options=strdup(temp_service->failure_prediction_options); if(new_service->failure_prediction_options==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for duplicate definition of service.\n"); #endif free(new_service->host_name); free(new_service->template); free(new_service->name); free(new_service->service_description); free(new_service->servicegroups); free(new_service->check_command); free(new_service->check_period); free(new_service->event_handler); free(new_service->notification_period); free(new_service->contact_groups); free(new_service); return ERROR; } } /* add new service to head of list in memory */ new_service->next=xodtemplate_service_list; xodtemplate_service_list=new_service; #ifdef DEBUG0 printf("xodtemplate_duplicate_service() end\n"); #endif return OK; } /* duplicates a host escalation definition (with a new host name) */ int xodtemplate_duplicate_hostescalation(xodtemplate_hostescalation *temp_hostescalation, char *host_name){ xodtemplate_hostescalation *new_hostescalation; #ifdef DEBUG0 printf("xodtemplate_duplicate_hostescalation() start\n"); #endif /* allocate memory for a new host escalation definition */ new_hostescalation=(xodtemplate_hostescalation *)malloc(sizeof(xodtemplate_hostescalation)); if(new_hostescalation==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for duplicate definition of host escalation.\n"); #endif return ERROR; } /* defaults */ new_hostescalation->template=NULL; new_hostescalation->name=NULL; new_hostescalation->hostgroup_name=NULL; new_hostescalation->host_name=NULL; new_hostescalation->contact_groups=NULL; new_hostescalation->escalation_period=NULL; new_hostescalation->has_been_resolved=temp_hostescalation->has_been_resolved; new_hostescalation->register_object=temp_hostescalation->register_object; new_hostescalation->_config_file=temp_hostescalation->_config_file; new_hostescalation->_start_line=temp_hostescalation->_start_line; new_hostescalation->first_notification=temp_hostescalation->first_notification; new_hostescalation->last_notification=temp_hostescalation->last_notification; new_hostescalation->have_first_notification=temp_hostescalation->have_first_notification; new_hostescalation->have_last_notification=temp_hostescalation->have_last_notification; new_hostescalation->notification_interval=temp_hostescalation->notification_interval; new_hostescalation->have_notification_interval=temp_hostescalation->have_notification_interval; new_hostescalation->escalate_on_down=temp_hostescalation->escalate_on_down; new_hostescalation->escalate_on_unreachable=temp_hostescalation->escalate_on_unreachable; new_hostescalation->escalate_on_recovery=temp_hostescalation->escalate_on_recovery; new_hostescalation->have_escalation_options=temp_hostescalation->have_escalation_options; /* allocate memory for and copy string members of hostescalation definition */ if(temp_hostescalation->host_name!=NULL){ new_hostescalation->host_name=strdup(host_name); if(new_hostescalation->host_name==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for duplicate definition of host escalation.\n"); #endif free(new_hostescalation); return ERROR; } } if(temp_hostescalation->template!=NULL){ new_hostescalation->template=strdup(temp_hostescalation->template); if(new_hostescalation->template==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for duplicate definition of host escalation.\n"); #endif free(new_hostescalation->host_name); free(new_hostescalation); return ERROR; } } if(temp_hostescalation->name!=NULL){ new_hostescalation->name=strdup(temp_hostescalation->name); if(new_hostescalation->name==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for duplicate definition of host escalation.\n"); #endif free(new_hostescalation->host_name); free(new_hostescalation->template); free(new_hostescalation); return ERROR; } } if(temp_hostescalation->contact_groups!=NULL){ new_hostescalation->contact_groups=strdup(temp_hostescalation->contact_groups); if(new_hostescalation->contact_groups==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for duplicate definition of host escalation.\n"); #endif free(new_hostescalation->host_name); free(new_hostescalation->template); free(new_hostescalation->name); free(new_hostescalation); return ERROR; } } if(temp_hostescalation->escalation_period!=NULL){ new_hostescalation->escalation_period=strdup(temp_hostescalation->escalation_period); if(new_hostescalation->escalation_period==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for duplicate definition of host escalation.\n"); #endif free(new_hostescalation->contact_groups); free(new_hostescalation->host_name); free(new_hostescalation->template); free(new_hostescalation->name); free(new_hostescalation); return ERROR; } } /* add new hostescalation to head of list in memory */ new_hostescalation->next=xodtemplate_hostescalation_list; xodtemplate_hostescalation_list=new_hostescalation; #ifdef DEBUG0 printf("xodtemplate_duplicate_hostescalation() end\n"); #endif return OK; } /* duplicates a service escalation definition (with a new host name and/or service description) */ int xodtemplate_duplicate_serviceescalation(xodtemplate_serviceescalation *temp_serviceescalation, char *host_name, char *svc_description){ xodtemplate_serviceescalation *new_serviceescalation; #ifdef DEBUG0 printf("xodtemplate_duplicate_serviceescalation() start\n"); #endif /* allocate memory for a new service escalation definition */ new_serviceescalation=(xodtemplate_serviceescalation *)malloc(sizeof(xodtemplate_serviceescalation)); if(new_serviceescalation==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for duplicate definition of service escalation.\n"); #endif return ERROR; } /* defaults */ new_serviceescalation->template=NULL; new_serviceescalation->name=NULL; new_serviceescalation->servicegroup_name=NULL; new_serviceescalation->hostgroup_name=NULL; new_serviceescalation->host_name=NULL; new_serviceescalation->service_description=NULL; new_serviceescalation->contact_groups=NULL; new_serviceescalation->escalation_period=NULL; new_serviceescalation->has_been_resolved=temp_serviceescalation->has_been_resolved; new_serviceescalation->register_object=temp_serviceescalation->register_object; new_serviceescalation->_config_file=temp_serviceescalation->_config_file; new_serviceescalation->_start_line=temp_serviceescalation->_start_line; new_serviceescalation->first_notification=temp_serviceescalation->first_notification; new_serviceescalation->last_notification=temp_serviceescalation->last_notification; new_serviceescalation->have_first_notification=temp_serviceescalation->have_first_notification; new_serviceescalation->have_last_notification=temp_serviceescalation->have_last_notification; new_serviceescalation->notification_interval=temp_serviceescalation->notification_interval; new_serviceescalation->have_notification_interval=temp_serviceescalation->have_notification_interval; new_serviceescalation->escalate_on_warning=temp_serviceescalation->escalate_on_warning; new_serviceescalation->escalate_on_unknown=temp_serviceescalation->escalate_on_unknown; new_serviceescalation->escalate_on_critical=temp_serviceescalation->escalate_on_critical; new_serviceescalation->escalate_on_recovery=temp_serviceescalation->escalate_on_recovery; new_serviceescalation->have_escalation_options=temp_serviceescalation->have_escalation_options; /* allocate memory for and copy string members of serviceescalation definition */ if(host_name!=NULL){ new_serviceescalation->host_name=strdup(host_name); if(new_serviceescalation->host_name==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for duplicate definition of service escalation.\n"); #endif free(new_serviceescalation); return ERROR; } } else if(temp_serviceescalation->host_name!=NULL){ new_serviceescalation->host_name=strdup(temp_serviceescalation->host_name); if(new_serviceescalation->host_name==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for duplicate definition of service escalation.\n"); #endif free(new_serviceescalation); return ERROR; } } if(temp_serviceescalation->template!=NULL){ new_serviceescalation->template=strdup(temp_serviceescalation->template); if(new_serviceescalation->template==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for duplicate definition of service escalation.\n"); #endif free(new_serviceescalation->host_name); free(new_serviceescalation); return ERROR; } } if(temp_serviceescalation->name!=NULL){ new_serviceescalation->name=strdup(temp_serviceescalation->name); if(new_serviceescalation->name==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for duplicate definition of service escalation.\n"); #endif free(new_serviceescalation->host_name); free(new_serviceescalation->template); free(new_serviceescalation); return ERROR; } } if(svc_description!=NULL){ new_serviceescalation->service_description=strdup(svc_description); if(new_serviceescalation->service_description==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for duplicate definition of service escalation.\n"); #endif free(new_serviceescalation->host_name); free(new_serviceescalation->template); free(new_serviceescalation->name); free(new_serviceescalation); return ERROR; } } else if(temp_serviceescalation->service_description!=NULL){ new_serviceescalation->service_description=strdup(temp_serviceescalation->service_description); if(new_serviceescalation->service_description==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for duplicate definition of service escalation.\n"); #endif free(new_serviceescalation->host_name); free(new_serviceescalation->template); free(new_serviceescalation->name); free(new_serviceescalation); return ERROR; } } if(temp_serviceescalation->contact_groups!=NULL){ new_serviceescalation->contact_groups=strdup(temp_serviceescalation->contact_groups); if(new_serviceescalation->contact_groups==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for duplicate definition of service escalation.\n"); #endif free(new_serviceescalation->service_description); free(new_serviceescalation->host_name); free(new_serviceescalation->template); free(new_serviceescalation->name); free(new_serviceescalation); return ERROR; } } if(temp_serviceescalation->escalation_period!=NULL){ new_serviceescalation->escalation_period=strdup(temp_serviceescalation->escalation_period); if(new_serviceescalation->escalation_period==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for duplicate definition of service escalation.\n"); #endif free(new_serviceescalation->contact_groups); free(new_serviceescalation->service_description); free(new_serviceescalation->host_name); free(new_serviceescalation->template); free(new_serviceescalation->name); free(new_serviceescalation); return ERROR; } } /* add new serviceescalation to head of list in memory */ new_serviceescalation->next=xodtemplate_serviceescalation_list; xodtemplate_serviceescalation_list=new_serviceescalation; #ifdef DEBUG0 printf("xodtemplate_duplicate_serviceescalation() end\n"); #endif return OK; } /* duplicates a host dependency definition (with master and dependent host names) */ int xodtemplate_duplicate_hostdependency(xodtemplate_hostdependency *temp_hostdependency, char *master_host_name, char *dependent_host_name){ xodtemplate_hostdependency *new_hostdependency; #ifdef DEBUG0 printf("xodtemplate_duplicate_hostdependency() start\n"); #endif /* allocate memory for a new host dependency definition */ new_hostdependency=(xodtemplate_hostdependency *)malloc(sizeof(xodtemplate_hostdependency)); if(new_hostdependency==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for duplicate definition of host dependency.\n"); #endif return ERROR; } /* defaults */ new_hostdependency->template=NULL; new_hostdependency->name=NULL; new_hostdependency->hostgroup_name=NULL; new_hostdependency->dependent_hostgroup_name=NULL; new_hostdependency->host_name=NULL; new_hostdependency->dependent_host_name=NULL; new_hostdependency->has_been_resolved=temp_hostdependency->has_been_resolved; new_hostdependency->register_object=temp_hostdependency->register_object; new_hostdependency->_config_file=temp_hostdependency->_config_file; new_hostdependency->_start_line=temp_hostdependency->_start_line; new_hostdependency->fail_notify_on_up=temp_hostdependency->fail_notify_on_up; new_hostdependency->fail_notify_on_down=temp_hostdependency->fail_notify_on_down; new_hostdependency->fail_notify_on_unreachable=temp_hostdependency->fail_notify_on_unreachable; new_hostdependency->fail_notify_on_pending=temp_hostdependency->fail_notify_on_pending; new_hostdependency->have_notification_dependency_options=temp_hostdependency->have_notification_dependency_options; new_hostdependency->fail_execute_on_up=temp_hostdependency->fail_execute_on_up; new_hostdependency->fail_execute_on_down=temp_hostdependency->fail_execute_on_down; new_hostdependency->fail_execute_on_unreachable=temp_hostdependency->fail_execute_on_unreachable; new_hostdependency->fail_execute_on_pending=temp_hostdependency->fail_execute_on_pending; new_hostdependency->have_execution_dependency_options=temp_hostdependency->have_execution_dependency_options; new_hostdependency->inherits_parent=temp_hostdependency->inherits_parent; new_hostdependency->have_inherits_parent=temp_hostdependency->have_inherits_parent; /* allocate memory for and copy string members of hostdependency definition */ if(temp_hostdependency->host_name!=NULL){ new_hostdependency->host_name=strdup(master_host_name); if(new_hostdependency->host_name==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for duplicate definition of host dependency.\n"); #endif free(new_hostdependency); return ERROR; } } if(temp_hostdependency->dependent_host_name!=NULL){ new_hostdependency->dependent_host_name=strdup(dependent_host_name); if(new_hostdependency->dependent_host_name==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for duplicate definition of host dependency.\n"); #endif free(new_hostdependency); return ERROR; } } if(temp_hostdependency->template!=NULL){ new_hostdependency->template=strdup(temp_hostdependency->template); if(new_hostdependency->template==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for duplicate definition of host dependency.\n"); #endif free(new_hostdependency->host_name); free(new_hostdependency); return ERROR; } } if(temp_hostdependency->name!=NULL){ new_hostdependency->name=strdup(temp_hostdependency->name); if(new_hostdependency->name==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for duplicate definition of host dependency.\n"); #endif free(new_hostdependency->host_name); free(new_hostdependency->template); free(new_hostdependency); return ERROR; } } /* add new hostdependency to head of list in memory */ new_hostdependency->next=xodtemplate_hostdependency_list; xodtemplate_hostdependency_list=new_hostdependency; #ifdef DEBUG0 printf("xodtemplate_duplicate_hostdependency() end\n"); #endif return OK; } /* duplicates a service dependency definition */ int xodtemplate_duplicate_servicedependency(xodtemplate_servicedependency *temp_servicedependency, char *master_host_name, char *master_service_description, char *dependent_host_name, char *dependent_service_description){ xodtemplate_servicedependency *new_servicedependency; #ifdef DEBUG0 printf("xodtemplate_duplicate_servicedependency() start\n"); #endif /* allocate memory for a new service dependency definition */ new_servicedependency=(xodtemplate_servicedependency *)malloc(sizeof(xodtemplate_servicedependency)); if(new_servicedependency==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for duplicate definition of service dependency.\n"); #endif return ERROR; } /* defaults */ new_servicedependency->template=NULL; new_servicedependency->name=NULL; new_servicedependency->servicegroup_name=NULL; new_servicedependency->hostgroup_name=NULL; new_servicedependency->dependent_servicegroup_name=NULL; new_servicedependency->dependent_hostgroup_name=NULL; new_servicedependency->host_name=NULL; new_servicedependency->dependent_host_name=NULL; new_servicedependency->has_been_resolved=temp_servicedependency->has_been_resolved; new_servicedependency->register_object=temp_servicedependency->register_object; new_servicedependency->_config_file=temp_servicedependency->_config_file; new_servicedependency->_start_line=temp_servicedependency->_start_line; new_servicedependency->fail_notify_on_ok=temp_servicedependency->fail_notify_on_ok; new_servicedependency->fail_notify_on_unknown=temp_servicedependency->fail_notify_on_unknown; new_servicedependency->fail_notify_on_warning=temp_servicedependency->fail_notify_on_warning; new_servicedependency->fail_notify_on_critical=temp_servicedependency->fail_notify_on_critical; new_servicedependency->fail_notify_on_pending=temp_servicedependency->fail_notify_on_pending; new_servicedependency->have_notification_dependency_options=temp_servicedependency->have_notification_dependency_options; new_servicedependency->fail_execute_on_ok=temp_servicedependency->fail_execute_on_ok; new_servicedependency->fail_execute_on_unknown=temp_servicedependency->fail_execute_on_unknown; new_servicedependency->fail_execute_on_warning=temp_servicedependency->fail_execute_on_warning; new_servicedependency->fail_execute_on_critical=temp_servicedependency->fail_execute_on_critical; new_servicedependency->fail_execute_on_pending=temp_servicedependency->fail_execute_on_pending; new_servicedependency->have_execution_dependency_options=temp_servicedependency->have_execution_dependency_options; new_servicedependency->inherits_parent=temp_servicedependency->inherits_parent; new_servicedependency->have_inherits_parent=temp_servicedependency->have_inherits_parent; /* allocate memory for and copy string members of hostdependency definition */ if(temp_servicedependency->host_name!=NULL){ new_servicedependency->host_name=strdup(master_host_name); if(new_servicedependency->host_name==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for duplicate definition of service dependency.\n"); #endif free(new_servicedependency); return ERROR; } } if(temp_servicedependency->service_description!=NULL){ new_servicedependency->service_description=strdup(master_service_description); if(new_servicedependency->service_description==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for duplicate definition of service dependency.\n"); #endif free(new_servicedependency); return ERROR; } } if(temp_servicedependency->dependent_host_name!=NULL){ new_servicedependency->dependent_host_name=strdup(dependent_host_name); if(new_servicedependency->dependent_host_name==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for duplicate definition of service dependency.\n"); #endif free(new_servicedependency); return ERROR; } } if(temp_servicedependency->dependent_service_description!=NULL){ new_servicedependency->dependent_service_description=strdup(dependent_service_description); if(new_servicedependency->dependent_service_description==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for duplicate definition of service dependency.\n"); #endif free(new_servicedependency); return ERROR; } } if(temp_servicedependency->template!=NULL){ new_servicedependency->template=strdup(temp_servicedependency->template); if(new_servicedependency->template==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for duplicate definition of service dependency.\n"); #endif free(new_servicedependency->host_name); free(new_servicedependency); return ERROR; } } if(temp_servicedependency->name!=NULL){ new_servicedependency->name=strdup(temp_servicedependency->name); if(new_servicedependency->name==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for duplicate definition of service dependency.\n"); #endif free(new_servicedependency->host_name); free(new_servicedependency->template); free(new_servicedependency); return ERROR; } } /* add new servicedependency to head of list in memory */ new_servicedependency->next=xodtemplate_servicedependency_list; xodtemplate_servicedependency_list=new_servicedependency; #ifdef DEBUG0 printf("xodtemplate_duplicate_servicedependency() end\n"); #endif return OK; } /* duplicates a hostextinfo object definition */ int xodtemplate_duplicate_hostextinfo(xodtemplate_hostextinfo *this_hostextinfo, char *host_name){ xodtemplate_hostextinfo *new_hostextinfo; #ifdef DEBUG0 printf("xodtemplate_duplicate_hostextinfo() start\n"); #endif new_hostextinfo=(xodtemplate_hostextinfo *)malloc(sizeof(xodtemplate_hostextinfo)); if(new_hostextinfo==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for duplicate definition of extended host info.\n"); #endif return ERROR; } new_hostextinfo->template=NULL; new_hostextinfo->name=NULL; new_hostextinfo->host_name=NULL; new_hostextinfo->hostgroup_name=NULL; new_hostextinfo->notes=NULL; new_hostextinfo->notes_url=NULL; new_hostextinfo->action_url=NULL; new_hostextinfo->icon_image=NULL; new_hostextinfo->icon_image_alt=NULL; new_hostextinfo->vrml_image=NULL; new_hostextinfo->statusmap_image=NULL; /* duplicate strings (host_name member is passed in) */ if(host_name!=NULL) new_hostextinfo->host_name=strdup(host_name); if(this_hostextinfo->template!=NULL) new_hostextinfo->template=strdup(this_hostextinfo->template); if(this_hostextinfo->name!=NULL) new_hostextinfo->name=strdup(this_hostextinfo->name); if(this_hostextinfo->notes!=NULL) new_hostextinfo->notes=strdup(this_hostextinfo->notes); if(this_hostextinfo->notes_url!=NULL) new_hostextinfo->notes_url=strdup(this_hostextinfo->notes_url); if(this_hostextinfo->action_url!=NULL) new_hostextinfo->action_url=strdup(this_hostextinfo->action_url); if(this_hostextinfo->icon_image!=NULL) new_hostextinfo->icon_image=strdup(this_hostextinfo->icon_image); if(this_hostextinfo->icon_image_alt!=NULL) new_hostextinfo->icon_image_alt=strdup(this_hostextinfo->icon_image_alt); if(this_hostextinfo->vrml_image!=NULL) new_hostextinfo->vrml_image=strdup(this_hostextinfo->vrml_image); if(this_hostextinfo->statusmap_image!=NULL) new_hostextinfo->statusmap_image=strdup(this_hostextinfo->statusmap_image); /* duplicate non-string members */ new_hostextinfo->x_2d=this_hostextinfo->x_2d; new_hostextinfo->y_2d=this_hostextinfo->y_2d; new_hostextinfo->have_2d_coords=this_hostextinfo->have_2d_coords; new_hostextinfo->x_3d=this_hostextinfo->x_3d; new_hostextinfo->y_3d=this_hostextinfo->y_3d; new_hostextinfo->z_3d=this_hostextinfo->z_3d; new_hostextinfo->have_3d_coords=this_hostextinfo->have_3d_coords; new_hostextinfo->has_been_resolved=this_hostextinfo->has_been_resolved; new_hostextinfo->register_object=this_hostextinfo->register_object; /* add new object to head of list */ new_hostextinfo->next=xodtemplate_hostextinfo_list; xodtemplate_hostextinfo_list=new_hostextinfo; #ifdef DEBUG0 printf("xodtemplate_duplicate_hostextinfo() end\n"); #endif return OK; } /* duplicates a serviceextinfo object definition */ int xodtemplate_duplicate_serviceextinfo(xodtemplate_serviceextinfo *this_serviceextinfo, char *host_name){ xodtemplate_serviceextinfo *new_serviceextinfo; #ifdef DEBUG0 printf("xodtemplate_duplicate_serviceextinfo() start\n"); #endif new_serviceextinfo=(xodtemplate_serviceextinfo *)malloc(sizeof(xodtemplate_serviceextinfo)); if(new_serviceextinfo==NULL){ #ifdef DEBUG1 printf("Error: Could not allocate memory for duplicate definition of extended service info.\n"); #endif return ERROR; } new_serviceextinfo->template=NULL; new_serviceextinfo->name=NULL; new_serviceextinfo->host_name=NULL; new_serviceextinfo->service_description=NULL; new_serviceextinfo->hostgroup_name=NULL; new_serviceextinfo->notes=NULL; new_serviceextinfo->notes_url=NULL; new_serviceextinfo->action_url=NULL; new_serviceextinfo->icon_image=NULL; new_serviceextinfo->icon_image_alt=NULL; new_serviceextinfo->has_been_resolved=this_serviceextinfo->has_been_resolved; new_serviceextinfo->register_object=this_serviceextinfo->register_object; /* duplicate strings (host_name member is passed in) */ if(host_name!=NULL) new_serviceextinfo->host_name=strdup(host_name); if(this_serviceextinfo->template!=NULL) new_serviceextinfo->template=strdup(this_serviceextinfo->template); if(this_serviceextinfo->name!=NULL) new_serviceextinfo->name=strdup(this_serviceextinfo->name); if(this_serviceextinfo->service_description!=NULL) new_serviceextinfo->service_description=strdup(this_serviceextinfo->service_description); if(this_serviceextinfo->notes!=NULL) new_serviceextinfo->notes=strdup(this_serviceextinfo->notes); if(this_serviceextinfo->notes_url!=NULL) new_serviceextinfo->notes_url=strdup(this_serviceextinfo->notes_url); if(this_serviceextinfo->action_url!=NULL) new_serviceextinfo->action_url=strdup(this_serviceextinfo->action_url); if(this_serviceextinfo->icon_image!=NULL) new_serviceextinfo->icon_image=strdup(this_serviceextinfo->icon_image); if(this_serviceextinfo->icon_image_alt!=NULL) new_serviceextinfo->icon_image_alt=strdup(this_serviceextinfo->icon_image_alt); /* add new object to head of list */ new_serviceextinfo->next=xodtemplate_serviceextinfo_list; xodtemplate_serviceextinfo_list=new_serviceextinfo; #ifdef DEBUG0 printf("xodtemplate_duplicate_serviceextinfo() end\n"); #endif return OK; } #endif /******************************************************************/ /***************** OBJECT RESOLUTION FUNCTIONS ********************/ /******************************************************************/ #ifdef NSCORE /* resolves object definitions */ int xodtemplate_resolve_objects(void){ xodtemplate_timeperiod *temp_timeperiod; xodtemplate_command *temp_command; xodtemplate_contactgroup *temp_contactgroup; xodtemplate_hostgroup *temp_hostgroup; xodtemplate_servicegroup *temp_servicegroup; xodtemplate_servicedependency *temp_servicedependency; xodtemplate_serviceescalation *temp_serviceescalation; xodtemplate_contact *temp_contact; xodtemplate_host *temp_host; xodtemplate_service *temp_service; xodtemplate_hostdependency *temp_hostdependency; xodtemplate_hostescalation *temp_hostescalation; xodtemplate_hostextinfo *temp_hostextinfo; xodtemplate_serviceextinfo *temp_serviceextinfo; #ifdef DEBUG0 printf("xodtemplate_resolve_objects() start\n"); #endif /* resolve all timeperiod objects */ for(temp_timeperiod=xodtemplate_timeperiod_list;temp_timeperiod!=NULL;temp_timeperiod=temp_timeperiod->next){ if(xodtemplate_resolve_timeperiod(temp_timeperiod)==ERROR) return ERROR; } /* resolve all command objects */ for(temp_command=xodtemplate_command_list;temp_command!=NULL;temp_command=temp_command->next){ if(xodtemplate_resolve_command(temp_command)==ERROR) return ERROR; } /* resolve all contactgroup objects */ for(temp_contactgroup=xodtemplate_contactgroup_list;temp_contactgroup!=NULL;temp_contactgroup=temp_contactgroup->next){ if(xodtemplate_resolve_contactgroup(temp_contactgroup)==ERROR) return ERROR; } /* resolve all hostgroup objects */ for(temp_hostgroup=xodtemplate_hostgroup_list;temp_hostgroup!=NULL;temp_hostgroup=temp_hostgroup->next){ if(xodtemplate_resolve_hostgroup(temp_hostgroup)==ERROR) return ERROR; } /* resolve all servicegroup objects */ for(temp_servicegroup=xodtemplate_servicegroup_list;temp_servicegroup!=NULL;temp_servicegroup=temp_servicegroup->next){ if(xodtemplate_resolve_servicegroup(temp_servicegroup)==ERROR) return ERROR; } /* resolve all servicedependency objects */ for(temp_servicedependency=xodtemplate_servicedependency_list;temp_servicedependency!=NULL;temp_servicedependency=temp_servicedependency->next){ if(xodtemplate_resolve_servicedependency(temp_servicedependency)==ERROR) return ERROR; } /* resolve all serviceescalation objects */ for(temp_serviceescalation=xodtemplate_serviceescalation_list;temp_serviceescalation!=NULL;temp_serviceescalation=temp_serviceescalation->next){ if(xodtemplate_resolve_serviceescalation(temp_serviceescalation)==ERROR) return ERROR; } /* resolve all contact objects */ for(temp_contact=xodtemplate_contact_list;temp_contact!=NULL;temp_contact=temp_contact->next){ if(xodtemplate_resolve_contact(temp_contact)==ERROR) return ERROR; } /* resolve all host objects */ for(temp_host=xodtemplate_host_list;temp_host!=NULL;temp_host=temp_host->next){ if(xodtemplate_resolve_host(temp_host)==ERROR) return ERROR; } /* resolve all service objects */ for(temp_service=xodtemplate_service_list;temp_service!=NULL;temp_service=temp_service->next){ if(xodtemplate_resolve_service(temp_service)==ERROR) return ERROR; } /* resolve all hostdependency objects */ for(temp_hostdependency=xodtemplate_hostdependency_list;temp_hostdependency!=NULL;temp_hostdependency=temp_hostdependency->next){ if(xodtemplate_resolve_hostdependency(temp_hostdependency)==ERROR) return ERROR; } /* resolve all hostescalation objects */ for(temp_hostescalation=xodtemplate_hostescalation_list;temp_hostescalation!=NULL;temp_hostescalation=temp_hostescalation->next){ if(xodtemplate_resolve_hostescalation(temp_hostescalation)==ERROR) return ERROR; } /* resolve all hostextinfo objects */ for(temp_hostextinfo=xodtemplate_hostextinfo_list;temp_hostextinfo!=NULL;temp_hostextinfo=temp_hostextinfo->next){ if(xodtemplate_resolve_hostextinfo(temp_hostextinfo)==ERROR) return ERROR; } /* resolve all serviceextinfo objects */ for(temp_serviceextinfo=xodtemplate_serviceextinfo_list;temp_serviceextinfo!=NULL;temp_serviceextinfo=temp_serviceextinfo->next){ if(xodtemplate_resolve_serviceextinfo(temp_serviceextinfo)==ERROR) return ERROR; } #ifdef DEBUG0 printf("xodtemplate_resolve_objects() end\n"); #endif return OK; } /* resolves a timeperiod object */ int xodtemplate_resolve_timeperiod(xodtemplate_timeperiod *this_timeperiod){ xodtemplate_timeperiod *template_timeperiod; int x; #ifdef NSCORE char temp_buffer[MAX_XODTEMPLATE_INPUT_BUFFER]; #endif #ifdef DEBUG0 printf("xodtemplate_resolve_timeperiod() start\n"); #endif /* return if this timeperiod has already been resolved */ if(this_timeperiod->has_been_resolved==TRUE) return OK; /* set the resolved flag */ this_timeperiod->has_been_resolved=TRUE; /* return if we have no template */ if(this_timeperiod->template==NULL) return OK; template_timeperiod=xodtemplate_find_timeperiod(this_timeperiod->template); if(template_timeperiod==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Template '%s' specified in timeperiod definition could not be not found (config file '%s', starting on line %d)\n",this_timeperiod->template,xodtemplate_config_file_name(this_timeperiod->_config_file),this_timeperiod->_start_line); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return ERROR; } /* resolve the template timeperiod... */ xodtemplate_resolve_timeperiod(template_timeperiod); /* apply missing properties from template timeperiod... */ if(this_timeperiod->timeperiod_name==NULL && template_timeperiod->timeperiod_name!=NULL) this_timeperiod->timeperiod_name=strdup(template_timeperiod->timeperiod_name); if(this_timeperiod->alias==NULL && template_timeperiod->alias!=NULL) this_timeperiod->alias=strdup(template_timeperiod->alias); for(x=0;x<7;x++){ if(this_timeperiod->timeranges[x]==NULL && template_timeperiod->timeranges[x]!=NULL){ this_timeperiod->timeranges[x]=strdup(template_timeperiod->timeranges[x]); } } #ifdef DEBUG0 printf("xodtemplate_resolve_timeperiod() end\n"); #endif return OK; } /* resolves a command object */ int xodtemplate_resolve_command(xodtemplate_command *this_command){ xodtemplate_command *template_command; #ifdef NSCORE char temp_buffer[MAX_XODTEMPLATE_INPUT_BUFFER]; #endif #ifdef DEBUG0 printf("xodtemplate_resolve_command() start\n"); #endif /* return if this command has already been resolved */ if(this_command->has_been_resolved==TRUE) return OK; /* set the resolved flag */ this_command->has_been_resolved=TRUE; /* return if we have no template */ if(this_command->template==NULL) return OK; template_command=xodtemplate_find_command(this_command->template); if(template_command==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Template '%s' specified in command definition could not be not found (config file '%s', starting on line %d)\n",this_command->template,xodtemplate_config_file_name(this_command->_config_file),this_command->_start_line); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return ERROR; } /* resolve the template command... */ xodtemplate_resolve_command(template_command); /* apply missing properties from template command... */ if(this_command->command_name==NULL && template_command->command_name!=NULL) this_command->command_name=strdup(template_command->command_name); if(this_command->command_line==NULL && template_command->command_line!=NULL) this_command->command_line=strdup(template_command->command_line); #ifdef DEBUG0 printf("xodtemplate_resolve_command() end\n"); #endif return OK; } /* resolves a contactgroup object */ int xodtemplate_resolve_contactgroup(xodtemplate_contactgroup *this_contactgroup){ xodtemplate_contactgroup *template_contactgroup; #ifdef NSCORE char temp_buffer[MAX_XODTEMPLATE_INPUT_BUFFER]; #endif #ifdef DEBUG0 printf("xodtemplate_resolve_contactgroup() start\n"); #endif /* return if this contactgroup has already been resolved */ if(this_contactgroup->has_been_resolved==TRUE) return OK; /* set the resolved flag */ this_contactgroup->has_been_resolved=TRUE; /* return if we have no template */ if(this_contactgroup->template==NULL) return OK; template_contactgroup=xodtemplate_find_contactgroup(this_contactgroup->template); if(template_contactgroup==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Template '%s' specified in contactgroup definition could not be not found (config file '%s', starting on line %d)\n",this_contactgroup->template,xodtemplate_config_file_name(this_contactgroup->_config_file),this_contactgroup->_start_line); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return ERROR; } /* resolve the template contactgroup... */ xodtemplate_resolve_contactgroup(template_contactgroup); /* apply missing properties from template contactgroup... */ if(this_contactgroup->contactgroup_name==NULL && template_contactgroup->contactgroup_name!=NULL) this_contactgroup->contactgroup_name=strdup(template_contactgroup->contactgroup_name); if(this_contactgroup->alias==NULL && template_contactgroup->alias!=NULL) this_contactgroup->alias=strdup(template_contactgroup->alias); if(this_contactgroup->members==NULL && template_contactgroup->members!=NULL) this_contactgroup->members=strdup(template_contactgroup->members); #ifdef DEBUG0 printf("xodtemplate_resolve_contactgroup() end\n"); #endif return OK; } /* resolves a hostgroup object */ int xodtemplate_resolve_hostgroup(xodtemplate_hostgroup *this_hostgroup){ xodtemplate_hostgroup *template_hostgroup; #ifdef NSCORE char temp_buffer[MAX_XODTEMPLATE_INPUT_BUFFER]; #endif #ifdef DEBUG0 printf("xodtemplate_resolve_hostgroup() start\n"); #endif /* return if this hostgroup has already been resolved */ if(this_hostgroup->has_been_resolved==TRUE) return OK; /* set the resolved flag */ this_hostgroup->has_been_resolved=TRUE; /* return if we have no template */ if(this_hostgroup->template==NULL) return OK; template_hostgroup=xodtemplate_find_hostgroup(this_hostgroup->template); if(template_hostgroup==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Template '%s' specified in hostgroup definition could not be not found (config file '%s', starting on line %d)\n",this_hostgroup->template,xodtemplate_config_file_name(this_hostgroup->_config_file),this_hostgroup->_start_line); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return ERROR; } /* resolve the template hostgroup... */ xodtemplate_resolve_hostgroup(template_hostgroup); /* apply missing properties from template hostgroup... */ if(this_hostgroup->hostgroup_name==NULL && template_hostgroup->hostgroup_name!=NULL) this_hostgroup->hostgroup_name=strdup(template_hostgroup->hostgroup_name); if(this_hostgroup->alias==NULL && template_hostgroup->alias!=NULL) this_hostgroup->alias=strdup(template_hostgroup->alias); if(this_hostgroup->members==NULL && template_hostgroup->members!=NULL) this_hostgroup->members=strdup(template_hostgroup->members); #ifdef DEBUG0 printf("xodtemplate_resolve_hostgroup() end\n"); #endif return OK; } /* resolves a servicegroup object */ int xodtemplate_resolve_servicegroup(xodtemplate_servicegroup *this_servicegroup){ xodtemplate_servicegroup *template_servicegroup; #ifdef NSCORE char temp_buffer[MAX_XODTEMPLATE_INPUT_BUFFER]; #endif #ifdef DEBUG0 printf("xodtemplate_resolve_servicegroup() start\n"); #endif /* return if this servicegroup has already been resolved */ if(this_servicegroup->has_been_resolved==TRUE) return OK; /* set the resolved flag */ this_servicegroup->has_been_resolved=TRUE; /* return if we have no template */ if(this_servicegroup->template==NULL) return OK; template_servicegroup=xodtemplate_find_servicegroup(this_servicegroup->template); if(template_servicegroup==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Template '%s' specified in servicegroup definition could not be not found (config file '%s', starting on line %d)\n",this_servicegroup->template,xodtemplate_config_file_name(this_servicegroup->_config_file),this_servicegroup->_start_line); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return ERROR; } /* resolve the template servicegroup... */ xodtemplate_resolve_servicegroup(template_servicegroup); /* apply missing properties from template servicegroup... */ if(this_servicegroup->servicegroup_name==NULL && template_servicegroup->servicegroup_name!=NULL) this_servicegroup->servicegroup_name=strdup(template_servicegroup->servicegroup_name); if(this_servicegroup->alias==NULL && template_servicegroup->alias!=NULL) this_servicegroup->alias=strdup(template_servicegroup->alias); if(this_servicegroup->members==NULL && template_servicegroup->members!=NULL) this_servicegroup->members=strdup(template_servicegroup->members); #ifdef DEBUG0 printf("xodtemplate_resolve_servicegroup() end\n"); #endif return OK; } /* resolves a servicedependency object */ int xodtemplate_resolve_servicedependency(xodtemplate_servicedependency *this_servicedependency){ xodtemplate_servicedependency *template_servicedependency; #ifdef NSCORE char temp_buffer[MAX_XODTEMPLATE_INPUT_BUFFER]; #endif #ifdef DEBUG0 printf("xodtemplate_resolve_servicedependency() start\n"); #endif /* return if this servicedependency has already been resolved */ if(this_servicedependency->has_been_resolved==TRUE) return OK; /* set the resolved flag */ this_servicedependency->has_been_resolved=TRUE; /* return if we have no template */ if(this_servicedependency->template==NULL) return OK; template_servicedependency=xodtemplate_find_servicedependency(this_servicedependency->template); if(template_servicedependency==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Template '%s' specified in service dependency definition could not be not found (config file '%s', starting on line %d)\n",this_servicedependency->template,xodtemplate_config_file_name(this_servicedependency->_config_file),this_servicedependency->_start_line); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return ERROR; } /* resolve the template servicedependency... */ xodtemplate_resolve_servicedependency(template_servicedependency); /* apply missing properties from template servicedependency... */ if(this_servicedependency->servicegroup_name==NULL && template_servicedependency->servicegroup_name!=NULL) this_servicedependency->servicegroup_name=strdup(template_servicedependency->servicegroup_name); if(this_servicedependency->hostgroup_name==NULL && template_servicedependency->hostgroup_name!=NULL) this_servicedependency->hostgroup_name=strdup(template_servicedependency->hostgroup_name); if(this_servicedependency->host_name==NULL && template_servicedependency->host_name!=NULL) this_servicedependency->host_name=strdup(template_servicedependency->host_name); if(this_servicedependency->service_description==NULL && template_servicedependency->service_description!=NULL) this_servicedependency->service_description=strdup(template_servicedependency->service_description); if(this_servicedependency->dependent_servicegroup_name==NULL && template_servicedependency->dependent_servicegroup_name!=NULL) this_servicedependency->dependent_servicegroup_name=strdup(template_servicedependency->dependent_servicegroup_name); if(this_servicedependency->dependent_hostgroup_name==NULL && template_servicedependency->dependent_hostgroup_name!=NULL) this_servicedependency->dependent_hostgroup_name=strdup(template_servicedependency->dependent_hostgroup_name); if(this_servicedependency->dependent_host_name==NULL && template_servicedependency->dependent_host_name!=NULL) this_servicedependency->dependent_host_name=strdup(template_servicedependency->dependent_host_name); if(this_servicedependency->dependent_service_description==NULL && template_servicedependency->dependent_service_description!=NULL) this_servicedependency->dependent_service_description=strdup(template_servicedependency->dependent_service_description); if(this_servicedependency->have_inherits_parent==FALSE && template_servicedependency->have_inherits_parent==TRUE){ this_servicedependency->inherits_parent=template_servicedependency->inherits_parent; this_servicedependency->have_inherits_parent=TRUE; } if(this_servicedependency->have_execution_dependency_options==FALSE && template_servicedependency->have_execution_dependency_options==TRUE){ this_servicedependency->fail_execute_on_ok=template_servicedependency->fail_execute_on_ok; this_servicedependency->fail_execute_on_unknown=template_servicedependency->fail_execute_on_unknown; this_servicedependency->fail_execute_on_warning=template_servicedependency->fail_execute_on_warning; this_servicedependency->fail_execute_on_critical=template_servicedependency->fail_execute_on_critical; this_servicedependency->fail_execute_on_pending=template_servicedependency->fail_execute_on_pending; this_servicedependency->have_execution_dependency_options=TRUE; } if(this_servicedependency->have_notification_dependency_options==FALSE && template_servicedependency->have_notification_dependency_options==TRUE){ this_servicedependency->fail_notify_on_ok=template_servicedependency->fail_notify_on_ok; this_servicedependency->fail_notify_on_unknown=template_servicedependency->fail_notify_on_unknown; this_servicedependency->fail_notify_on_warning=template_servicedependency->fail_notify_on_warning; this_servicedependency->fail_notify_on_critical=template_servicedependency->fail_notify_on_critical; this_servicedependency->fail_notify_on_pending=template_servicedependency->fail_notify_on_pending; this_servicedependency->have_notification_dependency_options=TRUE; } #ifdef DEBUG0 printf("xodtemplate_resolve_servicedependency() end\n"); #endif return OK; } /* resolves a serviceescalation object */ int xodtemplate_resolve_serviceescalation(xodtemplate_serviceescalation *this_serviceescalation){ xodtemplate_serviceescalation *template_serviceescalation; #ifdef NSCORE char temp_buffer[MAX_XODTEMPLATE_INPUT_BUFFER]; #endif #ifdef DEBUG0 printf("xodtemplate_resolve_serviceescalation() start\n"); #endif /* return if this serviceescalation has already been resolved */ if(this_serviceescalation->has_been_resolved==TRUE) return OK; /* set the resolved flag */ this_serviceescalation->has_been_resolved=TRUE; /* return if we have no template */ if(this_serviceescalation->template==NULL) return OK; template_serviceescalation=xodtemplate_find_serviceescalation(this_serviceescalation->template); if(template_serviceescalation==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Template '%s' specified in service escalation definition could not be not found (config file '%s', starting on line %d)\n",this_serviceescalation->template,xodtemplate_config_file_name(this_serviceescalation->_config_file),this_serviceescalation->_start_line); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return ERROR; } /* resolve the template serviceescalation... */ xodtemplate_resolve_serviceescalation(template_serviceescalation); /* apply missing properties from template serviceescalation... */ if(this_serviceescalation->servicegroup_name==NULL && template_serviceescalation->servicegroup_name!=NULL) this_serviceescalation->servicegroup_name=strdup(template_serviceescalation->servicegroup_name); if(this_serviceescalation->hostgroup_name==NULL && template_serviceescalation->hostgroup_name!=NULL) this_serviceescalation->hostgroup_name=strdup(template_serviceescalation->hostgroup_name); if(this_serviceescalation->host_name==NULL && template_serviceescalation->host_name!=NULL) this_serviceescalation->host_name=strdup(template_serviceescalation->host_name); if(this_serviceescalation->service_description==NULL && template_serviceescalation->service_description!=NULL) this_serviceescalation->service_description=strdup(template_serviceescalation->service_description); if(this_serviceescalation->escalation_period==NULL && template_serviceescalation->escalation_period!=NULL) this_serviceescalation->escalation_period=strdup(template_serviceescalation->escalation_period); if(this_serviceescalation->contact_groups==NULL && template_serviceescalation->contact_groups!=NULL) this_serviceescalation->contact_groups=strdup(template_serviceescalation->contact_groups); if(this_serviceescalation->have_first_notification==FALSE && template_serviceescalation->have_first_notification==TRUE){ this_serviceescalation->first_notification=template_serviceescalation->first_notification; this_serviceescalation->have_first_notification=TRUE; } if(this_serviceescalation->have_last_notification==FALSE && template_serviceescalation->have_last_notification==TRUE){ this_serviceescalation->last_notification=template_serviceescalation->last_notification; this_serviceescalation->have_last_notification=TRUE; } if(this_serviceescalation->have_notification_interval==FALSE && template_serviceescalation->have_notification_interval==TRUE){ this_serviceescalation->notification_interval=template_serviceescalation->notification_interval; this_serviceescalation->have_notification_interval=TRUE; } if(this_serviceescalation->have_escalation_options==FALSE && template_serviceescalation->have_escalation_options==TRUE){ this_serviceescalation->escalate_on_warning=template_serviceescalation->escalate_on_warning; this_serviceescalation->escalate_on_unknown=template_serviceescalation->escalate_on_unknown; this_serviceescalation->escalate_on_critical=template_serviceescalation->escalate_on_critical; this_serviceescalation->escalate_on_recovery=template_serviceescalation->escalate_on_recovery; this_serviceescalation->have_escalation_options=TRUE; } #ifdef DEBUG0 printf("xodtemplate_resolve_servicedeescalation() end\n"); #endif return OK; } /* resolves a contact object */ int xodtemplate_resolve_contact(xodtemplate_contact *this_contact){ xodtemplate_contact *template_contact; int x; #ifdef NSCORE char temp_buffer[MAX_XODTEMPLATE_INPUT_BUFFER]; #endif #ifdef DEBUG0 printf("xodtemplate_resolve_contact() start\n"); #endif /* return if this contact has already been resolved */ if(this_contact->has_been_resolved==TRUE) return OK; /* set the resolved flag */ this_contact->has_been_resolved=TRUE; /* return if we have no template */ if(this_contact->template==NULL) return OK; template_contact=xodtemplate_find_contact(this_contact->template); if(template_contact==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Template '%s' specified in contact definition could not be not found (config file '%s', starting on line %d)\n",this_contact->template,xodtemplate_config_file_name(this_contact->_config_file),this_contact->_start_line); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return ERROR; } /* resolve the template contact... */ xodtemplate_resolve_contact(template_contact); /* apply missing properties from template contact... */ if(this_contact->contact_name==NULL && template_contact->contact_name!=NULL) this_contact->contact_name=strdup(template_contact->contact_name); if(this_contact->alias==NULL && template_contact->alias!=NULL) this_contact->alias=strdup(template_contact->alias); if(this_contact->email==NULL && template_contact->email!=NULL) this_contact->email=strdup(template_contact->email); if(this_contact->pager==NULL && template_contact->pager!=NULL) this_contact->pager=strdup(template_contact->pager); for(x=0;xaddress[x]==NULL && template_contact->address[x]!=NULL) this_contact->address[x]=strdup(template_contact->address[x]); } if(this_contact->contactgroups==NULL && template_contact->contactgroups!=NULL) this_contact->contactgroups=strdup(template_contact->contactgroups); if(this_contact->host_notification_period==NULL && template_contact->host_notification_period!=NULL) this_contact->host_notification_period=strdup(template_contact->host_notification_period); if(this_contact->service_notification_period==NULL && template_contact->service_notification_period!=NULL) this_contact->service_notification_period=strdup(template_contact->service_notification_period); if(this_contact->host_notification_commands==NULL && template_contact->host_notification_commands!=NULL) this_contact->host_notification_commands=strdup(template_contact->host_notification_commands); if(this_contact->service_notification_commands==NULL && template_contact->service_notification_commands!=NULL) this_contact->service_notification_commands=strdup(template_contact->service_notification_commands); if(this_contact->have_host_notification_options==FALSE && template_contact->have_host_notification_options==TRUE){ this_contact->notify_on_host_down=template_contact->notify_on_host_down; this_contact->notify_on_host_unreachable=template_contact->notify_on_host_unreachable; this_contact->notify_on_host_recovery=template_contact->notify_on_host_recovery; this_contact->notify_on_host_flapping=template_contact->notify_on_host_flapping; this_contact->have_host_notification_options=TRUE; } if(this_contact->have_service_notification_options==FALSE && template_contact->have_service_notification_options==TRUE){ this_contact->notify_on_service_unknown=template_contact->notify_on_service_unknown; this_contact->notify_on_service_warning=template_contact->notify_on_service_warning; this_contact->notify_on_service_critical=template_contact->notify_on_service_critical; this_contact->notify_on_service_recovery=template_contact->notify_on_service_recovery; this_contact->notify_on_service_flapping=template_contact->notify_on_service_flapping; this_contact->have_service_notification_options=TRUE; } #ifdef DEBUG0 printf("xodtemplate_resolve_contact() end\n"); #endif return OK; } /* resolves a host object */ int xodtemplate_resolve_host(xodtemplate_host *this_host){ xodtemplate_host *template_host; #ifdef NSCORE char temp_buffer[MAX_XODTEMPLATE_INPUT_BUFFER]; #endif #ifdef DEBUG0 printf("xodtemplate_resolve_host() start\n"); #endif /* return if this host has already been resolved */ if(this_host->has_been_resolved==TRUE) return OK; /* set the resolved flag */ this_host->has_been_resolved=TRUE; /* return if we have no template */ if(this_host->template==NULL) return OK; template_host=xodtemplate_find_host(this_host->template); if(template_host==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Template '%s' specified in host definition could not be not found (config file '%s', starting on line %d)\n",this_host->template,xodtemplate_config_file_name(this_host->_config_file),this_host->_start_line); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return ERROR; } /* resolve the template host... */ xodtemplate_resolve_host(template_host); /* apply missing properties from template host... */ if(this_host->host_name==NULL && template_host->host_name!=NULL) this_host->host_name=strdup(template_host->host_name); if(this_host->alias==NULL && template_host->alias!=NULL) this_host->alias=strdup(template_host->alias); if(this_host->address==NULL && template_host->address!=NULL) this_host->address=strdup(template_host->address); if(this_host->parents==NULL && template_host->parents!=NULL) this_host->parents=strdup(template_host->parents); if(this_host->hostgroups==NULL && template_host->hostgroups!=NULL) this_host->hostgroups=strdup(template_host->hostgroups); if(this_host->check_command==NULL && template_host->check_command!=NULL) this_host->check_command=strdup(template_host->check_command); if(this_host->check_period==NULL && template_host->check_period!=NULL) this_host->check_period=strdup(template_host->check_period); if(this_host->event_handler==NULL && template_host->event_handler!=NULL) this_host->event_handler=strdup(template_host->event_handler); if(this_host->contact_groups==NULL && template_host->contact_groups!=NULL) this_host->contact_groups=strdup(template_host->contact_groups); if(this_host->notification_period==NULL && template_host->notification_period!=NULL) this_host->notification_period=strdup(template_host->notification_period); if(this_host->failure_prediction_options==NULL && template_host->failure_prediction_options!=NULL) this_host->failure_prediction_options=strdup(template_host->failure_prediction_options); if(this_host->have_check_interval==FALSE && template_host->have_check_interval==TRUE){ this_host->check_interval=template_host->check_interval; this_host->have_check_interval=TRUE; } if(this_host->have_max_check_attempts==FALSE && template_host->have_max_check_attempts==TRUE){ this_host->max_check_attempts=template_host->max_check_attempts; this_host->have_max_check_attempts=TRUE; } if(this_host->have_active_checks_enabled==FALSE && template_host->have_active_checks_enabled==TRUE){ this_host->active_checks_enabled=template_host->active_checks_enabled; this_host->have_active_checks_enabled=TRUE; } if(this_host->have_passive_checks_enabled==FALSE && template_host->have_passive_checks_enabled==TRUE){ this_host->passive_checks_enabled=template_host->passive_checks_enabled; this_host->have_passive_checks_enabled=TRUE; } if(this_host->have_obsess_over_host==FALSE && template_host->have_obsess_over_host==TRUE){ this_host->obsess_over_host=template_host->obsess_over_host; this_host->have_obsess_over_host=TRUE; } if(this_host->have_event_handler_enabled==FALSE && template_host->have_event_handler_enabled==TRUE){ this_host->event_handler_enabled=template_host->event_handler_enabled; this_host->have_event_handler_enabled=TRUE; } if(this_host->have_check_freshness==FALSE && template_host->have_check_freshness==TRUE){ this_host->check_freshness=template_host->check_freshness; this_host->have_check_freshness=TRUE; } if(this_host->have_freshness_threshold==FALSE && template_host->have_freshness_threshold==TRUE){ this_host->freshness_threshold=template_host->freshness_threshold; this_host->have_freshness_threshold=TRUE; } if(this_host->have_low_flap_threshold==FALSE && template_host->have_low_flap_threshold==TRUE){ this_host->low_flap_threshold=template_host->low_flap_threshold; this_host->have_low_flap_threshold=TRUE; } if(this_host->have_high_flap_threshold==FALSE && template_host->have_high_flap_threshold==TRUE){ this_host->high_flap_threshold=template_host->high_flap_threshold; this_host->have_high_flap_threshold=TRUE; } if(this_host->have_flap_detection_enabled==FALSE && template_host->have_flap_detection_enabled==TRUE){ this_host->flap_detection_enabled=template_host->flap_detection_enabled; this_host->have_flap_detection_enabled=TRUE; } if(this_host->have_notification_options==FALSE && template_host->have_notification_options==TRUE){ this_host->notify_on_down=template_host->notify_on_down; this_host->notify_on_unreachable=template_host->notify_on_unreachable; this_host->notify_on_recovery=template_host->notify_on_recovery; this_host->notify_on_flapping=template_host->notify_on_flapping; this_host->have_notification_options=TRUE; } if(this_host->have_notifications_enabled==FALSE && template_host->have_notifications_enabled==TRUE){ this_host->notifications_enabled=template_host->notifications_enabled; this_host->have_notifications_enabled=TRUE; } if(this_host->have_notification_interval==FALSE && template_host->have_notification_interval==TRUE){ this_host->notification_interval=template_host->notification_interval; this_host->have_notification_interval=TRUE; } if(this_host->have_stalking_options==FALSE && template_host->have_stalking_options==TRUE){ this_host->stalk_on_up=template_host->stalk_on_up; this_host->stalk_on_down=template_host->stalk_on_down; this_host->stalk_on_unreachable=template_host->stalk_on_unreachable; this_host->have_stalking_options=TRUE; } if(this_host->have_process_perf_data==FALSE && template_host->have_process_perf_data==TRUE){ this_host->process_perf_data=template_host->process_perf_data; this_host->have_process_perf_data=TRUE; } if(this_host->have_failure_prediction_enabled==FALSE && template_host->have_failure_prediction_enabled==TRUE){ this_host->failure_prediction_enabled=template_host->failure_prediction_enabled; this_host->have_failure_prediction_enabled=TRUE; } if(this_host->have_retain_status_information==FALSE && template_host->have_retain_status_information==TRUE){ this_host->retain_status_information=template_host->retain_status_information; this_host->have_retain_status_information=TRUE; } if(this_host->have_retain_nonstatus_information==FALSE && template_host->have_retain_nonstatus_information==TRUE){ this_host->retain_nonstatus_information=template_host->retain_nonstatus_information; this_host->have_retain_nonstatus_information=TRUE; } #ifdef DEBUG0 printf("xodtemplate_resolve_host() end\n"); #endif return OK; } /* resolves a service object */ int xodtemplate_resolve_service(xodtemplate_service *this_service){ xodtemplate_service *template_service; #ifdef NSCORE char temp_buffer[MAX_XODTEMPLATE_INPUT_BUFFER]; #endif #ifdef DEBUG0 printf("xodtemplate_resolve_service() start\n"); #endif /* return if this service has already been resolved */ if(this_service->has_been_resolved==TRUE) return OK; /* set the resolved flag */ this_service->has_been_resolved=TRUE; /* return if we have no template */ if(this_service->template==NULL) return OK; template_service=xodtemplate_find_service(this_service->template); if(template_service==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Template '%s' specified in service definition could not be not found (config file '%s', starting on line %d)\n",this_service->template,xodtemplate_config_file_name(this_service->_config_file),this_service->_start_line); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return ERROR; } /* resolve the template service... */ xodtemplate_resolve_service(template_service); /* apply missing properties from template service... */ if(this_service->hostgroup_name==NULL && template_service->hostgroup_name!=NULL) this_service->hostgroup_name=strdup(template_service->hostgroup_name); if(this_service->host_name==NULL && template_service->host_name!=NULL) this_service->host_name=strdup(template_service->host_name); if(this_service->service_description==NULL && template_service->service_description!=NULL) this_service->service_description=strdup(template_service->service_description); if(this_service->servicegroups==NULL && template_service->servicegroups!=NULL) this_service->servicegroups=strdup(template_service->servicegroups); if(this_service->check_command==NULL && template_service->check_command!=NULL) this_service->check_command=strdup(template_service->check_command); if(this_service->check_period==NULL && template_service->check_period!=NULL) this_service->check_period=strdup(template_service->check_period); if(this_service->event_handler==NULL && template_service->event_handler!=NULL) this_service->event_handler=strdup(template_service->event_handler); if(this_service->notification_period==NULL && template_service->notification_period!=NULL) this_service->notification_period=strdup(template_service->notification_period); if(this_service->contact_groups==NULL && template_service->contact_groups!=NULL) this_service->contact_groups=strdup(template_service->contact_groups); if(this_service->failure_prediction_options==NULL && template_service->failure_prediction_options!=NULL) this_service->failure_prediction_options=strdup(template_service->failure_prediction_options); if(this_service->have_max_check_attempts==FALSE && template_service->have_max_check_attempts==TRUE){ this_service->max_check_attempts=template_service->max_check_attempts; this_service->have_max_check_attempts=TRUE; } if(this_service->have_normal_check_interval==FALSE && template_service->have_normal_check_interval==TRUE){ this_service->normal_check_interval=template_service->normal_check_interval; this_service->have_normal_check_interval=TRUE; } if(this_service->have_retry_check_interval==FALSE && template_service->have_retry_check_interval==TRUE){ this_service->retry_check_interval=template_service->retry_check_interval; this_service->have_retry_check_interval=TRUE; } if(this_service->have_active_checks_enabled==FALSE && template_service->have_active_checks_enabled==TRUE){ this_service->active_checks_enabled=template_service->active_checks_enabled; this_service->have_active_checks_enabled=TRUE; } if(this_service->have_passive_checks_enabled==FALSE && template_service->have_passive_checks_enabled==TRUE){ this_service->passive_checks_enabled=template_service->passive_checks_enabled; this_service->have_passive_checks_enabled=TRUE; } if(this_service->have_parallelize_check==FALSE && template_service->have_parallelize_check==TRUE){ this_service->parallelize_check=template_service->parallelize_check; this_service->have_parallelize_check=TRUE; } if(this_service->have_is_volatile==FALSE && template_service->have_is_volatile==TRUE){ this_service->is_volatile=template_service->is_volatile; this_service->have_is_volatile=TRUE; } if(this_service->have_obsess_over_service==FALSE && template_service->have_obsess_over_service==TRUE){ this_service->obsess_over_service=template_service->obsess_over_service; this_service->have_obsess_over_service=TRUE; } if(this_service->have_event_handler_enabled==FALSE && template_service->have_event_handler_enabled==TRUE){ this_service->event_handler_enabled=template_service->event_handler_enabled; this_service->have_event_handler_enabled=TRUE; } if(this_service->have_check_freshness==FALSE && template_service->have_check_freshness==TRUE){ this_service->check_freshness=template_service->check_freshness; this_service->have_check_freshness=TRUE; } if(this_service->have_freshness_threshold==FALSE && template_service->have_freshness_threshold==TRUE){ this_service->freshness_threshold=template_service->freshness_threshold; this_service->have_freshness_threshold=TRUE; } if(this_service->have_low_flap_threshold==FALSE && template_service->have_low_flap_threshold==TRUE){ this_service->low_flap_threshold=template_service->low_flap_threshold; this_service->have_low_flap_threshold=TRUE; } if(this_service->have_high_flap_threshold==FALSE && template_service->have_high_flap_threshold==TRUE){ this_service->high_flap_threshold=template_service->high_flap_threshold; this_service->have_high_flap_threshold=TRUE; } if(this_service->have_flap_detection_enabled==FALSE && template_service->have_flap_detection_enabled==TRUE){ this_service->flap_detection_enabled=template_service->flap_detection_enabled; this_service->have_flap_detection_enabled=TRUE; } if(this_service->have_notification_options==FALSE && template_service->have_notification_options==TRUE){ this_service->notify_on_unknown=template_service->notify_on_unknown; this_service->notify_on_warning=template_service->notify_on_warning; this_service->notify_on_critical=template_service->notify_on_critical; this_service->notify_on_recovery=template_service->notify_on_recovery; this_service->notify_on_flapping=template_service->notify_on_flapping; this_service->have_notification_options=TRUE; } if(this_service->have_notifications_enabled==FALSE && template_service->have_notifications_enabled==TRUE){ this_service->notifications_enabled=template_service->notifications_enabled; this_service->have_notifications_enabled=TRUE; } if(this_service->have_notification_interval==FALSE && template_service->have_notification_interval==TRUE){ this_service->notification_interval=template_service->notification_interval; this_service->have_notification_interval=TRUE; } if(this_service->have_stalking_options==FALSE && template_service->have_stalking_options==TRUE){ this_service->stalk_on_ok=template_service->stalk_on_ok; this_service->stalk_on_unknown=template_service->stalk_on_unknown; this_service->stalk_on_warning=template_service->stalk_on_warning; this_service->stalk_on_critical=template_service->stalk_on_critical; this_service->have_stalking_options=TRUE; } if(this_service->have_process_perf_data==FALSE && template_service->have_process_perf_data==TRUE){ this_service->process_perf_data=template_service->process_perf_data; this_service->have_process_perf_data=TRUE; } if(this_service->have_failure_prediction_enabled==FALSE && template_service->have_failure_prediction_enabled==TRUE){ this_service->failure_prediction_enabled=template_service->failure_prediction_enabled; this_service->have_failure_prediction_enabled=TRUE; } if(this_service->have_retain_status_information==FALSE && template_service->have_retain_status_information==TRUE){ this_service->retain_status_information=template_service->retain_status_information; this_service->have_retain_status_information=TRUE; } if(this_service->have_retain_nonstatus_information==FALSE && template_service->have_retain_nonstatus_information==TRUE){ this_service->retain_nonstatus_information=template_service->retain_nonstatus_information; this_service->have_retain_nonstatus_information=TRUE; } #ifdef DEBUG0 printf("xodtemplate_resolve_service() end\n"); #endif return OK; } /* resolves a hostdependency object */ int xodtemplate_resolve_hostdependency(xodtemplate_hostdependency *this_hostdependency){ xodtemplate_hostdependency *template_hostdependency; #ifdef NSCORE char temp_buffer[MAX_XODTEMPLATE_INPUT_BUFFER]; #endif #ifdef DEBUG0 printf("xodtemplate_resolve_hostdependency() start\n"); #endif /* return if this hostdependency has already been resolved */ if(this_hostdependency->has_been_resolved==TRUE) return OK; /* set the resolved flag */ this_hostdependency->has_been_resolved=TRUE; /* return if we have no template */ if(this_hostdependency->template==NULL) return OK; template_hostdependency=xodtemplate_find_hostdependency(this_hostdependency->template); if(template_hostdependency==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Template '%s' specified in host dependency definition could not be not found (config file '%s', starting on line %d)\n",this_hostdependency->template,xodtemplate_config_file_name(this_hostdependency->_config_file),this_hostdependency->_start_line); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return ERROR; } /* resolve the template hostdependency... */ xodtemplate_resolve_hostdependency(template_hostdependency); /* apply missing properties from template hostdependency... */ if(this_hostdependency->hostgroup_name==NULL && template_hostdependency->hostgroup_name!=NULL) this_hostdependency->hostgroup_name=strdup(template_hostdependency->hostgroup_name); if(this_hostdependency->dependent_hostgroup_name==NULL && template_hostdependency->dependent_hostgroup_name!=NULL) this_hostdependency->dependent_hostgroup_name=strdup(template_hostdependency->dependent_hostgroup_name); if(this_hostdependency->host_name==NULL && template_hostdependency->host_name!=NULL) this_hostdependency->host_name=strdup(template_hostdependency->host_name); if(this_hostdependency->dependent_host_name==NULL && template_hostdependency->dependent_host_name!=NULL) this_hostdependency->dependent_host_name=strdup(template_hostdependency->dependent_host_name); if(this_hostdependency->have_inherits_parent==FALSE && template_hostdependency->have_inherits_parent==TRUE){ this_hostdependency->inherits_parent=template_hostdependency->inherits_parent; this_hostdependency->have_inherits_parent=TRUE; } if(this_hostdependency->have_execution_dependency_options==FALSE && template_hostdependency->have_execution_dependency_options==TRUE){ this_hostdependency->fail_execute_on_up=template_hostdependency->fail_execute_on_up; this_hostdependency->fail_execute_on_down=template_hostdependency->fail_execute_on_down; this_hostdependency->fail_execute_on_unreachable=template_hostdependency->fail_execute_on_unreachable; this_hostdependency->fail_execute_on_pending=template_hostdependency->fail_execute_on_pending; this_hostdependency->have_execution_dependency_options=TRUE; } if(this_hostdependency->have_notification_dependency_options==FALSE && template_hostdependency->have_notification_dependency_options==TRUE){ this_hostdependency->fail_notify_on_up=template_hostdependency->fail_notify_on_up; this_hostdependency->fail_notify_on_down=template_hostdependency->fail_notify_on_down; this_hostdependency->fail_notify_on_unreachable=template_hostdependency->fail_notify_on_unreachable; this_hostdependency->fail_notify_on_pending=template_hostdependency->fail_notify_on_pending; this_hostdependency->have_notification_dependency_options=TRUE; } #ifdef DEBUG0 printf("xodtemplate_resolve_hostdependency() end\n"); #endif return OK; } /* resolves a hostescalation object */ int xodtemplate_resolve_hostescalation(xodtemplate_hostescalation *this_hostescalation){ xodtemplate_hostescalation *template_hostescalation; #ifdef NSCORE char temp_buffer[MAX_XODTEMPLATE_INPUT_BUFFER]; #endif #ifdef DEBUG0 printf("xodtemplate_resolve_hostescalation() start\n"); #endif /* return if this hostescalation has already been resolved */ if(this_hostescalation->has_been_resolved==TRUE) return OK; /* set the resolved flag */ this_hostescalation->has_been_resolved=TRUE; /* return if we have no template */ if(this_hostescalation->template==NULL) return OK; template_hostescalation=xodtemplate_find_hostescalation(this_hostescalation->template); if(template_hostescalation==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Template '%s' specified in host escalation definition could not be not found (config file '%s', starting on line %d)\n",this_hostescalation->template,xodtemplate_config_file_name(this_hostescalation->_config_file),this_hostescalation->_start_line); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return ERROR; } /* resolve the template hostescalation... */ xodtemplate_resolve_hostescalation(template_hostescalation); /* apply missing properties from template hostescalation... */ if(this_hostescalation->host_name==NULL && template_hostescalation->host_name!=NULL) this_hostescalation->host_name=strdup(template_hostescalation->host_name); if(this_hostescalation->escalation_period==NULL && template_hostescalation->escalation_period!=NULL) this_hostescalation->escalation_period=strdup(template_hostescalation->escalation_period); if(this_hostescalation->contact_groups==NULL && template_hostescalation->contact_groups!=NULL) this_hostescalation->contact_groups=strdup(template_hostescalation->contact_groups); if(this_hostescalation->have_first_notification==FALSE && template_hostescalation->have_first_notification==TRUE){ this_hostescalation->first_notification=template_hostescalation->first_notification; this_hostescalation->have_first_notification=TRUE; } if(this_hostescalation->have_last_notification==FALSE && template_hostescalation->have_last_notification==TRUE){ this_hostescalation->last_notification=template_hostescalation->last_notification; this_hostescalation->have_last_notification=TRUE; } if(this_hostescalation->have_notification_interval==FALSE && template_hostescalation->have_notification_interval==TRUE){ this_hostescalation->notification_interval=template_hostescalation->notification_interval; this_hostescalation->have_notification_interval=TRUE; } if(this_hostescalation->have_escalation_options==FALSE && template_hostescalation->have_escalation_options==TRUE){ this_hostescalation->escalate_on_down=template_hostescalation->escalate_on_down; this_hostescalation->escalate_on_unreachable=template_hostescalation->escalate_on_unreachable; this_hostescalation->escalate_on_recovery=template_hostescalation->escalate_on_recovery; this_hostescalation->have_escalation_options=TRUE; } #ifdef DEBUG0 printf("xodtemplate_resolve_hostdependency() end\n"); #endif return OK; } /* resolves a hostextinfo object */ int xodtemplate_resolve_hostextinfo(xodtemplate_hostextinfo *this_hostextinfo){ xodtemplate_hostextinfo *template_hostextinfo; #ifdef NSCORE char temp_buffer[MAX_XODTEMPLATE_INPUT_BUFFER]; #endif #ifdef DEBUG0 printf("xodtemplate_resolve_hostextinfo() start\n"); #endif /* return if this object has already been resolved */ if(this_hostextinfo->has_been_resolved==TRUE) return OK; /* set the resolved flag */ this_hostextinfo->has_been_resolved=TRUE; /* return if we have no template */ if(this_hostextinfo->template==NULL) return OK; template_hostextinfo=xodtemplate_find_hostextinfo(this_hostextinfo->template); if(template_hostextinfo==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Template '%s' specified in extended host info definition could not be not found (config file '%s', starting on line %d)\n",this_hostextinfo->template,xodtemplate_config_file_name(this_hostextinfo->_config_file),this_hostextinfo->_start_line); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return ERROR; } /* resolve the template hostextinfo... */ xodtemplate_resolve_hostextinfo(template_hostextinfo); /* apply missing properties from template hostextinfo... */ if(this_hostextinfo->host_name==NULL && template_hostextinfo->host_name!=NULL) this_hostextinfo->host_name=strdup(template_hostextinfo->host_name); if(this_hostextinfo->hostgroup_name==NULL && template_hostextinfo->hostgroup_name!=NULL) this_hostextinfo->hostgroup_name=strdup(template_hostextinfo->hostgroup_name); if(this_hostextinfo->notes==NULL && template_hostextinfo->notes!=NULL) this_hostextinfo->notes=strdup(template_hostextinfo->notes); if(this_hostextinfo->notes_url==NULL && template_hostextinfo->notes_url!=NULL) this_hostextinfo->notes_url=strdup(template_hostextinfo->notes_url); if(this_hostextinfo->action_url==NULL && template_hostextinfo->action_url!=NULL) this_hostextinfo->action_url=strdup(template_hostextinfo->action_url); if(this_hostextinfo->icon_image==NULL && template_hostextinfo->icon_image!=NULL) this_hostextinfo->icon_image=strdup(template_hostextinfo->icon_image); if(this_hostextinfo->icon_image_alt==NULL && template_hostextinfo->icon_image_alt!=NULL) this_hostextinfo->icon_image_alt=strdup(template_hostextinfo->icon_image_alt); if(this_hostextinfo->vrml_image==NULL && template_hostextinfo->vrml_image!=NULL) this_hostextinfo->vrml_image=strdup(template_hostextinfo->vrml_image); if(this_hostextinfo->statusmap_image==NULL && template_hostextinfo->statusmap_image!=NULL) this_hostextinfo->statusmap_image=strdup(template_hostextinfo->statusmap_image); if(this_hostextinfo->have_2d_coords==FALSE && template_hostextinfo->have_2d_coords==TRUE){ this_hostextinfo->x_2d=template_hostextinfo->x_2d; this_hostextinfo->y_2d=template_hostextinfo->y_2d; this_hostextinfo->have_2d_coords=TRUE; } if(this_hostextinfo->have_3d_coords==FALSE && template_hostextinfo->have_3d_coords==TRUE){ this_hostextinfo->x_3d=template_hostextinfo->x_3d; this_hostextinfo->y_3d=template_hostextinfo->y_3d; this_hostextinfo->z_3d=template_hostextinfo->z_3d; this_hostextinfo->have_3d_coords=TRUE; } #ifdef DEBUG0 printf("xodtemplate_resolve_hostextinfo() end\n"); #endif return OK; } /* resolves a serviceextinfo object */ int xodtemplate_resolve_serviceextinfo(xodtemplate_serviceextinfo *this_serviceextinfo){ xodtemplate_serviceextinfo *template_serviceextinfo; #ifdef NSCORE char temp_buffer[MAX_XODTEMPLATE_INPUT_BUFFER]; #endif #ifdef DEBUG0 printf("xodtemplate_resolve_serviceextinfo() start\n"); #endif /* return if this object has already been resolved */ if(this_serviceextinfo->has_been_resolved==TRUE) return OK; /* set the resolved flag */ this_serviceextinfo->has_been_resolved=TRUE; /* return if we have no template */ if(this_serviceextinfo->template==NULL) return OK; template_serviceextinfo=xodtemplate_find_serviceextinfo(this_serviceextinfo->template); if(template_serviceextinfo==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Template '%s' specified in extended service info definition could not be not found (config file '%s', starting on line %d)\n",this_serviceextinfo->template,xodtemplate_config_file_name(this_serviceextinfo->_config_file),this_serviceextinfo->_start_line); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return ERROR; } /* resolve the template serviceextinfo... */ xodtemplate_resolve_serviceextinfo(template_serviceextinfo); /* apply missing properties from template serviceextinfo... */ if(this_serviceextinfo->host_name==NULL && template_serviceextinfo->host_name!=NULL) this_serviceextinfo->host_name=strdup(template_serviceextinfo->host_name); if(this_serviceextinfo->hostgroup_name==NULL && template_serviceextinfo->hostgroup_name!=NULL) this_serviceextinfo->hostgroup_name=strdup(template_serviceextinfo->hostgroup_name); if(this_serviceextinfo->service_description==NULL && template_serviceextinfo->service_description!=NULL) this_serviceextinfo->service_description=strdup(template_serviceextinfo->service_description); if(this_serviceextinfo->notes==NULL && template_serviceextinfo->notes!=NULL) this_serviceextinfo->notes=strdup(template_serviceextinfo->notes); if(this_serviceextinfo->notes_url==NULL && template_serviceextinfo->notes_url!=NULL) this_serviceextinfo->notes_url=strdup(template_serviceextinfo->notes_url); if(this_serviceextinfo->action_url==NULL && template_serviceextinfo->action_url!=NULL) this_serviceextinfo->action_url=strdup(template_serviceextinfo->action_url); if(this_serviceextinfo->icon_image==NULL && template_serviceextinfo->icon_image!=NULL) this_serviceextinfo->icon_image=strdup(template_serviceextinfo->icon_image); if(this_serviceextinfo->icon_image_alt==NULL && template_serviceextinfo->icon_image_alt!=NULL) this_serviceextinfo->icon_image_alt=strdup(template_serviceextinfo->icon_image_alt); #ifdef DEBUG0 printf("xodtemplate_resolve_serviceextinfo() end\n"); #endif return OK; } #endif /******************************************************************/ /*************** OBJECT RECOMBOBULATION FUNCTIONS *****************/ /******************************************************************/ #ifdef NSCORE /* recombobulates contactgroup definitions */ int xodtemplate_recombobulate_contactgroups(void){ xodtemplate_contact *temp_contact; xodtemplate_contactgroup *temp_contactgroup; xodtemplate_contactlist *temp_contactlist; xodtemplate_contactlist *this_contactlist; char *contactgroup_names; char *temp_ptr; char *new_members; #ifdef NSCORE char temp_buffer[MAX_XODTEMPLATE_INPUT_BUFFER]; #endif #ifdef DEBUG0 printf("xodtemplate_recombobulate_contactgroups() start\n"); #endif /* This should happen before we expand contactgroup members, to avoid duplicate contact memberships 01/07/2006 EG */ /* process all contacts that have contactgroup directives */ for(temp_contact=xodtemplate_contact_list;temp_contact!=NULL;temp_contact=temp_contact->next){ /* skip contacts without contactgroup directives or contact names */ if(temp_contact->contactgroups==NULL || temp_contact->contact_name==NULL) continue; /* process the list of contactgroups */ contactgroup_names=strdup(temp_contact->contactgroups); if(contactgroup_names==NULL) continue; for(temp_ptr=strtok(contactgroup_names,",");temp_ptr;temp_ptr=strtok(NULL,",")){ /* strip trailing spaces */ strip(temp_ptr); /* find the contactgroup */ temp_contactgroup=xodtemplate_find_real_contactgroup(temp_ptr); if(temp_contactgroup==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not find contactgroup '%s' specified in contact '%s' definition (config file '%s', starting on line %d)\n",temp_ptr,temp_contact->contact_name,xodtemplate_config_file_name(temp_contact->_config_file),temp_contact->_start_line); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif free(contactgroup_names); return ERROR; } /* add this contact to the contactgroup members directive */ if(temp_contactgroup->members==NULL) temp_contactgroup->members=strdup(temp_contact->contact_name); else{ new_members=(char *)realloc(temp_contactgroup->members,strlen(temp_contactgroup->members)+strlen(temp_contact->contact_name)+2); if(new_members!=NULL){ temp_contactgroup->members=new_members; strcat(temp_contactgroup->members,","); strcat(temp_contactgroup->members,temp_contact->contact_name); } } } /* free memory */ free(contactgroup_names); } /* expand members of all contactgroups - this could be done in xodtemplate_register_contactgroup(), but we can save the CGIs some work if we do it here */ for(temp_contactgroup=xodtemplate_contactgroup_list;temp_contactgroup;temp_contactgroup=temp_contactgroup->next){ if(temp_contactgroup->members==NULL) continue; /* get list of contacts in the contactgroup */ temp_contactlist=xodtemplate_expand_contacts(temp_contactgroup->members); /* add all members to the contact group */ if(temp_contactlist==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not expand member contacts specified in contactgroup (config file '%s', starting on line %d)\n",xodtemplate_config_file_name(temp_contactgroup->_config_file),temp_contactgroup->_start_line); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return ERROR; } free(temp_contactgroup->members); temp_contactgroup->members=NULL; for(this_contactlist=temp_contactlist;this_contactlist;this_contactlist=this_contactlist->next){ /* add this contact to the contactgroup members directive */ if(temp_contactgroup->members==NULL) temp_contactgroup->members=strdup(this_contactlist->contact_name); else{ new_members=(char *)realloc(temp_contactgroup->members,strlen(temp_contactgroup->members)+strlen(this_contactlist->contact_name)+2); if(new_members!=NULL){ temp_contactgroup->members=new_members; strcat(temp_contactgroup->members,","); strcat(temp_contactgroup->members,this_contactlist->contact_name); } } } xodtemplate_free_contactlist(temp_contactlist); } #ifdef DEBUG0 printf("xodtemplate_recombobulate_contactgroups() end\n"); #endif return OK; } /* recombobulates hostgroup definitions */ int xodtemplate_recombobulate_hostgroups(void){ xodtemplate_host *temp_host; xodtemplate_hostgroup *temp_hostgroup; xodtemplate_hostlist *temp_hostlist; xodtemplate_hostlist *this_hostlist; char *hostgroup_names; char *temp_ptr; char *new_members; #ifdef NSCORE char temp_buffer[MAX_XODTEMPLATE_INPUT_BUFFER]; #endif #ifdef DEBUG0 printf("xodtemplate_recombobulate_hostgroups() start\n"); #endif /* This should happen before we expand hostgroup members, to avoid duplicate host memberships 01/07/2006 EG */ /* process all hosts that have hostgroup directives */ for(temp_host=xodtemplate_host_list;temp_host!=NULL;temp_host=temp_host->next){ /* skip hosts without hostgroup directives or host names */ if(temp_host->hostgroups==NULL || temp_host->host_name==NULL) continue; /* skip hosts that shouldn't be registered */ if(temp_host->register_object==FALSE) continue; /* process the list of hostgroups */ hostgroup_names=strdup(temp_host->hostgroups); if(hostgroup_names==NULL) continue; for(temp_ptr=strtok(hostgroup_names,",");temp_ptr;temp_ptr=strtok(NULL,",")){ /* strip trailing spaces */ strip(temp_ptr); /* find the hostgroup */ temp_hostgroup=xodtemplate_find_real_hostgroup(temp_ptr); if(temp_hostgroup==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not find hostgroup '%s' specified in host '%s' definition (config file '%s', starting on line %d)\n",temp_ptr,temp_host->host_name,xodtemplate_config_file_name(temp_host->_config_file),temp_host->_start_line); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif free(hostgroup_names); return ERROR; } /* add this list to the hostgroup members directive */ if(temp_hostgroup->members==NULL) temp_hostgroup->members=strdup(temp_host->host_name); else{ new_members=(char *)realloc(temp_hostgroup->members,strlen(temp_hostgroup->members)+strlen(temp_host->host_name)+2); if(new_members!=NULL){ temp_hostgroup->members=new_members; strcat(temp_hostgroup->members,","); strcat(temp_hostgroup->members,temp_host->host_name); } } } /* free memory */ free(hostgroup_names); } /* expand members of all hostgroups - this could be done in xodtemplate_register_hostgroup(), but we can save the CGIs some work if we do it here */ for(temp_hostgroup=xodtemplate_hostgroup_list;temp_hostgroup;temp_hostgroup=temp_hostgroup->next){ if(temp_hostgroup->members==NULL) continue; /* skip hostgroups that shouldn't be registered */ if(temp_hostgroup->register_object==FALSE) continue; /* get list of hosts in the hostgroup */ temp_hostlist=xodtemplate_expand_hostgroups_and_hosts(NULL,temp_hostgroup->members); /* add all members to the host group */ if(temp_hostlist==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not expand member hosts specified in hostgroup (config file '%s', starting on line %d)\n",xodtemplate_config_file_name(temp_hostgroup->_config_file),temp_hostgroup->_start_line); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return ERROR; } free(temp_hostgroup->members); temp_hostgroup->members=NULL; for(this_hostlist=temp_hostlist;this_hostlist;this_hostlist=this_hostlist->next){ /* add this host to the hostgroup members directive */ if(temp_hostgroup->members==NULL) temp_hostgroup->members=strdup(this_hostlist->host_name); else{ new_members=(char *)realloc(temp_hostgroup->members,strlen(temp_hostgroup->members)+strlen(this_hostlist->host_name)+2); if(new_members!=NULL){ temp_hostgroup->members=new_members; strcat(temp_hostgroup->members,","); strcat(temp_hostgroup->members,this_hostlist->host_name); } } } xodtemplate_free_hostlist(temp_hostlist); } #ifdef DEBUG0 printf("xodtemplate_recombobulate_hostgroups() end\n"); #endif return OK; } /* recombobulates servicegroup definitions */ /***** THIS NEEDS TO BE CALLED AFTER OBJECTS (SERVICES) ARE RESOLVED AND DUPLICATED *****/ int xodtemplate_recombobulate_servicegroups(void){ xodtemplate_service *temp_service=NULL; xodtemplate_servicegroup *temp_servicegroup; xodtemplate_servicelist *temp_servicelist; xodtemplate_servicelist *this_servicelist; char *servicegroup_names; char *member_names; char *host_name=NULL; char *service_description=NULL; char *temp_ptr; char *temp_ptr2; char *new_members; #ifdef NSCORE char temp_buffer[MAX_XODTEMPLATE_INPUT_BUFFER]; #endif #ifdef DEBUG0 printf("xodtemplate_recombobulate_servicegroups() start\n"); #endif /* This should happen before we expand servicegroup members, to avoid duplicate service memberships 01/07/2006 EG */ /* process all services that have servicegroup directives */ for(temp_service=xodtemplate_service_list;temp_service!=NULL;temp_service=temp_service->next){ /* skip services without servicegroup directives or service names */ if(temp_service->servicegroups==NULL || temp_service->host_name==NULL || temp_service->service_description==NULL) continue; /* skip services that shouldn't be registered */ if(temp_service->register_object==FALSE) continue; /* process the list of servicegroups */ servicegroup_names=strdup(temp_service->servicegroups); if(servicegroup_names==NULL) continue; for(temp_ptr=strtok(servicegroup_names,",");temp_ptr;temp_ptr=strtok(NULL,",")){ /* strip trailing spaces */ strip(temp_ptr); /* find the servicegroup */ temp_servicegroup=xodtemplate_find_real_servicegroup(temp_ptr); if(temp_servicegroup==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not find servicegroup '%s' specified in service '%s' on host '%s' definition (config file '%s', starting on line %d)\n",temp_ptr,temp_service->service_description,temp_service->host_name,xodtemplate_config_file_name(temp_service->_config_file),temp_service->_start_line); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif free(servicegroup_names); return ERROR; } /* add this list to the servicegroup members directive */ if(temp_servicegroup->members==NULL){ temp_servicegroup->members=(char *)malloc(strlen(temp_service->host_name)+strlen(temp_service->service_description)+2); if(temp_servicegroup->members!=NULL){ strcpy(temp_servicegroup->members,temp_service->host_name); strcat(temp_servicegroup->members,","); strcat(temp_servicegroup->members,temp_service->service_description); } } else{ new_members=(char *)realloc(temp_servicegroup->members,strlen(temp_servicegroup->members)+strlen(temp_service->host_name)+strlen(temp_service->service_description)+3); if(new_members!=NULL){ temp_servicegroup->members=new_members; strcat(temp_servicegroup->members,","); strcat(temp_servicegroup->members,temp_service->host_name); strcat(temp_servicegroup->members,","); strcat(temp_servicegroup->members,temp_service->service_description); } } } } /* expand members of all servicegroups - this could be done in xodtemplate_register_servicegroup(), but we can save the CGIs some work if we do it here */ for(temp_servicegroup=xodtemplate_servicegroup_list;temp_servicegroup;temp_servicegroup=temp_servicegroup->next){ if(temp_servicegroup->members==NULL) continue; /* skip servicegroups that shouldn't be registered */ if(temp_servicegroup->register_object==FALSE) continue; member_names=temp_servicegroup->members; temp_servicegroup->members=NULL; for(temp_ptr=member_names;temp_ptr;temp_ptr=strchr(temp_ptr+1,',')){ /* this is the host name */ if(host_name==NULL) host_name=strdup((temp_ptr[0]==',')?temp_ptr+1:temp_ptr); /* this is the service description */ else{ service_description=strdup(temp_ptr+1); /* strsep and strtok cannot be used, as they're used in expand_servicegroups...() */ temp_ptr2=strchr(host_name,','); if(temp_ptr2) temp_ptr2[0]='\x0'; temp_ptr2=strchr(service_description,','); if(temp_ptr2) temp_ptr2[0]='\x0'; /* strip trailing spaces */ strip(host_name); strip(service_description); /* get list of services in the servicegroup */ temp_servicelist=xodtemplate_expand_servicegroups_and_services(NULL,host_name,service_description); /* add all members to the service group */ if(temp_servicelist==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not expand member services specified in servicegroup (config file '%s', starting on line %d)\n",xodtemplate_config_file_name(temp_servicegroup->_config_file),temp_servicegroup->_start_line); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif free(member_names); free(host_name); free(service_description); return ERROR; } for(this_servicelist=temp_servicelist;this_servicelist;this_servicelist=this_servicelist->next){ /* add this service to the servicegroup members directive */ if(temp_servicegroup->members==NULL){ temp_servicegroup->members=(char *)malloc(strlen(this_servicelist->host_name)+strlen(this_servicelist->service_description)+2); if(temp_servicegroup!=NULL){ strcpy(temp_servicegroup->members,this_servicelist->host_name); strcat(temp_servicegroup->members,","); strcat(temp_servicegroup->members,this_servicelist->service_description); } } else{ new_members=(char *)realloc(temp_servicegroup->members,strlen(temp_servicegroup->members)+strlen(this_servicelist->host_name)+strlen(this_servicelist->service_description)+3); if(new_members!=NULL){ temp_servicegroup->members=new_members; strcat(temp_servicegroup->members,","); strcat(temp_servicegroup->members,this_servicelist->host_name); strcat(temp_servicegroup->members,","); strcat(temp_servicegroup->members,this_servicelist->service_description); } } } xodtemplate_free_servicelist(temp_servicelist); free(host_name); free(service_description); host_name=NULL; service_description=NULL; } } free(member_names); /* error if there were an odd number of items specified (unmatched host/service pair) */ if(host_name!=NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Servicegroup members must be specified in , pairs (config file '%s', starting on line %d)\n",xodtemplate_config_file_name(temp_servicegroup->_config_file),temp_servicegroup->_start_line); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif free(host_name); return ERROR; } } #ifdef DEBUG0 printf("xodtemplate_recombobulate_servicegroups() end\n"); #endif return OK; } #endif /******************************************************************/ /******************* OBJECT SEARCH FUNCTIONS **********************/ /******************************************************************/ #ifdef NSCORE /* finds a specific timeperiod object */ xodtemplate_timeperiod *xodtemplate_find_timeperiod(char *name){ xodtemplate_timeperiod *temp_timeperiod; if(name==NULL) return NULL; for(temp_timeperiod=xodtemplate_timeperiod_list;temp_timeperiod!=NULL;temp_timeperiod=temp_timeperiod->next){ if(temp_timeperiod->name==NULL) continue; if(!strcmp(temp_timeperiod->name,name)) break; } return temp_timeperiod; } /* finds a specific command object */ xodtemplate_command *xodtemplate_find_command(char *name){ xodtemplate_command *temp_command; if(name==NULL) return NULL; for(temp_command=xodtemplate_command_list;temp_command!=NULL;temp_command=temp_command->next){ if(temp_command->name==NULL) continue; if(!strcmp(temp_command->name,name)) break; } return temp_command; } /* finds a specific contactgroup object */ xodtemplate_contactgroup *xodtemplate_find_contactgroup(char *name){ xodtemplate_contactgroup *temp_contactgroup; if(name==NULL) return NULL; for(temp_contactgroup=xodtemplate_contactgroup_list;temp_contactgroup!=NULL;temp_contactgroup=temp_contactgroup->next){ if(temp_contactgroup->name==NULL) continue; if(!strcmp(temp_contactgroup->name,name)) break; } return temp_contactgroup; } /* finds a specific contactgroup object by its REAL name, not its TEMPLATE name */ xodtemplate_contactgroup *xodtemplate_find_real_contactgroup(char *name){ xodtemplate_contactgroup *temp_contactgroup; if(name==NULL) return NULL; for(temp_contactgroup=xodtemplate_contactgroup_list;temp_contactgroup!=NULL;temp_contactgroup=temp_contactgroup->next){ if(temp_contactgroup->register_object==FALSE) continue; if(temp_contactgroup->contactgroup_name==NULL) continue; if(!strcmp(temp_contactgroup->contactgroup_name,name)) break; } return temp_contactgroup; } /* finds a specific hostgroup object */ xodtemplate_hostgroup *xodtemplate_find_hostgroup(char *name){ xodtemplate_hostgroup *temp_hostgroup; if(name==NULL) return NULL; for(temp_hostgroup=xodtemplate_hostgroup_list;temp_hostgroup!=NULL;temp_hostgroup=temp_hostgroup->next){ if(temp_hostgroup->name==NULL) continue; if(!strcmp(temp_hostgroup->name,name)) break; } return temp_hostgroup; } /* finds a specific hostgroup object by its REAL name, not its TEMPLATE name */ xodtemplate_hostgroup *xodtemplate_find_real_hostgroup(char *name){ xodtemplate_hostgroup *temp_hostgroup; if(name==NULL) return NULL; for(temp_hostgroup=xodtemplate_hostgroup_list;temp_hostgroup!=NULL;temp_hostgroup=temp_hostgroup->next){ if(temp_hostgroup->register_object==FALSE) continue; if(temp_hostgroup->hostgroup_name==NULL) continue; if(!strcmp(temp_hostgroup->hostgroup_name,name)) break; } return temp_hostgroup; } /* finds a specific servicegroup object */ xodtemplate_servicegroup *xodtemplate_find_servicegroup(char *name){ xodtemplate_servicegroup *temp_servicegroup; if(name==NULL) return NULL; for(temp_servicegroup=xodtemplate_servicegroup_list;temp_servicegroup!=NULL;temp_servicegroup=temp_servicegroup->next){ if(temp_servicegroup->name==NULL) continue; if(!strcmp(temp_servicegroup->name,name)) break; } return temp_servicegroup; } /* finds a specific servicegroup object by its REAL name, not its TEMPLATE name */ xodtemplate_servicegroup *xodtemplate_find_real_servicegroup(char *name){ xodtemplate_servicegroup *temp_servicegroup; if(name==NULL) return NULL; for(temp_servicegroup=xodtemplate_servicegroup_list;temp_servicegroup!=NULL;temp_servicegroup=temp_servicegroup->next){ if(temp_servicegroup->register_object==FALSE) continue; if(temp_servicegroup->servicegroup_name==NULL) continue; if(!strcmp(temp_servicegroup->servicegroup_name,name)) break; } return temp_servicegroup; } /* finds a specific servicedependency object */ xodtemplate_servicedependency *xodtemplate_find_servicedependency(char *name){ xodtemplate_servicedependency *temp_servicedependency; if(name==NULL) return NULL; for(temp_servicedependency=xodtemplate_servicedependency_list;temp_servicedependency!=NULL;temp_servicedependency=temp_servicedependency->next){ if(temp_servicedependency->name==NULL) continue; if(!strcmp(temp_servicedependency->name,name)) break; } return temp_servicedependency; } /* finds a specific serviceescalation object */ xodtemplate_serviceescalation *xodtemplate_find_serviceescalation(char *name){ xodtemplate_serviceescalation *temp_serviceescalation; if(name==NULL) return NULL; for(temp_serviceescalation=xodtemplate_serviceescalation_list;temp_serviceescalation!=NULL;temp_serviceescalation=temp_serviceescalation->next){ if(temp_serviceescalation->name==NULL) continue; if(!strcmp(temp_serviceescalation->name,name)) break; } return temp_serviceescalation; } /* finds a specific contact object */ xodtemplate_contact *xodtemplate_find_contact(char *name){ xodtemplate_contact *temp_contact; if(name==NULL) return NULL; for(temp_contact=xodtemplate_contact_list;temp_contact!=NULL;temp_contact=temp_contact->next){ if(temp_contact->name==NULL) continue; if(!strcmp(temp_contact->name,name)) break; } return temp_contact; } /* finds a specific contact object by its REAL name, not its TEMPLATE name */ xodtemplate_contact *xodtemplate_find_real_contact(char *name){ xodtemplate_contact *temp_contact; if(name==NULL) return NULL; for(temp_contact=xodtemplate_contact_list;temp_contact!=NULL;temp_contact=temp_contact->next){ if(temp_contact->register_object==FALSE) continue; if(temp_contact->contact_name==NULL) continue; if(!strcmp(temp_contact->contact_name,name)) break; } return temp_contact; } /* finds a specific host object */ xodtemplate_host *xodtemplate_find_host(char *name){ xodtemplate_host *temp_host; if(name==NULL) return NULL; for(temp_host=xodtemplate_host_list;temp_host!=NULL;temp_host=temp_host->next){ if(temp_host->name==NULL) continue; if(!strcmp(temp_host->name,name)) break; } return temp_host; } /* finds a specific host object by its REAL name, not its TEMPLATE name */ xodtemplate_host *xodtemplate_find_real_host(char *name){ xodtemplate_host *temp_host; if(name==NULL) return NULL; for(temp_host=xodtemplate_host_list;temp_host!=NULL;temp_host=temp_host->next){ if(temp_host->register_object==FALSE) continue; if(temp_host->host_name==NULL) continue; if(!strcmp(temp_host->host_name,name)) break; } return temp_host; } /* finds a specific hostdependency object */ xodtemplate_hostdependency *xodtemplate_find_hostdependency(char *name){ xodtemplate_hostdependency *temp_hostdependency; if(name==NULL) return NULL; for(temp_hostdependency=xodtemplate_hostdependency_list;temp_hostdependency!=NULL;temp_hostdependency=temp_hostdependency->next){ if(temp_hostdependency->name==NULL) continue; if(!strcmp(temp_hostdependency->name,name)) break; } return temp_hostdependency; } /* finds a specific hostescalation object */ xodtemplate_hostescalation *xodtemplate_find_hostescalation(char *name){ xodtemplate_hostescalation *temp_hostescalation; if(name==NULL) return NULL; for(temp_hostescalation=xodtemplate_hostescalation_list;temp_hostescalation!=NULL;temp_hostescalation=temp_hostescalation->next){ if(temp_hostescalation->name==NULL) continue; if(!strcmp(temp_hostescalation->name,name)) break; } return temp_hostescalation; } /* finds a specific hostextinfo object */ xodtemplate_hostextinfo *xodtemplate_find_hostextinfo(char *name){ xodtemplate_hostextinfo *temp_hostextinfo; if(name==NULL) return NULL; for(temp_hostextinfo=xodtemplate_hostextinfo_list;temp_hostextinfo!=NULL;temp_hostextinfo=temp_hostextinfo->next){ if(temp_hostextinfo->name==NULL) continue; if(!strcmp(temp_hostextinfo->name,name)) break; } return temp_hostextinfo; } /* finds a specific serviceextinfo object */ xodtemplate_serviceextinfo *xodtemplate_find_serviceextinfo(char *name){ xodtemplate_serviceextinfo *temp_serviceextinfo; if(name==NULL) return NULL; for(temp_serviceextinfo=xodtemplate_serviceextinfo_list;temp_serviceextinfo!=NULL;temp_serviceextinfo=temp_serviceextinfo->next){ if(temp_serviceextinfo->name==NULL) continue; if(!strcmp(temp_serviceextinfo->name,name)) break; } return temp_serviceextinfo; } /* finds a specific service object */ xodtemplate_service *xodtemplate_find_service(char *name){ xodtemplate_service *temp_service; for(temp_service=xodtemplate_service_list;temp_service!=NULL;temp_service=temp_service->next){ if(temp_service->name==NULL) continue; if(!strcmp(temp_service->name,name)) break; } return temp_service; } /* finds a specific service object by its REAL name, not its TEMPLATE name */ xodtemplate_service *xodtemplate_find_real_service(char *host_name, char *service_description){ xodtemplate_service *temp_service; if(host_name==NULL || service_description==NULL || xodtemplate_service_list==NULL) return NULL; for(temp_service=xodtemplate_service_list;temp_service!=NULL;temp_service=temp_service->next){ if(temp_service->register_object==FALSE) continue; if(temp_service->host_name==NULL || temp_service->service_description==NULL) continue; if(!strcmp(host_name,temp_service->host_name) && !strcmp(service_description,temp_service->service_description)) break; } return temp_service; } #endif /******************************************************************/ /**************** OBJECT REGISTRATION FUNCTIONS *******************/ /******************************************************************/ /* registers object definitions */ int xodtemplate_register_objects(void){ int result=OK; xodtemplate_timeperiod *temp_timeperiod; xodtemplate_command *temp_command; xodtemplate_contactgroup *temp_contactgroup; xodtemplate_hostgroup *temp_hostgroup; xodtemplate_servicegroup *temp_servicegroup; xodtemplate_contact *temp_contact; xodtemplate_host *temp_host; xodtemplate_service *temp_service; xodtemplate_servicedependency *temp_servicedependency; xodtemplate_serviceescalation *temp_serviceescalation; xodtemplate_hostdependency *temp_hostdependency; xodtemplate_hostescalation *temp_hostescalation; xodtemplate_hostextinfo *temp_hostextinfo; xodtemplate_serviceextinfo *temp_serviceextinfo; #ifdef DEBUG0 printf("xodtemplate_register_objects() start\n"); #endif /* register timeperiods */ for(temp_timeperiod=xodtemplate_timeperiod_list;temp_timeperiod!=NULL;temp_timeperiod=temp_timeperiod->next){ if((result=xodtemplate_register_timeperiod(temp_timeperiod))==ERROR) return ERROR; } /* register commands */ for(temp_command=xodtemplate_command_list;temp_command!=NULL;temp_command=temp_command->next){ if((result=xodtemplate_register_command(temp_command))==ERROR) return ERROR; } /* register contactgroups */ for(temp_contactgroup=xodtemplate_contactgroup_list;temp_contactgroup!=NULL;temp_contactgroup=temp_contactgroup->next){ if((result=xodtemplate_register_contactgroup(temp_contactgroup))==ERROR) return ERROR; } /* register hostgroups */ for(temp_hostgroup=xodtemplate_hostgroup_list;temp_hostgroup!=NULL;temp_hostgroup=temp_hostgroup->next){ if((result=xodtemplate_register_hostgroup(temp_hostgroup))==ERROR) return ERROR; } /* register servicegroups */ for(temp_servicegroup=xodtemplate_servicegroup_list;temp_servicegroup!=NULL;temp_servicegroup=temp_servicegroup->next){ if((result=xodtemplate_register_servicegroup(temp_servicegroup))==ERROR) return ERROR; } /* register contacts */ for(temp_contact=xodtemplate_contact_list;temp_contact!=NULL;temp_contact=temp_contact->next){ if((result=xodtemplate_register_contact(temp_contact))==ERROR) return ERROR; } /* register hosts */ for(temp_host=xodtemplate_host_list;temp_host!=NULL;temp_host=temp_host->next){ if((result=xodtemplate_register_host(temp_host))==ERROR) return ERROR; } /* register services */ for(temp_service=xodtemplate_service_list;temp_service!=NULL;temp_service=temp_service->next){ if((result=xodtemplate_register_service(temp_service))==ERROR) return ERROR; } /* register service dependencies */ for(temp_servicedependency=xodtemplate_servicedependency_list;temp_servicedependency!=NULL;temp_servicedependency=temp_servicedependency->next){ if((result=xodtemplate_register_servicedependency(temp_servicedependency))==ERROR) return ERROR; } /* register service escalations */ for(temp_serviceescalation=xodtemplate_serviceescalation_list;temp_serviceescalation!=NULL;temp_serviceescalation=temp_serviceescalation->next){ if((result=xodtemplate_register_serviceescalation(temp_serviceescalation))==ERROR) return ERROR; } /* register host dependencies */ for(temp_hostdependency=xodtemplate_hostdependency_list;temp_hostdependency!=NULL;temp_hostdependency=temp_hostdependency->next){ if((result=xodtemplate_register_hostdependency(temp_hostdependency))==ERROR) return ERROR; } /* register host escalations */ for(temp_hostescalation=xodtemplate_hostescalation_list;temp_hostescalation!=NULL;temp_hostescalation=temp_hostescalation->next){ if((result=xodtemplate_register_hostescalation(temp_hostescalation))==ERROR) return ERROR; } /* register host extended info */ for(temp_hostextinfo=xodtemplate_hostextinfo_list;temp_hostextinfo!=NULL;temp_hostextinfo=temp_hostextinfo->next){ if((result=xodtemplate_register_hostextinfo(temp_hostextinfo))==ERROR) return ERROR; } /* register service extended info */ for(temp_serviceextinfo=xodtemplate_serviceextinfo_list;temp_serviceextinfo!=NULL;temp_serviceextinfo=temp_serviceextinfo->next){ if((result=xodtemplate_register_serviceextinfo(temp_serviceextinfo))==ERROR) return ERROR; } #ifdef DEBUG0 printf("xodtemplate_register_objects() end\n"); #endif return OK; } /* registers a timeperiod definition */ int xodtemplate_register_timeperiod(xodtemplate_timeperiod *this_timeperiod){ timeperiod *new_timeperiod; timerange *new_timerange; int day; char *day_range_ptr; char *day_range_start_buffer; char *range_ptr; char *range_buffer; char *time_ptr; char *time_buffer; int hours; int minutes; unsigned long range_start_time; unsigned long range_end_time; #ifdef NSCORE char temp_buffer[MAX_XODTEMPLATE_INPUT_BUFFER]; #endif #ifdef DEBUG0 printf("xodtemplate_register_timeperiod() start\n"); #endif /* bail out if we shouldn't register this object */ if(this_timeperiod->register_object==FALSE) return OK; /* add the timeperiod */ new_timeperiod=add_timeperiod(this_timeperiod->timeperiod_name,this_timeperiod->alias); /* return with an error if we couldn't add the timeperiod */ if(new_timeperiod==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not register timeperiod (config file '%s', starting on line %d)\n",xodtemplate_config_file_name(this_timeperiod->_config_file),this_timeperiod->_start_line); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return ERROR; } /* add all necessary timeranges to timeperiod */ for(day=0;day<7;day++){ if(this_timeperiod->timeranges[day]==NULL) continue; day_range_ptr=this_timeperiod->timeranges[day]; for(day_range_start_buffer=my_strsep(&day_range_ptr,", ");day_range_start_buffer!=NULL;day_range_start_buffer=my_strsep(&day_range_ptr,", ")){ range_ptr=day_range_start_buffer; range_buffer=my_strsep(&range_ptr,"-"); if(range_buffer==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not add timerange for day %d to timeperiod (No start time delimiter) (config file '%s', starting on line %d)\n",day,xodtemplate_config_file_name(this_timeperiod->_config_file),this_timeperiod->_start_line); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return ERROR; } time_ptr=range_buffer; time_buffer=my_strsep(&time_ptr,":"); if(time_buffer==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not add timerange for day %d to timeperiod (No start time hours) (config file '%s', starting on line %d)\n",day,xodtemplate_config_file_name(this_timeperiod->_config_file),this_timeperiod->_start_line); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return ERROR; } hours=atoi(time_buffer); time_buffer=my_strsep(&time_ptr,":"); if(time_buffer==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not add timerange for day %d to timeperiod (No start time minutes) (config file '%s', starting on line %d)\n",day,xodtemplate_config_file_name(this_timeperiod->_config_file),this_timeperiod->_start_line); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return ERROR; } minutes=atoi(time_buffer); /* calculate the range start time in seconds */ range_start_time=(unsigned long)((minutes*60)+(hours*60*60)); range_buffer=my_strsep(&range_ptr,"-"); if(range_buffer==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not add timerange for day %d to timeperiod (No end time delimiter) (config file '%s', starting on line %d)\n",day,xodtemplate_config_file_name(this_timeperiod->_config_file),this_timeperiod->_start_line); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return ERROR; } time_ptr=range_buffer; time_buffer=my_strsep(&time_ptr,":"); if(time_buffer==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not add timerange for day %d to timeperiod (No end time hours) (config file '%s', starting on line %d)\n",day,xodtemplate_config_file_name(this_timeperiod->_config_file),this_timeperiod->_start_line); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return ERROR; } hours=atoi(time_buffer); time_buffer=my_strsep(&time_ptr,":"); if(time_buffer==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not add timerange for day %d to timeperiod (No end time minutes) (config file '%s', starting on line %d)\n",day,xodtemplate_config_file_name(this_timeperiod->_config_file),this_timeperiod->_start_line); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return ERROR; } minutes=atoi(time_buffer); /* calculate the range end time in seconds */ range_end_time=(unsigned long)((minutes*60)+(hours*3600)); /* add the new time range to the time period */ new_timerange=add_timerange_to_timeperiod(new_timeperiod,day,range_start_time,range_end_time); if(new_timerange==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not add timerange for day %d to timeperiod (config file '%s', starting on line %d)\n",day,xodtemplate_config_file_name(this_timeperiod->_config_file),this_timeperiod->_start_line); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return ERROR; } } } #ifdef DEBUG0 printf("xodtemplate_register_timeperiod() end\n"); #endif return OK; } /* registers a command definition */ int xodtemplate_register_command(xodtemplate_command *this_command){ command *new_command; #ifdef NSCORE char temp_buffer[MAX_XODTEMPLATE_INPUT_BUFFER]; #endif #ifdef DEBUG0 printf("xodtemplate_register_command() start\n"); #endif /* bail out if we shouldn't register this object */ if(this_command->register_object==FALSE) return OK; /* add the command */ new_command=add_command(this_command->command_name,this_command->command_line); /* return with an error if we couldn't add the command */ if(new_command==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not register command (config file '%s', starting on line %d)\n",xodtemplate_config_file_name(this_command->_config_file),this_command->_start_line); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return ERROR; } #ifdef DEBUG0 printf("xodtemplate_register_command() end\n"); #endif return OK; } /* registers a contactgroup definition */ int xodtemplate_register_contactgroup(xodtemplate_contactgroup *this_contactgroup){ contactgroup *new_contactgroup; contactgroupmember *new_contactgroupmember; char *contact_name; #ifdef NSCORE char temp_buffer[MAX_XODTEMPLATE_INPUT_BUFFER]; #endif #ifdef DEBUG0 printf("xodtemplate_register_contactgroup() start\n"); #endif /* bail out if we shouldn't register this object */ if(this_contactgroup->register_object==FALSE) return OK; /* add the contact group */ new_contactgroup=add_contactgroup(this_contactgroup->contactgroup_name,this_contactgroup->alias); /* return with an error if we couldn't add the contactgroup */ if(new_contactgroup==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not register contactgroup (config file '%s', starting on line %d)\n",xodtemplate_config_file_name(this_contactgroup->_config_file),this_contactgroup->_start_line); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return ERROR; } /* add all members to the contact group */ if(this_contactgroup->members==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Contactgroup has no members (config file '%s', starting on line %d)\n",xodtemplate_config_file_name(this_contactgroup->_config_file),this_contactgroup->_start_line); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return ERROR; } for(contact_name=strtok(this_contactgroup->members,",");contact_name!=NULL;contact_name=strtok(NULL,",")){ strip(contact_name); new_contactgroupmember=add_contact_to_contactgroup(new_contactgroup,contact_name); if(new_contactgroupmember==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not add contact '%s' to contactgroup (config file '%s', starting on line %d)\n",contact_name,xodtemplate_config_file_name(this_contactgroup->_config_file),this_contactgroup->_start_line); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return ERROR; } } #ifdef DEBUG0 printf("xodtemplate_register_contactgroup() end\n"); #endif return OK; } /* registers a hostgroup definition */ int xodtemplate_register_hostgroup(xodtemplate_hostgroup *this_hostgroup){ hostgroup *new_hostgroup; hostgroupmember *new_hostgroupmember; char *host_name; #ifdef NSCORE char temp_buffer[MAX_XODTEMPLATE_INPUT_BUFFER]; #endif #ifdef DEBUG0 printf("xodtemplate_register_hostgroup() start\n"); #endif /* bail out if we shouldn't register this object */ if(this_hostgroup->register_object==FALSE) return OK; /* add the host group */ new_hostgroup=add_hostgroup(this_hostgroup->hostgroup_name,this_hostgroup->alias); /* return with an error if we couldn't add the hostgroup */ if(new_hostgroup==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not register hostgroup (config file '%s', starting on line %d)\n",xodtemplate_config_file_name(this_hostgroup->_config_file),this_hostgroup->_start_line); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return ERROR; } /* add all members to hostgroup */ if(this_hostgroup->members==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Hostgroup has no members (config file '%s', starting on line %d)\n",xodtemplate_config_file_name(this_hostgroup->_config_file),this_hostgroup->_start_line); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return ERROR; } for(host_name=strtok(this_hostgroup->members,",");host_name!=NULL;host_name=strtok(NULL,",")){ strip(host_name); new_hostgroupmember=add_host_to_hostgroup(new_hostgroup,host_name); if(new_hostgroupmember==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not add host '%s' to hostgroup (config file '%s', starting on line %d)\n",host_name,xodtemplate_config_file_name(this_hostgroup->_config_file),this_hostgroup->_start_line); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return ERROR; } } #ifdef DEBUG0 printf("xodtemplate_register_hostgroup() end\n"); #endif return OK; } /* registers a servicegroup definition */ int xodtemplate_register_servicegroup(xodtemplate_servicegroup *this_servicegroup){ servicegroup *new_servicegroup; servicegroupmember *new_servicegroupmember; char *host_name; char *svc_description; #ifdef NSCORE char temp_buffer[MAX_XODTEMPLATE_INPUT_BUFFER]; #endif #ifdef DEBUG0 printf("xodtemplate_register_servicegroup() start\n"); #endif /* bail out if we shouldn't register this object */ if(this_servicegroup->register_object==FALSE) return OK; /* add the service group */ new_servicegroup=add_servicegroup(this_servicegroup->servicegroup_name,this_servicegroup->alias); /* return with an error if we couldn't add the servicegroup */ if(new_servicegroup==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not register servicegroup (config file '%s', starting on line %d)\n",xodtemplate_config_file_name(this_servicegroup->_config_file),this_servicegroup->_start_line); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return ERROR; } /* add all members to servicegroup */ if(this_servicegroup->members==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Servicegroup has no members (config file '%s', starting on line %d)\n",xodtemplate_config_file_name(this_servicegroup->_config_file),this_servicegroup->_start_line); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return ERROR; } for(host_name=strtok(this_servicegroup->members,",");host_name!=NULL;host_name=strtok(NULL,",")){ strip(host_name); svc_description=strtok(NULL,","); if(svc_description==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Missing service name in servicegroup definition (config file '%s', starting on line %d)\n",xodtemplate_config_file_name(this_servicegroup->_config_file),this_servicegroup->_start_line); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return ERROR; } strip(svc_description); new_servicegroupmember=add_service_to_servicegroup(new_servicegroup,host_name,svc_description); if(new_servicegroupmember==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not add service '%s' on host '%s' to servicegroup (config file '%s', starting on line %d)\n",svc_description,host_name,xodtemplate_config_file_name(this_servicegroup->_config_file),this_servicegroup->_start_line); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return ERROR; } } #ifdef DEBUG0 printf("xodtemplate_register_servicegroup() end\n"); #endif return OK; } /* registers a servicedependency definition */ int xodtemplate_register_servicedependency(xodtemplate_servicedependency *this_servicedependency){ servicedependency *new_servicedependency; #ifdef NSCORE char temp_buffer[MAX_XODTEMPLATE_INPUT_BUFFER]; #endif #ifdef DEBUG0 printf("xodtemplate_register_servicedependency() start\n"); #endif /* bail out if we shouldn't register this object */ if(this_servicedependency->register_object==FALSE) return OK; /* throw a warning on servicedeps that have no options */ if(this_servicedependency->have_notification_dependency_options==FALSE && this_servicedependency->have_execution_dependency_options==FALSE){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Warning: Ignoring lame service dependency (config file '%s', line %d)\n",xodtemplate_config_file_name(this_servicedependency->_config_file),this_servicedependency->_start_line); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_WARNING,TRUE); #endif return OK; } /* add the servicedependency */ if(this_servicedependency->have_execution_dependency_options==TRUE){ new_servicedependency=add_service_dependency(this_servicedependency->dependent_host_name,this_servicedependency->dependent_service_description,this_servicedependency->host_name,this_servicedependency->service_description,EXECUTION_DEPENDENCY,this_servicedependency->inherits_parent,this_servicedependency->fail_execute_on_ok,this_servicedependency->fail_execute_on_warning,this_servicedependency->fail_execute_on_unknown,this_servicedependency->fail_execute_on_critical,this_servicedependency->fail_execute_on_pending); /* return with an error if we couldn't add the servicedependency */ if(new_servicedependency==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not register service execution dependency (config file '%s', starting on line %d)\n",xodtemplate_config_file_name(this_servicedependency->_config_file),this_servicedependency->_start_line); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return ERROR; } } if(this_servicedependency->have_notification_dependency_options==TRUE){ new_servicedependency=add_service_dependency(this_servicedependency->dependent_host_name,this_servicedependency->dependent_service_description,this_servicedependency->host_name,this_servicedependency->service_description,NOTIFICATION_DEPENDENCY,this_servicedependency->inherits_parent,this_servicedependency->fail_notify_on_ok,this_servicedependency->fail_notify_on_warning,this_servicedependency->fail_notify_on_unknown,this_servicedependency->fail_notify_on_critical,this_servicedependency->fail_notify_on_pending); /* return with an error if we couldn't add the servicedependency */ if(new_servicedependency==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not register service notification dependency (config file '%s', starting on line %d)\n",xodtemplate_config_file_name(this_servicedependency->_config_file),this_servicedependency->_start_line); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return ERROR; } } #ifdef DEBUG0 printf("xodtemplate_register_servicedependency() end\n"); #endif return OK; } /* registers a serviceescalation definition */ int xodtemplate_register_serviceescalation(xodtemplate_serviceescalation *this_serviceescalation){ serviceescalation *new_serviceescalation; contactgroupsmember *new_contactgroupsmember; char *contact_group; #ifdef NSCORE char temp_buffer[MAX_XODTEMPLATE_INPUT_BUFFER]; #endif #ifdef DEBUG0 printf("xodtemplate_register_serviceescalation() start\n"); #endif /* bail out if we shouldn't register this object */ if(this_serviceescalation->register_object==FALSE) return OK; /* default options if none specified */ if(this_serviceescalation->have_escalation_options==FALSE){ this_serviceescalation->escalate_on_warning=TRUE; this_serviceescalation->escalate_on_unknown=TRUE; this_serviceescalation->escalate_on_critical=TRUE; this_serviceescalation->escalate_on_recovery=TRUE; } /* add the serviceescalation */ new_serviceescalation=add_serviceescalation(this_serviceescalation->host_name,this_serviceescalation->service_description,this_serviceescalation->first_notification,this_serviceescalation->last_notification,this_serviceescalation->notification_interval,this_serviceescalation->escalation_period,this_serviceescalation->escalate_on_warning,this_serviceescalation->escalate_on_unknown,this_serviceescalation->escalate_on_critical,this_serviceescalation->escalate_on_recovery); /* return with an error if we couldn't add the serviceescalation */ if(new_serviceescalation==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not register service escalation (config file '%s', starting on line %d)\n",xodtemplate_config_file_name(this_serviceescalation->_config_file),this_serviceescalation->_start_line); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return ERROR; } /* add the contact groups */ if(this_serviceescalation->contact_groups==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Service escalation has no contact groups (config file '%s', starting on line %d)\n",xodtemplate_config_file_name(this_serviceescalation->_config_file),this_serviceescalation->_start_line); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return ERROR; } for(contact_group=strtok(this_serviceescalation->contact_groups,", ");contact_group!=NULL;contact_group=strtok(NULL,", ")){ new_contactgroupsmember=add_contactgroup_to_serviceescalation(new_serviceescalation,contact_group); if(new_contactgroupsmember==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not add contactgroup '%s' to service escalation (config file '%s', starting on line %d)\n",contact_group,xodtemplate_config_file_name(this_serviceescalation->_config_file),this_serviceescalation->_start_line); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return ERROR; } } #ifdef DEBUG0 printf("xodtemplate_register_serviceescalation() end\n"); #endif return OK; } /* registers a contact definition */ int xodtemplate_register_contact(xodtemplate_contact *this_contact){ contact *new_contact; char *command_name; commandsmember *new_commandsmember; #ifdef NSCORE char temp_buffer[MAX_XODTEMPLATE_INPUT_BUFFER]; #endif #ifdef DEBUG0 printf("xodtemplate_register_contact() start\n"); #endif /* bail out if we shouldn't register this object */ if(this_contact->register_object==FALSE) return OK; /* add the contact */ new_contact=add_contact(this_contact->contact_name,this_contact->alias,this_contact->email,this_contact->pager,this_contact->address,this_contact->service_notification_period,this_contact->host_notification_period,this_contact->notify_on_service_recovery,this_contact->notify_on_service_critical,this_contact->notify_on_service_warning,this_contact->notify_on_service_unknown,this_contact->notify_on_service_flapping,this_contact->notify_on_host_recovery,this_contact->notify_on_host_down,this_contact->notify_on_host_unreachable,this_contact->notify_on_host_flapping); /* return with an error if we couldn't add the contact */ if(new_contact==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not register contact (config file '%s', starting on line %d)\n",xodtemplate_config_file_name(this_contact->_config_file),this_contact->_start_line); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return ERROR; } /* add all the host notification commands */ if(this_contact->host_notification_commands!=NULL){ for(command_name=strtok(this_contact->host_notification_commands,", ");command_name!=NULL;command_name=strtok(NULL,", ")){ new_commandsmember=add_host_notification_command_to_contact(new_contact,command_name); if(new_commandsmember==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not add host notification command '%s' to contact (config file '%s', starting on line %d)\n",command_name,xodtemplate_config_file_name(this_contact->_config_file),this_contact->_start_line); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return ERROR; } } } /* add all the service notification commands */ if(this_contact->service_notification_commands!=NULL){ for(command_name=strtok(this_contact->service_notification_commands,", ");command_name!=NULL;command_name=strtok(NULL,", ")){ new_commandsmember=add_service_notification_command_to_contact(new_contact,command_name); if(new_commandsmember==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not add service notification command '%s' to contact (config file '%s', starting on line %d)\n",command_name,xodtemplate_config_file_name(this_contact->_config_file),this_contact->_start_line); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return ERROR; } } } #ifdef DEBUG0 printf("xodtemplate_register_contact() end\n"); #endif return OK; } /* registers a host definition */ int xodtemplate_register_host(xodtemplate_host *this_host){ host *new_host; char *parent_host; hostsmember *new_hostsmember; contactgroupsmember *new_contactgroupsmember; char *contact_group; #ifdef NSCORE char temp_buffer[MAX_XODTEMPLATE_INPUT_BUFFER]; #endif #ifdef DEBUG0 printf("xodtemplate_register_host() start\n"); #endif /* bail out if we shouldn't register this object */ if(this_host->register_object==FALSE) return OK; /* if host has no alias or address, use host name - added 3/11/05 */ if(this_host->alias==NULL && this_host->host_name!=NULL) this_host->alias=strdup(this_host->host_name); if(this_host->address==NULL && this_host->host_name!=NULL) this_host->address=strdup(this_host->host_name); /* add the host definition */ new_host=add_host(this_host->host_name,this_host->alias,(this_host->address==NULL)?this_host->host_name:this_host->address,this_host->check_period,this_host->check_interval,this_host->max_check_attempts,this_host->notify_on_recovery,this_host->notify_on_down,this_host->notify_on_unreachable,this_host->notify_on_flapping,this_host->notification_interval,this_host->notification_period,this_host->notifications_enabled,this_host->check_command,this_host->active_checks_enabled,this_host->passive_checks_enabled,this_host->event_handler,this_host->event_handler_enabled,this_host->flap_detection_enabled,this_host->low_flap_threshold,this_host->high_flap_threshold,this_host->stalk_on_up,this_host->stalk_on_down,this_host->stalk_on_unreachable,this_host->process_perf_data,this_host->failure_prediction_enabled,this_host->failure_prediction_options,this_host->check_freshness,this_host->freshness_threshold,this_host->retain_status_information,this_host->retain_nonstatus_information,this_host->obsess_over_host); #ifdef TEST_DEBUG printf("HOST: %s, MAXATTEMPTS: %d, NOTINVERVAL: %d \n",this_host->host_name,this_host->max_check_attempts,this_host->notification_interval); #endif /* return with an error if we couldn't add the host */ if(new_host==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not register host (config file '%s', starting on line %d)\n",xodtemplate_config_file_name(this_host->_config_file),this_host->_start_line); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return ERROR; } /* add the parent hosts */ if(this_host->parents!=NULL){ for(parent_host=strtok(this_host->parents,",");parent_host!=NULL;parent_host=strtok(NULL,",")){ strip(parent_host); new_hostsmember=add_parent_host_to_host(new_host,parent_host); if(new_hostsmember==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not add parent host '%s' to host (config file '%s', starting on line %d)\n",parent_host,xodtemplate_config_file_name(this_host->_config_file),this_host->_start_line); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return ERROR; } } } /* add all contact groups to the host group */ if(this_host->contact_groups!=NULL){ for(contact_group=strtok(this_host->contact_groups,",");contact_group!=NULL;contact_group=strtok(NULL,",")){ strip(contact_group); new_contactgroupsmember=add_contactgroup_to_host(new_host,contact_group); if(new_contactgroupsmember==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not add contactgroup '%s' to host (config file '%s', starting on line %d)\n",contact_group,xodtemplate_config_file_name(this_host->_config_file),this_host->_start_line); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return ERROR; } } } #ifdef DEBUG0 printf("xodtemplate_register_host() end\n"); #endif return OK; } /* registers a service definition */ int xodtemplate_register_service(xodtemplate_service *this_service){ service *new_service; contactgroupsmember *new_contactgroupsmember; char *contactgroup_name; #ifdef NSCORE char temp_buffer[MAX_XODTEMPLATE_INPUT_BUFFER]; #endif #ifdef DEBUG0 printf("xodtemplate_register_service() start\n"); #endif /* bail out if we shouldn't register this object */ if(this_service->register_object==FALSE) return OK; /* add the service */ new_service=add_service(this_service->host_name,this_service->service_description,this_service->check_period,this_service->max_check_attempts,this_service->parallelize_check,this_service->passive_checks_enabled,this_service->normal_check_interval,this_service->retry_check_interval,this_service->notification_interval,this_service->notification_period,this_service->notify_on_recovery,this_service->notify_on_unknown,this_service->notify_on_warning,this_service->notify_on_critical,this_service->notify_on_flapping,this_service->notifications_enabled,this_service->is_volatile,this_service->event_handler,this_service->event_handler_enabled,this_service->check_command,this_service->active_checks_enabled,this_service->flap_detection_enabled,this_service->low_flap_threshold,this_service->high_flap_threshold,this_service->stalk_on_ok,this_service->stalk_on_warning,this_service->stalk_on_unknown,this_service->stalk_on_critical,this_service->process_perf_data,this_service->failure_prediction_enabled,this_service->failure_prediction_options,this_service->check_freshness,this_service->freshness_threshold,this_service->retain_status_information,this_service->retain_nonstatus_information,this_service->obsess_over_service); /* return with an error if we couldn't add the service */ if(new_service==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not register service (config file '%s', starting on line %d)\n",xodtemplate_config_file_name(this_service->_config_file),this_service->_start_line); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return ERROR; } /* add all the contact groups to the service */ if(this_service->contact_groups!=NULL){ for(contactgroup_name=strtok(this_service->contact_groups,",");contactgroup_name!=NULL;contactgroup_name=strtok(NULL,",")){ /* add this contactgroup to the service definition */ strip(contactgroup_name); new_contactgroupsmember=add_contactgroup_to_service(new_service,contactgroup_name); /* stop adding contact groups if we ran into an error */ if(new_contactgroupsmember==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not add contact group '%s' to service (config file '%s', starting on line %d)\n",contactgroup_name,xodtemplate_config_file_name(this_service->_config_file),this_service->_start_line); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return ERROR; } } } #ifdef DEBUG0 printf("xodtemplate_register_service() end\n"); #endif return OK; } /* registers a hostdependency definition */ int xodtemplate_register_hostdependency(xodtemplate_hostdependency *this_hostdependency){ hostdependency *new_hostdependency; #ifdef NSCORE char temp_buffer[MAX_XODTEMPLATE_INPUT_BUFFER]; #endif #ifdef DEBUG0 printf("xodtemplate_register_hostdependency() start\n"); #endif /* bail out if we shouldn't register this object */ if(this_hostdependency->register_object==FALSE) return OK; /* add the host execution dependency */ if(this_hostdependency->have_execution_dependency_options==TRUE){ new_hostdependency=add_host_dependency(this_hostdependency->dependent_host_name,this_hostdependency->host_name,EXECUTION_DEPENDENCY,this_hostdependency->inherits_parent,this_hostdependency->fail_execute_on_up,this_hostdependency->fail_execute_on_down,this_hostdependency->fail_execute_on_unreachable,this_hostdependency->fail_execute_on_pending); /* return with an error if we couldn't add the hostdependency */ if(new_hostdependency==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not register host execution dependency (config file '%s', starting on line %d)\n",xodtemplate_config_file_name(this_hostdependency->_config_file),this_hostdependency->_start_line); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return ERROR; } } /* add the host notification dependency */ if(this_hostdependency->have_notification_dependency_options==TRUE){ new_hostdependency=add_host_dependency(this_hostdependency->dependent_host_name,this_hostdependency->host_name,NOTIFICATION_DEPENDENCY,this_hostdependency->inherits_parent,this_hostdependency->fail_notify_on_up,this_hostdependency->fail_notify_on_down,this_hostdependency->fail_notify_on_unreachable,this_hostdependency->fail_notify_on_pending); /* return with an error if we couldn't add the hostdependency */ if(new_hostdependency==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not register host notification dependency (config file '%s', starting on line %d)\n",xodtemplate_config_file_name(this_hostdependency->_config_file),this_hostdependency->_start_line); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return ERROR; } } #ifdef DEBUG0 printf("xodtemplate_register_hostdependency() end\n"); #endif return OK; } /* registers a hostescalation definition */ int xodtemplate_register_hostescalation(xodtemplate_hostescalation *this_hostescalation){ hostescalation *new_hostescalation; contactgroupsmember *new_contactgroupsmember; char *contact_group; #ifdef NSCORE char temp_buffer[MAX_XODTEMPLATE_INPUT_BUFFER]; #endif #ifdef DEBUG0 printf("xodtemplate_register_hostescalation() start\n"); #endif /* bail out if we shouldn't register this object */ if(this_hostescalation->register_object==FALSE) return OK; /* default options if none specified */ if(this_hostescalation->have_escalation_options==FALSE){ this_hostescalation->escalate_on_down=TRUE; this_hostescalation->escalate_on_unreachable=TRUE; this_hostescalation->escalate_on_recovery=TRUE; } /* add the hostescalation */ new_hostescalation=add_hostescalation(this_hostescalation->host_name,this_hostescalation->first_notification,this_hostescalation->last_notification,this_hostescalation->notification_interval,this_hostescalation->escalation_period,this_hostescalation->escalate_on_down,this_hostescalation->escalate_on_unreachable,this_hostescalation->escalate_on_recovery); /* return with an error if we couldn't add the hostescalation */ if(new_hostescalation==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not register host escalation (config file '%s', starting on line %d)\n",xodtemplate_config_file_name(this_hostescalation->_config_file),this_hostescalation->_start_line); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return ERROR; } /* add the contact groups */ if(this_hostescalation->contact_groups==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Host escalation has no contact groups (config file '%s', starting on line %d)\n",xodtemplate_config_file_name(this_hostescalation->_config_file),this_hostescalation->_start_line); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return ERROR; } for(contact_group=strtok(this_hostescalation->contact_groups,", ");contact_group!=NULL;contact_group=strtok(NULL,", ")){ new_contactgroupsmember=add_contactgroup_to_hostescalation(new_hostescalation,contact_group); if(new_contactgroupsmember==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not add contactgroup '%s' to host escalation (config file '%s', starting on line %d)\n",contact_group,xodtemplate_config_file_name(this_hostescalation->_config_file),this_hostescalation->_start_line); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return ERROR; } } #ifdef DEBUG0 printf("xodtemplate_register_hostescalation() end\n"); #endif return OK; } /* registers a hostextinfo definition */ int xodtemplate_register_hostextinfo(xodtemplate_hostextinfo *this_hostextinfo){ hostextinfo *new_hostextinfo; #ifdef NSCORE char temp_buffer[MAX_XODTEMPLATE_INPUT_BUFFER]; #endif #ifdef DEBUG0 printf("xodtemplate_register_hostextinfo() start\n"); #endif /* bail out if we shouldn't register this object */ if(this_hostextinfo->register_object==FALSE) return OK; /* register the extended host object */ new_hostextinfo=add_hostextinfo(this_hostextinfo->host_name,this_hostextinfo->notes,this_hostextinfo->notes_url,this_hostextinfo->action_url,this_hostextinfo->icon_image,this_hostextinfo->vrml_image,this_hostextinfo->statusmap_image,this_hostextinfo->icon_image_alt,this_hostextinfo->x_2d,this_hostextinfo->y_2d,this_hostextinfo->x_3d,this_hostextinfo->y_3d,this_hostextinfo->z_3d,this_hostextinfo->have_2d_coords,this_hostextinfo->have_3d_coords); /* return with an error if we couldn't add the definition */ if(new_hostextinfo==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not register extended host information (config file '%s', starting on line %d)\n",xodtemplate_config_file_name(this_hostextinfo->_config_file),this_hostextinfo->_start_line); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return ERROR; } #ifdef DEBUG0 printf("xodtemplate_register_hostextinfo() end\n"); #endif return OK; } /* registers a serviceextinfo definition */ int xodtemplate_register_serviceextinfo(xodtemplate_serviceextinfo *this_serviceextinfo){ serviceextinfo *new_serviceextinfo; #ifdef NSCORE char temp_buffer[MAX_XODTEMPLATE_INPUT_BUFFER]; #endif #ifdef DEBUG0 printf("xodtemplate_register_serviceextinfo() start\n"); #endif /* bail out if we shouldn't register this object */ if(this_serviceextinfo->register_object==FALSE) return OK; /* register the extended service object */ new_serviceextinfo=add_serviceextinfo(this_serviceextinfo->host_name,this_serviceextinfo->service_description,this_serviceextinfo->notes,this_serviceextinfo->notes_url,this_serviceextinfo->action_url,this_serviceextinfo->icon_image,this_serviceextinfo->icon_image_alt); /* return with an error if we couldn't add the definition */ if(new_serviceextinfo==NULL){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not register extended service information (config file '%s', starting on line %d)\n",xodtemplate_config_file_name(this_serviceextinfo->_config_file),this_serviceextinfo->_start_line); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif return ERROR; } #ifdef DEBUG0 printf("xodtemplate_register_serviceextinfo() end\n"); #endif return OK; } /******************************************************************/ /********************** SORTING FUNCTIONS *************************/ /******************************************************************/ #ifdef NSCORE /* sorts all objects by name */ int xodtemplate_sort_objects(void){ #ifdef DEBUG0 printf("xodtemplate_sort_objects() start\n"); #endif /* sort timeperiods */ if(xodtemplate_sort_timeperiods()==ERROR) return ERROR; /* sort commands */ if(xodtemplate_sort_commands()==ERROR) return ERROR; /* sort contactgroups */ if(xodtemplate_sort_contactgroups()==ERROR) return ERROR; /* sort hostgroups */ if(xodtemplate_sort_hostgroups()==ERROR) return ERROR; /* sort servicegroups */ if(xodtemplate_sort_servicegroups()==ERROR) return ERROR; /* sort contacts */ if(xodtemplate_sort_contacts()==ERROR) return ERROR; /* sort hosts */ if(xodtemplate_sort_hosts()==ERROR) return ERROR; /* sort services */ if(xodtemplate_sort_services()==ERROR) return ERROR; /* sort service dependencies */ if(xodtemplate_sort_servicedependencies()==ERROR) return ERROR; /* sort service escalations */ if(xodtemplate_sort_serviceescalations()==ERROR) return ERROR; /* sort host dependencies */ if(xodtemplate_sort_hostdependencies()==ERROR) return ERROR; /* sort hostescalations */ if(xodtemplate_sort_hostescalations()==ERROR) return ERROR; /* sort host extended info */ if(xodtemplate_sort_hostextinfo()==ERROR) return ERROR; /* sort service extended info */ if(xodtemplate_sort_serviceextinfo()==ERROR) return ERROR; #ifdef DEBUG0 printf("xodtemplate_sort_objects() end\n"); #endif return OK; } /* used to compare two strings (object names) */ int xodtemplate_compare_strings1(char *string1, char *string2){ if(string1==NULL && string2==NULL) return 0; else if(string1==NULL) return -1; else if(string2==NULL) return 1; else return strcmp(string1,string2); } /* used to compare two sets of strings (dually-named objects, i.e. services) */ int xodtemplate_compare_strings2(char *string1a, char *string1b, char *string2a, char *string2b){ int result; if((result=xodtemplate_compare_strings1(string1a,string2a))==0) result=xodtemplate_compare_strings1(string1b,string2b); return result; } /* sort timeperiods by name */ int xodtemplate_sort_timeperiods(){ xodtemplate_timeperiod *new_timeperiod_list=NULL; xodtemplate_timeperiod *temp_timeperiod=NULL; xodtemplate_timeperiod *last_timeperiod=NULL; xodtemplate_timeperiod *temp_timeperiod_orig=NULL; xodtemplate_timeperiod *next_timeperiod_orig=NULL; #ifdef DEBUG0 printf("xodtemplate_sort_timeperiods() start\n"); #endif /* sort all existing timeperiods */ for(temp_timeperiod_orig=xodtemplate_timeperiod_list;temp_timeperiod_orig!=NULL;temp_timeperiod_orig=next_timeperiod_orig){ next_timeperiod_orig=temp_timeperiod_orig->next; /* add timeperiod to new list, sorted by timeperiod name */ last_timeperiod=new_timeperiod_list; for(temp_timeperiod=new_timeperiod_list;temp_timeperiod!=NULL;temp_timeperiod=temp_timeperiod->next){ if(xodtemplate_compare_strings1(temp_timeperiod_orig->timeperiod_name,temp_timeperiod->timeperiod_name)<=0) break; else last_timeperiod=temp_timeperiod; } /* first item added to new sorted list */ if(new_timeperiod_list==NULL){ temp_timeperiod_orig->next=NULL; new_timeperiod_list=temp_timeperiod_orig; } /* item goes at head of new sorted list */ else if(temp_timeperiod==new_timeperiod_list){ temp_timeperiod_orig->next=new_timeperiod_list; new_timeperiod_list=temp_timeperiod_orig; } /* item goes in middle or at end of new sorted list */ else{ temp_timeperiod_orig->next=temp_timeperiod; last_timeperiod->next=temp_timeperiod_orig; } } /* list is now sorted */ xodtemplate_timeperiod_list=new_timeperiod_list; #ifdef DEBUG0 printf("xodtemplate_sort_timeperiods() end\n"); #endif return OK; } /* sort commands by name */ int xodtemplate_sort_commands(){ xodtemplate_command *new_command_list=NULL; xodtemplate_command *temp_command=NULL; xodtemplate_command *last_command=NULL; xodtemplate_command *temp_command_orig=NULL; xodtemplate_command *next_command_orig=NULL; #ifdef DEBUG0 printf("xodtemplate_sort_commands() start\n"); #endif /* sort all existing commands */ for(temp_command_orig=xodtemplate_command_list;temp_command_orig!=NULL;temp_command_orig=next_command_orig){ next_command_orig=temp_command_orig->next; /* add command to new list, sorted by command name */ last_command=new_command_list; for(temp_command=new_command_list;temp_command!=NULL;temp_command=temp_command->next){ if(xodtemplate_compare_strings1(temp_command_orig->command_name,temp_command->command_name)<=0) break; else last_command=temp_command; } /* first item added to new sorted list */ if(new_command_list==NULL){ temp_command_orig->next=NULL; new_command_list=temp_command_orig; } /* item goes at head of new sorted list */ else if(temp_command==new_command_list){ temp_command_orig->next=new_command_list; new_command_list=temp_command_orig; } /* item goes in middle or at end of new sorted list */ else{ temp_command_orig->next=temp_command; last_command->next=temp_command_orig; } } /* list is now sorted */ xodtemplate_command_list=new_command_list; #ifdef DEBUG0 printf("xodtemplate_sort_commands() end\n"); #endif return OK; } /* sort contactgroups by name */ int xodtemplate_sort_contactgroups(){ xodtemplate_contactgroup *new_contactgroup_list=NULL; xodtemplate_contactgroup *temp_contactgroup=NULL; xodtemplate_contactgroup *last_contactgroup=NULL; xodtemplate_contactgroup *temp_contactgroup_orig=NULL; xodtemplate_contactgroup *next_contactgroup_orig=NULL; #ifdef DEBUG0 printf("xodtemplate_sort_contactgroups() start\n"); #endif /* sort all existing contactgroups */ for(temp_contactgroup_orig=xodtemplate_contactgroup_list;temp_contactgroup_orig!=NULL;temp_contactgroup_orig=next_contactgroup_orig){ next_contactgroup_orig=temp_contactgroup_orig->next; /* add contactgroup to new list, sorted by contactgroup name */ last_contactgroup=new_contactgroup_list; for(temp_contactgroup=new_contactgroup_list;temp_contactgroup!=NULL;temp_contactgroup=temp_contactgroup->next){ if(xodtemplate_compare_strings1(temp_contactgroup_orig->contactgroup_name,temp_contactgroup->contactgroup_name)<=0) break; else last_contactgroup=temp_contactgroup; } /* first item added to new sorted list */ if(new_contactgroup_list==NULL){ temp_contactgroup_orig->next=NULL; new_contactgroup_list=temp_contactgroup_orig; } /* item goes at head of new sorted list */ else if(temp_contactgroup==new_contactgroup_list){ temp_contactgroup_orig->next=new_contactgroup_list; new_contactgroup_list=temp_contactgroup_orig; } /* item goes in middle or at end of new sorted list */ else{ temp_contactgroup_orig->next=temp_contactgroup; last_contactgroup->next=temp_contactgroup_orig; } } /* list is now sorted */ xodtemplate_contactgroup_list=new_contactgroup_list; #ifdef DEBUG0 printf("xodtemplate_sort_contactgroups() end\n"); #endif return OK; } /* sort hostgroups by name */ int xodtemplate_sort_hostgroups(){ xodtemplate_hostgroup *new_hostgroup_list=NULL; xodtemplate_hostgroup *temp_hostgroup=NULL; xodtemplate_hostgroup *last_hostgroup=NULL; xodtemplate_hostgroup *temp_hostgroup_orig=NULL; xodtemplate_hostgroup *next_hostgroup_orig=NULL; #ifdef DEBUG0 printf("xodtemplate_sort_hostgroups() start\n"); #endif /* sort all existing hostgroups */ for(temp_hostgroup_orig=xodtemplate_hostgroup_list;temp_hostgroup_orig!=NULL;temp_hostgroup_orig=next_hostgroup_orig){ next_hostgroup_orig=temp_hostgroup_orig->next; /* add hostgroup to new list, sorted by hostgroup name */ last_hostgroup=new_hostgroup_list; for(temp_hostgroup=new_hostgroup_list;temp_hostgroup!=NULL;temp_hostgroup=temp_hostgroup->next){ if(xodtemplate_compare_strings1(temp_hostgroup_orig->hostgroup_name,temp_hostgroup->hostgroup_name)<=0) break; else last_hostgroup=temp_hostgroup; } /* first item added to new sorted list */ if(new_hostgroup_list==NULL){ temp_hostgroup_orig->next=NULL; new_hostgroup_list=temp_hostgroup_orig; } /* item goes at head of new sorted list */ else if(temp_hostgroup==new_hostgroup_list){ temp_hostgroup_orig->next=new_hostgroup_list; new_hostgroup_list=temp_hostgroup_orig; } /* item goes in middle or at end of new sorted list */ else{ temp_hostgroup_orig->next=temp_hostgroup; last_hostgroup->next=temp_hostgroup_orig; } } /* list is now sorted */ xodtemplate_hostgroup_list=new_hostgroup_list; #ifdef DEBUG0 printf("xodtemplate_sort_hostgroups() end\n"); #endif return OK; } /* sort servicegroups by name */ int xodtemplate_sort_servicegroups(){ xodtemplate_servicegroup *new_servicegroup_list=NULL; xodtemplate_servicegroup *temp_servicegroup=NULL; xodtemplate_servicegroup *last_servicegroup=NULL; xodtemplate_servicegroup *temp_servicegroup_orig=NULL; xodtemplate_servicegroup *next_servicegroup_orig=NULL; #ifdef DEBUG0 printf("xodtemplate_sort_servicegroups() start\n"); #endif /* sort all existing servicegroups */ for(temp_servicegroup_orig=xodtemplate_servicegroup_list;temp_servicegroup_orig!=NULL;temp_servicegroup_orig=next_servicegroup_orig){ next_servicegroup_orig=temp_servicegroup_orig->next; /* add servicegroup to new list, sorted by servicegroup name */ last_servicegroup=new_servicegroup_list; for(temp_servicegroup=new_servicegroup_list;temp_servicegroup!=NULL;temp_servicegroup=temp_servicegroup->next){ if(xodtemplate_compare_strings1(temp_servicegroup_orig->servicegroup_name,temp_servicegroup->servicegroup_name)<=0) break; else last_servicegroup=temp_servicegroup; } /* first item added to new sorted list */ if(new_servicegroup_list==NULL){ temp_servicegroup_orig->next=NULL; new_servicegroup_list=temp_servicegroup_orig; } /* item goes at head of new sorted list */ else if(temp_servicegroup==new_servicegroup_list){ temp_servicegroup_orig->next=new_servicegroup_list; new_servicegroup_list=temp_servicegroup_orig; } /* item goes in middle or at end of new sorted list */ else{ temp_servicegroup_orig->next=temp_servicegroup; last_servicegroup->next=temp_servicegroup_orig; } } /* list is now sorted */ xodtemplate_servicegroup_list=new_servicegroup_list; #ifdef DEBUG0 printf("xodtemplate_sort_servicegroups() end\n"); #endif return OK; } /* sort contacts by name */ int xodtemplate_sort_contacts(){ xodtemplate_contact *new_contact_list=NULL; xodtemplate_contact *temp_contact=NULL; xodtemplate_contact *last_contact=NULL; xodtemplate_contact *temp_contact_orig=NULL; xodtemplate_contact *next_contact_orig=NULL; #ifdef DEBUG0 printf("xodtemplate_sort_contacts() start\n"); #endif /* sort all existing contacts */ for(temp_contact_orig=xodtemplate_contact_list;temp_contact_orig!=NULL;temp_contact_orig=next_contact_orig){ next_contact_orig=temp_contact_orig->next; /* add contact to new list, sorted by contact name */ last_contact=new_contact_list; for(temp_contact=new_contact_list;temp_contact!=NULL;temp_contact=temp_contact->next){ if(xodtemplate_compare_strings1(temp_contact_orig->contact_name,temp_contact->contact_name)<=0) break; else last_contact=temp_contact; } /* first item added to new sorted list */ if(new_contact_list==NULL){ temp_contact_orig->next=NULL; new_contact_list=temp_contact_orig; } /* item goes at head of new sorted list */ else if(temp_contact==new_contact_list){ temp_contact_orig->next=new_contact_list; new_contact_list=temp_contact_orig; } /* item goes in middle or at end of new sorted list */ else{ temp_contact_orig->next=temp_contact; last_contact->next=temp_contact_orig; } } /* list is now sorted */ xodtemplate_contact_list=new_contact_list; #ifdef DEBUG0 printf("xodtemplate_sort_contacts() end\n"); #endif return OK; } /* sort hosts by name */ int xodtemplate_sort_hosts(){ xodtemplate_host *new_host_list=NULL; xodtemplate_host *temp_host=NULL; xodtemplate_host *last_host=NULL; xodtemplate_host *temp_host_orig=NULL; xodtemplate_host *next_host_orig=NULL; #ifdef DEBUG0 printf("xodtemplate_sort_hosts() start\n"); #endif /* sort all existing hosts */ for(temp_host_orig=xodtemplate_host_list;temp_host_orig!=NULL;temp_host_orig=next_host_orig){ next_host_orig=temp_host_orig->next; /* add host to new list, sorted by host name */ last_host=new_host_list; for(temp_host=new_host_list;temp_host!=NULL;temp_host=temp_host->next){ if(xodtemplate_compare_strings1(temp_host_orig->host_name,temp_host->host_name)<=0) break; else last_host=temp_host; } /* first item added to new sorted list */ if(new_host_list==NULL){ temp_host_orig->next=NULL; new_host_list=temp_host_orig; } /* item goes at head of new sorted list */ else if(temp_host==new_host_list){ temp_host_orig->next=new_host_list; new_host_list=temp_host_orig; } /* item goes in middle or at end of new sorted list */ else{ temp_host_orig->next=temp_host; last_host->next=temp_host_orig; } } /* list is now sorted */ xodtemplate_host_list=new_host_list; #ifdef DEBUG0 printf("xodtemplate_sort_hosts() end\n"); #endif return OK; } /* sort services by name */ int xodtemplate_sort_services(){ xodtemplate_service *new_service_list=NULL; xodtemplate_service *temp_service=NULL; xodtemplate_service *last_service=NULL; xodtemplate_service *temp_service_orig=NULL; xodtemplate_service *next_service_orig=NULL; #ifdef DEBUG0 printf("xodtemplate_sort_services() start\n"); #endif /* sort all existing services */ for(temp_service_orig=xodtemplate_service_list;temp_service_orig!=NULL;temp_service_orig=next_service_orig){ next_service_orig=temp_service_orig->next; /* add service to new list, sorted by host name then service description */ last_service=new_service_list; for(temp_service=new_service_list;temp_service!=NULL;temp_service=temp_service->next){ if(xodtemplate_compare_strings2(temp_service_orig->host_name,temp_service_orig->service_description,temp_service->host_name,temp_service->service_description)<=0) break; else last_service=temp_service; } /* first item added to new sorted list */ if(new_service_list==NULL){ temp_service_orig->next=NULL; new_service_list=temp_service_orig; } /* item goes at head of new sorted list */ else if(temp_service==new_service_list){ temp_service_orig->next=new_service_list; new_service_list=temp_service_orig; } /* item goes in middle or at end of new sorted list */ else{ temp_service_orig->next=temp_service; last_service->next=temp_service_orig; } } /* list is now sorted */ xodtemplate_service_list=new_service_list; #ifdef DEBUG0 printf("xodtemplate_sort_services() end\n"); #endif return OK; } /* sort servicedependencies by name */ int xodtemplate_sort_servicedependencies(){ xodtemplate_servicedependency *new_servicedependency_list=NULL; xodtemplate_servicedependency *temp_servicedependency=NULL; xodtemplate_servicedependency *last_servicedependency=NULL; xodtemplate_servicedependency *temp_servicedependency_orig=NULL; xodtemplate_servicedependency *next_servicedependency_orig=NULL; #ifdef DEBUG0 printf("xodtemplate_sort_servicedependencies() start\n"); #endif /* sort all existing servicedependencies */ for(temp_servicedependency_orig=xodtemplate_servicedependency_list;temp_servicedependency_orig!=NULL;temp_servicedependency_orig=next_servicedependency_orig){ next_servicedependency_orig=temp_servicedependency_orig->next; /* add servicedependency to new list, sorted by host name then service description */ last_servicedependency=new_servicedependency_list; for(temp_servicedependency=new_servicedependency_list;temp_servicedependency!=NULL;temp_servicedependency=temp_servicedependency->next){ if(xodtemplate_compare_strings2(temp_servicedependency_orig->host_name,temp_servicedependency_orig->service_description,temp_servicedependency->host_name,temp_servicedependency->service_description)<=0) break; else last_servicedependency=temp_servicedependency; } /* first item added to new sorted list */ if(new_servicedependency_list==NULL){ temp_servicedependency_orig->next=NULL; new_servicedependency_list=temp_servicedependency_orig; } /* item goes at head of new sorted list */ else if(temp_servicedependency==new_servicedependency_list){ temp_servicedependency_orig->next=new_servicedependency_list; new_servicedependency_list=temp_servicedependency_orig; } /* item goes in middle or at end of new sorted list */ else{ temp_servicedependency_orig->next=temp_servicedependency; last_servicedependency->next=temp_servicedependency_orig; } } /* list is now sorted */ xodtemplate_servicedependency_list=new_servicedependency_list; #ifdef DEBUG0 printf("xodtemplate_sort_servicedependencies() end\n"); #endif return OK; } /* sort serviceescalations by name */ int xodtemplate_sort_serviceescalations(){ xodtemplate_serviceescalation *new_serviceescalation_list=NULL; xodtemplate_serviceescalation *temp_serviceescalation=NULL; xodtemplate_serviceescalation *last_serviceescalation=NULL; xodtemplate_serviceescalation *temp_serviceescalation_orig=NULL; xodtemplate_serviceescalation *next_serviceescalation_orig=NULL; #ifdef DEBUG0 printf("xodtemplate_sort_serviceescalations() start\n"); #endif /* sort all existing serviceescalations */ for(temp_serviceescalation_orig=xodtemplate_serviceescalation_list;temp_serviceescalation_orig!=NULL;temp_serviceescalation_orig=next_serviceescalation_orig){ next_serviceescalation_orig=temp_serviceescalation_orig->next; /* add serviceescalation to new list, sorted by host name then service description */ last_serviceescalation=new_serviceescalation_list; for(temp_serviceescalation=new_serviceescalation_list;temp_serviceescalation!=NULL;temp_serviceescalation=temp_serviceescalation->next){ if(xodtemplate_compare_strings2(temp_serviceescalation_orig->host_name,temp_serviceescalation_orig->service_description,temp_serviceescalation->host_name,temp_serviceescalation->service_description)<=0) break; else last_serviceescalation=temp_serviceescalation; } /* first item added to new sorted list */ if(new_serviceescalation_list==NULL){ temp_serviceescalation_orig->next=NULL; new_serviceescalation_list=temp_serviceescalation_orig; } /* item goes at head of new sorted list */ else if(temp_serviceescalation==new_serviceescalation_list){ temp_serviceescalation_orig->next=new_serviceescalation_list; new_serviceescalation_list=temp_serviceescalation_orig; } /* item goes in middle or at end of new sorted list */ else{ temp_serviceescalation_orig->next=temp_serviceescalation; last_serviceescalation->next=temp_serviceescalation_orig; } } /* list is now sorted */ xodtemplate_serviceescalation_list=new_serviceescalation_list; #ifdef DEBUG0 printf("xodtemplate_sort_serviceescalations() end\n"); #endif return OK; } /* sort hostescalations by name */ int xodtemplate_sort_hostescalations(){ xodtemplate_hostescalation *new_hostescalation_list=NULL; xodtemplate_hostescalation *temp_hostescalation=NULL; xodtemplate_hostescalation *last_hostescalation=NULL; xodtemplate_hostescalation *temp_hostescalation_orig=NULL; xodtemplate_hostescalation *next_hostescalation_orig=NULL; #ifdef DEBUG0 printf("xodtemplate_sort_hostescalations() start\n"); #endif /* sort all existing hostescalations */ for(temp_hostescalation_orig=xodtemplate_hostescalation_list;temp_hostescalation_orig!=NULL;temp_hostescalation_orig=next_hostescalation_orig){ next_hostescalation_orig=temp_hostescalation_orig->next; /* add hostescalation to new list, sorted by host name then hostescalation description */ last_hostescalation=new_hostescalation_list; for(temp_hostescalation=new_hostescalation_list;temp_hostescalation!=NULL;temp_hostescalation=temp_hostescalation->next){ if(xodtemplate_compare_strings1(temp_hostescalation_orig->host_name,temp_hostescalation->host_name)<=0) break; else last_hostescalation=temp_hostescalation; } /* first item added to new sorted list */ if(new_hostescalation_list==NULL){ temp_hostescalation_orig->next=NULL; new_hostescalation_list=temp_hostescalation_orig; } /* item goes at head of new sorted list */ else if(temp_hostescalation==new_hostescalation_list){ temp_hostescalation_orig->next=new_hostescalation_list; new_hostescalation_list=temp_hostescalation_orig; } /* item goes in middle or at end of new sorted list */ else{ temp_hostescalation_orig->next=temp_hostescalation; last_hostescalation->next=temp_hostescalation_orig; } } /* list is now sorted */ xodtemplate_hostescalation_list=new_hostescalation_list; #ifdef DEBUG0 printf("xodtemplate_sort_hostescalations() end\n"); #endif return OK; } /* sort hostdependencies by name */ int xodtemplate_sort_hostdependencies(){ xodtemplate_hostdependency *new_hostdependency_list=NULL; xodtemplate_hostdependency *temp_hostdependency=NULL; xodtemplate_hostdependency *last_hostdependency=NULL; xodtemplate_hostdependency *temp_hostdependency_orig=NULL; xodtemplate_hostdependency *next_hostdependency_orig=NULL; #ifdef DEBUG0 printf("xodtemplate_sort_hostdependencies() start\n"); #endif /* sort all existing hostdependencys */ for(temp_hostdependency_orig=xodtemplate_hostdependency_list;temp_hostdependency_orig!=NULL;temp_hostdependency_orig=next_hostdependency_orig){ next_hostdependency_orig=temp_hostdependency_orig->next; /* add hostdependency to new list, sorted by host name then hostdependency description */ last_hostdependency=new_hostdependency_list; for(temp_hostdependency=new_hostdependency_list;temp_hostdependency!=NULL;temp_hostdependency=temp_hostdependency->next){ if(xodtemplate_compare_strings1(temp_hostdependency_orig->host_name,temp_hostdependency->host_name)<=0) break; else last_hostdependency=temp_hostdependency; } /* first item added to new sorted list */ if(new_hostdependency_list==NULL){ temp_hostdependency_orig->next=NULL; new_hostdependency_list=temp_hostdependency_orig; } /* item goes at head of new sorted list */ else if(temp_hostdependency==new_hostdependency_list){ temp_hostdependency_orig->next=new_hostdependency_list; new_hostdependency_list=temp_hostdependency_orig; } /* item goes in middle or at end of new sorted list */ else{ temp_hostdependency_orig->next=temp_hostdependency; last_hostdependency->next=temp_hostdependency_orig; } } /* list is now sorted */ xodtemplate_hostdependency_list=new_hostdependency_list; #ifdef DEBUG0 printf("xodtemplate_sort_hostdependencies() end\n"); #endif return OK; } /* sort extended host info by name */ int xodtemplate_sort_hostextinfo(){ xodtemplate_hostextinfo *new_hostextinfo_list=NULL; xodtemplate_hostextinfo *temp_hostextinfo=NULL; xodtemplate_hostextinfo *last_hostextinfo=NULL; xodtemplate_hostextinfo *temp_hostextinfo_orig=NULL; xodtemplate_hostextinfo *next_hostextinfo_orig=NULL; #ifdef DEBUG0 printf("xodtemplate_sort_hostextinfo() start\n"); #endif /* sort all existing existing host info */ for(temp_hostextinfo_orig=xodtemplate_hostextinfo_list;temp_hostextinfo_orig!=NULL;temp_hostextinfo_orig=next_hostextinfo_orig){ next_hostextinfo_orig=temp_hostextinfo_orig->next; /* add hostextinfo to new list, sorted by host name then hostextinfo description */ last_hostextinfo=new_hostextinfo_list; for(temp_hostextinfo=new_hostextinfo_list;temp_hostextinfo!=NULL;temp_hostextinfo=temp_hostextinfo->next){ if(xodtemplate_compare_strings1(temp_hostextinfo_orig->host_name,temp_hostextinfo->host_name)<=0) break; else last_hostextinfo=temp_hostextinfo; } /* first item added to new sorted list */ if(new_hostextinfo_list==NULL){ temp_hostextinfo_orig->next=NULL; new_hostextinfo_list=temp_hostextinfo_orig; } /* item goes at head of new sorted list */ else if(temp_hostextinfo==new_hostextinfo_list){ temp_hostextinfo_orig->next=new_hostextinfo_list; new_hostextinfo_list=temp_hostextinfo_orig; } /* item goes in middle or at end of new sorted list */ else{ temp_hostextinfo_orig->next=temp_hostextinfo; last_hostextinfo->next=temp_hostextinfo_orig; } } /* list is now sorted */ xodtemplate_hostextinfo_list=new_hostextinfo_list; #ifdef DEBUG0 printf("xodtemplate_sort_hostextinfo() end\n"); #endif return OK; } /* sort extended service info by name */ int xodtemplate_sort_serviceextinfo(){ xodtemplate_serviceextinfo *new_serviceextinfo_list=NULL; xodtemplate_serviceextinfo *temp_serviceextinfo=NULL; xodtemplate_serviceextinfo *last_serviceextinfo=NULL; xodtemplate_serviceextinfo *temp_serviceextinfo_orig=NULL; xodtemplate_serviceextinfo *next_serviceextinfo_orig=NULL; #ifdef DEBUG0 printf("xodtemplate_sort_serviceextinfo() start\n"); #endif /* sort all existing extended service info */ for(temp_serviceextinfo_orig=xodtemplate_serviceextinfo_list;temp_serviceextinfo_orig!=NULL;temp_serviceextinfo_orig=next_serviceextinfo_orig){ next_serviceextinfo_orig=temp_serviceextinfo_orig->next; /* add serviceextinfo to new list, sorted by host name then service description */ last_serviceextinfo=new_serviceextinfo_list; for(temp_serviceextinfo=new_serviceextinfo_list;temp_serviceextinfo!=NULL;temp_serviceextinfo=temp_serviceextinfo->next){ if(xodtemplate_compare_strings2(temp_serviceextinfo_orig->host_name,temp_serviceextinfo_orig->service_description,temp_serviceextinfo->host_name,temp_serviceextinfo->service_description)<=0) break; else last_serviceextinfo=temp_serviceextinfo; } /* first item added to new sorted list */ if(new_serviceextinfo_list==NULL){ temp_serviceextinfo_orig->next=NULL; new_serviceextinfo_list=temp_serviceextinfo_orig; } /* item goes at head of new sorted list */ else if(temp_serviceextinfo==new_serviceextinfo_list){ temp_serviceextinfo_orig->next=new_serviceextinfo_list; new_serviceextinfo_list=temp_serviceextinfo_orig; } /* item goes in middle or at end of new sorted list */ else{ temp_serviceextinfo_orig->next=temp_serviceextinfo; last_serviceextinfo->next=temp_serviceextinfo_orig; } } /* list is now sorted */ xodtemplate_serviceextinfo_list=new_serviceextinfo_list; #ifdef DEBUG0 printf("xodtemplate_sort_serviceextinfo() end\n"); #endif return OK; } #endif /******************************************************************/ /*********************** CACHE FUNCTIONS **************************/ /******************************************************************/ #ifdef NSCORE /* writes cached object definitions for use by web interface */ int xodtemplate_cache_objects(char *cache_file){ FILE *fp; char temp_buffer[MAX_XODTEMPLATE_INPUT_BUFFER]; int x; char *days[7]={"sunday","monday","tuesday","wednesday","thursday","friday","saturday"}; xodtemplate_timeperiod *temp_timeperiod; xodtemplate_command *temp_command; xodtemplate_contactgroup *temp_contactgroup; xodtemplate_hostgroup *temp_hostgroup; xodtemplate_servicegroup *temp_servicegroup; xodtemplate_contact *temp_contact; xodtemplate_host *temp_host; xodtemplate_service *temp_service; xodtemplate_servicedependency *temp_servicedependency; xodtemplate_serviceescalation *temp_serviceescalation; xodtemplate_hostdependency *temp_hostdependency; xodtemplate_hostescalation *temp_hostescalation; xodtemplate_hostextinfo *temp_hostextinfo; xodtemplate_serviceextinfo *temp_serviceextinfo; time_t current_time; #ifdef DEBUG0 printf("xodtemplate_cache_objects() start\n"); #endif time(¤t_time); /* open the cache file for writing */ fp=fopen(cache_file,"w"); if(fp==NULL){ snprintf(temp_buffer,sizeof(temp_buffer)-1,"Warning: Could not open object cache file '%s' for writing!\n",cache_file); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_WARNING,TRUE); return ERROR; } /* write header to cache file */ fprintf(fp,"########################################\n"); fprintf(fp,"# NAGIOS OBJECT CACHE FILE\n"); fprintf(fp,"#\n"); fprintf(fp,"# THIS FILE IS AUTOMATICALLY GENERATED\n"); fprintf(fp,"# BY NAGIOS. DO NOT MODIFY THIS FILE!\n"); fprintf(fp,"#\n"); fprintf(fp,"# Created: %s",ctime(¤t_time)); fprintf(fp,"########################################\n\n"); /* cache timeperiods */ for(temp_timeperiod=xodtemplate_timeperiod_list;temp_timeperiod!=NULL;temp_timeperiod=temp_timeperiod->next){ if(temp_timeperiod->register_object==FALSE) continue; fprintf(fp,"define timeperiod {\n"); if(temp_timeperiod->timeperiod_name) fprintf(fp,"\ttimeperiod_name\t%s\n",temp_timeperiod->timeperiod_name); if(temp_timeperiod->alias) fprintf(fp,"\talias\t%s\n",temp_timeperiod->alias); for(x=0;x<7;x++){ if(temp_timeperiod->timeranges[x]!=NULL) fprintf(fp,"\t%s\t%s\n",days[x],temp_timeperiod->timeranges[x]); } fprintf(fp,"\t}\n\n"); } /* cache commands */ for(temp_command=xodtemplate_command_list;temp_command!=NULL;temp_command=temp_command->next){ if(temp_command->register_object==FALSE) continue; fprintf(fp,"define command {\n"); if(temp_command->command_name) fprintf(fp,"\tcommand_name\t%s\n",temp_command->command_name); if(temp_command->command_line) fprintf(fp,"\tcommand_line\t%s\n",temp_command->command_line); fprintf(fp,"\t}\n\n"); } /* cache contactgroups */ for(temp_contactgroup=xodtemplate_contactgroup_list;temp_contactgroup!=NULL;temp_contactgroup=temp_contactgroup->next){ if(temp_contactgroup->register_object==FALSE) continue; fprintf(fp,"define contactgroup {\n"); if(temp_contactgroup->contactgroup_name) fprintf(fp,"\tcontactgroup_name\t%s\n",temp_contactgroup->contactgroup_name); if(temp_contactgroup->alias) fprintf(fp,"\talias\t%s\n",temp_contactgroup->alias); if(temp_contactgroup->members) fprintf(fp,"\tmembers\t%s\n",temp_contactgroup->members); fprintf(fp,"\t}\n\n"); } /* cache hostgroups */ for(temp_hostgroup=xodtemplate_hostgroup_list;temp_hostgroup!=NULL;temp_hostgroup=temp_hostgroup->next){ if(temp_hostgroup->register_object==FALSE) continue; fprintf(fp,"define hostgroup {\n"); if(temp_hostgroup->hostgroup_name) fprintf(fp,"\thostgroup_name\t%s\n",temp_hostgroup->hostgroup_name); if(temp_hostgroup->alias) fprintf(fp,"\talias\t%s\n",temp_hostgroup->alias); if(temp_hostgroup->members) fprintf(fp,"\tmembers\t%s\n",temp_hostgroup->members); fprintf(fp,"\t}\n\n"); } /* cache servicegroups */ for(temp_servicegroup=xodtemplate_servicegroup_list;temp_servicegroup!=NULL;temp_servicegroup=temp_servicegroup->next){ if(temp_servicegroup->register_object==FALSE) continue; fprintf(fp,"define servicegroup {\n"); if(temp_servicegroup->servicegroup_name) fprintf(fp,"\tservicegroup_name\t%s\n",temp_servicegroup->servicegroup_name); if(temp_servicegroup->alias) fprintf(fp,"\talias\t%s\n",temp_servicegroup->alias); if(temp_servicegroup->members) fprintf(fp,"\tmembers\t%s\n",temp_servicegroup->members); fprintf(fp,"\t}\n\n"); } /* cache contacts */ for(temp_contact=xodtemplate_contact_list;temp_contact!=NULL;temp_contact=temp_contact->next){ if(temp_contact->register_object==FALSE) continue; fprintf(fp,"define contact {\n"); if(temp_contact->contact_name) fprintf(fp,"\tcontact_name\t%s\n",temp_contact->contact_name); if(temp_contact->alias) fprintf(fp,"\talias\t%s\n",temp_contact->alias); if(temp_contact->service_notification_period) fprintf(fp,"\tservice_notification_period\t%s\n",temp_contact->service_notification_period); if(temp_contact->host_notification_period) fprintf(fp,"\thost_notification_period\t%s\n",temp_contact->host_notification_period); fprintf(fp,"\tservice_notification_options\t"); x=0; if(temp_contact->notify_on_service_warning==TRUE) fprintf(fp,"%sw",(x++>0)?",":""); if(temp_contact->notify_on_service_unknown==TRUE) fprintf(fp,"%su",(x++>0)?",":""); if(temp_contact->notify_on_service_critical==TRUE) fprintf(fp,"%sc",(x++>0)?",":""); if(temp_contact->notify_on_service_recovery==TRUE) fprintf(fp,"%sr",(x++>0)?",":""); if(temp_contact->notify_on_service_flapping==TRUE) fprintf(fp,"%sf",(x++>0)?",":""); if(x==0) fprintf(fp,"n"); fprintf(fp,"\n"); fprintf(fp,"\thost_notification_options\t"); x=0; if(temp_contact->notify_on_host_down==TRUE) fprintf(fp,"%sd",(x++>0)?",":""); if(temp_contact->notify_on_host_unreachable==TRUE) fprintf(fp,"%su",(x++>0)?",":""); if(temp_contact->notify_on_host_recovery==TRUE) fprintf(fp,"%sr",(x++>0)?",":""); if(temp_contact->notify_on_host_flapping==TRUE) fprintf(fp,"%sf",(x++>0)?",":""); if(x==0) fprintf(fp,"n"); fprintf(fp,"\n"); if(temp_contact->service_notification_commands) fprintf(fp,"\tservice_notification_commands\t%s\n",temp_contact->service_notification_commands); if(temp_contact->host_notification_commands) fprintf(fp,"\thost_notification_commands\t%s\n",temp_contact->host_notification_commands); if(temp_contact->email) fprintf(fp,"\temail\t%s\n",temp_contact->email); if(temp_contact->pager) fprintf(fp,"\tpager\t%s\n",temp_contact->pager); fprintf(fp,"\t}\n\n"); } /* cache hosts */ for(temp_host=xodtemplate_host_list;temp_host!=NULL;temp_host=temp_host->next){ if(temp_host->register_object==FALSE) continue; fprintf(fp,"define host {\n"); if(temp_host->host_name) fprintf(fp,"\thost_name\t%s\n",temp_host->host_name); if(temp_host->alias) fprintf(fp,"\talias\t%s\n",temp_host->alias); if(temp_host->address) fprintf(fp,"\taddress\t%s\n",temp_host->address); if(temp_host->parents) fprintf(fp,"\tparents\t%s\n",temp_host->parents); if(temp_host->check_period) fprintf(fp,"\tcheck_period\t%s\n",temp_host->check_period); if(temp_host->check_command) fprintf(fp,"\tcheck_command\t%s\n",temp_host->check_command); if(temp_host->event_handler) fprintf(fp,"\tevent_handler\t%s\n",temp_host->event_handler); if(temp_host->contact_groups) fprintf(fp,"\tcontact_groups\t%s\n",temp_host->contact_groups); if(temp_host->notification_period) fprintf(fp,"\tnotification_period\t%s\n",temp_host->notification_period); if(temp_host->failure_prediction_options) fprintf(fp,"\tfailure_prediction_options\t%s\n",temp_host->failure_prediction_options); fprintf(fp,"\tcheck_interval\t%d\n",temp_host->check_interval); fprintf(fp,"\tmax_check_attempts\t%d\n",temp_host->max_check_attempts); fprintf(fp,"\tactive_checks_enabled\t%d\n",temp_host->active_checks_enabled); fprintf(fp,"\tpassive_checks_enabled\t%d\n",temp_host->passive_checks_enabled); fprintf(fp,"\tobsess_over_host\t%d\n",temp_host->obsess_over_host); fprintf(fp,"\tevent_handler_enabled\t%d\n",temp_host->event_handler_enabled); fprintf(fp,"\tlow_flap_threshold\t%f\n",temp_host->low_flap_threshold); fprintf(fp,"\thigh_flap_threshold\t%f\n",temp_host->high_flap_threshold); fprintf(fp,"\tflap_detection_enabled\t%d\n",temp_host->flap_detection_enabled); fprintf(fp,"\tfreshness_threshold\t%d\n",temp_host->freshness_threshold); fprintf(fp,"\tcheck_freshness\t%d\n",temp_host->check_freshness); fprintf(fp,"\tnotification_options\t"); x=0; if(temp_host->notify_on_down==TRUE) fprintf(fp,"%sd",(x++>0)?",":""); if(temp_host->notify_on_unreachable==TRUE) fprintf(fp,"%su",(x++>0)?",":""); if(temp_host->notify_on_recovery==TRUE) fprintf(fp,"%sr",(x++>0)?",":""); if(temp_host->notify_on_flapping==TRUE) fprintf(fp,"%sf",(x++>0)?",":""); if(x==0) fprintf(fp,"n"); fprintf(fp,"\n"); fprintf(fp,"\tnotifications_enabled\t%d\n",temp_host->notifications_enabled); fprintf(fp,"\tnotification_interval\t%d\n",temp_host->notification_interval); fprintf(fp,"\tstalking_options\t"); x=0; if(temp_host->stalk_on_up==TRUE) fprintf(fp,"%so",(x++>0)?",":""); if(temp_host->stalk_on_down==TRUE) fprintf(fp,"%sd",(x++>0)?",":""); if(temp_host->stalk_on_unreachable==TRUE) fprintf(fp,"%su",(x++>0)?",":""); if(x==0) fprintf(fp,"n"); fprintf(fp,"\n"); fprintf(fp,"\tprocess_perf_data\t%d\n",temp_host->process_perf_data); fprintf(fp,"\tfailure_prediction_enabled\t%d\n",temp_host->failure_prediction_enabled); fprintf(fp,"\tretain_status_information\t%d\n",temp_host->retain_status_information); fprintf(fp,"\tretain_nonstatus_information\t%d\n",temp_host->retain_nonstatus_information); fprintf(fp,"\t}\n\n"); } /* cache services */ for(temp_service=xodtemplate_service_list;temp_service!=NULL;temp_service=temp_service->next){ if(temp_service->register_object==FALSE) continue; fprintf(fp,"define service {\n"); if(temp_service->host_name) fprintf(fp,"\thost_name\t%s\n",temp_service->host_name); if(temp_service->service_description) fprintf(fp,"\tservice_description\t%s\n",temp_service->service_description); if(temp_service->check_period) fprintf(fp,"\tcheck_period\t%s\n",temp_service->check_period); if(temp_service->check_command) fprintf(fp,"\tcheck_command\t%s\n",temp_service->check_command); if(temp_service->event_handler) fprintf(fp,"\tevent_handler\t%s\n",temp_service->event_handler); if(temp_service->contact_groups) fprintf(fp,"\tcontact_groups\t%s\n",temp_service->contact_groups); if(temp_service->notification_period) fprintf(fp,"\tnotification_period\t%s\n",temp_service->notification_period); if(temp_service->failure_prediction_options) fprintf(fp,"\tfailure_prediction_options\t%s\n",temp_service->failure_prediction_options); fprintf(fp,"\tnormal_check_interval\t%d\n",temp_service->normal_check_interval); fprintf(fp,"\tretry_check_interval\t%d\n",temp_service->retry_check_interval); fprintf(fp,"\tmax_check_attempts\t%d\n",temp_service->max_check_attempts); fprintf(fp,"\tis_volatile\t%d\n",temp_service->is_volatile); fprintf(fp,"\tparallelize_check\t%d\n",temp_service->parallelize_check); fprintf(fp,"\tactive_checks_enabled\t%d\n",temp_service->active_checks_enabled); fprintf(fp,"\tpassive_checks_enabled\t%d\n",temp_service->passive_checks_enabled); fprintf(fp,"\tobsess_over_service\t%d\n",temp_service->obsess_over_service); fprintf(fp,"\tevent_handler_enabled\t%d\n",temp_service->event_handler_enabled); fprintf(fp,"\tlow_flap_threshold\t%f\n",temp_service->low_flap_threshold); fprintf(fp,"\thigh_flap_threshold\t%f\n",temp_service->high_flap_threshold); fprintf(fp,"\tflap_detection_enabled\t%d\n",temp_service->flap_detection_enabled); fprintf(fp,"\tfreshness_threshold\t%d\n",temp_service->freshness_threshold); fprintf(fp,"\tcheck_freshness\t%d\n",temp_service->check_freshness); fprintf(fp,"\tnotification_options\t"); x=0; if(temp_service->notify_on_unknown==TRUE) fprintf(fp,"%su",(x++>0)?",":""); if(temp_service->notify_on_warning==TRUE) fprintf(fp,"%sw",(x++>0)?",":""); if(temp_service->notify_on_critical==TRUE) fprintf(fp,"%sc",(x++>0)?",":""); if(temp_service->notify_on_recovery==TRUE) fprintf(fp,"%sr",(x++>0)?",":""); if(temp_service->notify_on_flapping==TRUE) fprintf(fp,"%sf",(x++>0)?",":""); if(x==0) fprintf(fp,"n"); fprintf(fp,"\n"); fprintf(fp,"\tnotifications_enabled\t%d\n",temp_service->notifications_enabled); fprintf(fp,"\tnotification_interval\t%d\n",temp_service->notification_interval); fprintf(fp,"\tstalking_options\t"); x=0; if(temp_service->stalk_on_ok==TRUE) fprintf(fp,"%so",(x++>0)?",":""); if(temp_service->stalk_on_unknown==TRUE) fprintf(fp,"%su",(x++>0)?",":""); if(temp_service->stalk_on_warning==TRUE) fprintf(fp,"%sw",(x++>0)?",":""); if(temp_service->stalk_on_critical==TRUE) fprintf(fp,"%sc",(x++>0)?",":""); if(x==0) fprintf(fp,"n"); fprintf(fp,"\n"); fprintf(fp,"\tprocess_perf_data\t%d\n",temp_service->process_perf_data); fprintf(fp,"\tfailure_prediction_enabled\t%d\n",temp_service->failure_prediction_enabled); fprintf(fp,"\tretain_status_information\t%d\n",temp_service->retain_status_information); fprintf(fp,"\tretain_nonstatus_information\t%d\n",temp_service->retain_nonstatus_information); fprintf(fp,"\t}\n\n"); } /* cache service dependencies */ for(temp_servicedependency=xodtemplate_servicedependency_list;temp_servicedependency!=NULL;temp_servicedependency=temp_servicedependency->next){ if(temp_servicedependency->register_object==FALSE) continue; fprintf(fp,"define servicedependency {\n"); if(temp_servicedependency->host_name) fprintf(fp,"\thost_name\t%s\n",temp_servicedependency->host_name); if(temp_servicedependency->service_description) fprintf(fp,"\tservice_description\t%s\n",temp_servicedependency->service_description); if(temp_servicedependency->dependent_host_name) fprintf(fp,"\tdependent_host_name\t%s\n",temp_servicedependency->dependent_host_name); if(temp_servicedependency->dependent_service_description) fprintf(fp,"\tdependent_service_description\t%s\n",temp_servicedependency->dependent_service_description); fprintf(fp,"\tinherits_parent\t%d\n",temp_servicedependency->inherits_parent); if(temp_servicedependency->have_notification_dependency_options==TRUE){ fprintf(fp,"\tnotification_failure_options\t"); x=0; if(temp_servicedependency->fail_notify_on_ok==TRUE) fprintf(fp,"%so",(x++>0)?",":""); if(temp_servicedependency->fail_notify_on_unknown==TRUE) fprintf(fp,"%su",(x++>0)?",":""); if(temp_servicedependency->fail_notify_on_warning==TRUE) fprintf(fp,"%sw",(x++>0)?",":""); if(temp_servicedependency->fail_notify_on_critical==TRUE) fprintf(fp,"%sc",(x++>0)?",":""); if(temp_servicedependency->fail_notify_on_pending==TRUE) fprintf(fp,"%sp",(x++>0)?",":""); if(x==0) fprintf(fp,"n"); fprintf(fp,"\n"); } if(temp_servicedependency->have_execution_dependency_options==TRUE){ fprintf(fp,"\texecution_failure_options\t"); x=0; if(temp_servicedependency->fail_execute_on_ok==TRUE) fprintf(fp,"%so",(x++>0)?",":""); if(temp_servicedependency->fail_execute_on_unknown==TRUE) fprintf(fp,"%su",(x++>0)?",":""); if(temp_servicedependency->fail_execute_on_warning==TRUE) fprintf(fp,"%sw",(x++>0)?",":""); if(temp_servicedependency->fail_execute_on_critical==TRUE) fprintf(fp,"%sc",(x++>0)?",":""); if(temp_servicedependency->fail_execute_on_pending==TRUE) fprintf(fp,"%sp",(x++>0)?",":""); if(x==0) fprintf(fp,"n"); fprintf(fp,"\n"); } fprintf(fp,"\t}\n\n"); } /* cache service escalations */ for(temp_serviceescalation=xodtemplate_serviceescalation_list;temp_serviceescalation!=NULL;temp_serviceescalation=temp_serviceescalation->next){ if(temp_serviceescalation->register_object==FALSE) continue; fprintf(fp,"define serviceescalation {\n"); if(temp_serviceescalation->host_name) fprintf(fp,"\thost_name\t%s\n",temp_serviceescalation->host_name); if(temp_serviceescalation->service_description) fprintf(fp,"\tservice_description\t%s\n",temp_serviceescalation->service_description); fprintf(fp,"\tfirst_notification\t%d\n",temp_serviceescalation->first_notification); fprintf(fp,"\tlast_notification\t%d\n",temp_serviceescalation->last_notification); fprintf(fp,"\tnotification_interval\t%d\n",temp_serviceescalation->notification_interval); if(temp_serviceescalation->escalation_period) fprintf(fp,"\tescalation_period\t%s\n",temp_serviceescalation->escalation_period); if(temp_serviceescalation->have_escalation_options==TRUE){ fprintf(fp,"\tescalation_options\t"); x=0; if(temp_serviceescalation->escalate_on_warning==TRUE) fprintf(fp,"%sw",(x++>0)?",":""); if(temp_serviceescalation->escalate_on_unknown==TRUE) fprintf(fp,"%su",(x++>0)?",":""); if(temp_serviceescalation->escalate_on_critical==TRUE) fprintf(fp,"%sc",(x++>0)?",":""); if(temp_serviceescalation->escalate_on_recovery==TRUE) fprintf(fp,"%sr",(x++>0)?",":""); if(x==0) fprintf(fp,"n"); fprintf(fp,"\n"); } if(temp_serviceescalation->contact_groups) fprintf(fp,"\tcontact_groups\t%s\n",temp_serviceescalation->contact_groups); fprintf(fp,"\t}\n\n"); } /* cache host dependencies */ for(temp_hostdependency=xodtemplate_hostdependency_list;temp_hostdependency!=NULL;temp_hostdependency=temp_hostdependency->next){ if(temp_hostdependency->register_object==FALSE) continue; fprintf(fp,"define hostdependency {\n"); if(temp_hostdependency->host_name) fprintf(fp,"\thost_name\t%s\n",temp_hostdependency->host_name); if(temp_hostdependency->dependent_host_name) fprintf(fp,"\tdependent_host_name\t%s\n",temp_hostdependency->dependent_host_name); fprintf(fp,"\tinherits_parent\t%d\n",temp_hostdependency->inherits_parent); if(temp_hostdependency->have_notification_dependency_options==TRUE){ fprintf(fp,"\tnotification_failure_options\t"); x=0; if(temp_hostdependency->fail_notify_on_up==TRUE) fprintf(fp,"%so",(x++>0)?",":""); if(temp_hostdependency->fail_notify_on_down==TRUE) fprintf(fp,"%sd",(x++>0)?",":""); if(temp_hostdependency->fail_notify_on_unreachable==TRUE) fprintf(fp,"%su",(x++>0)?",":""); if(temp_hostdependency->fail_notify_on_pending==TRUE) fprintf(fp,"%sp",(x++>0)?",":""); if(x==0) fprintf(fp,"n"); fprintf(fp,"\n"); } if(temp_hostdependency->have_execution_dependency_options==TRUE){ fprintf(fp,"\texecution_failure_options\t"); x=0; if(temp_hostdependency->fail_execute_on_up==TRUE) fprintf(fp,"%so",(x++>0)?",":""); if(temp_hostdependency->fail_execute_on_down==TRUE) fprintf(fp,"%sd",(x++>0)?",":""); if(temp_hostdependency->fail_execute_on_unreachable==TRUE) fprintf(fp,"%su",(x++>0)?",":""); if(temp_hostdependency->fail_execute_on_pending==TRUE) fprintf(fp,"%sp",(x++>0)?",":""); if(x==0) fprintf(fp,"n"); fprintf(fp,"\n"); } fprintf(fp,"\t}\n\n"); } /* cache host escalations */ for(temp_hostescalation=xodtemplate_hostescalation_list;temp_hostescalation!=NULL;temp_hostescalation=temp_hostescalation->next){ if(temp_hostescalation->register_object==FALSE) continue; fprintf(fp,"define hostescalation {\n"); if(temp_hostescalation->host_name) fprintf(fp,"\thost_name\t%s\n",temp_hostescalation->host_name); fprintf(fp,"\tfirst_notification\t%d\n",temp_hostescalation->first_notification); fprintf(fp,"\tlast_notification\t%d\n",temp_hostescalation->last_notification); fprintf(fp,"\tnotification_interval\t%d\n",temp_hostescalation->notification_interval); if(temp_hostescalation->escalation_period) fprintf(fp,"\tescalation_period\t%s\n",temp_hostescalation->escalation_period); if(temp_hostescalation->have_escalation_options==TRUE){ fprintf(fp,"\tescalation_options\t"); x=0; if(temp_hostescalation->escalate_on_down==TRUE) fprintf(fp,"%sd",(x++>0)?",":""); if(temp_hostescalation->escalate_on_unreachable==TRUE) fprintf(fp,"%su",(x++>0)?",":""); if(temp_hostescalation->escalate_on_recovery==TRUE) fprintf(fp,"%sr",(x++>0)?",":""); if(x==0) fprintf(fp,"n"); fprintf(fp,"\n"); } if(temp_hostescalation->contact_groups) fprintf(fp,"\tcontact_groups\t%s\n",temp_hostescalation->contact_groups); fprintf(fp,"\t}\n\n"); } /* cache host extended info */ for(temp_hostextinfo=xodtemplate_hostextinfo_list;temp_hostextinfo!=NULL;temp_hostextinfo=temp_hostextinfo->next){ if(temp_hostextinfo->register_object==FALSE) continue; fprintf(fp,"define hostextinfo {\n"); if(temp_hostextinfo->host_name) fprintf(fp,"\thost_name\t%s\n",temp_hostextinfo->host_name); if(temp_hostextinfo->icon_image) fprintf(fp,"\ticon_image\t%s\n",temp_hostextinfo->icon_image); if(temp_hostextinfo->icon_image_alt) fprintf(fp,"\ticon_image_alt\t%s\n",temp_hostextinfo->icon_image_alt); if(temp_hostextinfo->vrml_image) fprintf(fp,"\tvrml_image\t%s\n",temp_hostextinfo->vrml_image); if(temp_hostextinfo->statusmap_image) fprintf(fp,"\tstatusmap_image\t%s\n",temp_hostextinfo->statusmap_image); if(temp_hostextinfo->have_2d_coords==TRUE) fprintf(fp,"\t2d_coords\t%d,%d\n",temp_hostextinfo->x_2d,temp_hostextinfo->y_2d); if(temp_hostextinfo->have_3d_coords==TRUE) fprintf(fp,"\t3d_coords\t%f,%f,%f\n",temp_hostextinfo->x_3d,temp_hostextinfo->y_3d,temp_hostextinfo->z_3d); if(temp_hostextinfo->notes) fprintf(fp,"\tnotes\t%s\n",temp_hostextinfo->notes); if(temp_hostextinfo->notes_url) fprintf(fp,"\tnotes_url\t%s\n",temp_hostextinfo->notes_url); if(temp_hostextinfo->action_url) fprintf(fp,"\taction_url\t%s\n",temp_hostextinfo->action_url); fprintf(fp,"\t}\n\n"); } /* cache service extended info */ for(temp_serviceextinfo=xodtemplate_serviceextinfo_list;temp_serviceextinfo!=NULL;temp_serviceextinfo=temp_serviceextinfo->next){ if(temp_serviceextinfo->register_object==FALSE) continue; fprintf(fp,"define serviceextinfo {\n"); if(temp_serviceextinfo->host_name) fprintf(fp,"\thost_name\t%s\n",temp_serviceextinfo->host_name); if(temp_serviceextinfo->service_description) fprintf(fp,"\tservice_description\t%s\n",temp_serviceextinfo->service_description); if(temp_serviceextinfo->icon_image) fprintf(fp,"\ticon_image\t%s\n",temp_serviceextinfo->icon_image); if(temp_serviceextinfo->icon_image_alt) fprintf(fp,"\ticon_image_alt\t%s\n",temp_serviceextinfo->icon_image_alt); if(temp_serviceextinfo->notes) fprintf(fp,"\tnotes\t%s\n",temp_serviceextinfo->notes); if(temp_serviceextinfo->notes_url) fprintf(fp,"\tnotes_url\t%s\n",temp_serviceextinfo->notes_url); if(temp_serviceextinfo->action_url) fprintf(fp,"\taction_url\t%s\n",temp_serviceextinfo->action_url); fprintf(fp,"\t}\n\n"); } fclose(fp); #ifdef DEBUG0 printf("xodtemplate_cache_objects() end\n"); #endif return OK; } #endif /******************************************************************/ /********************** CLEANUP FUNCTIONS *************************/ /******************************************************************/ /* frees memory */ int xodtemplate_free_memory(void){ xodtemplate_timeperiod *this_timeperiod; xodtemplate_timeperiod *next_timeperiod; xodtemplate_command *this_command; xodtemplate_command *next_command; xodtemplate_contactgroup *this_contactgroup; xodtemplate_contactgroup *next_contactgroup; xodtemplate_hostgroup *this_hostgroup; xodtemplate_hostgroup *next_hostgroup; xodtemplate_servicegroup *this_servicegroup; xodtemplate_servicegroup *next_servicegroup; xodtemplate_servicedependency *this_servicedependency; xodtemplate_servicedependency *next_servicedependency; xodtemplate_serviceescalation *this_serviceescalation; xodtemplate_serviceescalation *next_serviceescalation; xodtemplate_contact *this_contact; xodtemplate_contact *next_contact; xodtemplate_host *this_host; xodtemplate_host *next_host; xodtemplate_service *this_service; xodtemplate_service *next_service; xodtemplate_hostdependency *this_hostdependency; xodtemplate_hostdependency *next_hostdependency; xodtemplate_hostescalation *this_hostescalation; xodtemplate_hostescalation *next_hostescalation; xodtemplate_hostextinfo *this_hostextinfo; xodtemplate_hostextinfo *next_hostextinfo; xodtemplate_serviceextinfo *this_serviceextinfo; xodtemplate_serviceextinfo *next_serviceextinfo; int x; #ifdef DEBUG0 printf("xodtemplate_free_memory() start\n"); #endif /* free memory allocated to timeperiod list */ for(this_timeperiod=xodtemplate_timeperiod_list;this_timeperiod!=NULL;this_timeperiod=next_timeperiod){ next_timeperiod=this_timeperiod->next; free(this_timeperiod->template); free(this_timeperiod->name); free(this_timeperiod->timeperiod_name); free(this_timeperiod->alias); for(x=0;x<7;x++) free(this_timeperiod->timeranges[x]); free(this_timeperiod); } xodtemplate_timeperiod_list=NULL; /* free memory allocated to command list */ for(this_command=xodtemplate_command_list;this_command!=NULL;this_command=next_command){ next_command=this_command->next; free(this_command->template); free(this_command->name); free(this_command->command_name); free(this_command->command_line); free(this_command); } xodtemplate_command_list=NULL; /* free memory allocated to contactgroup list */ for(this_contactgroup=xodtemplate_contactgroup_list;this_contactgroup!=NULL;this_contactgroup=next_contactgroup){ next_contactgroup=this_contactgroup->next; free(this_contactgroup->template); free(this_contactgroup->name); free(this_contactgroup->contactgroup_name); free(this_contactgroup->alias); free(this_contactgroup->members); free(this_contactgroup); } xodtemplate_contactgroup_list=NULL; /* free memory allocated to hostgroup list */ for(this_hostgroup=xodtemplate_hostgroup_list;this_hostgroup!=NULL;this_hostgroup=next_hostgroup){ next_hostgroup=this_hostgroup->next; free(this_hostgroup->template); free(this_hostgroup->name); free(this_hostgroup->hostgroup_name); free(this_hostgroup->alias); free(this_hostgroup->members); free(this_hostgroup); } xodtemplate_hostgroup_list=NULL; /* free memory allocated to servicegroup list */ for(this_servicegroup=xodtemplate_servicegroup_list;this_servicegroup!=NULL;this_servicegroup=next_servicegroup){ next_servicegroup=this_servicegroup->next; free(this_servicegroup->template); free(this_servicegroup->name); free(this_servicegroup->servicegroup_name); free(this_servicegroup->alias); free(this_servicegroup->members); free(this_servicegroup); } xodtemplate_servicegroup_list=NULL; /* free memory allocated to servicedependency list */ for(this_servicedependency=xodtemplate_servicedependency_list;this_servicedependency!=NULL;this_servicedependency=next_servicedependency){ next_servicedependency=this_servicedependency->next; free(this_servicedependency->template); free(this_servicedependency->name); free(this_servicedependency->servicegroup_name); free(this_servicedependency->hostgroup_name); free(this_servicedependency->host_name); free(this_servicedependency->service_description); free(this_servicedependency->dependent_servicegroup_name); free(this_servicedependency->dependent_hostgroup_name); free(this_servicedependency->dependent_host_name); free(this_servicedependency->dependent_service_description); free(this_servicedependency); } xodtemplate_servicedependency_list=NULL; /* free memory allocated to serviceescalation list */ for(this_serviceescalation=xodtemplate_serviceescalation_list;this_serviceescalation!=NULL;this_serviceescalation=next_serviceescalation){ next_serviceescalation=this_serviceescalation->next; free(this_serviceescalation->template); free(this_serviceescalation->name); free(this_serviceescalation->servicegroup_name); free(this_serviceescalation->hostgroup_name); free(this_serviceescalation->host_name); free(this_serviceescalation->service_description); free(this_serviceescalation->escalation_period); free(this_serviceescalation->contact_groups); free(this_serviceescalation); } xodtemplate_serviceescalation_list=NULL; /* free memory allocated to contact list */ for(this_contact=xodtemplate_contact_list;this_contact!=NULL;this_contact=next_contact){ next_contact=this_contact->next; free(this_contact->template); free(this_contact->name); free(this_contact->contact_name); free(this_contact->alias); free(this_contact->contactgroups); free(this_contact->email); free(this_contact->pager); for(x=0;xaddress[x]); free(this_contact->service_notification_period); free(this_contact->service_notification_commands); free(this_contact->host_notification_period); free(this_contact->host_notification_commands); free(this_contact); } xodtemplate_contact_list=NULL; /* free memory allocated to host list */ for(this_host=xodtemplate_host_list;this_host!=NULL;this_host=next_host){ next_host=this_host->next; free(this_host->template); free(this_host->name); free(this_host->host_name); free(this_host->alias); free(this_host->address); free(this_host->parents); free(this_host->hostgroups); free(this_host->check_command); free(this_host->check_period); free(this_host->event_handler); free(this_host->contact_groups); free(this_host->notification_period); free(this_host->failure_prediction_options); free(this_host); } xodtemplate_host_list=NULL; /* free memory allocated to service list (chained hash) */ for(this_service=xodtemplate_service_list;this_service!=NULL;this_service=next_service){ next_service=this_service->next; free(this_service->template); free(this_service->name); free(this_service->hostgroup_name); free(this_service->host_name); free(this_service->service_description); free(this_service->servicegroups); free(this_service->check_command); free(this_service->check_period); free(this_service->event_handler); free(this_service->notification_period); free(this_service->contact_groups); free(this_service->failure_prediction_options); free(this_service); } xodtemplate_service_list=NULL; /* free memory allocated to hostdependency list */ for(this_hostdependency=xodtemplate_hostdependency_list;this_hostdependency!=NULL;this_hostdependency=next_hostdependency){ next_hostdependency=this_hostdependency->next; free(this_hostdependency->template); free(this_hostdependency->name); free(this_hostdependency->hostgroup_name); free(this_hostdependency->dependent_hostgroup_name); free(this_hostdependency->host_name); free(this_hostdependency->dependent_host_name); free(this_hostdependency); } xodtemplate_hostdependency_list=NULL; /* free memory allocated to hostescalation list */ for(this_hostescalation=xodtemplate_hostescalation_list;this_hostescalation!=NULL;this_hostescalation=next_hostescalation){ next_hostescalation=this_hostescalation->next; free(this_hostescalation->template); free(this_hostescalation->name); free(this_hostescalation->hostgroup_name); free(this_hostescalation->host_name); free(this_hostescalation->escalation_period); free(this_hostescalation->contact_groups); free(this_hostescalation); } xodtemplate_hostescalation_list=NULL; /* free memory allocated to hostextinfo list */ for(this_hostextinfo=xodtemplate_hostextinfo_list;this_hostextinfo!=NULL;this_hostextinfo=next_hostextinfo){ next_hostextinfo=this_hostextinfo->next; free(this_hostextinfo->template); free(this_hostextinfo->name); free(this_hostextinfo->host_name); free(this_hostextinfo->hostgroup_name); free(this_hostextinfo->notes); free(this_hostextinfo->notes_url); free(this_hostextinfo->action_url); free(this_hostextinfo->icon_image); free(this_hostextinfo->icon_image_alt); free(this_hostextinfo->vrml_image); free(this_hostextinfo->statusmap_image); free(this_hostextinfo); } xodtemplate_hostextinfo_list=NULL; /* free memory allocated to serviceextinfo list */ for(this_serviceextinfo=xodtemplate_serviceextinfo_list;this_serviceextinfo!=NULL;this_serviceextinfo=next_serviceextinfo){ next_serviceextinfo=this_serviceextinfo->next; free(this_serviceextinfo->template); free(this_serviceextinfo->name); free(this_serviceextinfo->host_name); free(this_serviceextinfo->hostgroup_name); free(this_serviceextinfo->service_description); free(this_serviceextinfo->notes); free(this_serviceextinfo->notes_url); free(this_serviceextinfo->action_url); free(this_serviceextinfo->icon_image); free(this_serviceextinfo->icon_image_alt); free(this_serviceextinfo); } xodtemplate_serviceextinfo_list=NULL; /* free memory for the config file names */ for(x=0;xnext; free(this_contactlist->contact_name); free(this_contactlist); } temp_list=NULL; #ifdef DEBUG0 printf("xodtemplate_free_contactlist() end\n"); #endif return OK; } /* remove an entry from the contact list */ void xodtemplate_remove_contactlist_item(xodtemplate_contactlist *item,xodtemplate_contactlist **list){ xodtemplate_contactlist *temp_item; #ifdef DEBUG0 printf("xodtemplate_remove_contactlist_item() start\n"); #endif if(item==NULL || list==NULL) return; if(*list==NULL) return; if(*list==item) *list=item->next; else{ for(temp_item=*list;temp_item!=NULL;temp_item=temp_item->next){ if(temp_item->next==item){ temp_item->next=item->next; free(item->contact_name); free(item); break; } } } #ifdef DEBUG0 printf("xodtemplate_remove_contactlist_item() end\n"); #endif return; } /* frees memory allocated to a temporary host list */ int xodtemplate_free_hostlist(xodtemplate_hostlist *temp_list){ xodtemplate_hostlist *this_hostlist; xodtemplate_hostlist *next_hostlist; #ifdef DEBUG0 printf("xodtemplate_free_hostlist() start\n"); #endif /* free memory allocated to host name list */ for(this_hostlist=temp_list;this_hostlist!=NULL;this_hostlist=next_hostlist){ next_hostlist=this_hostlist->next; free(this_hostlist->host_name); free(this_hostlist); } temp_list=NULL; #ifdef DEBUG0 printf("xodtemplate_free_hostlist() end\n"); #endif return OK; } /* remove an entry from the host list */ void xodtemplate_remove_hostlist_item(xodtemplate_hostlist *item,xodtemplate_hostlist **list){ xodtemplate_hostlist *temp_item; #ifdef DEBUG0 printf("xodtemplate_remove_hostlist_item() start\n"); #endif if(item==NULL || list==NULL) return; if(*list==NULL) return; if(*list==item) *list=item->next; else{ for(temp_item=*list;temp_item!=NULL;temp_item=temp_item->next){ if(temp_item->next==item){ temp_item->next=item->next; free(item->host_name); free(item); break; } } } #ifdef DEBUG0 printf("xodtemplate_remove_hostlist_item() end\n"); #endif return; } /* frees memory allocated to a temporary service list */ int xodtemplate_free_servicelist(xodtemplate_servicelist *temp_list){ xodtemplate_servicelist *this_servicelist; xodtemplate_servicelist *next_servicelist; #ifdef DEBUG0 printf("xodtemplate_free_servicelist() start\n"); #endif /* free memory allocated to service name list */ for(this_servicelist=temp_list;this_servicelist!=NULL;this_servicelist=next_servicelist){ next_servicelist=this_servicelist->next; free(this_servicelist->host_name); free(this_servicelist->service_description); free(this_servicelist); } temp_list=NULL; #ifdef DEBUG0 printf("xodtemplate_free_servicelist() end\n"); #endif return OK; } /* remove an entry from the service list */ void xodtemplate_remove_servicelist_item(xodtemplate_servicelist *item,xodtemplate_servicelist **list){ xodtemplate_servicelist *temp_item; #ifdef DEBUG0 printf("xodtemplate_remove_servicelist_item() start\n"); #endif if(item==NULL || list==NULL) return; if(*list==NULL) return; if(*list==item) *list=item->next; else{ for(temp_item=*list;temp_item!=NULL;temp_item=temp_item->next){ if(temp_item->next==item){ temp_item->next=item->next; free(item->host_name); free(item->service_description); free(item); break; } } } #ifdef DEBUG0 printf("xodtemplate_remove_servicelist_item() end\n"); #endif return; } /******************************************************************/ /********************** UTILITY FUNCTIONS *************************/ /******************************************************************/ #ifdef NSCORE /* expands a comma-delimited list of contact names */ xodtemplate_contactlist *xodtemplate_expand_contacts(char *contacts){ xodtemplate_contactlist *temp_list=NULL; xodtemplate_contactlist *reject_list=NULL; xodtemplate_contactlist *list_ptr=NULL; xodtemplate_contactlist *reject_ptr=NULL; int result; #ifdef DEBUG0 printf("xodtemplate_expand_contacts() start\n"); #endif /* process contact names */ if(contacts!=NULL){ /* expand contacts */ result=xodtemplate_expand_contacts2(&temp_list,&reject_list,contacts); if(result!=OK){ xodtemplate_free_contactlist(temp_list); xodtemplate_free_contactlist(reject_list); return NULL; } /* remove rejects (if any) from the list (no duplicate entries exist in either list) */ for(reject_ptr=reject_list;reject_ptr!=NULL;reject_ptr=reject_ptr->next){ for(list_ptr=temp_list;list_ptr!=NULL;list_ptr=list_ptr->next){ if(!strcmp(reject_ptr->contact_name,list_ptr->contact_name)){ xodtemplate_remove_contactlist_item(list_ptr,&temp_list); break; } } } xodtemplate_free_contactlist(reject_list); reject_list=NULL; } #ifdef DEBUG0 printf("xodtemplate_expand_contacts() end\n"); #endif return temp_list; } /* expands contacts */ int xodtemplate_expand_contacts2(xodtemplate_contactlist **list, xodtemplate_contactlist **reject_list,char *contacts){ char *contact_names; char *temp_ptr; xodtemplate_contact *temp_contact; regex_t preg; int found_match=TRUE; int reject_item=FALSE; int use_regexp=FALSE; #ifdef NSCORE char temp_buffer[MAX_XODTEMPLATE_INPUT_BUFFER]; #endif #ifdef DEBUG0 printf("xodtemplate_expand_contacts2() start\n"); #endif if(list==NULL || contacts==NULL) return ERROR; contact_names=strdup(contacts); if(contact_names==NULL) return ERROR; /* expand each contact name */ for(temp_ptr=strtok(contact_names,",");temp_ptr;temp_ptr=strtok(NULL,",")){ found_match=FALSE; reject_item=FALSE; /* strip trailing spaces */ strip(temp_ptr); /* should we use regular expression matching? */ if(use_regexp_matches==TRUE && (use_true_regexp_matching==TRUE || strstr(temp_ptr,"*") || strstr(temp_ptr,"?"))) use_regexp=TRUE; /* use regular expression matching */ if(use_regexp==TRUE){ /* compile regular expression */ if(regcomp(&preg,temp_ptr,0)){ free(contact_names); return ERROR; } /* test match against all contacts */ for(temp_contact=xodtemplate_contact_list;temp_contact!=NULL;temp_contact=temp_contact->next){ if(temp_contact->contact_name==NULL) continue; /* skip this contact if it did not match the expression */ if(regexec(&preg,temp_contact->contact_name,0,NULL,0)) continue; found_match=TRUE; /* dont' add contacts that shouldn't be registered */ if(temp_contact->register_object==FALSE) continue; /* add contact to list */ xodtemplate_add_contact_to_contactlist(list,temp_contact->contact_name); } /* free memory allocated to compiled regexp */ regfree(&preg); } /* use standard matching... */ else{ /* return a list of all contacts */ if(!strcmp(temp_ptr,"*")){ found_match=TRUE; for(temp_contact=xodtemplate_contact_list;temp_contact!=NULL;temp_contact=temp_contact->next){ if(temp_contact->contact_name==NULL) continue; /* dont' add contacts that shouldn't be registered */ if(temp_contact->register_object==FALSE) continue; /* add contact to list */ xodtemplate_add_contact_to_contactlist(list,temp_contact->contact_name); } } /* else this is just a single contact... */ else{ /* this contact should be excluded (rejected) */ if(temp_ptr[0]=='!'){ reject_item=TRUE; temp_ptr++; } /* find the contact */ temp_contact=xodtemplate_find_real_contact(temp_ptr); if(temp_contact!=NULL){ found_match=TRUE; /* add contact to list */ xodtemplate_add_contact_to_contactlist((reject_item==TRUE)?reject_list:list,temp_ptr); } } } if(found_match==FALSE){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not find any contact matching '%s'\n",temp_ptr); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif break; } } /* free memory */ free(contact_names); #ifdef DEBUG0 printf("xodtemplate_expand_contacts2() end\n"); #endif if(found_match==FALSE) return ERROR; return OK; } /* adds a contact entry to the list of expanded (accepted) or rejected contacts */ int xodtemplate_add_contact_to_contactlist(xodtemplate_contactlist **list, char *contact_name){ xodtemplate_contactlist *temp_item; xodtemplate_contactlist *new_item; if(list==NULL || contact_name==NULL) return ERROR; /* skip this contact if its already in the list */ for(temp_item=*list;temp_item;temp_item=temp_item->next) if(!strcmp(temp_item->contact_name,contact_name)) break; if(temp_item) return OK; /* allocate memory for a new list item */ new_item=(xodtemplate_contactlist *)malloc(sizeof(xodtemplate_contactlist)); if(new_item==NULL) return ERROR; /* save the contact name */ new_item->contact_name=strdup(contact_name); if(new_item->contact_name==NULL){ free(new_item); return ERROR; } /* add new item to head of list */ new_item->next=*list; *list=new_item; return OK; } /* expands a comma-delimited list of hostgroups and/or hosts to member host names */ xodtemplate_hostlist *xodtemplate_expand_hostgroups_and_hosts(char *hostgroups,char *hosts){ xodtemplate_hostlist *temp_list=NULL; xodtemplate_hostlist *reject_list=NULL; xodtemplate_hostlist *list_ptr=NULL; xodtemplate_hostlist *reject_ptr=NULL; int result; #ifdef DEBUG0 printf("xodtemplate_expand_hostgroups_and_hosts() start\n"); #endif /* process list of hostgroups... */ if(hostgroups!=NULL){ /* expand host */ result=xodtemplate_expand_hostgroups(&temp_list,&reject_list,hostgroups); if(result!=OK){ xodtemplate_free_hostlist(temp_list); xodtemplate_free_hostlist(reject_list); return NULL; } /* remove rejects (if any) from the list (no duplicate entries exist in either list) */ for(reject_ptr=reject_list;reject_ptr!=NULL;reject_ptr=reject_ptr->next){ for(list_ptr=temp_list;list_ptr!=NULL;list_ptr=list_ptr->next){ if(!strcmp(reject_ptr->host_name,list_ptr->host_name)){ xodtemplate_remove_hostlist_item(list_ptr,&temp_list); break; } } } xodtemplate_free_hostlist(reject_list); reject_list=NULL; } /* process host names */ if(hosts!=NULL){ /* expand hosts */ result=xodtemplate_expand_hosts(&temp_list,&reject_list,hosts); if(result!=OK){ xodtemplate_free_hostlist(temp_list); xodtemplate_free_hostlist(reject_list); return NULL; } /* remove rejects (if any) from the list (no duplicate entries exist in either list) */ /* NOTE: rejects from this list also affect hosts generated from processing hostgroup names (see above) */ for(reject_ptr=reject_list;reject_ptr!=NULL;reject_ptr=reject_ptr->next){ for(list_ptr=temp_list;list_ptr!=NULL;list_ptr=list_ptr->next){ if(!strcmp(reject_ptr->host_name,list_ptr->host_name)){ xodtemplate_remove_hostlist_item(list_ptr,&temp_list); break; } } } xodtemplate_free_hostlist(reject_list); reject_list=NULL; } #ifdef DEBUG0 printf("xodtemplate_expand_hostgroups_and_hosts() end\n"); #endif return temp_list; } /* expands hostgroups */ int xodtemplate_expand_hostgroups(xodtemplate_hostlist **list, xodtemplate_hostlist **reject_list, char *hostgroups){ char *hostgroup_names; char *temp_ptr; xodtemplate_hostgroup *temp_hostgroup; regex_t preg; int found_match=TRUE; int reject_item=FALSE; int use_regexp=FALSE; #ifdef NSCORE char temp_buffer[MAX_XODTEMPLATE_INPUT_BUFFER]; #endif #ifdef DEBUG0 printf("xodtemplate_expand_hostgroups() start\n"); #endif if(list==NULL || hostgroups==NULL) return ERROR; /* allocate memory for hostgroup name list */ hostgroup_names=strdup(hostgroups); if(hostgroup_names==NULL) return ERROR; for(temp_ptr=strtok(hostgroup_names,",");temp_ptr;temp_ptr=strtok(NULL,",")){ found_match=FALSE; reject_item=FALSE; /* strip trailing spaces */ strip(temp_ptr); /* should we use regular expression matching? */ if(use_regexp_matches==TRUE && (use_true_regexp_matching==TRUE || strstr(temp_ptr,"*") || strstr(temp_ptr,"?"))) use_regexp=TRUE; else use_regexp=FALSE; /* use regular expression matching */ if(use_regexp==TRUE){ /* compile regular expression */ if(regcomp(&preg,temp_ptr,0)){ free(hostgroup_names); return ERROR; } /* test match against all hostgroup names */ for(temp_hostgroup=xodtemplate_hostgroup_list;temp_hostgroup!=NULL;temp_hostgroup=temp_hostgroup->next){ if(temp_hostgroup->hostgroup_name==NULL) continue; /* skip this hostgroup if it did not match the expression */ if(regexec(&preg,temp_hostgroup->hostgroup_name,0,NULL,0)) continue; found_match=TRUE; /* dont' add hostgroups that shouldn't be registered */ if(temp_hostgroup->register_object==FALSE) continue; /* add hostgroup members to list */ xodtemplate_add_hostgroup_members_to_hostlist(list,temp_hostgroup); } /* free memory allocated to compiled regexp */ regfree(&preg); } /* use standard matching... */ else{ /* return a list of all hostgroups */ if(!strcmp(temp_ptr,"*")){ found_match=TRUE; for(temp_hostgroup=xodtemplate_hostgroup_list;temp_hostgroup!=NULL;temp_hostgroup=temp_hostgroup->next){ /* dont' add hostgroups that shouldn't be registered */ if(temp_hostgroup->register_object==FALSE) continue; /* add hostgroup to list */ xodtemplate_add_hostgroup_members_to_hostlist(list,temp_hostgroup); } } /* else this is just a single hostgroup... */ else{ /* this hostgroup should be excluded (rejected) */ if(temp_ptr[0]=='!'){ reject_item=TRUE; temp_ptr++; } /* find the hostgroup */ temp_hostgroup=xodtemplate_find_real_hostgroup(temp_ptr); if(temp_hostgroup!=NULL){ found_match=TRUE; /* add hostgroup members to proper list */ xodtemplate_add_hostgroup_members_to_hostlist((reject_item==TRUE)?reject_list:list,temp_hostgroup); } } } if(found_match==FALSE){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not find any hostgroup matching '%s'\n",temp_ptr); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif break; } } /* free memory */ free(hostgroup_names); #ifdef DEBUG0 printf("xodtemplate_expand_hostgroups() end\n"); #endif if(found_match==FALSE) return ERROR; return OK; } /* expands hosts */ int xodtemplate_expand_hosts(xodtemplate_hostlist **list, xodtemplate_hostlist **reject_list,char *hosts){ char *host_names; char *temp_ptr; xodtemplate_host *temp_host; regex_t preg; int found_match=TRUE; int reject_item=FALSE; int use_regexp=FALSE; #ifdef NSCORE char temp_buffer[MAX_XODTEMPLATE_INPUT_BUFFER]; #endif #ifdef DEBUG0 printf("xodtemplate_expand_hosts() start\n"); #endif if(list==NULL || hosts==NULL) return ERROR; host_names=strdup(hosts); if(host_names==NULL) return ERROR; /* expand each host name */ for(temp_ptr=strtok(host_names,",");temp_ptr;temp_ptr=strtok(NULL,",")){ found_match=FALSE; reject_item=FALSE; /* strip trailing spaces */ strip(temp_ptr); /* should we use regular expression matching? */ if(use_regexp_matches==TRUE && (use_true_regexp_matching==TRUE || strstr(temp_ptr,"*") || strstr(temp_ptr,"?"))) use_regexp=TRUE; /* use regular expression matching */ if(use_regexp==TRUE){ /* compile regular expression */ if(regcomp(&preg,temp_ptr,0)){ free(host_names); return ERROR; } /* test match against all hosts */ for(temp_host=xodtemplate_host_list;temp_host!=NULL;temp_host=temp_host->next){ if(temp_host->host_name==NULL) continue; /* skip this host if it did not match the expression */ if(regexec(&preg,temp_host->host_name,0,NULL,0)) continue; found_match=TRUE; /* dont' add hosts that shouldn't be registered */ if(temp_host->register_object==FALSE) continue; /* add host to list */ xodtemplate_add_host_to_hostlist(list,temp_host->host_name); } /* free memory allocated to compiled regexp */ regfree(&preg); } /* use standard matching... */ else{ /* return a list of all hosts */ if(!strcmp(temp_ptr,"*")){ found_match=TRUE; for(temp_host=xodtemplate_host_list;temp_host!=NULL;temp_host=temp_host->next){ if(temp_host->host_name==NULL) continue; /* dont' add hosts that shouldn't be registered */ if(temp_host->register_object==FALSE) continue; /* add host to list */ xodtemplate_add_host_to_hostlist(list,temp_host->host_name); } } /* else this is just a single host... */ else{ /* this host should be excluded (rejected) */ if(temp_ptr[0]=='!'){ reject_item=TRUE; temp_ptr++; } /* find the host */ temp_host=xodtemplate_find_real_host(temp_ptr); if(temp_host!=NULL){ found_match=TRUE; /* add host to list */ xodtemplate_add_host_to_hostlist((reject_item==TRUE)?reject_list:list,temp_ptr); } } } if(found_match==FALSE){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not find any host matching '%s'\n",temp_ptr); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif break; } } /* free memory */ free(host_names); #ifdef DEBUG0 printf("xodtemplate_expand_hosts() end\n"); #endif if(found_match==FALSE) return ERROR; return OK; } /* adds members of a hostgroups to the list of expanded (accepted) or rejected hosts */ int xodtemplate_add_hostgroup_members_to_hostlist(xodtemplate_hostlist **list, xodtemplate_hostgroup *temp_hostgroup){ char *group_members; char *member_name; char *member_ptr; if(list==NULL || temp_hostgroup==NULL) return ERROR; /* skip hostgroups with no defined members */ if(temp_hostgroup->members==NULL) return OK; /* save a copy of the members */ group_members=strdup(temp_hostgroup->members); if(group_members==NULL) return ERROR; /* process all hosts that belong to the hostgroup */ /* NOTE: members of the group have already have been expanded by xodtemplate_recombobulate_hostgroups(), so we don't need to do it here */ member_ptr=group_members; for(member_name=my_strsep(&member_ptr,",");member_name!=NULL;member_name=my_strsep(&member_ptr,",")){ /* strip trailing spaces from member name */ strip(member_name); /* add host to the list */ xodtemplate_add_host_to_hostlist(list,member_name); } free(group_members); return OK; } /* adds a host entry to the list of expanded (accepted) or rejected hosts */ int xodtemplate_add_host_to_hostlist(xodtemplate_hostlist **list, char *host_name){ xodtemplate_hostlist *temp_item; xodtemplate_hostlist *new_item; if(list==NULL || host_name==NULL) return ERROR; /* skip this host if its already in the list */ for(temp_item=*list;temp_item;temp_item=temp_item->next) if(!strcmp(temp_item->host_name,host_name)) break; if(temp_item) return OK; /* allocate memory for a new list item */ new_item=(xodtemplate_hostlist *)malloc(sizeof(xodtemplate_hostlist)); if(new_item==NULL) return ERROR; /* save the host name */ new_item->host_name=strdup(host_name); if(new_item->host_name==NULL){ free(new_item); return ERROR; } /* add new item to head of list */ new_item->next=*list; *list=new_item; return OK; } /* expands a comma-delimited list of servicegroups and/or service descriptions */ xodtemplate_servicelist *xodtemplate_expand_servicegroups_and_services(char *servicegroups,char *host_name,char *services){ xodtemplate_servicelist *temp_list=NULL; xodtemplate_servicelist *reject_list=NULL; xodtemplate_servicelist *list_ptr=NULL; xodtemplate_servicelist *reject_ptr=NULL; int result; #ifdef DEBUG0 printf("xodtemplate_expand_servicegroups_and_services() start\n"); #endif /* process list of servicegroups... */ if(servicegroups!=NULL){ /* expand services */ result=xodtemplate_expand_servicegroups(&temp_list,&reject_list,servicegroups); if(result!=OK){ xodtemplate_free_servicelist(temp_list); xodtemplate_free_servicelist(reject_list); return NULL; } /* remove rejects (if any) from the list (no duplicate entries exist in either list) */ for(reject_ptr=reject_list;reject_ptr!=NULL;reject_ptr=reject_ptr->next){ for(list_ptr=temp_list;list_ptr!=NULL;list_ptr=list_ptr->next){ if(!strcmp(reject_ptr->host_name,list_ptr->host_name) && !strcmp(reject_ptr->service_description,list_ptr->service_description)){ xodtemplate_remove_servicelist_item(list_ptr,&temp_list); break; } } } xodtemplate_free_servicelist(reject_list); reject_list=NULL; } /* process service names */ if(host_name!=NULL && services!=NULL){ /* expand services */ result=xodtemplate_expand_services(&temp_list,&reject_list,host_name,services); if(result!=OK){ xodtemplate_free_servicelist(temp_list); xodtemplate_free_servicelist(reject_list); return NULL; } /* remove rejects (if any) from the list (no duplicate entries exist in either list) */ /* NOTE: rejects from this list also affect hosts generated from processing hostgroup names (see above) */ for(reject_ptr=reject_list;reject_ptr!=NULL;reject_ptr=reject_ptr->next){ for(list_ptr=temp_list;list_ptr!=NULL;list_ptr=list_ptr->next){ if(!strcmp(reject_ptr->host_name,list_ptr->host_name) && !strcmp(reject_ptr->service_description,list_ptr->service_description)){ xodtemplate_remove_servicelist_item(list_ptr,&temp_list); break; } } } xodtemplate_free_servicelist(reject_list); reject_list=NULL; } #ifdef DEBUG0 printf("xodtemplate_expand_servicegroups_and_services() end\n"); #endif return temp_list; } /* expands servicegroups */ int xodtemplate_expand_servicegroups(xodtemplate_servicelist **list, xodtemplate_servicelist **reject_list, char *servicegroups){ xodtemplate_servicegroup *temp_servicegroup; regex_t preg; char *servicegroup_names; char *temp_ptr; int found_match=TRUE; int reject_item=FALSE; int use_regexp=FALSE; #ifdef NSCORE char temp_buffer[MAX_XODTEMPLATE_INPUT_BUFFER]; #endif #ifdef DEBUG0 printf("xodtemplate_expand_servicegroups() start\n"); #endif if(list==NULL || servicegroups==NULL) return ERROR; /* allocate memory for servicegroup name list */ servicegroup_names=strdup(servicegroups); if(servicegroup_names==NULL) return ERROR; /* expand each servicegroup */ for(temp_ptr=strtok(servicegroup_names,",");temp_ptr;temp_ptr=strtok(NULL,",")){ found_match=FALSE; reject_item=FALSE; /* strip trailing spaces */ strip(temp_ptr); /* should we use regular expression matching? */ if(use_regexp_matches==TRUE && (use_true_regexp_matching==TRUE || strstr(temp_ptr,"*") || strstr(temp_ptr,"?"))) use_regexp=TRUE; else use_regexp=FALSE; /* use regular expression matching */ if(use_regexp==TRUE){ /* compile regular expression */ if(regcomp(&preg,temp_ptr,0)){ free(servicegroup_names); return ERROR; } /* test match against all servicegroup names */ for(temp_servicegroup=xodtemplate_servicegroup_list;temp_servicegroup!=NULL;temp_servicegroup=temp_servicegroup->next){ if(temp_servicegroup->servicegroup_name==NULL) continue; /* skip this servicegroup if it did not match the expression */ if(regexec(&preg,temp_servicegroup->servicegroup_name,0,NULL,0)) continue; found_match=TRUE; /* dont' add servicegroups that shouldn't be registered */ if(temp_servicegroup->register_object==FALSE) continue; /* add servicegroup members to list */ xodtemplate_add_servicegroup_members_to_servicelist(list,temp_servicegroup); } /* free memory allocated to compiled regexp */ regfree(&preg); } /* use standard matching... */ else{ /* return a list of all servicegroups */ if(!strcmp(temp_ptr,"*")){ found_match=TRUE; for(temp_servicegroup=xodtemplate_servicegroup_list;temp_servicegroup!=NULL;temp_servicegroup=temp_servicegroup->next){ /* dont' add servicegroups that shouldn't be registered */ if(temp_servicegroup->register_object==FALSE) continue; /* add servicegroup to list */ xodtemplate_add_servicegroup_members_to_servicelist(list,temp_servicegroup); } } /* else this is just a single servicegroup... */ else{ /* this servicegroup should be excluded (rejected) */ if(temp_ptr[0]=='!'){ reject_item=TRUE; temp_ptr++; } /* find the servicegroup */ temp_servicegroup=xodtemplate_find_real_servicegroup(temp_ptr); if(temp_servicegroup!=NULL){ found_match=TRUE; /* add servicegroup members to list */ xodtemplate_add_servicegroup_members_to_servicelist((reject_item==TRUE)?reject_list:list,temp_servicegroup); } } } /* we didn't find a matching servicegroup */ if(found_match==FALSE){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not find any servicegroup matching '%s'\n",temp_ptr); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif break; } } /* free memory */ free(servicegroup_names); #ifdef DEBUG0 printf("xodtemplate_expand_servicegroups() end\n"); #endif if(found_match==FALSE) return ERROR; return OK; } /* expands services (host name is not expanded) */ int xodtemplate_expand_services(xodtemplate_servicelist **list, xodtemplate_servicelist **reject_list, char *host_name, char *services){ char *service_names; char *temp_ptr; xodtemplate_service *temp_service; regex_t preg; regex_t preg2; int found_match=TRUE; int reject_item=FALSE; int use_regexp_host=FALSE; int use_regexp_service=FALSE; #ifdef NSCORE char temp_buffer[MAX_XODTEMPLATE_INPUT_BUFFER]; #endif #ifdef DEBUG0 printf("xodtemplate_expand_services() start\n"); #endif if(list==NULL || host_name==NULL || services==NULL) return ERROR; /* should we use regular expression matching for the host name? */ if(use_regexp_matches==TRUE && (use_true_regexp_matching==TRUE || strstr(host_name,"*") || strstr(host_name,"?"))) use_regexp_host=TRUE; /* compile regular expression for host name */ if(use_regexp_host==TRUE){ if(regcomp(&preg2,host_name,0)) return ERROR; } service_names=strdup(services); if(service_names==NULL){ if(use_regexp_host==TRUE) regfree(&preg2); return ERROR; } /* expand each service description */ for(temp_ptr=strtok(service_names,",");temp_ptr;temp_ptr=strtok(NULL,",")){ found_match=FALSE; reject_item=FALSE; /* strip trailing spaces */ strip(temp_ptr); /* should we use regular expression matching for the service description? */ if(use_regexp_matches==TRUE && (use_true_regexp_matching==TRUE || strstr(temp_ptr,"*") || strstr(temp_ptr,"?"))) use_regexp_service=TRUE; else use_regexp_service=FALSE; /* compile regular expression for service description */ if(use_regexp_service==TRUE){ if(regcomp(&preg,temp_ptr,0)){ if(use_regexp_host==TRUE) regfree(&preg2); free(service_names); return ERROR; } } /* use regular expression matching */ if(use_regexp_host==TRUE || use_regexp_service==TRUE){ /* test match against all services */ for(temp_service=xodtemplate_service_list;temp_service!=NULL;temp_service=temp_service->next){ if(temp_service->host_name==NULL || temp_service->service_description==NULL) continue; /* skip this service if it doesn't match the host name expression */ if(use_regexp_host==TRUE){ if(regexec(&preg2,temp_service->host_name,0,NULL,0)) continue; } else{ if(strcmp(temp_service->host_name,host_name)) continue; } /* skip this service if it doesn't match the service description expression */ if(use_regexp_service==TRUE){ if(regexec(&preg,temp_service->service_description,0,NULL,0)) continue; } else{ if(strcmp(temp_service->service_description,temp_ptr)) continue; } found_match=TRUE; /* dont' add services that shouldn't be registered */ if(temp_service->register_object==FALSE) continue; /* add service to the list */ xodtemplate_add_service_to_servicelist(list,host_name,temp_service->service_description); } /* free memory allocated to compiled regexp */ if(use_regexp_service==TRUE) regfree(&preg); } /* use standard matching... */ else{ /* return a list of all services on the host */ if(!strcmp(temp_ptr,"*")){ found_match=TRUE; for(temp_service=xodtemplate_service_list;temp_service!=NULL;temp_service=temp_service->next){ if(temp_service->host_name==NULL || temp_service->service_description==NULL) continue; if(strcmp(temp_service->host_name,host_name)) continue; /* dont' add services that shouldn't be registered */ if(temp_service->register_object==FALSE) continue; /* add service to the list */ xodtemplate_add_service_to_servicelist(list,host_name,temp_service->service_description); } } /* else this is just a single service... */ else{ /* this service should be excluded (rejected) */ if(temp_ptr[0]=='!'){ reject_item=TRUE; temp_ptr++; } /* find the service */ temp_service=xodtemplate_find_real_service(host_name,temp_ptr); if(temp_service!=NULL){ found_match=TRUE; /* add service to the list */ xodtemplate_add_service_to_servicelist((reject_item==TRUE)?reject_list:list,host_name,temp_service->service_description); } } } /* we didn't find a match */ if(found_match==FALSE){ #ifdef NSCORE snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not find a service matching host name '%s' and description '%s'\n",host_name,temp_ptr); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); #endif break; } } if(use_regexp_host==TRUE) regfree(&preg2); free(service_names); #ifdef DEBUG0 printf("xodtemplate_expand_services() end\n"); #endif if(found_match==FALSE) return ERROR; return OK; } /* adds members of a servicegroups to the list of expanded services */ int xodtemplate_add_servicegroup_members_to_servicelist(xodtemplate_servicelist **list, xodtemplate_servicegroup *temp_servicegroup){ char *group_members; char *member_name; char *host_name; char *member_ptr; if(list==NULL || temp_servicegroup==NULL) return ERROR; /* skip servicegroups with no defined members */ if(temp_servicegroup->members==NULL) return OK; /* save a copy of the members */ group_members=strdup(temp_servicegroup->members); if(group_members==NULL) return ERROR; /* process all services that belong to the servicegroup */ /* NOTE: members of the group have already have been expanded by xodtemplate_recombobulate_servicegroups(), so we don't need to do it here */ member_ptr=group_members; host_name=NULL; for(member_name=my_strsep(&member_ptr,",");member_name!=NULL;member_name=my_strsep(&member_ptr,",")){ /* strip trailing spaces from member name */ strip(member_name); /* host name */ if(host_name==NULL){ host_name=strdup(member_name); if(host_name==NULL){ free(group_members); return ERROR; } } /* service description */ else{ /* add service to the list */ xodtemplate_add_service_to_servicelist(list,host_name,member_name); free(host_name); host_name=NULL; } } free(group_members); return OK; } /* adds a service entry to the list of expanded services */ int xodtemplate_add_service_to_servicelist(xodtemplate_servicelist **list, char *host_name, char *description){ xodtemplate_servicelist *temp_item; xodtemplate_servicelist *new_item; if(list==NULL || host_name==NULL || description==NULL) return ERROR; /* skip this service if its already in the list */ for(temp_item=*list;temp_item;temp_item=temp_item->next) if(!strcmp(temp_item->host_name,host_name) && !strcmp(temp_item->service_description,description)) break; if(temp_item) return OK; /* allocate memory for a new list item */ new_item=(xodtemplate_servicelist *)malloc(sizeof(xodtemplate_servicelist)); if(new_item==NULL) return ERROR; /* save the host name and service description */ new_item->host_name=strdup(host_name); new_item->service_description=strdup(description); if(new_item->host_name==NULL || new_item->service_description==NULL){ free(new_item); return ERROR; } /* add new item to head of list */ new_item->next=*list; *list=new_item; return OK; } /* returns the name of a numbered config file */ char *xodtemplate_config_file_name(int config_file){ if(config_file<=xodtemplate_current_config_file) return xodtemplate_config_files[config_file-1]; return "?"; } #endif nagios-2.6/xdata/xodtemplate.h0000664000076500007650000005365110336571237016020 0ustar nagiosnagios/***************************************************************************** * * XODTEMPLATE.H - Template-based object configuration data header file * * Copyright (c) 2001-2004 Ethan Galstad (nagios@nagios.org) * Last Modified: 10-24-2004 * * 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. * *****************************************************************************/ #ifndef _XODTEMPLATE_H #define _XODTEMPLATE_H /*********** GENERAL DEFINITIONS ************/ #define MAX_XODTEMPLATE_INPUT_BUFFER 65535 #define MAX_XODTEMPLATE_CONTACT_ADDRESSES 6 #define XODTEMPLATE_NONE 0 #define XODTEMPLATE_TIMEPERIOD 1 #define XODTEMPLATE_COMMAND 2 #define XODTEMPLATE_CONTACT 3 #define XODTEMPLATE_CONTACTGROUP 4 #define XODTEMPLATE_HOST 5 #define XODTEMPLATE_HOSTGROUP 6 #define XODTEMPLATE_SERVICE 7 #define XODTEMPLATE_SERVICEDEPENDENCY 8 #define XODTEMPLATE_HOSTGROUPESCALATION 9 /* no longer implemented */ #define XODTEMPLATE_SERVICEESCALATION 10 #define XODTEMPLATE_HOSTESCALATION 11 #define XODTEMPLATE_HOSTDEPENDENCY 12 #define XODTEMPLATE_HOSTEXTINFO 13 #define XODTEMPLATE_SERVICEEXTINFO 14 #define XODTEMPLATE_SERVICEGROUP 15 /********** STRUCTURE DEFINITIONS **********/ /* TIMEPERIOD TEMPLATE STRUCTURE */ typedef struct xodtemplate_timeperiod_struct{ char *template; char *name; int _config_file; int _start_line; char *timeperiod_name; char *alias; char *timeranges[7]; int has_been_resolved; int register_object; struct xodtemplate_timeperiod_struct *next; }xodtemplate_timeperiod; /* COMMAND TEMPLATE STRUCTURE */ typedef struct xodtemplate_command_struct{ char *template; char *name; int _config_file; int _start_line; char *command_name; char *command_line; int has_been_resolved; int register_object; struct xodtemplate_command_struct *next; }xodtemplate_command; /* CONTACT TEMPLATE STRUCTURE */ typedef struct xodtemplate_contact_struct{ char *template; char *name; int _config_file; int _start_line; char *contact_name; char *alias; char *contactgroups; char *email; char *pager; char *address[MAX_XODTEMPLATE_CONTACT_ADDRESSES]; char *host_notification_period; char *host_notification_commands; int notify_on_host_down; int notify_on_host_unreachable; int notify_on_host_recovery; int notify_on_host_flapping; char *service_notification_period; char *service_notification_commands; int notify_on_service_unknown; int notify_on_service_warning; int notify_on_service_critical; int notify_on_service_recovery; int notify_on_service_flapping; int have_host_notification_options; int have_service_notification_options; int has_been_resolved; int register_object; struct xodtemplate_contact_struct *next; }xodtemplate_contact; /* CONTACTGROUP TEMPLATE STRUCTURE */ typedef struct xodtemplate_contactgroup_struct{ char *template; char *name; int _config_file; int _start_line; char *contactgroup_name; char *alias; char *members; int has_been_resolved; int register_object; struct xodtemplate_contactgroup_struct *next; }xodtemplate_contactgroup; /* HOST TEMPLATE STRUCTURE */ typedef struct xodtemplate_host_struct{ char *template; char *name; int _config_file; int _start_line; char *host_name; char *alias; char *address; char *parents; char *hostgroups; char *check_command; char *check_period; int check_interval; int max_check_attempts; int active_checks_enabled; int passive_checks_enabled; int obsess_over_host; char *event_handler; int event_handler_enabled; int check_freshness; int freshness_threshold; float low_flap_threshold; float high_flap_threshold; int flap_detection_enabled; char *contact_groups; int notify_on_down; int notify_on_unreachable; int notify_on_recovery; int notify_on_flapping; int notifications_enabled; char *notification_period; int notification_interval; int stalk_on_up; int stalk_on_down; int stalk_on_unreachable; int process_perf_data; int failure_prediction_enabled; char *failure_prediction_options; int retain_status_information; int retain_nonstatus_information; int have_check_interval; int have_max_check_attempts; int have_active_checks_enabled; int have_passive_checks_enabled; int have_obsess_over_host; int have_event_handler_enabled; int have_check_freshness; int have_freshness_threshold; int have_low_flap_threshold; int have_high_flap_threshold; int have_flap_detection_enabled; int have_notification_options; int have_notifications_enabled; int have_notification_interval; int have_stalking_options; int have_process_perf_data; int have_failure_prediction_enabled; int have_retain_status_information; int have_retain_nonstatus_information; int has_been_resolved; int register_object; struct xodtemplate_host_struct *next; }xodtemplate_host; /* HOSTGROUP TEMPLATE STRUCTURE */ typedef struct xodtemplate_hostgroup_struct{ char *template; char *name; int _config_file; int _start_line; char *hostgroup_name; char *alias; char *members; int has_been_resolved; int register_object; struct xodtemplate_hostgroup_struct *next; }xodtemplate_hostgroup; /* SERVICE TEMPLATE STRUCTURE */ typedef struct xodtemplate_service_struct{ char *template; char *name; int _config_file; int _start_line; char *hostgroup_name; char *host_name; char *service_description; char *servicegroups; char *check_command; int max_check_attempts; int normal_check_interval; int retry_check_interval; char *check_period; int active_checks_enabled; int passive_checks_enabled; int parallelize_check; int is_volatile; int obsess_over_service; char *event_handler; int event_handler_enabled; int check_freshness; int freshness_threshold; double low_flap_threshold; double high_flap_threshold; int flap_detection_enabled; int notify_on_unknown; int notify_on_warning; int notify_on_critical; int notify_on_recovery; int notify_on_flapping; int notifications_enabled; char *notification_period; int notification_interval; char *contact_groups; int stalk_on_ok; int stalk_on_unknown; int stalk_on_warning; int stalk_on_critical; int process_perf_data; int failure_prediction_enabled; char *failure_prediction_options; int retain_status_information; int retain_nonstatus_information; int have_max_check_attempts; int have_normal_check_interval; int have_retry_check_interval; int have_active_checks_enabled; int have_passive_checks_enabled; int have_parallelize_check; int have_is_volatile; int have_obsess_over_service; int have_event_handler_enabled; int have_check_freshness; int have_freshness_threshold; int have_low_flap_threshold; int have_high_flap_threshold; int have_flap_detection_enabled; int have_notification_options; int have_notifications_enabled; int have_notification_dependencies; int have_notification_interval; int have_stalking_options; int have_process_perf_data; int have_failure_prediction_enabled; int have_retain_status_information; int have_retain_nonstatus_information; int has_been_resolved; int register_object; struct xodtemplate_service_struct *next; }xodtemplate_service; /* SERVICEGROUP TEMPLATE STRUCTURE */ typedef struct xodtemplate_servicegroup_struct{ char *template; char *name; int _config_file; int _start_line; char *servicegroup_name; char *alias; char *members; int has_been_resolved; int register_object; struct xodtemplate_servicegroup_struct *next; }xodtemplate_servicegroup; /* SERVICEDEPENDENCY TEMPLATE STRUCTURE */ typedef struct xodtemplate_servicedependency_struct{ char *template; char *name; int _config_file; int _start_line; char *servicegroup_name; char *hostgroup_name; char *host_name; char *service_description; char *dependent_servicegroup_name; char *dependent_hostgroup_name; char *dependent_host_name; char *dependent_service_description; int inherits_parent; int fail_notify_on_ok; int fail_notify_on_unknown; int fail_notify_on_warning; int fail_notify_on_critical; int fail_notify_on_pending; int fail_execute_on_ok; int fail_execute_on_unknown; int fail_execute_on_warning; int fail_execute_on_critical; int fail_execute_on_pending; int have_inherits_parent; int have_notification_dependency_options; int have_execution_dependency_options; int has_been_resolved; int register_object; struct xodtemplate_servicedependency_struct *next; }xodtemplate_servicedependency; /* SERVICEESCALATION TEMPLATE STRUCTURE */ typedef struct xodtemplate_serviceescalation_struct{ char *template; char *name; int _config_file; int _start_line; char *servicegroup_name; char *hostgroup_name; char *host_name; char *service_description; int first_notification; int last_notification; int notification_interval; char *escalation_period; int escalate_on_warning; int escalate_on_unknown; int escalate_on_critical; int escalate_on_recovery; char *contact_groups; int have_first_notification; int have_last_notification; int have_notification_interval; int have_escalation_options; int has_been_resolved; int register_object; struct xodtemplate_serviceescalation_struct *next; }xodtemplate_serviceescalation; /* HOSTDEPENDENCY TEMPLATE STRUCTURE */ typedef struct xodtemplate_hostdependency_struct{ char *template; char *name; int _config_file; int _start_line; char *hostgroup_name; char *dependent_hostgroup_name; char *host_name; char *dependent_host_name; int inherits_parent; int fail_notify_on_up; int fail_notify_on_down; int fail_notify_on_unreachable; int fail_notify_on_pending; int fail_execute_on_up; int fail_execute_on_down; int fail_execute_on_unreachable; int fail_execute_on_pending; int have_inherits_parent; int have_notification_dependency_options; int have_execution_dependency_options; int has_been_resolved; int register_object; struct xodtemplate_hostdependency_struct *next; }xodtemplate_hostdependency; /* HOSTESCALATION TEMPLATE STRUCTURE */ typedef struct xodtemplate_hostescalation_struct{ char *template; char *name; int _config_file; int _start_line; char *hostgroup_name; char *host_name; int first_notification; int last_notification; int notification_interval; char *escalation_period; int escalate_on_down; int escalate_on_unreachable; int escalate_on_recovery; char *contact_groups; int have_first_notification; int have_last_notification; int have_notification_interval; int have_escalation_options; int has_been_resolved; int register_object; struct xodtemplate_hostescalation_struct *next; }xodtemplate_hostescalation; /* HOSTEXTINFO TEMPLATE STRUCTURE */ typedef struct xodtemplate_hostextinfo_struct{ char *template; char *name; int _config_file; int _start_line; char *host_name; char *hostgroup_name; char *notes; char *notes_url; char *action_url; char *icon_image; char *icon_image_alt; char *vrml_image; char *statusmap_image; int x_2d; int y_2d; double x_3d; double y_3d; double z_3d; int have_2d_coords; int have_3d_coords; int has_been_resolved; int register_object; struct xodtemplate_hostextinfo_struct *next; }xodtemplate_hostextinfo; /* SERVICEEXTINFO TEMPLATE STRUCTURE */ typedef struct xodtemplate_serviceextinfo_struct{ char *template; char *name; int _config_file; int _start_line; char *host_name; char *hostgroup_name; char *service_description; char *notes; char *notes_url; char *action_url; char *icon_image; char *icon_image_alt; int has_been_resolved; int register_object; struct xodtemplate_serviceextinfo_struct *next; }xodtemplate_serviceextinfo; /* CONTACT LIST STRUCTURE */ typedef struct xodtemplate_contactlist_struct{ char *contact_name; struct xodtemplate_contactlist_struct *next; }xodtemplate_contactlist; /* HOST LIST STRUCTURE */ typedef struct xodtemplate_hostlist_struct{ char *host_name; struct xodtemplate_hostlist_struct *next; }xodtemplate_hostlist; /* SERVICE LIST STRUCTURE */ typedef struct xodtemplate_servicelist_struct{ char *host_name; char *service_description; struct xodtemplate_servicelist_struct *next; }xodtemplate_servicelist; /***** CHAINED HASH DATA STRUCTURES ******/ typedef struct xodtemplate_service_cursor_struct{ int xodtemplate_service_iterator; xodtemplate_service *current_xodtemplate_service; }xodtemplate_service_cursor; /********* FUNCTION DEFINITIONS **********/ int xodtemplate_read_config_data(char *,int,int); /* top-level routine processes all config files */ int xodtemplate_grab_config_info(char *); /* grabs variables from main config file */ int xodtemplate_process_config_file(char *,int); /* process data in a specific config file */ int xodtemplate_process_config_dir(char *,int); /* process all files in a specific config directory */ #ifdef NSCORE char *xodtemplate_config_file_name(int); /* returns the name of a numbered config file */ xodtemplate_contactlist *xodtemplate_expand_contacts(char *); int xodtemplate_expand_contacts2(xodtemplate_contactlist **,xodtemplate_contactlist **,char *); int xodtemplate_add_contact_to_contactlist(xodtemplate_contactlist **,char *); xodtemplate_hostlist *xodtemplate_expand_hostgroups_and_hosts(char *,char *); int xodtemplate_expand_hostgroups(xodtemplate_hostlist **,xodtemplate_hostlist **,char *); int xodtemplate_expand_hosts(xodtemplate_hostlist **,xodtemplate_hostlist **,char *); int xodtemplate_add_hostgroup_members_to_hostlist(xodtemplate_hostlist **,xodtemplate_hostgroup *); int xodtemplate_add_host_to_hostlist(xodtemplate_hostlist **,char *); xodtemplate_servicelist *xodtemplate_expand_servicegroups_and_services(char *,char *,char *); int xodtemplate_expand_servicegroups(xodtemplate_servicelist **,xodtemplate_servicelist **,char *); int xodtemplate_expand_services(xodtemplate_servicelist **,xodtemplate_servicelist **,char *,char *); int xodtemplate_add_servicegroup_members_to_servicelist(xodtemplate_servicelist **,xodtemplate_servicegroup *); int xodtemplate_add_service_to_servicelist(xodtemplate_servicelist **,char *,char *); #endif int xodtemplate_free_contactlist(xodtemplate_contactlist *); void xodtemplate_remove_contactlist_item(xodtemplate_contactlist *,xodtemplate_contactlist **); int xodtemplate_free_hostlist(xodtemplate_hostlist *); void xodtemplate_remove_hostlist_item(xodtemplate_hostlist *,xodtemplate_hostlist **); int xodtemplate_free_servicelist(xodtemplate_servicelist *); void xodtemplate_remove_servicelist_item(xodtemplate_servicelist *,xodtemplate_servicelist **); int xodtemplate_begin_object_definition(char *,int,int,int); int xodtemplate_add_object_property(char *,int); int xodtemplate_end_object_definition(int); int xodtemplate_register_objects(void); int xodtemplate_free_memory(void); #ifdef NSCORE int xodtemplate_duplicate_objects(void); int xodtemplate_duplicate_services(void); int xodtemplate_resolve_objects(void); int xodtemplate_sort_objects(void); int xodtemplate_compare_strings1(char *,char *); int xodtemplate_compare_strings2(char *,char *,char *,char *); int xodtemplate_cache_objects(char *); int xodtemplate_duplicate_service(xodtemplate_service *,char *); int xodtemplate_duplicate_hostescalation(xodtemplate_hostescalation *,char *); int xodtemplate_duplicate_serviceescalation(xodtemplate_serviceescalation *,char *,char *); int xodtemplate_duplicate_hostdependency(xodtemplate_hostdependency *,char *,char *); int xodtemplate_duplicate_servicedependency(xodtemplate_servicedependency *,char *,char *,char *,char *); int xodtemplate_duplicate_hostextinfo(xodtemplate_hostextinfo *,char *); int xodtemplate_duplicate_serviceextinfo(xodtemplate_serviceextinfo *,char *); int xodtemplate_recombobulate_contactgroups(void); int xodtemplate_recombobulate_hostgroups(void); int xodtemplate_recombobulate_servicegroups(void); int xodtemplate_resolve_timeperiod(xodtemplate_timeperiod *); int xodtemplate_resolve_command(xodtemplate_command *); int xodtemplate_resolve_contactgroup(xodtemplate_contactgroup *); int xodtemplate_resolve_hostgroup(xodtemplate_hostgroup *); int xodtemplate_resolve_servicegroup(xodtemplate_servicegroup *); int xodtemplate_resolve_servicedependency(xodtemplate_servicedependency *); int xodtemplate_resolve_serviceescalation(xodtemplate_serviceescalation *); int xodtemplate_resolve_contact(xodtemplate_contact *); int xodtemplate_resolve_host(xodtemplate_host *); int xodtemplate_resolve_service(xodtemplate_service *); int xodtemplate_resolve_hostdependency(xodtemplate_hostdependency *); int xodtemplate_resolve_hostescalation(xodtemplate_hostescalation *); int xodtemplate_resolve_hostextinfo(xodtemplate_hostextinfo *); int xodtemplate_resolve_serviceextinfo(xodtemplate_serviceextinfo *); int xodtemplate_sort_timeperiods(void); int xodtemplate_sort_commands(void); int xodtemplate_sort_contactgroups(void); int xodtemplate_sort_hostgroups(void); int xodtemplate_sort_servicegroups(void); int xodtemplate_sort_contacts(void); int xodtemplate_sort_hosts(void); int xodtemplate_sort_services(void); int xodtemplate_sort_servicedependencies(void); int xodtemplate_sort_serviceescalations(void); int xodtemplate_sort_hostdependencies(void); int xodtemplate_sort_hostescalations(void); int xodtemplate_sort_hostextinfo(void); int xodtemplate_sort_serviceextinfo(void); xodtemplate_timeperiod *xodtemplate_find_timeperiod(char *); xodtemplate_command *xodtemplate_find_command(char *); xodtemplate_contactgroup *xodtemplate_find_contactgroup(char *); xodtemplate_contactgroup *xodtemplate_find_real_contactgroup(char *); xodtemplate_hostgroup *xodtemplate_find_hostgroup(char *); xodtemplate_hostgroup *xodtemplate_find_real_hostgroup(char *); xodtemplate_servicegroup *xodtemplate_find_servicegroup(char *); xodtemplate_servicegroup *xodtemplate_find_real_servicegroup(char *); xodtemplate_servicedependency *xodtemplate_find_servicedependency(char *); xodtemplate_serviceescalation *xodtemplate_find_serviceescalation(char *); xodtemplate_contact *xodtemplate_find_contact(char *); xodtemplate_contact *xodtemplate_find_real_contact(char *); xodtemplate_host *xodtemplate_find_host(char *); xodtemplate_host *xodtemplate_find_real_host(char *); xodtemplate_service *xodtemplate_find_service(char *); xodtemplate_service *xodtemplate_find_real_service(char *,char *); xodtemplate_hostdependency *xodtemplate_find_hostdependency(char *); xodtemplate_hostescalation *xodtemplate_find_hostescalation(char *); xodtemplate_hostextinfo *xodtemplate_find_hostextinfo(char *); xodtemplate_serviceextinfo *xodtemplate_find_serviceextinfo(char *); #endif int xodtemplate_register_timeperiod(xodtemplate_timeperiod *); int xodtemplate_register_command(xodtemplate_command *); int xodtemplate_register_contactgroup(xodtemplate_contactgroup *); int xodtemplate_register_hostgroup(xodtemplate_hostgroup *); int xodtemplate_register_servicegroup(xodtemplate_servicegroup *); int xodtemplate_register_servicedependency(xodtemplate_servicedependency *); int xodtemplate_register_serviceescalation(xodtemplate_serviceescalation *); int xodtemplate_register_contact(xodtemplate_contact *); int xodtemplate_register_host(xodtemplate_host *); int xodtemplate_register_service(xodtemplate_service *); int xodtemplate_register_hostdependency(xodtemplate_hostdependency *); int xodtemplate_register_hostescalation(xodtemplate_hostescalation *); int xodtemplate_register_hostextinfo(xodtemplate_hostextinfo *); int xodtemplate_register_serviceextinfo(xodtemplate_serviceextinfo *); #endif nagios-2.6/xdata/xpddefault.c0000664000076500007650000006504410336571237015624 0ustar nagiosnagios/***************************************************************************** * * XPDDEFAULT.C - Default performance data routines * * Copyright (c) 2000-2004 Ethan Galstad (nagios@nagios.org) * Last Modified: 12-05-2004 * * 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/nagios.h" /**** DATA INPUT-SPECIFIC HEADER FILES ****/ #include "xpddefault.h" int xpddefault_perfdata_timeout; char *xpddefault_host_perfdata_command=NULL; char *xpddefault_service_perfdata_command=NULL; char *xpddefault_host_perfdata_file_template=NULL; char *xpddefault_service_perfdata_file_template=NULL; char *xpddefault_host_perfdata_file=NULL; char *xpddefault_service_perfdata_file=NULL; int xpddefault_host_perfdata_file_append=TRUE; int xpddefault_service_perfdata_file_append=TRUE; unsigned long xpddefault_host_perfdata_file_processing_interval=0L; unsigned long xpddefault_service_perfdata_file_processing_interval=0L; char *xpddefault_host_perfdata_file_processing_command; char *xpddefault_service_perfdata_file_processing_command; FILE *xpddefault_host_perfdata_fp=NULL; FILE *xpddefault_service_perfdata_fp=NULL; extern char *macro_x[MACRO_X_COUNT]; /******************************************************************/ /************** INITIALIZATION & CLEANUP FUNCTIONS ****************/ /******************************************************************/ /* initializes performance data */ int xpddefault_initialize_performance_data(char *config_file){ char buffer[MAX_INPUT_BUFFER]; char temp_buffer[MAX_INPUT_BUFFER]; char *temp_command_name; time_t current_time; time(¤t_time); /* default values */ xpddefault_perfdata_timeout=DEFAULT_PERFDATA_TIMEOUT; xpddefault_host_perfdata_command=NULL; xpddefault_service_perfdata_command=NULL; xpddefault_host_perfdata_file_template=NULL; xpddefault_service_perfdata_file_template=NULL; xpddefault_host_perfdata_file=NULL; xpddefault_service_perfdata_file=NULL; xpddefault_host_perfdata_fp=NULL; xpddefault_service_perfdata_fp=NULL; xpddefault_host_perfdata_file_processing_interval=0L; xpddefault_service_perfdata_file_processing_interval=0L; xpddefault_host_perfdata_file_processing_command=NULL; xpddefault_service_perfdata_file_processing_command=NULL; /* grab config info from main config file */ xpddefault_grab_config_info(config_file); /* make sure we have some templates defined */ if(xpddefault_host_perfdata_file_template==NULL) xpddefault_host_perfdata_file_template=strdup(DEFAULT_HOST_PERFDATA_FILE_TEMPLATE); if(xpddefault_service_perfdata_file_template==NULL) xpddefault_service_perfdata_file_template=strdup(DEFAULT_SERVICE_PERFDATA_FILE_TEMPLATE); /* process special chars in templates */ xpddefault_preprocess_file_templates(xpddefault_host_perfdata_file_template); xpddefault_preprocess_file_templates(xpddefault_service_perfdata_file_template); /* open the performance data files */ xpddefault_open_host_perfdata_file(); xpddefault_open_service_perfdata_file(); /* verify that performance data commands are valid */ if(xpddefault_host_perfdata_command!=NULL){ strncpy(temp_buffer,xpddefault_host_perfdata_command,sizeof(temp_buffer)); temp_buffer[sizeof(temp_buffer)-1]='\x0'; /* get the command name, leave any arguments behind */ temp_command_name=my_strtok(temp_buffer,"!"); if(find_command(temp_command_name)==NULL){ snprintf(buffer,sizeof(buffer),"Warning: Host performance command '%s' was not found - host performance data will not be processed!\n",temp_command_name); buffer[sizeof(buffer)-1]='\x0'; write_to_logs_and_console(buffer,NSLOG_RUNTIME_WARNING,TRUE); free(xpddefault_host_perfdata_command); xpddefault_host_perfdata_command=NULL; } } if(xpddefault_service_perfdata_command!=NULL){ strncpy(temp_buffer,xpddefault_service_perfdata_command,sizeof(temp_buffer)); temp_buffer[sizeof(temp_buffer)-1]='\x0'; /* get the command name, leave any arguments behind */ temp_command_name=my_strtok(temp_buffer,"!"); if(find_command(temp_command_name)==NULL){ snprintf(buffer,sizeof(buffer),"Warning: Service performance command '%s' was not found - service performance data will not be processed!\n",temp_command_name); buffer[sizeof(buffer)-1]='\x0'; write_to_logs_and_console(buffer,NSLOG_RUNTIME_WARNING,TRUE); free(xpddefault_service_perfdata_command); xpddefault_service_perfdata_command=NULL; } } if(xpddefault_host_perfdata_file_processing_command!=NULL){ strncpy(temp_buffer,xpddefault_host_perfdata_file_processing_command,sizeof(temp_buffer)); temp_buffer[sizeof(temp_buffer)-1]='\x0'; /* get the command name, leave any arguments behind */ temp_command_name=my_strtok(temp_buffer,"!"); if(find_command(temp_command_name)==NULL){ snprintf(buffer,sizeof(buffer),"Warning: Host performance file processing command '%s' was not found - host performance data file will not be processed!\n",temp_command_name); buffer[sizeof(buffer)-1]='\x0'; write_to_logs_and_console(buffer,NSLOG_RUNTIME_WARNING,TRUE); free(xpddefault_host_perfdata_file_processing_command); xpddefault_host_perfdata_file_processing_command=NULL; } } if(xpddefault_service_perfdata_file_processing_command!=NULL){ strncpy(temp_buffer,xpddefault_service_perfdata_file_processing_command,sizeof(temp_buffer)); temp_buffer[sizeof(temp_buffer)-1]='\x0'; /* get the command name, leave any arguments behind */ temp_command_name=my_strtok(temp_buffer,"!"); if(find_command(temp_command_name)==NULL){ snprintf(buffer,sizeof(buffer),"Warning: Service performance file processing command '%s' was not found - service performance data file will not be processed!\n",temp_command_name); buffer[sizeof(buffer)-1]='\x0'; write_to_logs_and_console(buffer,NSLOG_RUNTIME_WARNING,TRUE); free(xpddefault_service_perfdata_file_processing_command); xpddefault_service_perfdata_file_processing_command=NULL; } } /* periodically process the host perfdata file */ if(xpddefault_host_perfdata_file_processing_interval>0 && xpddefault_host_perfdata_file_processing_command!=NULL) schedule_new_event(EVENT_USER_FUNCTION,TRUE,current_time+xpddefault_host_perfdata_file_processing_interval,TRUE,xpddefault_host_perfdata_file_processing_interval,NULL,TRUE,xpddefault_process_host_perfdata_file,NULL); /* periodically process the service perfdata file */ if(xpddefault_service_perfdata_file_processing_interval>0 && xpddefault_service_perfdata_file_processing_command!=NULL) schedule_new_event(EVENT_USER_FUNCTION,TRUE,current_time+xpddefault_service_perfdata_file_processing_interval,TRUE,xpddefault_service_perfdata_file_processing_interval,NULL,TRUE,xpddefault_process_service_perfdata_file,NULL); /* save the host perf data file macro */ if(macro_x[MACRO_HOSTPERFDATAFILE]!=NULL){ free(macro_x[MACRO_HOSTPERFDATAFILE]); macro_x[MACRO_HOSTPERFDATAFILE]=NULL; } if(xpddefault_host_perfdata_file!=NULL) macro_x[MACRO_HOSTPERFDATAFILE]=(char *)strdup(xpddefault_host_perfdata_file); if(macro_x[MACRO_HOSTPERFDATAFILE]!=NULL) strip(macro_x[MACRO_HOSTPERFDATAFILE]); /* save the service perf data file macro */ if(macro_x[MACRO_SERVICEPERFDATAFILE]!=NULL){ free(macro_x[MACRO_SERVICEPERFDATAFILE]); macro_x[MACRO_SERVICEPERFDATAFILE]=NULL; } if(xpddefault_service_perfdata_file!=NULL) macro_x[MACRO_SERVICEPERFDATAFILE]=(char *)strdup(xpddefault_service_perfdata_file); if(macro_x[MACRO_SERVICEPERFDATAFILE]!=NULL) strip(macro_x[MACRO_SERVICEPERFDATAFILE]); return OK; } /* grabs configuration information from main config file */ int xpddefault_grab_config_info(char *config_file){ char *input=NULL; char temp_buffer[MAX_INPUT_BUFFER]; char variable[MAX_INPUT_BUFFER]; char value[MAX_INPUT_BUFFER]; char *temp_ptr; mmapfile *thefile; int error=FALSE; /* open the config file for reading */ if((thefile=mmap_fopen(config_file))==NULL){ snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not open main config file '%s' for reading performance variables!\n",config_file); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_CONFIG_ERROR,TRUE); return ERROR; } /* read in all lines from the config file */ while(1){ /* free memory */ free(input); /* read the next line */ if((input=mmap_fgets(thefile))==NULL) break; strip(input); /* skip blank lines and comments */ if(input[0]=='#' || input[0]=='\x0') continue; /* get the variable name */ temp_ptr=my_strtok(input,"="); /* if there is no variable name, return error */ if(temp_ptr==NULL){ error=TRUE; break; } /* else the variable is good */ strncpy(variable,temp_ptr,sizeof(variable)); variable[sizeof(variable)-1]='\x0'; /* get the value */ temp_ptr=my_strtok(NULL,"="); /* if no value exists, return error */ if(temp_ptr==NULL){ error=TRUE; break; } /* else the value is good */ strncpy(value,temp_ptr,sizeof(value)); value[sizeof(value)-1]='\x0'; strip(value); if(!strcmp(variable,"perfdata_timeout")){ strip(value); xpddefault_perfdata_timeout=atoi(value); if(xpddefault_perfdata_timeout<=0){ error=TRUE; break; } } else if(!strcmp(variable,"host_perfdata_command")) xpddefault_host_perfdata_command=strdup(value); else if(!strcmp(variable,"service_perfdata_command")) xpddefault_service_perfdata_command=strdup(value); else if(!strcmp(variable,"host_perfdata_file_template")) xpddefault_host_perfdata_file_template=strdup(value); else if(!strcmp(variable,"service_perfdata_file_template")) xpddefault_service_perfdata_file_template=strdup(value); else if(!strcmp(variable,"host_perfdata_file")) xpddefault_host_perfdata_file=strdup(value); else if(!strcmp(variable,"service_perfdata_file")) xpddefault_service_perfdata_file=strdup(value); else if(!strcmp(variable,"host_perfdata_file_mode")){ if(!strstr(value,"w")) xpddefault_host_perfdata_file_append=FALSE; else xpddefault_host_perfdata_file_append=TRUE; } else if(!strcmp(variable,"service_perfdata_file_mode")){ if(!strstr(value,"w")) xpddefault_service_perfdata_file_append=FALSE; else xpddefault_service_perfdata_file_append=TRUE; } else if(!strcmp(variable,"host_perfdata_file_processing_interval")) xpddefault_host_perfdata_file_processing_interval=strtoul(value,NULL,0); else if(!strcmp(variable,"service_perfdata_file_processing_interval")) xpddefault_service_perfdata_file_processing_interval=strtoul(value,NULL,0); else if(!strcmp(variable,"host_perfdata_file_processing_command")) xpddefault_host_perfdata_file_processing_command=strdup(value); else if(!strcmp(variable,"service_perfdata_file_processing_command")) xpddefault_service_perfdata_file_processing_command=strdup(value); } /* free memory and close the file */ free(input); mmap_fclose(thefile); return OK; } /* cleans up performance data */ int xpddefault_cleanup_performance_data(char *config_file){ /* free memory */ xpddefault_free_memory(); /* close the files */ xpddefault_close_host_perfdata_file(); xpddefault_close_service_perfdata_file(); return OK; } /* frees allocated memory */ int xpddefault_free_memory(void){ /* free memory */ if(xpddefault_host_perfdata_command!=NULL){ free(xpddefault_host_perfdata_command); xpddefault_host_perfdata_command=NULL; } if(xpddefault_service_perfdata_command!=NULL){ free(xpddefault_service_perfdata_command); xpddefault_service_perfdata_command=NULL; } if(xpddefault_host_perfdata_file_template!=NULL){ free(xpddefault_host_perfdata_file_template); xpddefault_host_perfdata_file_template=NULL; } if(xpddefault_service_perfdata_file_template!=NULL){ free(xpddefault_service_perfdata_file_template); xpddefault_service_perfdata_file_template=NULL; } if(xpddefault_host_perfdata_file!=NULL){ free(xpddefault_host_perfdata_file); xpddefault_host_perfdata_file=NULL; } if(xpddefault_service_perfdata_file!=NULL){ free(xpddefault_service_perfdata_file); xpddefault_service_perfdata_file=NULL; } if(xpddefault_host_perfdata_file_processing_command!=NULL){ free(xpddefault_host_perfdata_file_processing_command); xpddefault_host_perfdata_file_processing_command=NULL; } if(xpddefault_service_perfdata_file_processing_command!=NULL){ free(xpddefault_service_perfdata_file_processing_command); xpddefault_service_perfdata_file_processing_command=NULL; } return OK; } /******************************************************************/ /****************** PERFORMANCE DATA FUNCTIONS ********************/ /******************************************************************/ /* updates service performance data */ int xpddefault_update_service_performance_data(service *svc){ /* run the performance data command */ xpddefault_run_service_performance_data_command(svc); /* update the performance data file */ xpddefault_update_service_performance_data_file(svc); return OK; } /* updates host performance data */ int xpddefault_update_host_performance_data(host *hst){ /* run the performance data command */ xpddefault_run_host_performance_data_command(hst); /* update the performance data file */ xpddefault_update_host_performance_data_file(hst); return OK; } /******************************************************************/ /************** PERFORMANCE DATA COMMAND FUNCTIONS ****************/ /******************************************************************/ /* runs the service performance data command */ int xpddefault_run_service_performance_data_command(service *svc){ char raw_command_line[MAX_INPUT_BUFFER]; char processed_command_line[MAX_INPUT_BUFFER]; char temp_buffer[MAX_INPUT_BUFFER]; host *temp_host; int early_timeout=FALSE; double exectime; int result=OK; int macro_options=STRIP_ILLEGAL_MACRO_CHARS|ESCAPE_MACRO_CHARS; /* we don't have a command */ if(xpddefault_service_perfdata_command==NULL) return OK; /* find the associated host */ temp_host=find_host(svc->host_name); /* update service macros */ clear_volatile_macros(); grab_host_macros(temp_host); grab_service_macros(svc); grab_summary_macros(NULL); /* get the raw command line */ get_raw_command_line(xpddefault_service_perfdata_command,raw_command_line,sizeof(raw_command_line),macro_options); strip(raw_command_line); #ifdef DEBUG3 printf("\tRaw service performance data command line: %s\n",raw_command_line); #endif /* process any macros in the raw command line */ process_macros(raw_command_line,processed_command_line,(int)sizeof(processed_command_line),macro_options); #ifdef DEBUG3 printf("\tProcessed service performance data command line: %s\n",processed_command_line); #endif /* run the command */ my_system(processed_command_line,xpddefault_perfdata_timeout,&early_timeout,&exectime,NULL,0); /* check to see if the command timed out */ if(early_timeout==TRUE){ snprintf(temp_buffer,sizeof(temp_buffer),"Warning: Service performance data command '%s' for service '%s' on host '%s' timed out after %d seconds\n",processed_command_line,svc->description,svc->host_name,xpddefault_perfdata_timeout); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_RUNTIME_WARNING,TRUE); } return result; } /* runs the host performance data command */ int xpddefault_run_host_performance_data_command(host *hst){ char raw_command_line[MAX_INPUT_BUFFER]; char processed_command_line[MAX_INPUT_BUFFER]; char temp_buffer[MAX_INPUT_BUFFER]; int early_timeout=FALSE; double exectime; int result=OK; int macro_options=STRIP_ILLEGAL_MACRO_CHARS|ESCAPE_MACRO_CHARS; /* we don't have a command */ if(xpddefault_host_perfdata_command==NULL) return OK; /* update host macros */ clear_volatile_macros(); grab_host_macros(hst); grab_summary_macros(NULL); /* get the raw command line */ get_raw_command_line(xpddefault_host_perfdata_command,raw_command_line,sizeof(raw_command_line),macro_options); strip(raw_command_line); #ifdef DEBUG3 printf("\tRaw host performance data command line: %s\n",raw_command_line); #endif /* process any macros in the raw command line */ process_macros(raw_command_line,processed_command_line,(int)sizeof(processed_command_line),macro_options); #ifdef DEBUG3 printf("\tProcessed host performance data command line: %s\n",processed_command_line); #endif /* run the command */ my_system(processed_command_line,xpddefault_perfdata_timeout,&early_timeout,&exectime,NULL,0); /* check to see if the command timed out */ if(early_timeout==TRUE){ snprintf(temp_buffer,sizeof(temp_buffer),"Warning: Host performance data command '%s' for host '%s' timed out after %d seconds\n",processed_command_line,hst->name,xpddefault_perfdata_timeout); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_RUNTIME_WARNING,TRUE); } return result; } /******************************************************************/ /**************** FILE PERFORMANCE DATA FUNCTIONS *****************/ /******************************************************************/ /* open the host performance data file for writing */ int xpddefault_open_host_perfdata_file(void){ char buffer[MAX_INPUT_BUFFER]; if(xpddefault_host_perfdata_file!=NULL){ xpddefault_host_perfdata_fp=fopen(xpddefault_host_perfdata_file,(xpddefault_host_perfdata_file_append==TRUE)?"a":"w"); if(xpddefault_host_perfdata_fp==NULL){ snprintf(buffer,sizeof(buffer),"Warning: File '%s' could not be opened - host performance data will not be written to file!\n",xpddefault_host_perfdata_file); buffer[sizeof(buffer)-1]='\x0'; write_to_logs_and_console(buffer,NSLOG_RUNTIME_WARNING,TRUE); return ERROR; } } return OK; } /* open the service performance data file for writing */ int xpddefault_open_service_perfdata_file(void){ char buffer[MAX_INPUT_BUFFER]; if(xpddefault_service_perfdata_file!=NULL){ xpddefault_service_perfdata_fp=fopen(xpddefault_service_perfdata_file,(xpddefault_service_perfdata_file_append==TRUE)?"a":"w"); if(xpddefault_service_perfdata_fp==NULL){ snprintf(buffer,sizeof(buffer),"Warning: File '%s' could not be opened - service performance data will not be written to file!\n",xpddefault_service_perfdata_file); buffer[sizeof(buffer)-1]='\x0'; write_to_logs_and_console(buffer,NSLOG_RUNTIME_WARNING,TRUE); return ERROR; } } return OK; } /* close the host performance data file */ int xpddefault_close_host_perfdata_file(void){ if(xpddefault_host_perfdata_fp!=NULL) fclose(xpddefault_host_perfdata_fp); return OK; } /* close the service performance data file */ int xpddefault_close_service_perfdata_file(void){ if(xpddefault_service_perfdata_fp!=NULL) fclose(xpddefault_service_perfdata_fp); return OK; } /* processes delimiter characters in templates */ int xpddefault_preprocess_file_templates(char *template){ char *tempbuf; int x=0; int y=0; if(template==NULL) return OK; /* allocate temporary buffer */ tempbuf=(char *)malloc(strlen(template)+1); if(tempbuf==NULL) return ERROR; strcpy(tempbuf,""); for(x=0,y=0;xhost_name); /* update service macros */ clear_volatile_macros(); grab_host_macros(temp_host); grab_service_macros(svc); grab_summary_macros(NULL); /* get the raw line to write */ strncpy(raw_output,xpddefault_service_perfdata_file_template,sizeof(raw_output)); raw_output[sizeof(raw_output)-1]='\x0'; #ifdef DEBUG3 printf("\tRaw service performance data output: %s\n",raw_output); #endif /* process any macros in the raw output line */ process_macros(raw_output,processed_output,(int)sizeof(processed_output),0); #ifdef DEBUG3 printf("\tProcessed service performance data output: %s\n",processed_output); #endif /* write the processed output line containing performance data to the service perfdata file */ fputs(processed_output,xpddefault_service_perfdata_fp); fputs("\n",xpddefault_service_perfdata_fp); fflush(xpddefault_service_perfdata_fp); return result; } /* updates host performance data file */ int xpddefault_update_host_performance_data_file(host *hst){ char raw_output[MAX_INPUT_BUFFER]; char processed_output[MAX_INPUT_BUFFER]; int result=OK; /* we don't have a host perfdata file */ if(xpddefault_host_perfdata_fp==NULL || xpddefault_host_perfdata_file_template==NULL) return OK; /* update host macros */ clear_volatile_macros(); grab_host_macros(hst); grab_summary_macros(NULL); /* get the raw output */ strncpy(raw_output,xpddefault_host_perfdata_file_template,sizeof(raw_output)); raw_output[sizeof(raw_output)-1]='\x0'; #ifdef DEBUG3 printf("\tRaw host performance output: %s\n",raw_output); #endif /* process any macros in the raw output */ process_macros(raw_output,processed_output,(int)sizeof(processed_output),0); #ifdef DEBUG3 printf("\tProcessed host performance data output: %s\n",processed_output); #endif /* write the processed output line containing performance data to the host perfdata file */ fputs(processed_output,xpddefault_host_perfdata_fp); fputs("\n",xpddefault_host_perfdata_fp); fflush(xpddefault_host_perfdata_fp); return result; } /* periodically process the host perf data file */ int xpddefault_process_host_perfdata_file(void){ char raw_command_line[MAX_INPUT_BUFFER]; char processed_command_line[MAX_INPUT_BUFFER]; char temp_buffer[MAX_INPUT_BUFFER]; int early_timeout=FALSE; double exectime; int result=OK; int macro_options=STRIP_ILLEGAL_MACRO_CHARS|ESCAPE_MACRO_CHARS; /* we don't have a command */ if(xpddefault_host_perfdata_file_processing_command==NULL) return OK; /* close the performance data files */ xpddefault_close_host_perfdata_file(); xpddefault_close_service_perfdata_file(); /* update macros */ clear_volatile_macros(); grab_datetime_macros(); grab_summary_macros(NULL); /* get the raw command line */ get_raw_command_line(xpddefault_host_perfdata_file_processing_command,raw_command_line,sizeof(raw_command_line),macro_options); strip(raw_command_line); #ifdef DEBUG3 printf("\tRaw host performance data file processing command line: %s\n",raw_command_line); #endif /* process any macros in the raw command line */ process_macros(raw_command_line,processed_command_line,(int)sizeof(processed_command_line),macro_options); #ifdef DEBUG3 printf("\tProcessed host performance data file processing command line: %s\n",processed_command_line); #endif /* run the command */ my_system(processed_command_line,xpddefault_perfdata_timeout,&early_timeout,&exectime,NULL,0); /* check to see if the command timed out */ if(early_timeout==TRUE){ snprintf(temp_buffer,sizeof(temp_buffer),"Warning: Host performance data file processing command '%s' timed out after %d seconds\n",processed_command_line,xpddefault_perfdata_timeout); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_RUNTIME_WARNING,TRUE); } /* re-open the performance data files */ xpddefault_open_service_perfdata_file(); xpddefault_open_host_perfdata_file(); return result; } /* periodically process the service perf data file */ int xpddefault_process_service_perfdata_file(void){ char raw_command_line[MAX_INPUT_BUFFER]; char processed_command_line[MAX_INPUT_BUFFER]; char temp_buffer[MAX_INPUT_BUFFER]; int early_timeout=FALSE; double exectime; int result=OK; int macro_options=STRIP_ILLEGAL_MACRO_CHARS|ESCAPE_MACRO_CHARS; /* we don't have a command */ if(xpddefault_service_perfdata_file_processing_command==NULL) return OK; /* close the performance data files */ xpddefault_close_host_perfdata_file(); xpddefault_close_service_perfdata_file(); /* update macros */ clear_volatile_macros(); grab_datetime_macros(); grab_summary_macros(NULL); /* get the raw command line */ get_raw_command_line(xpddefault_service_perfdata_file_processing_command,raw_command_line,sizeof(raw_command_line),macro_options); strip(raw_command_line); #ifdef DEBUG3 printf("\tRaw service performance data file processing command line: %s\n",raw_command_line); #endif /* process any macros in the raw command line */ process_macros(raw_command_line,processed_command_line,(int)sizeof(processed_command_line),macro_options); #ifdef DEBUG3 printf("\tProcessed service performance data file processing command line: %s\n",processed_command_line); #endif /* run the command */ my_system(processed_command_line,xpddefault_perfdata_timeout,&early_timeout,&exectime,NULL,0); /* check to see if the command timed out */ if(early_timeout==TRUE){ snprintf(temp_buffer,sizeof(temp_buffer),"Warning: Service performance data file processing command '%s' timed out after %d seconds\n",processed_command_line,xpddefault_perfdata_timeout); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_RUNTIME_WARNING,TRUE); } /* re-open the performance data files */ xpddefault_open_service_perfdata_file(); xpddefault_open_host_perfdata_file(); return result; } nagios-2.6/xdata/xpddefault.h0000664000076500007650000000424510336571237015625 0ustar nagiosnagios/***************************************************************************** * * XPDDEFAULT.H - Include file for default performance data routines * * Copyright (c) 2001-2004 Ethan Galstad (nagios@nagios.org) * Last Modified: 11-29-2004 * * 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. * *****************************************************************************/ #include "../include/objects.h" #define DEFAULT_HOST_PERFDATA_FILE_TEMPLATE "[HOSTPERFDATA]\t$TIMET$\t$HOSTNAME$\t$HOSTEXECUTIONTIME$\t$HOSTOUTPUT$\t$HOSTPERFDATA$" #define DEFAULT_SERVICE_PERFDATA_FILE_TEMPLATE "[SERVICEPERFDATA]\t$TIMET$\t$HOSTNAME$\t$SERVICEDESC$\t$SERVICEEXECUTIONTIME$\t$SERVICELATENCY$\t$SERVICEOUTPUT$\t$SERVICEPERFDATA$" int xpddefault_initialize_performance_data(char *); int xpddefault_cleanup_performance_data(char *); int xpddefault_free_memory(void); int xpddefault_grab_config_info(char *); int xpddefault_update_service_performance_data(service *); int xpddefault_update_host_performance_data(host *); int xpddefault_run_service_performance_data_command(service *); int xpddefault_run_host_performance_data_command(host *); int xpddefault_update_service_performance_data_file(service *); int xpddefault_update_host_performance_data_file(host *); int xpddefault_preprocess_file_templates(char *); int xpddefault_open_host_perfdata_file(void); int xpddefault_open_service_perfdata_file(void); int xpddefault_close_host_perfdata_file(void); int xpddefault_close_service_perfdata_file(void); int xpddefault_process_host_perfdata_file(void); int xpddefault_process_service_perfdata_file(void); nagios-2.6/xdata/xrddefault.c0000664000076500007650000011541510415470231015612 0ustar nagiosnagios/***************************************************************************** * * XRDDEFAULT.C - Default external state retention routines for Nagios * * Copyright (c) 1999-2006 Ethan Galstad (nagios@nagios.org) * Last Modified: 04-07-2006 * * 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 "../include/nagios.h" #include "../include/sretention.h" /**** STATE INFORMATION SPECIFIC HEADER FILES ****/ #include "xrddefault.h" extern host *host_list; extern service *service_list; extern char *global_host_event_handler; extern char *global_service_event_handler; extern char *macro_x[MACRO_X_COUNT]; extern int enable_notifications; extern int execute_service_checks; extern int accept_passive_service_checks; extern int execute_host_checks; extern int accept_passive_host_checks; extern int enable_event_handlers; extern int obsess_over_services; extern int obsess_over_hosts; extern int enable_flap_detection; extern int enable_failure_prediction; extern int process_performance_data; extern int check_service_freshness; extern int check_host_freshness; extern int use_retained_program_state; extern int use_retained_scheduling_info; extern int retention_scheduling_horizon; extern unsigned long modified_host_process_attributes; extern unsigned long modified_service_process_attributes; char xrddefault_retention_file[MAX_FILENAME_LENGTH]=""; char xrddefault_temp_file[MAX_FILENAME_LENGTH]=""; /******************************************************************/ /********************* CONFIG INITIALIZATION *********************/ /******************************************************************/ int xrddefault_grab_config_info(char *main_config_file){ char *input=NULL; char *temp_ptr; mmapfile *thefile; /* initialize the location of the retention file */ strncpy(xrddefault_retention_file,DEFAULT_RETENTION_FILE,sizeof(xrddefault_retention_file)-1); strncpy(xrddefault_temp_file,DEFAULT_TEMP_FILE,sizeof(xrddefault_temp_file)-1); xrddefault_retention_file[sizeof(xrddefault_retention_file)-1]='\x0'; xrddefault_temp_file[sizeof(xrddefault_temp_file)-1]='\x0'; /* open the main config file for reading */ if((thefile=mmap_fopen(main_config_file))==NULL){ #ifdef DEBUG1 printf("Error: Cannot open main configuration file '%s' for reading!\n",main_config_file); #endif return ERROR; } /* read in all lines from the main config file */ while(1){ /* free memory */ free(input); /* read the next line */ if((input=mmap_fgets(thefile))==NULL) break; strip(input); /* skip blank lines and comments */ if(input[0]=='#' || input[0]=='\x0') continue; temp_ptr=my_strtok(input,"="); if(temp_ptr==NULL) continue; /* temp file definition */ if(!strcmp(temp_ptr,"temp_file")){ temp_ptr=my_strtok(NULL,"\n"); if(temp_ptr==NULL) continue; strncpy(xrddefault_temp_file,temp_ptr,sizeof(xrddefault_temp_file)-1); xrddefault_temp_file[sizeof(xrddefault_temp_file)-1]='\x0'; } /* retention file location */ else if(!strcmp(temp_ptr,"xrddefault_retention_file") || !strcmp(temp_ptr,"state_retention_file")){ temp_ptr=my_strtok(NULL,"\n"); if(temp_ptr==NULL) continue; strncpy(xrddefault_retention_file,temp_ptr,sizeof(xrddefault_retention_file)-1); xrddefault_retention_file[sizeof(xrddefault_retention_file)-1]='\x0'; } } /* free memory and close the file */ free(input); mmap_fclose(thefile); /* save the retention file macro */ if(macro_x[MACRO_RETENTIONDATAFILE]!=NULL) free(macro_x[MACRO_RETENTIONDATAFILE]); macro_x[MACRO_RETENTIONDATAFILE]=(char *)strdup(xrddefault_retention_file); if(macro_x[MACRO_RETENTIONDATAFILE]!=NULL) strip(macro_x[MACRO_RETENTIONDATAFILE]); return OK; } /******************************************************************/ /**************** DEFAULT STATE OUTPUT FUNCTION *******************/ /******************************************************************/ int xrddefault_save_state_information(char *main_config_file){ char temp_buffer[MAX_INPUT_BUFFER]; char temp_file[MAX_FILENAME_LENGTH]; time_t current_time; int result=OK; FILE *fp=NULL; host *temp_host=NULL; service *temp_service=NULL; int x, fd=0; #ifdef DEBUG0 printf("xrddefault_save_state_information() start\n"); #endif /* grab config info */ if(xrddefault_grab_config_info(main_config_file)==ERROR){ snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Failed to grab configuration information for retention data!\n"); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_RUNTIME_ERROR,TRUE); return ERROR; } /* open a safe temp file for output */ snprintf(temp_file,sizeof(temp_file)-1,"%sXXXXXX",xrddefault_temp_file); temp_file[sizeof(temp_file)-1]='\x0'; if((fd=mkstemp(temp_file))==-1) return ERROR; fp=fdopen(fd,"w"); if(fp==NULL){ close(fd); unlink(temp_file); snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Could not open temp state retention file '%s' for writing!\n",temp_file); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_RUNTIME_ERROR,TRUE); return ERROR; } /* write version info to status file */ fprintf(fp,"########################################\n"); fprintf(fp,"# NAGIOS STATE RETENTION FILE\n"); fprintf(fp,"#\n"); fprintf(fp,"# THIS FILE IS AUTOMATICALLY GENERATED\n"); fprintf(fp,"# BY NAGIOS. DO NOT MODIFY THIS FILE!\n"); fprintf(fp,"########################################\n\n"); time(¤t_time); /* write file info */ fprintf(fp,"info {\n"); fprintf(fp,"\tcreated=%lu\n",current_time); fprintf(fp,"\tversion=%s\n",PROGRAM_VERSION); fprintf(fp,"\t}\n\n"); /* save program state information */ fprintf(fp,"program {\n"); fprintf(fp,"\tmodified_host_attributes=%lu\n",modified_host_process_attributes); fprintf(fp,"\tmodified_service_attributes=%lu\n",modified_service_process_attributes); fprintf(fp,"\tenable_notifications=%d\n",enable_notifications); fprintf(fp,"\tactive_service_checks_enabled=%d\n",execute_service_checks); fprintf(fp,"\tpassive_service_checks_enabled=%d\n",accept_passive_service_checks); fprintf(fp,"\tactive_host_checks_enabled=%d\n",execute_host_checks); fprintf(fp,"\tpassive_host_checks_enabled=%d\n",accept_passive_host_checks); fprintf(fp,"\tenable_event_handlers=%d\n",enable_event_handlers); fprintf(fp,"\tobsess_over_services=%d\n",obsess_over_services); fprintf(fp,"\tobsess_over_hosts=%d\n",obsess_over_hosts); fprintf(fp,"\tcheck_service_freshness=%d\n",check_service_freshness); fprintf(fp,"\tcheck_host_freshness=%d\n",check_host_freshness); fprintf(fp,"\tenable_flap_detection=%d\n",enable_flap_detection); fprintf(fp,"\tenable_failure_prediction=%d\n",enable_failure_prediction); fprintf(fp,"\tprocess_performance_data=%d\n",process_performance_data); fprintf(fp,"\tglobal_host_event_handler=%s\n",(global_host_event_handler==NULL)?"":global_host_event_handler); fprintf(fp,"\tglobal_service_event_handler=%s\n",(global_service_event_handler==NULL)?"":global_service_event_handler); fprintf(fp,"\t}\n\n"); /* save host state information */ for(temp_host=host_list;temp_host!=NULL;temp_host=temp_host->next){ fprintf(fp,"host {\n"); fprintf(fp,"\thost_name=%s\n",temp_host->name); fprintf(fp,"\tmodified_attributes=%lu\n",temp_host->modified_attributes); fprintf(fp,"\tcheck_command=%s\n",(temp_host->host_check_command==NULL)?"":temp_host->host_check_command); fprintf(fp,"\tevent_handler=%s\n",(temp_host->event_handler==NULL)?"":temp_host->event_handler); fprintf(fp,"\thas_been_checked=%d\n",temp_host->has_been_checked); fprintf(fp,"\tcheck_execution_time=%.3f\n",temp_host->execution_time); fprintf(fp,"\tcheck_latency=%.3f\n",temp_host->latency); fprintf(fp,"\tcheck_type=%d\n",temp_host->check_type); fprintf(fp,"\tcurrent_state=%d\n",temp_host->current_state); fprintf(fp,"\tlast_state=%d\n",temp_host->last_state); fprintf(fp,"\tlast_hard_state=%d\n",temp_host->last_hard_state); fprintf(fp,"\tplugin_output=%s\n",(temp_host->plugin_output==NULL)?"":temp_host->plugin_output); fprintf(fp,"\tperformance_data=%s\n",(temp_host->perf_data==NULL)?"":temp_host->perf_data); fprintf(fp,"\tlast_check=%lu\n",temp_host->last_check); fprintf(fp,"\tnext_check=%lu\n",temp_host->next_check); fprintf(fp,"\tcurrent_attempt=%d\n",temp_host->current_attempt); fprintf(fp,"\tmax_attempts=%d\n",temp_host->max_attempts); fprintf(fp,"\tnormal_check_interval=%d\n",temp_host->check_interval); fprintf(fp,"\tstate_type=%d\n",temp_host->state_type); fprintf(fp,"\tlast_state_change=%lu\n",temp_host->last_state_change); fprintf(fp,"\tlast_hard_state_change=%lu\n",temp_host->last_hard_state_change); fprintf(fp,"\tlast_time_up=%lu\n",temp_host->last_time_up); fprintf(fp,"\tlast_time_down=%lu\n",temp_host->last_time_down); fprintf(fp,"\tlast_time_unreachable=%lu\n",temp_host->last_time_unreachable); fprintf(fp,"\tnotified_on_down=%d\n",temp_host->notified_on_down); fprintf(fp,"\tnotified_on_unreachable=%d\n",temp_host->notified_on_unreachable); fprintf(fp,"\tlast_notification=%lu\n",temp_host->last_host_notification); fprintf(fp,"\tcurrent_notification_number=%d\n",temp_host->current_notification_number); fprintf(fp,"\tnotifications_enabled=%d\n",temp_host->notifications_enabled); fprintf(fp,"\tproblem_has_been_acknowledged=%d\n",temp_host->problem_has_been_acknowledged); fprintf(fp,"\tacknowledgement_type=%d\n",temp_host->acknowledgement_type); fprintf(fp,"\tactive_checks_enabled=%d\n",temp_host->checks_enabled); fprintf(fp,"\tpassive_checks_enabled=%d\n",temp_host->accept_passive_host_checks); fprintf(fp,"\tevent_handler_enabled=%d\n",temp_host->event_handler_enabled); fprintf(fp,"\tflap_detection_enabled=%d\n",temp_host->flap_detection_enabled); fprintf(fp,"\tfailure_prediction_enabled=%d\n",temp_host->failure_prediction_enabled); fprintf(fp,"\tprocess_performance_data=%d\n",temp_host->process_performance_data); fprintf(fp,"\tobsess_over_host=%d\n",temp_host->obsess_over_host); fprintf(fp,"\tis_flapping=%d\n",temp_host->is_flapping); fprintf(fp,"\tpercent_state_change=%.2f\n",temp_host->percent_state_change); fprintf(fp,"\tstate_history="); for(x=0;x0)?",":"",temp_host->state_history[(x+temp_host->state_history_index)%MAX_STATE_HISTORY_ENTRIES]); fprintf(fp,"\n"); fprintf(fp,"\t}\n\n"); } /* save service state information */ for(temp_service=service_list;temp_service!=NULL;temp_service=temp_service->next){ fprintf(fp,"service {\n"); fprintf(fp,"\thost_name=%s\n",temp_service->host_name); fprintf(fp,"\tservice_description=%s\n",temp_service->description); fprintf(fp,"\tmodified_attributes=%lu\n",temp_service->modified_attributes); fprintf(fp,"\tcheck_command=%s\n",(temp_service->service_check_command==NULL)?"":temp_service->service_check_command); fprintf(fp,"\tevent_handler=%s\n",(temp_service->event_handler==NULL)?"":temp_service->event_handler); fprintf(fp,"\thas_been_checked=%d\n",temp_service->has_been_checked); fprintf(fp,"\tcheck_execution_time=%.3f\n",temp_service->execution_time); fprintf(fp,"\tcheck_latency=%.3f\n",temp_service->latency); fprintf(fp,"\tcheck_type=%d\n",temp_service->check_type); fprintf(fp,"\tcurrent_state=%d\n",temp_service->current_state); fprintf(fp,"\tlast_state=%d\n",temp_service->last_state); fprintf(fp,"\tlast_hard_state=%d\n",temp_service->last_hard_state); fprintf(fp,"\tcurrent_attempt=%d\n",temp_service->current_attempt); fprintf(fp,"\tmax_attempts=%d\n",temp_service->max_attempts); fprintf(fp,"\tnormal_check_interval=%d\n",temp_service->check_interval); fprintf(fp,"\tretry_check_interval=%d\n",temp_service->retry_interval); fprintf(fp,"\tstate_type=%d\n",temp_service->state_type); fprintf(fp,"\tlast_state_change=%lu\n",temp_service->last_state_change); fprintf(fp,"\tlast_hard_state_change=%lu\n",temp_service->last_hard_state_change); fprintf(fp,"\tlast_time_ok=%lu\n",temp_service->last_time_ok); fprintf(fp,"\tlast_time_warning=%lu\n",temp_service->last_time_warning); fprintf(fp,"\tlast_time_unknown=%lu\n",temp_service->last_time_unknown); fprintf(fp,"\tlast_time_critical=%lu\n",temp_service->last_time_critical); fprintf(fp,"\tplugin_output=%s\n",(temp_service->plugin_output==NULL)?"":temp_service->plugin_output); fprintf(fp,"\tperformance_data=%s\n",(temp_service->perf_data==NULL)?"":temp_service->perf_data); fprintf(fp,"\tlast_check=%lu\n",temp_service->last_check); fprintf(fp,"\tnext_check=%lu\n",temp_service->next_check); fprintf(fp,"\tnotified_on_unknown=%d\n",temp_service->notified_on_unknown); fprintf(fp,"\tnotified_on_warning=%d\n",temp_service->notified_on_warning); fprintf(fp,"\tnotified_on_critical=%d\n",temp_service->notified_on_critical); fprintf(fp,"\tcurrent_notification_number=%d\n",temp_service->current_notification_number); fprintf(fp,"\tlast_notification=%lu\n",temp_service->last_notification); fprintf(fp,"\tnotifications_enabled=%d\n",temp_service->notifications_enabled); fprintf(fp,"\tactive_checks_enabled=%d\n",temp_service->checks_enabled); fprintf(fp,"\tpassive_checks_enabled=%d\n",temp_service->accept_passive_service_checks); fprintf(fp,"\tevent_handler_enabled=%d\n",temp_service->event_handler_enabled); fprintf(fp,"\tproblem_has_been_acknowledged=%d\n",temp_service->problem_has_been_acknowledged); fprintf(fp,"\tacknowledgement_type=%d\n",temp_service->acknowledgement_type); fprintf(fp,"\tflap_detection_enabled=%d\n",temp_service->flap_detection_enabled); fprintf(fp,"\tfailure_prediction_enabled=%d\n",temp_service->failure_prediction_enabled); fprintf(fp,"\tprocess_performance_data=%d\n",temp_service->process_performance_data); fprintf(fp,"\tobsess_over_service=%d\n",temp_service->obsess_over_service); fprintf(fp,"\tis_flapping=%d\n",temp_service->is_flapping); fprintf(fp,"\tpercent_state_change=%.2f\n",temp_service->percent_state_change); fprintf(fp,"\tstate_history="); for(x=0;x0)?",":"",temp_service->state_history[(x+temp_service->state_history_index)%MAX_STATE_HISTORY_ENTRIES]); fprintf(fp,"\n"); fprintf(fp,"\t}\n\n"); } fclose(fp); /* move the temp file to the retention file (overwrite the old retention file) */ if(my_rename(temp_file,xrddefault_retention_file)) return ERROR; #ifdef DEBUG0 printf("xrddefault_save_state_information() end\n"); #endif return result; } /******************************************************************/ /***************** DEFAULT STATE INPUT FUNCTION *******************/ /******************************************************************/ int xrddefault_read_state_information(char *main_config_file){ char temp_buffer[MAX_INPUT_BUFFER]; char temp_buffer2[MAX_INPUT_BUFFER]; char *input=NULL; char *temp_ptr; mmapfile *thefile; char *host_name=NULL; char *service_description=NULL; int data_type=XRDDEFAULT_NO_DATA; int x; host *temp_host=NULL; service *temp_service=NULL; command *temp_command=NULL; char *var; char *val; char *ch; time_t creation_time; time_t current_time; int scheduling_info_is_ok=FALSE; #ifdef DEBUG0 printf("xrddefault_read_state_information() start\n"); #endif /* grab config info */ if(xrddefault_grab_config_info(main_config_file)==ERROR){ snprintf(temp_buffer,sizeof(temp_buffer)-1,"Error: Failed to grab configuration information for retention data!\n"); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_RUNTIME_ERROR,TRUE); return ERROR; } /* open the retention file for reading */ if((thefile=mmap_fopen(xrddefault_retention_file))==NULL) return ERROR; /* read all lines in the retention file */ while(1){ /* free memory */ free(input); /* read the next line */ if((input=mmap_fgets(thefile))==NULL) break; strip(input); /* skip blank lines and comments */ if(input[0]=='#' || input[0]=='\x0') continue; else if(!strcmp(input,"info {")) data_type=XRDDEFAULT_INFO_DATA; else if(!strcmp(input,"program {")) data_type=XRDDEFAULT_PROGRAM_DATA; else if(!strcmp(input,"host {")) data_type=XRDDEFAULT_HOST_DATA; else if(!strcmp(input,"service {")) data_type=XRDDEFAULT_SERVICE_DATA; else if(!strcmp(input,"}")){ switch(data_type){ case XRDDEFAULT_INFO_DATA: break; case XRDDEFAULT_PROGRAM_DATA: /* adjust modified attributes if necessary */ if(use_retained_program_state==FALSE){ modified_host_process_attributes=MODATTR_NONE; modified_service_process_attributes=MODATTR_NONE; } break; case XRDDEFAULT_HOST_DATA: if(temp_host!=NULL){ /* adjust modified attributes if necessary */ if(temp_host->retain_nonstatus_information==FALSE) temp_host->modified_attributes=MODATTR_NONE; /* calculate next possible notification time */ if(temp_host->current_state!=HOST_UP && temp_host->last_host_notification!=(time_t)0) temp_host->next_host_notification=get_next_host_notification_time(temp_host,temp_host->last_host_notification); /* update host status */ update_host_status(temp_host,FALSE); /* check for flapping */ check_for_host_flapping(temp_host,FALSE); /* handle new vars added */ if(temp_host->last_hard_state_change==(time_t)0) temp_host->last_hard_state_change=temp_host->last_state_change; } free(host_name); host_name=NULL; temp_host=NULL; break; case XRDDEFAULT_SERVICE_DATA: if(temp_service!=NULL){ /* adjust modified attributes if necessary */ if(temp_service->retain_nonstatus_information==FALSE) temp_service->modified_attributes=MODATTR_NONE; /* calculate next possible notification time */ if(temp_service->current_state!=STATE_OK && temp_service->last_notification!=(time_t)0) temp_service->next_notification=get_next_service_notification_time(temp_service,temp_service->last_notification); /* fix old vars */ if(temp_service->has_been_checked==FALSE && temp_service->state_type==SOFT_STATE) temp_service->state_type=HARD_STATE; /* update service status */ update_service_status(temp_service,FALSE); /* check for flapping */ check_for_service_flapping(temp_service,FALSE); /* handle new vars added */ if(temp_service->last_hard_state_change==(time_t)0) temp_service->last_hard_state_change=temp_service->last_state_change; } free(host_name); host_name=NULL; free(service_description); service_description=NULL; temp_service=NULL; break; default: break; } data_type=XRDDEFAULT_NO_DATA; } else if(data_type!=XRDDEFAULT_NO_DATA){ var=strtok(input,"="); val=strtok(NULL,"\n"); if(val==NULL) continue; switch(data_type){ case XRDDEFAULT_INFO_DATA: if(!strcmp(var,"created")){ creation_time=strtoul(val,NULL,10); time(¤t_time); if(current_time-creation_time0)?TRUE:FALSE; } else if(!strcmp(var,"active_service_checks_enabled")){ if(modified_service_process_attributes & MODATTR_ACTIVE_CHECKS_ENABLED) execute_service_checks=(atoi(val)>0)?TRUE:FALSE; } else if(!strcmp(var,"passive_service_checks_enabled")){ if(modified_service_process_attributes & MODATTR_PASSIVE_CHECKS_ENABLED) accept_passive_service_checks=(atoi(val)>0)?TRUE:FALSE; } else if(!strcmp(var,"active_host_checks_enabled")){ if(modified_host_process_attributes & MODATTR_ACTIVE_CHECKS_ENABLED) execute_host_checks=(atoi(val)>0)?TRUE:FALSE; } else if(!strcmp(var,"passive_host_checks_enabled")){ if(modified_host_process_attributes & MODATTR_PASSIVE_CHECKS_ENABLED) accept_passive_host_checks=(atoi(val)>0)?TRUE:FALSE; } else if(!strcmp(var,"enable_event_handlers")){ if(modified_host_process_attributes & MODATTR_EVENT_HANDLER_ENABLED) enable_event_handlers=(atoi(val)>0)?TRUE:FALSE; } else if(!strcmp(var,"obsess_over_services")){ if(modified_service_process_attributes & MODATTR_OBSESSIVE_HANDLER_ENABLED) obsess_over_services=(atoi(val)>0)?TRUE:FALSE; } else if(!strcmp(var,"obsess_over_hosts")){ if(modified_host_process_attributes & MODATTR_OBSESSIVE_HANDLER_ENABLED) obsess_over_hosts=(atoi(val)>0)?TRUE:FALSE; } else if(!strcmp(var,"check_service_freshness")){ if(modified_service_process_attributes & MODATTR_FRESHNESS_CHECKS_ENABLED) check_service_freshness=(atoi(val)>0)?TRUE:FALSE; } else if(!strcmp(var,"check_host_freshness")){ if(modified_host_process_attributes & MODATTR_FRESHNESS_CHECKS_ENABLED) check_host_freshness=(atoi(val)>0)?TRUE:FALSE; } else if(!strcmp(var,"enable_flap_detection")){ if(modified_host_process_attributes & MODATTR_FLAP_DETECTION_ENABLED) enable_flap_detection=(atoi(val)>0)?TRUE:FALSE; } else if(!strcmp(var,"enable_failure_prediction")){ if(modified_host_process_attributes & MODATTR_FAILURE_PREDICTION_ENABLED) enable_failure_prediction=(atoi(val)>0)?TRUE:FALSE; } else if(!strcmp(var,"process_performance_data")){ if(modified_host_process_attributes & MODATTR_PERFORMANCE_DATA_ENABLED) process_performance_data=(atoi(val)>0)?TRUE:FALSE; } else if(!strcmp(var,"global_host_event_handler")){ if(modified_host_process_attributes & MODATTR_EVENT_HANDLER_COMMAND){ /* make sure the check command still exists... */ strncpy(temp_buffer2,val,sizeof(temp_buffer2)); temp_buffer2[sizeof(temp_buffer2)-1]='\x0'; temp_ptr=my_strtok(temp_buffer2,"!"); temp_command=find_command(temp_ptr); temp_ptr=strdup(val); if(temp_command!=NULL && temp_ptr!=NULL){ free(global_host_event_handler); global_host_event_handler=temp_ptr; } } } else if(!strcmp(var,"global_service_event_handler")){ if(modified_service_process_attributes & MODATTR_EVENT_HANDLER_COMMAND){ /* make sure the check command still exists... */ strncpy(temp_buffer2,val,sizeof(temp_buffer2)); temp_buffer2[sizeof(temp_buffer2)-1]='\x0'; temp_ptr=my_strtok(temp_buffer2,"!"); temp_command=find_command(temp_ptr); temp_ptr=strdup(val); if(temp_command!=NULL && temp_ptr!=NULL){ free(global_service_event_handler); global_service_event_handler=temp_ptr; } } } } break; case XRDDEFAULT_HOST_DATA: if(!strcmp(var,"host_name")){ host_name=strdup(val); temp_host=find_host(host_name); } else if(temp_host!=NULL){ if(!strcmp(var,"modified_attributes")) temp_host->modified_attributes=strtoul(val,NULL,10); if(temp_host->retain_status_information==TRUE){ if(!strcmp(var,"has_been_checked")) temp_host->has_been_checked=(atoi(val)>0)?TRUE:FALSE; else if(!strcmp(var,"check_execution_time")) temp_host->execution_time=strtod(val,NULL); else if(!strcmp(var,"check_latency")) temp_host->latency=strtod(val,NULL); else if(!strcmp(var,"check_type")) temp_host->check_type=atoi(val); else if(!strcmp(var,"current_state")) temp_host->current_state=atoi(val); else if(!strcmp(var,"last_state")) temp_host->last_state=atoi(val); else if(!strcmp(var,"last_hard_state")) temp_host->last_hard_state=atoi(val); else if(!strcmp(var,"plugin_output")){ strncpy(temp_host->plugin_output,val,MAX_PLUGINOUTPUT_LENGTH-1); temp_host->plugin_output[MAX_PLUGINOUTPUT_LENGTH-1]='\x0'; } else if(!strcmp(var,"performance_data")){ strncpy(temp_host->perf_data,val,MAX_PLUGINOUTPUT_LENGTH-1); temp_host->perf_data[MAX_PLUGINOUTPUT_LENGTH-1]='\x0'; } else if(!strcmp(var,"last_check")) temp_host->last_check=strtoul(val,NULL,10); else if(!strcmp(var,"next_check")){ if(use_retained_scheduling_info==TRUE && scheduling_info_is_ok==TRUE) temp_host->next_check=strtoul(val,NULL,10); } else if(!strcmp(var,"current_attempt")) temp_host->current_attempt=(atoi(val)>0)?TRUE:FALSE; else if(!strcmp(var,"state_type")) temp_host->state_type=atoi(val); else if(!strcmp(var,"last_state_change")) temp_host->last_state_change=strtoul(val,NULL,10); else if(!strcmp(var,"last_hard_state_change")) temp_host->last_hard_state_change=strtoul(val,NULL,10); else if(!strcmp(var,"last_time_up")) temp_host->last_time_up=strtoul(val,NULL,10); else if(!strcmp(var,"last_time_down")) temp_host->last_time_down=strtoul(val,NULL,10); else if(!strcmp(var,"last_time_unreachable")) temp_host->last_time_unreachable=strtoul(val,NULL,10); else if(!strcmp(var,"notified_on_down")) temp_host->notified_on_down=(atoi(val)>0)?TRUE:FALSE; else if(!strcmp(var,"notified_on_unreachable")) temp_host->notified_on_unreachable=(atoi(val)>0)?TRUE:FALSE; else if(!strcmp(var,"last_notification")) temp_host->last_host_notification=strtoul(val,NULL,10); else if(!strcmp(var,"current_notification_number")) temp_host->current_notification_number=atoi(val); else if(!strcmp(var,"state_history")){ temp_ptr=val; for(x=0;xstate_history[x]=atoi(ch); else break; } temp_host->state_history_index=0; } } if(temp_host->retain_nonstatus_information==TRUE){ if(!strcmp(var,"problem_has_been_acknowledged")) temp_host->problem_has_been_acknowledged=(atoi(val)>0)?TRUE:FALSE; else if(!strcmp(var,"acknowledgement_type")) temp_host->acknowledgement_type=atoi(val); else if(!strcmp(var,"notifications_enabled")){ if(temp_host->modified_attributes & MODATTR_NOTIFICATIONS_ENABLED) temp_host->notifications_enabled=(atoi(val)>0)?TRUE:FALSE; } else if(!strcmp(var,"active_checks_enabled")){ if(temp_host->modified_attributes & MODATTR_ACTIVE_CHECKS_ENABLED) temp_host->checks_enabled=(atoi(val)>0)?TRUE:FALSE; } else if(!strcmp(var,"passive_checks_enabled")){ if(temp_host->modified_attributes & MODATTR_PASSIVE_CHECKS_ENABLED) temp_host->accept_passive_host_checks=(atoi(val)>0)?TRUE:FALSE; } else if(!strcmp(var,"event_handler_enabled")){ if(temp_host->modified_attributes & MODATTR_EVENT_HANDLER_ENABLED) temp_host->event_handler_enabled=(atoi(val)>0)?TRUE:FALSE; } else if(!strcmp(var,"flap_detection_enabled")){ if(temp_host->modified_attributes & MODATTR_FLAP_DETECTION_ENABLED) temp_host->flap_detection_enabled=(atoi(val)>0)?TRUE:FALSE; } else if(!strcmp(var,"failure_prediction_enabled")){ if(temp_host->modified_attributes & MODATTR_FAILURE_PREDICTION_ENABLED) temp_host->failure_prediction_enabled=(atoi(val)>0)?TRUE:FALSE; } else if(!strcmp(var,"process_performance_data")){ if(temp_host->modified_attributes & MODATTR_PERFORMANCE_DATA_ENABLED) temp_host->process_performance_data=(atoi(val)>0)?TRUE:FALSE; } else if(!strcmp(var,"obsess_over_host")){ if(temp_host->modified_attributes & MODATTR_OBSESSIVE_HANDLER_ENABLED) temp_host->obsess_over_host=(atoi(val)>0)?TRUE:FALSE; } else if(!strcmp(var,"check_command")){ if(temp_host->modified_attributes & MODATTR_CHECK_COMMAND){ /* make sure the check command still exists... */ strncpy(temp_buffer2,val,sizeof(temp_buffer2)); temp_buffer2[sizeof(temp_buffer2)-1]='\x0'; temp_ptr=my_strtok(temp_buffer2,"!"); temp_command=find_command(temp_ptr); temp_ptr=strdup(val); if(temp_command!=NULL && temp_ptr!=NULL){ free(temp_host->host_check_command); temp_host->host_check_command=temp_ptr; } } } else if(!strcmp(var,"event_handler")){ if(temp_host->modified_attributes & MODATTR_EVENT_HANDLER_COMMAND){ /* make sure the check command still exists... */ strncpy(temp_buffer2,val,sizeof(temp_buffer2)); temp_buffer2[sizeof(temp_buffer2)-1]='\x0'; temp_ptr=my_strtok(temp_buffer2,"!"); temp_command=find_command(temp_ptr); temp_ptr=strdup(val); if(temp_command!=NULL && temp_ptr!=NULL){ free(temp_host->event_handler); temp_host->event_handler=temp_ptr; } } } else if(!strcmp(var,"normal_check_interval")){ if(temp_host->modified_attributes & MODATTR_NORMAL_CHECK_INTERVAL && atoi(val)>=0) temp_host->check_interval=atoi(val); } else if(!strcmp(var,"max_attempts")){ if(temp_host->modified_attributes & MODATTR_MAX_CHECK_ATTEMPTS && atoi(val)>=1){ temp_host->max_attempts=atoi(val); /* adjust current attempt number if in a hard state */ if(temp_host->state_type==HARD_STATE && temp_host->current_state!=HOST_UP && temp_host->current_attempt>1) temp_host->current_attempt=temp_host->max_attempts; } } } } break; case XRDDEFAULT_SERVICE_DATA: if(!strcmp(var,"host_name")){ host_name=strdup(val); temp_service=find_service(host_name,service_description); } else if(!strcmp(var,"service_description")){ service_description=strdup(val); temp_service=find_service(host_name,service_description); } else if(temp_service!=NULL){ if(!strcmp(var,"modified_attributes")) temp_service->modified_attributes=strtoul(val,NULL,10); if(temp_service->retain_status_information==TRUE){ if(!strcmp(var,"has_been_checked")) temp_service->has_been_checked=(atoi(val)>0)?TRUE:FALSE; else if(!strcmp(var,"check_execution_time")) temp_service->execution_time=strtod(val,NULL); else if(!strcmp(var,"check_latency")) temp_service->latency=strtod(val,NULL); else if(!strcmp(var,"check_type")) temp_service->check_type=atoi(val); else if(!strcmp(var,"current_state")) temp_service->current_state=atoi(val); else if(!strcmp(var,"last_state")) temp_service->last_state=atoi(val); else if(!strcmp(var,"last_hard_state")) temp_service->last_hard_state=atoi(val); else if(!strcmp(var,"current_attempt")) temp_service->current_attempt=atoi(val); else if(!strcmp(var,"state_type")) temp_service->state_type=atoi(val); else if(!strcmp(var,"last_state_change")) temp_service->last_state_change=strtoul(val,NULL,10); else if(!strcmp(var,"last_hard_state_change")) temp_service->last_hard_state_change=strtoul(val,NULL,10); else if(!strcmp(var,"last_time_ok")) temp_service->last_time_ok=strtoul(val,NULL,10); else if(!strcmp(var,"last_time_warning")) temp_service->last_time_warning=strtoul(val,NULL,10); else if(!strcmp(var,"last_time_unknown")) temp_service->last_time_unknown=strtoul(val,NULL,10); else if(!strcmp(var,"last_time_critical")) temp_service->last_time_critical=strtoul(val,NULL,10); else if(!strcmp(var,"plugin_output")){ strncpy(temp_service->plugin_output,val,MAX_PLUGINOUTPUT_LENGTH-1); temp_service->plugin_output[MAX_PLUGINOUTPUT_LENGTH-1]='\x0'; } else if(!strcmp(var,"performance_data")){ strncpy(temp_service->perf_data,val,MAX_PLUGINOUTPUT_LENGTH-1); temp_service->perf_data[MAX_PLUGINOUTPUT_LENGTH-1]='\x0'; } else if(!strcmp(var,"last_check")) temp_service->last_check=strtoul(val,NULL,10); else if(!strcmp(var,"next_check")){ if(use_retained_scheduling_info==TRUE && scheduling_info_is_ok==TRUE) temp_service->next_check=strtoul(val,NULL,10); } else if(!strcmp(var,"notified_on_unknown")) temp_service->notified_on_unknown=(atoi(val)>0)?TRUE:FALSE; else if(!strcmp(var,"notified_on_warning")) temp_service->notified_on_warning=(atoi(val)>0)?TRUE:FALSE; else if(!strcmp(var,"notified_on_critical")) temp_service->notified_on_critical=(atoi(val)>0)?TRUE:FALSE; else if(!strcmp(var,"current_notification_number")) temp_service->current_notification_number=atoi(val); else if(!strcmp(var,"last_notification")) temp_service->last_notification=strtoul(val,NULL,10); else if(!strcmp(var,"state_history")){ temp_ptr=val; for(x=0;xstate_history[x]=atoi(ch); else break; } temp_service->state_history_index=0; } } if(temp_service->retain_nonstatus_information==TRUE){ if(!strcmp(var,"problem_has_been_acknowledged")) temp_service->problem_has_been_acknowledged=(atoi(val)>0)?TRUE:FALSE; else if(!strcmp(var,"acknowledgement_type")) temp_service->acknowledgement_type=atoi(val); else if(!strcmp(var,"notifications_enabled")){ if(temp_service->modified_attributes & MODATTR_NOTIFICATIONS_ENABLED) temp_service->notifications_enabled=(atoi(val)>0)?TRUE:FALSE; } else if(!strcmp(var,"active_checks_enabled")){ if(temp_service->modified_attributes & MODATTR_ACTIVE_CHECKS_ENABLED) temp_service->checks_enabled=(atoi(val)>0)?TRUE:FALSE; } else if(!strcmp(var,"passive_checks_enabled")){ if(temp_service->modified_attributes & MODATTR_PASSIVE_CHECKS_ENABLED) temp_service->accept_passive_service_checks=(atoi(val)>0)?TRUE:FALSE; } else if(!strcmp(var,"event_handler_enabled")){ if(temp_service->modified_attributes & MODATTR_EVENT_HANDLER_ENABLED) temp_service->event_handler_enabled=(atoi(val)>0)?TRUE:FALSE; } else if(!strcmp(var,"flap_detection_enabled")){ if(temp_service->modified_attributes & MODATTR_FLAP_DETECTION_ENABLED) temp_service->flap_detection_enabled=(atoi(val)>0)?TRUE:FALSE; } else if(!strcmp(var,"failure_prediction_enabled")){ if(temp_service->modified_attributes & MODATTR_FAILURE_PREDICTION_ENABLED) temp_service->failure_prediction_enabled=(atoi(val)>0)?TRUE:FALSE; } else if(!strcmp(var,"process_performance_data")){ if(temp_service->modified_attributes & MODATTR_PERFORMANCE_DATA_ENABLED) temp_service->process_performance_data=(atoi(val)>0)?TRUE:FALSE; } else if(!strcmp(var,"obsess_over_service")){ if(temp_service->modified_attributes & MODATTR_OBSESSIVE_HANDLER_ENABLED) temp_service->obsess_over_service=(atoi(val)>0)?TRUE:FALSE; } else if(!strcmp(var,"check_command")){ if(temp_service->modified_attributes & MODATTR_CHECK_COMMAND){ /* make sure the check command still exists... */ strncpy(temp_buffer2,val,sizeof(temp_buffer2)); temp_buffer2[sizeof(temp_buffer2)-1]='\x0'; temp_ptr=my_strtok(temp_buffer2,"!"); temp_command=find_command(temp_ptr); temp_ptr=strdup(val); if(temp_command!=NULL && temp_ptr!=NULL){ free(temp_service->service_check_command); temp_service->service_check_command=temp_ptr; } } } else if(!strcmp(var,"event_handler")){ if(temp_service->modified_attributes & MODATTR_EVENT_HANDLER_COMMAND){ /* make sure the check command still exists... */ strncpy(temp_buffer2,val,sizeof(temp_buffer2)); temp_buffer2[sizeof(temp_buffer2)-1]='\x0'; temp_ptr=my_strtok(temp_buffer2,"!"); temp_command=find_command(temp_ptr); temp_ptr=strdup(val); if(temp_command!=NULL && temp_ptr!=NULL){ free(temp_service->event_handler); temp_service->event_handler=temp_ptr; } } } else if(!strcmp(var,"normal_check_interval")){ if(temp_service->modified_attributes & MODATTR_NORMAL_CHECK_INTERVAL && atoi(val)>=0) temp_service->check_interval=atoi(val); } else if(!strcmp(var,"retry_check_interval")){ if(temp_service->modified_attributes & MODATTR_RETRY_CHECK_INTERVAL && atoi(val)>=0) temp_service->retry_interval=atoi(val); } else if(!strcmp(var,"max_attempts")){ if(temp_service->modified_attributes & MODATTR_MAX_CHECK_ATTEMPTS && atoi(val)>=1){ temp_service->max_attempts=atoi(val); /* adjust current attempt number if in a hard state */ if(temp_service->state_type==HARD_STATE && temp_service->current_state!=STATE_OK && temp_service->current_attempt>1) temp_service->current_attempt=temp_service->max_attempts; } } } } break; default: break; } } } /* free memory and close the file */ free(input); mmap_fclose(thefile); #ifdef DEBUG0 printf("xrddefault_read_state_information() end\n"); #endif return OK; } nagios-2.6/xdata/xrddefault.h0000664000076500007650000000262510336571237015627 0ustar nagiosnagios/***************************************************************************** * * XRDDEFAULT.H - Header file for default state retention routines * * Copyright (c) 1999-2003 Ethan Galstad (nagios@nagios.org) * Last Modified: 02-12-2003 * * 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. * *****************************************************************************/ #define XRDDEFAULT_NO_DATA 0 #define XRDDEFAULT_INFO_DATA 1 #define XRDDEFAULT_PROGRAM_DATA 2 #define XRDDEFAULT_HOST_DATA 3 #define XRDDEFAULT_SERVICE_DATA 4 int xrddefault_grab_config_info(char *); int xrddefault_save_state_information(char *); /* saves all host and service state information */ int xrddefault_read_state_information(char *); /* reads in initial host and service state information */ nagios-2.6/xdata/xsddefault.c0000664000076500007650000010114510433670166015617 0ustar nagiosnagios/***************************************************************************** * * XSDDEFAULT.C - Default external status data input routines for Nagios * * Copyright (c) 2000-2006 Ethan Galstad (nagios@nagios.org) * Last Modified: 05-20-2006 * * 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/locations.h" #include "../include/statusdata.h" #ifdef NSCORE #include "../include/nagios.h" #endif #ifdef NSCGI #include "../include/cgiutils.h" #endif /**** IMPLEMENTATION SPECIFIC HEADER FILES ****/ #include "xsddefault.h" #ifdef NSCGI time_t program_start; int daemon_mode; time_t last_command_check; time_t last_log_rotation; int enable_notifications; int execute_service_checks; int accept_passive_service_checks; int execute_host_checks; int accept_passive_host_checks; int enable_event_handlers; int obsess_over_services; int obsess_over_hosts; int check_service_freshness; int check_host_freshness; int enable_flap_detection; int enable_failure_prediction; int process_performance_data; int nagios_pid; #endif #ifdef NSCORE extern time_t program_start; extern int nagios_pid; extern int daemon_mode; extern time_t last_command_check; extern time_t last_log_rotation; extern int enable_notifications; extern int execute_service_checks; extern int accept_passive_service_checks; extern int execute_host_checks; extern int accept_passive_host_checks; extern int enable_event_handlers; extern int obsess_over_services; extern int obsess_over_hosts; extern int check_service_freshness; extern int check_host_freshness; extern int enable_flap_detection; extern int enable_failure_prediction; extern int process_performance_data; extern int aggregate_status_updates; extern char *macro_x[MACRO_X_COUNT]; extern host *host_list; extern service *service_list; extern unsigned long modified_host_process_attributes; extern unsigned long modified_service_process_attributes; extern char *global_host_event_handler; extern char *global_service_event_handler; #endif char xsddefault_status_log[MAX_FILENAME_LENGTH]=""; char xsddefault_temp_file[MAX_FILENAME_LENGTH]=""; #ifdef NSCORE char xsddefault_aggregate_temp_file[MAX_INPUT_BUFFER]; #endif /******************************************************************/ /***************** COMMON CONFIG INITIALIZATION ******************/ /******************************************************************/ /* grab configuration information */ int xsddefault_grab_config_info(char *config_file){ char *input=NULL; mmapfile *thefile; #ifdef NSCGI char *input2=NULL; mmapfile *thefile2; char *temp_buffer; #endif /*** CORE PASSES IN MAIN CONFIG FILE, CGIS PASS IN CGI CONFIG FILE! ***/ /* initialize the location of the status log */ strncpy(xsddefault_status_log,DEFAULT_STATUS_FILE,sizeof(xsddefault_status_log)-1); strncpy(xsddefault_temp_file,DEFAULT_TEMP_FILE,sizeof(xsddefault_temp_file)-1); xsddefault_status_log[sizeof(xsddefault_status_log)-1]='\x0'; xsddefault_temp_file[sizeof(xsddefault_temp_file)-1]='\x0'; /* open the config file for reading */ if((thefile=mmap_fopen(config_file))==NULL) return ERROR; /* read in all lines from the main config file */ while(1){ /* free memory */ free(input); /* read the next line */ if((input=mmap_fgets(thefile))==NULL) break; strip(input); /* skip blank lines and comments */ if(input[0]=='#' || input[0]=='\x0') continue; #ifdef NSCGI /* CGI needs to find and read contents of main config file, since it was passed the name of the CGI config file */ if(strstr(input,"main_config_file")==input){ temp_buffer=strtok(input,"="); temp_buffer=strtok(NULL,"\n"); if(temp_buffer==NULL) continue; if((thefile2=mmap_fopen(temp_buffer))==NULL) continue; /* read in all lines from the main config file */ while(1){ /* free memory */ free(input2); /* read the next line */ if((input2=mmap_fgets(thefile2))==NULL) break; strip(input2); /* skip blank lines and comments */ if(input2[0]=='#' || input2[0]=='\x0') continue; xsddefault_grab_config_directives(input2); } /* free memory and close the file */ free(input2); mmap_fclose(thefile2); } #endif #ifdef NSCORE /* core reads variables directly from the main config file */ xsddefault_grab_config_directives(input); #endif } /* free memory and close the file */ free(input); mmap_fclose(thefile); /* we didn't find the status log name */ if(!strcmp(xsddefault_status_log,"")) return ERROR; /* we didn't find the temp file */ if(!strcmp(xsddefault_temp_file,"")) return ERROR; #ifdef NSCORE /* save the status file macro */ if(macro_x[MACRO_STATUSDATAFILE]!=NULL) free(macro_x[MACRO_STATUSDATAFILE]); macro_x[MACRO_STATUSDATAFILE]=(char *)strdup(xsddefault_status_log); if(macro_x[MACRO_STATUSDATAFILE]!=NULL) strip(macro_x[MACRO_STATUSDATAFILE]); #endif return OK; } void xsddefault_grab_config_directives(char *input_buffer){ char *temp_buffer; /* status log definition */ if((strstr(input_buffer,"status_file")==input_buffer) || (strstr(input_buffer,"xsddefault_status_log")==input_buffer)){ temp_buffer=strtok(input_buffer,"="); temp_buffer=strtok(NULL,"\n"); if(temp_buffer==NULL) return; strncpy(xsddefault_status_log,temp_buffer,sizeof(xsddefault_status_log)-1); xsddefault_status_log[sizeof(xsddefault_status_log)-1]='\x0'; } /* temp file definition */ if((strstr(input_buffer,"temp_file")==input_buffer) || (strstr(input_buffer,"xsddefault_temp_file")==input_buffer)){ temp_buffer=strtok(input_buffer,"="); temp_buffer=strtok(NULL,"\n"); if(temp_buffer==NULL) return; strncpy(xsddefault_temp_file,temp_buffer,sizeof(xsddefault_temp_file)-1); xsddefault_temp_file[sizeof(xsddefault_temp_file)-1]='\x0'; } return; } #ifdef NSCORE /******************************************************************/ /********************* INIT/CLEANUP FUNCTIONS *********************/ /******************************************************************/ /* initialize status data */ int xsddefault_initialize_status_data(char *config_file){ int result; /* grab configuration data */ result=xsddefault_grab_config_info(config_file); if(result==ERROR) return ERROR; /* delete the old status log (it might not exist) */ unlink(xsddefault_status_log); return OK; } /* cleanup status data before terminating */ int xsddefault_cleanup_status_data(char *config_file, int delete_status_data){ /* delete the status log */ if(delete_status_data==TRUE){ if(unlink(xsddefault_status_log)) return ERROR; } return OK; } /******************************************************************/ /****************** STATUS DATA OUTPUT FUNCTIONS ******************/ /******************************************************************/ /* write all status data to file */ int xsddefault_save_status_data(void){ char temp_buffer[MAX_INPUT_BUFFER]; host *temp_host; service *temp_service; time_t current_time; int fd=0; FILE *fp=NULL; /* open a safe temp file for output */ snprintf(xsddefault_aggregate_temp_file,sizeof(xsddefault_aggregate_temp_file)-1,"%sXXXXXX",xsddefault_temp_file); xsddefault_aggregate_temp_file[sizeof(xsddefault_aggregate_temp_file)-1]='\x0'; if((fd=mkstemp(xsddefault_aggregate_temp_file))==-1){ /* log an error */ snprintf(temp_buffer,sizeof(temp_buffer),"Error: Unable to create temp file for writing status data!\n"); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_RUNTIME_ERROR,TRUE); return ERROR; } fp=fdopen(fd,"w"); if(fp==NULL){ close(fd); unlink(xsddefault_aggregate_temp_file); /* log an error */ snprintf(temp_buffer,sizeof(temp_buffer),"Error: Unable to open temp file '%s' for writing status data!\n",xsddefault_aggregate_temp_file); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_RUNTIME_ERROR,TRUE); return ERROR; } /* write version info to status file */ fprintf(fp,"########################################\n"); fprintf(fp,"# NAGIOS STATUS FILE\n"); fprintf(fp,"#\n"); fprintf(fp,"# THIS FILE IS AUTOMATICALLY GENERATED\n"); fprintf(fp,"# BY NAGIOS. DO NOT MODIFY THIS FILE!\n"); fprintf(fp,"########################################\n\n"); time(¤t_time); /* write file info */ fprintf(fp,"info {\n"); fprintf(fp,"\tcreated=%lu\n",current_time); fprintf(fp,"\tversion=%s\n",PROGRAM_VERSION); fprintf(fp,"\t}\n\n"); /* save program status data */ fprintf(fp,"program {\n"); fprintf(fp,"\tmodified_host_attributes=%lu\n",modified_host_process_attributes); fprintf(fp,"\tmodified_service_attributes=%lu\n",modified_service_process_attributes); fprintf(fp,"\tnagios_pid=%d\n",nagios_pid); fprintf(fp,"\tdaemon_mode=%d\n",daemon_mode); fprintf(fp,"\tprogram_start=%lu\n",program_start); fprintf(fp,"\tlast_command_check=%lu\n",last_command_check); fprintf(fp,"\tlast_log_rotation=%lu\n",last_log_rotation); fprintf(fp,"\tenable_notifications=%d\n",enable_notifications); fprintf(fp,"\tactive_service_checks_enabled=%d\n",execute_service_checks); fprintf(fp,"\tpassive_service_checks_enabled=%d\n",accept_passive_service_checks); fprintf(fp,"\tactive_host_checks_enabled=%d\n",execute_host_checks); fprintf(fp,"\tpassive_host_checks_enabled=%d\n",accept_passive_host_checks); fprintf(fp,"\tenable_event_handlers=%d\n",enable_event_handlers); fprintf(fp,"\tobsess_over_services=%d\n",obsess_over_services); fprintf(fp,"\tobsess_over_hosts=%d\n",obsess_over_hosts); fprintf(fp,"\tcheck_service_freshness=%d\n",check_service_freshness); fprintf(fp,"\tcheck_host_freshness=%d\n",check_host_freshness); fprintf(fp,"\tenable_flap_detection=%d\n",enable_flap_detection); fprintf(fp,"\tenable_failure_prediction=%d\n",enable_failure_prediction); fprintf(fp,"\tprocess_performance_data=%d\n",process_performance_data); fprintf(fp,"\tglobal_host_event_handler=%s\n",(global_host_event_handler==NULL)?"":global_host_event_handler); fprintf(fp,"\tglobal_service_event_handler=%s\n",(global_service_event_handler==NULL)?"":global_service_event_handler); fprintf(fp,"\t}\n\n"); /* save host status data */ for(temp_host=host_list;temp_host!=NULL;temp_host=temp_host->next){ fprintf(fp,"host {\n"); fprintf(fp,"\thost_name=%s\n",temp_host->name); fprintf(fp,"\tmodified_attributes=%lu\n",temp_host->modified_attributes); fprintf(fp,"\tcheck_command=%s\n",(temp_host->host_check_command==NULL)?"":temp_host->host_check_command); fprintf(fp,"\tevent_handler=%s\n",(temp_host->event_handler==NULL)?"":temp_host->event_handler); fprintf(fp,"\thas_been_checked=%d\n",temp_host->has_been_checked); fprintf(fp,"\tshould_be_scheduled=%d\n",temp_host->should_be_scheduled); fprintf(fp,"\tcheck_execution_time=%.3f\n",temp_host->execution_time); fprintf(fp,"\tcheck_latency=%.3f\n",temp_host->latency); fprintf(fp,"\tcheck_type=%d\n",temp_host->check_type); fprintf(fp,"\tcurrent_state=%d\n",temp_host->current_state); fprintf(fp,"\tlast_hard_state=%d\n",temp_host->last_hard_state); fprintf(fp,"\tplugin_output=%s\n",(temp_host->plugin_output==NULL)?"":temp_host->plugin_output); fprintf(fp,"\tperformance_data=%s\n",(temp_host->perf_data==NULL)?"":temp_host->perf_data); fprintf(fp,"\tlast_check=%lu\n",temp_host->last_check); fprintf(fp,"\tnext_check=%lu\n",temp_host->next_check); fprintf(fp,"\tcurrent_attempt=%d\n",temp_host->current_attempt); fprintf(fp,"\tmax_attempts=%d\n",temp_host->max_attempts); fprintf(fp,"\tstate_type=%d\n",temp_host->state_type); fprintf(fp,"\tlast_state_change=%lu\n",temp_host->last_state_change); fprintf(fp,"\tlast_hard_state_change=%lu\n",temp_host->last_hard_state_change); fprintf(fp,"\tlast_time_up=%lu\n",temp_host->last_time_up); fprintf(fp,"\tlast_time_down=%lu\n",temp_host->last_time_down); fprintf(fp,"\tlast_time_unreachable=%lu\n",temp_host->last_time_unreachable); fprintf(fp,"\tlast_notification=%lu\n",temp_host->last_host_notification); fprintf(fp,"\tnext_notification=%lu\n",temp_host->next_host_notification); fprintf(fp,"\tno_more_notifications=%d\n",temp_host->no_more_notifications); fprintf(fp,"\tcurrent_notification_number=%d\n",temp_host->current_notification_number); fprintf(fp,"\tnotifications_enabled=%d\n",temp_host->notifications_enabled); fprintf(fp,"\tproblem_has_been_acknowledged=%d\n",temp_host->problem_has_been_acknowledged); fprintf(fp,"\tacknowledgement_type=%d\n",temp_host->acknowledgement_type); fprintf(fp,"\tactive_checks_enabled=%d\n",temp_host->checks_enabled); fprintf(fp,"\tpassive_checks_enabled=%d\n",temp_host->accept_passive_host_checks); fprintf(fp,"\tevent_handler_enabled=%d\n",temp_host->event_handler_enabled); fprintf(fp,"\tflap_detection_enabled=%d\n",temp_host->flap_detection_enabled); fprintf(fp,"\tfailure_prediction_enabled=%d\n",temp_host->failure_prediction_enabled); fprintf(fp,"\tprocess_performance_data=%d\n",temp_host->process_performance_data); fprintf(fp,"\tobsess_over_host=%d\n",temp_host->obsess_over_host); fprintf(fp,"\tlast_update=%lu\n",current_time); fprintf(fp,"\tis_flapping=%d\n",temp_host->is_flapping); fprintf(fp,"\tpercent_state_change=%.2f\n",temp_host->percent_state_change); fprintf(fp,"\tscheduled_downtime_depth=%d\n",temp_host->scheduled_downtime_depth); /* fprintf(fp,"\tstate_history="); for(x=0;x0)?",":"",temp_host->state_history[(x+temp_host->state_history_index)%MAX_STATE_HISTORY_ENTRIES]); fprintf(fp,"\n"); */ fprintf(fp,"\t}\n\n"); } /* save service status data */ for(temp_service=service_list;temp_service!=NULL;temp_service=temp_service->next){ fprintf(fp,"service {\n"); fprintf(fp,"\thost_name=%s\n",temp_service->host_name); fprintf(fp,"\tservice_description=%s\n",temp_service->description); fprintf(fp,"\tmodified_attributes=%lu\n",temp_service->modified_attributes); fprintf(fp,"\tcheck_command=%s\n",(temp_service->service_check_command==NULL)?"":temp_service->service_check_command); fprintf(fp,"\tevent_handler=%s\n",(temp_service->event_handler==NULL)?"":temp_service->event_handler); fprintf(fp,"\thas_been_checked=%d\n",temp_service->has_been_checked); fprintf(fp,"\tshould_be_scheduled=%d\n",temp_service->should_be_scheduled); fprintf(fp,"\tcheck_execution_time=%.3f\n",temp_service->execution_time); fprintf(fp,"\tcheck_latency=%.3f\n",temp_service->latency); fprintf(fp,"\tcheck_type=%d\n",temp_service->check_type); fprintf(fp,"\tcurrent_state=%d\n",temp_service->current_state); fprintf(fp,"\tlast_hard_state=%d\n",temp_service->last_hard_state); fprintf(fp,"\tcurrent_attempt=%d\n",temp_service->current_attempt); fprintf(fp,"\tmax_attempts=%d\n",temp_service->max_attempts); fprintf(fp,"\tstate_type=%d\n",temp_service->state_type); fprintf(fp,"\tlast_state_change=%lu\n",temp_service->last_state_change); fprintf(fp,"\tlast_hard_state_change=%lu\n",temp_service->last_hard_state_change); fprintf(fp,"\tlast_time_ok=%lu\n",temp_service->last_time_ok); fprintf(fp,"\tlast_time_warning=%lu\n",temp_service->last_time_warning); fprintf(fp,"\tlast_time_unknown=%lu\n",temp_service->last_time_unknown); fprintf(fp,"\tlast_time_critical=%lu\n",temp_service->last_time_critical); fprintf(fp,"\tplugin_output=%s\n",(temp_service->plugin_output==NULL)?"":temp_service->plugin_output); fprintf(fp,"\tperformance_data=%s\n",(temp_service->perf_data==NULL)?"":temp_service->perf_data); fprintf(fp,"\tlast_check=%lu\n",temp_service->last_check); fprintf(fp,"\tnext_check=%lu\n",temp_service->next_check); fprintf(fp,"\tcurrent_notification_number=%d\n",temp_service->current_notification_number); fprintf(fp,"\tlast_notification=%lu\n",temp_service->last_notification); fprintf(fp,"\tnext_notification=%lu\n",temp_service->next_notification); fprintf(fp,"\tno_more_notifications=%d\n",temp_service->no_more_notifications); fprintf(fp,"\tnotifications_enabled=%d\n",temp_service->notifications_enabled); fprintf(fp,"\tactive_checks_enabled=%d\n",temp_service->checks_enabled); fprintf(fp,"\tpassive_checks_enabled=%d\n",temp_service->accept_passive_service_checks); fprintf(fp,"\tevent_handler_enabled=%d\n",temp_service->event_handler_enabled); fprintf(fp,"\tproblem_has_been_acknowledged=%d\n",temp_service->problem_has_been_acknowledged); fprintf(fp,"\tacknowledgement_type=%d\n",temp_service->acknowledgement_type); fprintf(fp,"\tflap_detection_enabled=%d\n",temp_service->flap_detection_enabled); fprintf(fp,"\tfailure_prediction_enabled=%d\n",temp_service->failure_prediction_enabled); fprintf(fp,"\tprocess_performance_data=%d\n",temp_service->process_performance_data); fprintf(fp,"\tobsess_over_service=%d\n",temp_service->obsess_over_service); fprintf(fp,"\tlast_update=%lu\n",current_time); fprintf(fp,"\tis_flapping=%d\n",temp_service->is_flapping); fprintf(fp,"\tpercent_state_change=%.2f\n",temp_service->percent_state_change); fprintf(fp,"\tscheduled_downtime_depth=%d\n",temp_service->scheduled_downtime_depth); /* fprintf(fp,"\tstate_history="); for(x=0;x0)?",":"",temp_service->state_history[(x+temp_service->state_history_index)%MAX_STATE_HISTORY_ENTRIES]); fprintf(fp,"\n"); */ fprintf(fp,"\t}\n\n"); } /* reset file permissions */ fchmod(fd,S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH); /* close the temp file */ fclose(fp); /* move the temp file to the status log (overwrite the old status log) */ if(my_rename(xsddefault_aggregate_temp_file,xsddefault_status_log)){ /* log an error */ snprintf(temp_buffer,sizeof(temp_buffer),"Error: Unable to update status data file '%s'!\n",xsddefault_status_log); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_logs_and_console(temp_buffer,NSLOG_RUNTIME_ERROR,TRUE); return ERROR; } return OK; } #endif #ifdef NSCGI /******************************************************************/ /****************** DEFAULT DATA INPUT FUNCTIONS ******************/ /******************************************************************/ /* read all program, host, and service status information */ int xsddefault_read_status_data(char *config_file,int options){ #ifdef BAD_MMAP char *input=NULL; mmapfile *thefile; #else char input[2048]=""; FILE *fp=NULL; #endif int data_type=XSDDEFAULT_NO_DATA; hoststatus *temp_hoststatus=NULL; servicestatus *temp_servicestatus=NULL; char *var; char *val; int result; /* grab configuration data */ result=xsddefault_grab_config_info(config_file); if(result==ERROR) return ERROR; /* open the status file for reading */ #ifdef BAD_MMAP if((thefile=mmap_fopen(xsddefault_status_log))==NULL) return ERROR; #else if((fp=fopen(xsddefault_status_log,"r"))==NULL) return ERROR; #endif /* read all lines in the status file */ while(1){ #ifdef BAD_MMAP /* free memory */ free(input); /* read the next line */ if((input=mmap_fgets(thefile))==NULL) break; #else strcpy(input,""); if(fgets(input,sizeof(input),fp)==NULL) break; #endif strip(input); /* skip blank lines and comments */ if(input[0]=='#' || input[0]=='\x0') continue; else if(!strcmp(input,"info {")) data_type=XSDDEFAULT_INFO_DATA; else if(!strcmp(input,"program {")) data_type=XSDDEFAULT_PROGRAM_DATA; else if(!strcmp(input,"host {")){ data_type=XSDDEFAULT_HOST_DATA; temp_hoststatus=(hoststatus *)malloc(sizeof(hoststatus)); if(temp_hoststatus){ temp_hoststatus->host_name=NULL; temp_hoststatus->plugin_output=NULL; temp_hoststatus->perf_data=NULL; } } else if(!strcmp(input,"service {")){ data_type=XSDDEFAULT_SERVICE_DATA; temp_servicestatus=(servicestatus *)malloc(sizeof(servicestatus)); if(temp_servicestatus){ temp_servicestatus->host_name=NULL; temp_servicestatus->description=NULL; temp_servicestatus->plugin_output=NULL; temp_servicestatus->perf_data=NULL; } } else if(!strcmp(input,"}")){ switch(data_type){ case XSDDEFAULT_INFO_DATA: break; case XSDDEFAULT_PROGRAM_DATA: break; case XSDDEFAULT_HOST_DATA: add_host_status(temp_hoststatus); temp_hoststatus=NULL; break; case XSDDEFAULT_SERVICE_DATA: add_service_status(temp_servicestatus); temp_servicestatus=NULL; break; default: break; } data_type=XSDDEFAULT_NO_DATA; } else if(data_type!=XSDDEFAULT_NO_DATA){ var=strtok(input,"="); val=strtok(NULL,"\n"); if(val==NULL) continue; switch(data_type){ case XSDDEFAULT_INFO_DATA: break; case XSDDEFAULT_PROGRAM_DATA: /* NOTE: some vars are not read, as they are not used by the CGIs (modified attributes, event handler commands, etc.) */ if(!strcmp(var,"nagios_pid")) nagios_pid=atoi(val); else if(!strcmp(var,"daemon_mode")) daemon_mode=(atoi(val)>0)?TRUE:FALSE; else if(!strcmp(var,"program_start")) program_start=strtoul(val,NULL,10); else if(!strcmp(var,"last_command_check")) last_command_check=strtoul(val,NULL,10); else if(!strcmp(var,"last_log_rotation")) last_log_rotation=strtoul(val,NULL,10); else if(!strcmp(var,"enable_notifications")) enable_notifications=(atoi(val)>0)?TRUE:FALSE; else if(!strcmp(var,"active_service_checks_enabled")) execute_service_checks=(atoi(val)>0)?TRUE:FALSE; else if(!strcmp(var,"passive_service_checks_enabled")) accept_passive_service_checks=(atoi(val)>0)?TRUE:FALSE; else if(!strcmp(var,"active_host_checks_enabled")) execute_host_checks=(atoi(val)>0)?TRUE:FALSE; else if(!strcmp(var,"passive_host_checks_enabled")) accept_passive_host_checks=(atoi(val)>0)?TRUE:FALSE; else if(!strcmp(var,"enable_event_handlers")) enable_event_handlers=(atoi(val)>0)?TRUE:FALSE; else if(!strcmp(var,"obsess_over_services")) obsess_over_services=(atoi(val)>0)?TRUE:FALSE; else if(!strcmp(var,"obsess_over_hosts")) obsess_over_hosts=(atoi(val)>0)?TRUE:FALSE; else if(!strcmp(var,"check_service_freshness")) check_service_freshness=(atoi(val)>0)?TRUE:FALSE; else if(!strcmp(var,"check_host_freshness")) check_host_freshness=(atoi(val)>0)?TRUE:FALSE; else if(!strcmp(var,"enable_flap_detection")) enable_flap_detection=(atoi(val)>0)?TRUE:FALSE; else if(!strcmp(var,"enable_failure_prediction")) enable_failure_prediction=(atoi(val)>0)?TRUE:FALSE; else if(!strcmp(var,"process_performance_data")) process_performance_data=(atoi(val)>0)?TRUE:FALSE; break; case XSDDEFAULT_HOST_DATA: /* NOTE: some vars are not read, as they are not used by the CGIs (modified attributes, event handler commands, etc.) */ if(temp_hoststatus!=NULL){ if(!strcmp(var,"host_name")) temp_hoststatus->host_name=strdup(val); else if(!strcmp(var,"has_been_checked")) temp_hoststatus->has_been_checked=(atoi(val)>0)?TRUE:FALSE; else if(!strcmp(var,"should_be_scheduled")) temp_hoststatus->should_be_scheduled=(atoi(val)>0)?TRUE:FALSE; else if(!strcmp(var,"check_execution_time")) temp_hoststatus->execution_time=strtod(val,NULL); else if(!strcmp(var,"check_latency")) temp_hoststatus->latency=strtod(val,NULL); else if(!strcmp(var,"check_type")) temp_hoststatus->check_type=atoi(val); else if(!strcmp(var,"current_state")) temp_hoststatus->status=atoi(val); else if(!strcmp(var,"last_hard_state")) temp_hoststatus->last_hard_state=atoi(val); else if(!strcmp(var,"plugin_output")) temp_hoststatus->plugin_output=strdup(val); else if(!strcmp(var,"performance_data")) temp_hoststatus->perf_data=strdup(val); else if(!strcmp(var,"current_attempt")) temp_hoststatus->current_attempt=atoi(val); else if(!strcmp(var,"max_attempts")) temp_hoststatus->max_attempts=atoi(val); else if(!strcmp(var,"last_check")) temp_hoststatus->last_check=strtoul(val,NULL,10); else if(!strcmp(var,"next_check")) temp_hoststatus->next_check=strtoul(val,NULL,10); else if(!strcmp(var,"current_attempt")) temp_hoststatus->current_attempt=(atoi(val)>0)?TRUE:FALSE; else if(!strcmp(var,"state_type")) temp_hoststatus->state_type=atoi(val); else if(!strcmp(var,"last_state_change")) temp_hoststatus->last_state_change=strtoul(val,NULL,10); else if(!strcmp(var,"last_hard_state_change")) temp_hoststatus->last_hard_state_change=strtoul(val,NULL,10); else if(!strcmp(var,"last_time_up")) temp_hoststatus->last_time_up=strtoul(val,NULL,10); else if(!strcmp(var,"last_time_down")) temp_hoststatus->last_time_down=strtoul(val,NULL,10); else if(!strcmp(var,"last_time_unreachable")) temp_hoststatus->last_time_unreachable=strtoul(val,NULL,10); else if(!strcmp(var,"last_notification")) temp_hoststatus->last_notification=strtoul(val,NULL,10); else if(!strcmp(var,"next_notification")) temp_hoststatus->next_notification=strtoul(val,NULL,10); else if(!strcmp(var,"no_more_notifications")) temp_hoststatus->no_more_notifications=(atoi(val)>0)?TRUE:FALSE; else if(!strcmp(var,"current_notification_number")) temp_hoststatus->current_notification_number=atoi(val); else if(!strcmp(var,"notifications_enabled")) temp_hoststatus->notifications_enabled=(atoi(val)>0)?TRUE:FALSE; else if(!strcmp(var,"problem_has_been_acknowledged")) temp_hoststatus->problem_has_been_acknowledged=(atoi(val)>0)?TRUE:FALSE; else if(!strcmp(var,"acknowledgement_type")) temp_hoststatus->acknowledgement_type=atoi(val); else if(!strcmp(var,"active_checks_enabled")) temp_hoststatus->checks_enabled=(atoi(val)>0)?TRUE:FALSE; else if(!strcmp(var,"passive_checks_enabled")) temp_hoststatus->accept_passive_host_checks=(atoi(val)>0)?TRUE:FALSE; else if(!strcmp(var,"event_handler_enabled")) temp_hoststatus->event_handler_enabled=(atoi(val)>0)?TRUE:FALSE; else if(!strcmp(var,"flap_detection_enabled")) temp_hoststatus->flap_detection_enabled=(atoi(val)>0)?TRUE:FALSE; else if(!strcmp(var,"failure_prediction_enabled")) temp_hoststatus->failure_prediction_enabled=(atoi(val)>0)?TRUE:FALSE; else if(!strcmp(var,"process_performance_data")) temp_hoststatus->process_performance_data=(atoi(val)>0)?TRUE:FALSE; else if(!strcmp(var,"obsess_over_host")) temp_hoststatus->obsess_over_host=(atoi(val)>0)?TRUE:FALSE; else if(!strcmp(var,"last_update")) temp_hoststatus->last_update=strtoul(val,NULL,10); else if(!strcmp(var,"is_flapping")) temp_hoststatus->is_flapping=(atoi(val)>0)?TRUE:FALSE; else if(!strcmp(var,"percent_state_change")) temp_hoststatus->percent_state_change=strtod(val,NULL); else if(!strcmp(var,"scheduled_downtime_depth")) temp_hoststatus->scheduled_downtime_depth=atoi(val); /* else if(!strcmp(var,"state_history")){ temp_ptr=val; for(x=0;xstate_history[x]=atoi(my_strsep(&temp_ptr,",")); temp_hoststatus->state_history_index=0; } */ } break; case XSDDEFAULT_SERVICE_DATA: /* NOTE: some vars are not read, as they are not used by the CGIs (modified attributes, event handler commands, etc.) */ if(temp_servicestatus!=NULL){ if(!strcmp(var,"host_name")) temp_servicestatus->host_name=strdup(val); else if(!strcmp(var,"service_description")) temp_servicestatus->description=strdup(val); else if(!strcmp(var,"has_been_checked")) temp_servicestatus->has_been_checked=(atoi(val)>0)?TRUE:FALSE; else if(!strcmp(var,"should_be_scheduled")) temp_servicestatus->should_be_scheduled=(atoi(val)>0)?TRUE:FALSE; else if(!strcmp(var,"check_execution_time")) temp_servicestatus->execution_time=strtod(val,NULL); else if(!strcmp(var,"check_latency")) temp_servicestatus->latency=strtod(val,NULL); else if(!strcmp(var,"check_type")) temp_servicestatus->check_type=atoi(val); else if(!strcmp(var,"current_state")) temp_servicestatus->status=atoi(val); else if(!strcmp(var,"last_hard_state")) temp_servicestatus->last_hard_state=atoi(val); else if(!strcmp(var,"current_attempt")) temp_servicestatus->current_attempt=atoi(val); else if(!strcmp(var,"max_attempts")) temp_servicestatus->max_attempts=atoi(val); else if(!strcmp(var,"state_type")) temp_servicestatus->state_type=atoi(val); else if(!strcmp(var,"last_state_change")) temp_servicestatus->last_state_change=strtoul(val,NULL,10); else if(!strcmp(var,"last_hard_state_change")) temp_servicestatus->last_hard_state_change=strtoul(val,NULL,10); else if(!strcmp(var,"last_time_ok")) temp_servicestatus->last_time_ok=strtoul(val,NULL,10); else if(!strcmp(var,"last_time_warning")) temp_servicestatus->last_time_warning=strtoul(val,NULL,10); else if(!strcmp(var,"last_time_unknown")) temp_servicestatus->last_time_unknown=strtoul(val,NULL,10); else if(!strcmp(var,"last_time_critical")) temp_servicestatus->last_time_critical=strtoul(val,NULL,10); else if(!strcmp(var,"plugin_output")) temp_servicestatus->plugin_output=strdup(val); else if(!strcmp(var,"performance_data")) temp_servicestatus->perf_data=strdup(val); else if(!strcmp(var,"last_check")) temp_servicestatus->last_check=strtoul(val,NULL,10); else if(!strcmp(var,"next_check")) temp_servicestatus->next_check=strtoul(val,NULL,10); else if(!strcmp(var,"current_notification_number")) temp_servicestatus->current_notification_number=atoi(val); else if(!strcmp(var,"last_notification")) temp_servicestatus->last_notification=strtoul(val,NULL,10); else if(!strcmp(var,"next_notification")) temp_servicestatus->next_notification=strtoul(val,NULL,10); else if(!strcmp(var,"no_more_notifications")) temp_servicestatus->no_more_notifications=(atoi(val)>0)?TRUE:FALSE; else if(!strcmp(var,"notifications_enabled")) temp_servicestatus->notifications_enabled=(atoi(val)>0)?TRUE:FALSE; else if(!strcmp(var,"active_checks_enabled")) temp_servicestatus->checks_enabled=(atoi(val)>0)?TRUE:FALSE; else if(!strcmp(var,"passive_checks_enabled")) temp_servicestatus->accept_passive_service_checks=(atoi(val)>0)?TRUE:FALSE; else if(!strcmp(var,"event_handler_enabled")) temp_servicestatus->event_handler_enabled=(atoi(val)>0)?TRUE:FALSE; else if(!strcmp(var,"problem_has_been_acknowledged")) temp_servicestatus->problem_has_been_acknowledged=(atoi(val)>0)?TRUE:FALSE; else if(!strcmp(var,"acknowledgement_type")) temp_servicestatus->acknowledgement_type=atoi(val); else if(!strcmp(var,"flap_detection_enabled")) temp_servicestatus->flap_detection_enabled=(atoi(val)>0)?TRUE:FALSE; else if(!strcmp(var,"failure_prediction_enabled")) temp_servicestatus->failure_prediction_enabled=(atoi(val)>0)?TRUE:FALSE; else if(!strcmp(var,"process_performance_data")) temp_servicestatus->process_performance_data=(atoi(val)>0)?TRUE:FALSE; else if(!strcmp(var,"obsess_over_service")) temp_servicestatus->obsess_over_service=(atoi(val)>0)?TRUE:FALSE; else if(!strcmp(var,"last_update")) temp_servicestatus->last_update=strtoul(val,NULL,10); else if(!strcmp(var,"is_flapping")) temp_servicestatus->is_flapping=(atoi(val)>0)?TRUE:FALSE; else if(!strcmp(var,"percent_state_change")) temp_servicestatus->percent_state_change=strtod(val,NULL); else if(!strcmp(var,"scheduled_downtime_depth")) temp_servicestatus->scheduled_downtime_depth=atoi(val); /* else if(!strcmp(var,"state_history")){ temp_ptr=val; for(x=0;xstate_history[x]=atoi(my_strsep(&temp_ptr,",")); temp_servicestatus->state_history_index=0; } */ } break; default: break; } } } /* free memory and close the file */ #ifdef BAD_MMAP free(input); mmap_fclose(thefile); #else fclose(fp); #endif return OK; } #endif nagios-2.6/xdata/xsddefault.h0000664000076500007650000000270510336571237015627 0ustar nagiosnagios/***************************************************************************** * * XSDDEFAULT.H - Header file for default status data routines * * Copyright (c) 1999-2003 Ethan Galstad (nagios@nagios.org) * Last Modified: 02-15-2003 * * 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. * *****************************************************************************/ #ifdef NSCORE int xsddefault_initialize_status_data(char *); int xsddefault_cleanup_status_data(char *,int); int xsddefault_save_status_data(void); #endif #ifdef NSCGI #define XSDDEFAULT_NO_DATA 0 #define XSDDEFAULT_INFO_DATA 1 #define XSDDEFAULT_PROGRAM_DATA 2 #define XSDDEFAULT_HOST_DATA 3 #define XSDDEFAULT_SERVICE_DATA 4 int xsddefault_read_status_data(char *,int); #endif int xsddefault_grab_config_info(char *); void xsddefault_grab_config_directives(char *);