/* Copyright (c) 2007, David Josephsen * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of David Josephsen nor the * names of this packages contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY David Josephsen ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL David Josephsen BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef NSCORE #define NSCORE #endif /* 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" #include "../include/objects.h" /* specify event broker API version (required) */ NEB_API_VERSION(CURRENT_NEB_API_VERSION); /*globals*/ void *nagfs_module_handle = NULL; char *nagfs_home = "/usr/share/nagios/status"; char *nagfs_fs_home = "/usr/share/nagios/status/local"; char *nagfs_meta_home = "/usr/share/nagios/status/meta"; char *nagfs_mesh_home = "/usr/share/nagios/status/mesh"; /* Nagfs Functions */ void nagfs_reminder_message(char *); int nagfs_handle_data(int,void *); int nagfs_write_service_status(char *, char *, int, int); int nagfs_write_host_status(char *, int, int); int nagfs_check_for_softfiles(char *); /* this function gets called when the module is loaded by the event broker */ int nebmodule_init(int flags, char *args, nebmodule *handle){ /* save our handle */ nagfs_module_handle = handle; /* log module info to the Nagios log file */ write_to_all_logs("nagfs: Copyright (c) 2007 Dave Josephsen (dave@skeptech.org)",NSLOG_INFO_MESSAGE); /* register to be notified of certain events... */ neb_register_callback(NEBCALLBACK_SERVICE_STATUS_DATA,nagfs_module_handle,0,nagfs_handle_data); neb_register_callback(NEBCALLBACK_HOST_STATUS_DATA,nagfs_module_handle,0,nagfs_handle_data); return OK; } /* 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,nagfs_handle_data); /* log a message to the Nagios log file */ snprintf(temp_buffer,sizeof(temp_buffer)-1,"nagfs: Goodbye world!\n"); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_all_logs(temp_buffer,NSLOG_INFO_MESSAGE); return OK; } /* handle data from Nagios daemon */ int nagfs_handle_data(int event_type, void *data){ nebstruct_service_status_data *ssdata=NULL; nebstruct_host_status_data *hsdata=NULL; service *svc=NULL; host *hst=NULL; char temp_buffer[1024]; /* what type of event/data do we have? */ switch(event_type){ case NEBCALLBACK_SERVICE_STATUS_DATA: //service status data occurs every time a check runs. We use this to update the service file in each hosts directory. ssdata=(nebstruct_service_status_data *)data; //ss data gives us a pointer directly to the service object svc=ssdata->object_ptr; nagfs_write_service_status(svc->host_name, svc->description, svc->current_state, svc->state_type ); break; case NEBCALLBACK_HOST_STATUS_DATA: //service status data occurs every time a host check runs. We use this to update the HOST file. hsdata=(nebstruct_host_status_data *)data; //ss data gives us a pointer directly to the service object hst=hsdata->object_ptr; nagfs_write_host_status(hst->name, hst->current_state, hst->state_type ); break; default: snprintf(temp_buffer,sizeof(temp_buffer)-1,"nagfs: just got some unknown data. Wierd.." ); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_all_logs(temp_buffer,NSLOG_INFO_MESSAGE); break; } return OK; } /* this function writes service status data from status update events to the * status filesystem. */ int nagfs_write_service_status(char *host_name, char *service_description, int state, int state_type){ int bufsize = 1024; char host_path[bufsize]; char service_path[bufsize]; char soft[bufsize]; char temp_buffer[bufsize]; DIR *dp; FILE *outfile; snprintf( host_path,bufsize,"%s/%s", nagfs_fs_home, host_name); snprintf( soft,bufsize,"%s/%s/%s.soft", nagfs_fs_home, host_name, service_description); //are we writing a normal file or a .soft file switch(state_type){ case 0: //the service is in a soft state write a .soft file snprintf( service_path,bufsize,"%s/%s/%s.soft", nagfs_fs_home, host_name, service_description); break; case 1: //the service is in a hard state snprintf( service_path,bufsize,"%s/%s/%s", nagfs_fs_home, host_name, service_description); //delete any soft files if they exist if((nagfs_check_for_softfiles(soft)) != OK){ snprintf(temp_buffer,sizeof(temp_buffer)-1,"nagfs: couldn't remove %s",service_path ); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_all_logs(temp_buffer,NSLOG_INFO_MESSAGE); } break; default: snprintf(temp_buffer,sizeof(temp_buffer)-1,"nagfs: just got an unknown state type. Wierd.." ); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_all_logs(temp_buffer,NSLOG_INFO_MESSAGE); break; } //create the directory if it doesn't exist if((dp = opendir(host_path)) == NULL) { if(( mkdir( host_path, S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH )) != OK){ snprintf(temp_buffer,sizeof(temp_buffer)-1,"nagfs: Couldn't create the directory: %s",host_path); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_all_logs(temp_buffer,NSLOG_INFO_MESSAGE); } }else{ closedir(dp); } //write the file if(( outfile=fopen(service_path,"w")) == NULL){ snprintf(temp_buffer,sizeof(temp_buffer)-1,"nagfs: Couldn't open file for writing: %s",service_path); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_all_logs(temp_buffer,NSLOG_INFO_MESSAGE); } fprintf(outfile,"%i",state); fclose(outfile); return OK; } /* same like above, just for hosts */ int nagfs_write_host_status(char *host_name, int state, int state_type){ int bufsize = 1024; char host_path[bufsize]; char host_file[bufsize]; char soft[bufsize]; char temp_buffer[bufsize]; DIR *dp; FILE *outfile; snprintf( host_path,bufsize,"%s/%s", nagfs_fs_home, host_name); snprintf( soft,bufsize,"%s/%s/HOST.soft", nagfs_fs_home, host_name); //are we writing a normal file or a .soft file switch(state_type){ case 0: //the service is in a soft state write a .soft file snprintf( host_file,bufsize,"%s/%s/HOST.soft", nagfs_fs_home, host_name ); break; case 1: //the host is in a hard state snprintf( host_file,bufsize,"%s/%s/HOST", nagfs_fs_home, host_name ); //delete softfiles if they exist if((nagfs_check_for_softfiles(soft)) != OK){ snprintf(temp_buffer,sizeof(temp_buffer)-1,"nagfs: couldn't remove %s",host_file ); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_all_logs(temp_buffer,NSLOG_INFO_MESSAGE); } break; default: snprintf(temp_buffer,sizeof(temp_buffer)-1,"nagfs: just got an unknown state type. Wierd.." ); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_all_logs(temp_buffer,NSLOG_INFO_MESSAGE); break; } //create the directory if it doesn't exist if((dp = opendir(host_path)) == NULL) { if(( mkdir( host_path, S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH )) != OK){ snprintf(temp_buffer,sizeof(temp_buffer)-1,"nagfs: Couldn't create the directory: %s",host_path); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_all_logs(temp_buffer,NSLOG_INFO_MESSAGE); } }else{ closedir(dp); } //write the file if(( outfile=fopen(host_file,"w")) == NULL){ snprintf(temp_buffer,sizeof(temp_buffer)-1,"nagfs: Couldn't open file for writing: %s",host_file); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_all_logs(temp_buffer,NSLOG_INFO_MESSAGE); } fprintf(outfile,"%i",state); fclose(outfile); return OK; } int nagfs_check_for_softfiles(char *soft_file){ FILE *search_file=NULL; if((search_file=fopen(soft_file,"r"))==NULL){ return OK; } else { fclose(search_file); if((remove(soft_file))!=0){ return 1; } } return OK; }