/* 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; /* set some info - this is completely optional, as Nagios doesn't do anything with this data */ neb_set_module_info(helloworld_module_handle, NEBMODULE_MODINFO_TITLE, "helloworld"); neb_set_module_info(helloworld_module_handle, NEBMODULE_MODINFO_AUTHOR, "Ethan Galstad"); neb_set_module_info(helloworld_module_handle, NEBMODULE_MODINFO_TITLE, "Copyright (c) 2003-2007 Ethan Galstad"); neb_set_module_info(helloworld_module_handle, NEBMODULE_MODINFO_VERSION, "noversion"); neb_set_module_info(helloworld_module_handle, NEBMODULE_MODINFO_LICENSE, "GPL v2"); neb_set_module_info(helloworld_module_handle, NEBMODULE_MODINFO_DESC, "A simple example to get you started with Nagios Event Broker (NEB) modules."); /* log module info to the Nagios log file */ write_to_all_logs("helloworld: Copyright (c) 2003-2007 Ethan Galstad ([email protected])", 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, (void *)helloworld_reminder_message, "How about you?", 0); /* register to be notified of certain events... */ neb_register_callback(NEBCALLBACK_AGGREGATED_STATUS_DATA, helloworld_module_handle, 0, helloworld_handle_data); return 0; }
/* process all config vars in a file */ int npcdmod_process_config_file(char *filename) { pnp_mmapfile *thefile = NULL; char *buf = NULL; char temp_buffer[1024]; int result = OK; /* open the file */ if ((thefile = pnp_mmap_fopen(filename)) == NULL) { snprintf(temp_buffer, sizeof(temp_buffer) - 1, "npcdmod ERROR: failed to open %s\n", filename); temp_buffer[sizeof(temp_buffer) - 1] = '\x0'; write_to_all_logs(temp_buffer, NSLOG_INFO_MESSAGE); return ERROR; } else { snprintf(temp_buffer, sizeof(temp_buffer) - 1, "npcdmod: %s initialized\n", filename); temp_buffer[sizeof(temp_buffer) - 1] = '\x0'; write_to_all_logs(temp_buffer, NSLOG_INFO_MESSAGE); } /* process each line of the file */ while ((buf = pnp_mmap_fgets(thefile))) { /* skip comments */ if (buf[0] == '#') { free(buf); continue; } /* skip blank lines */ if (!strcmp(buf, "")) { free(buf); continue; } /* skip new lines */ if (!strcmp(buf, "\n")) { free(buf); continue; } /* process the variable */ result = npcdmod_process_config_var(buf); /* free memory */ free(buf); if (result != OK) break; } /* close the file */ pnp_mmap_fclose(thefile); return result; }
/* gets called every X seconds by an event in the scheduling queue */ void npcdmod_file_roller() { char temp_buffer[1024]; char spool_file[1024]; int result = 0; time_t current_time; time(¤t_time); sprintf(spool_file, "%s%s.%d", spool_dir, perfdata_spool_filename, current_time); spool_file[sizeof(spool_file) - 1] = '\x0'; /* close actual file */ fclose(fp); /* move the original file */ result = my_rename(perfdata_file, spool_file); /* open a new file */ if ((fp = fopen(perfdata_file, "a")) == NULL) { snprintf(temp_buffer, sizeof(temp_buffer) - 1, "npcdmod: Could not reopen file. %s", strerror(errno), NSLOG_INFO_MESSAGE); temp_buffer[sizeof(temp_buffer) - 1] = '\x0'; write_to_all_logs(temp_buffer, NSLOG_INFO_MESSAGE); } return; }
/* write something to the log file, syslog, and possibly the console */ static void write_to_logs_and_console(char *buffer, unsigned long data_type, int display) { register int len = 0; register int x = 0; /* 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) { /* don't display warnings if we're just testing scheduling */ if(test_scheduling == TRUE && data_type == NSLOG_VERIFICATION_WARNING) return; write_to_console(buffer); } }
/* write a service problem/recovery to the nagios log file */ int log_service_event(service *svc) { char *temp_buffer = NULL; unsigned long log_options = 0L; host *temp_host = NULL; /* 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 */ if((temp_host = svc->host_ptr) == NULL) return ERROR; asprintf(&temp_buffer, "SERVICE ALERT: %s;%s;%s;%s;%d;%s\n", svc->host_name, svc->description, service_state_name(svc->current_state), state_type_name(svc->state_type), svc->current_attempt, (svc->plugin_output == NULL) ? "" : svc->plugin_output); write_to_all_logs(temp_buffer, log_options); free(temp_buffer); return OK; }
/* write a host problem/recovery to the log file */ int log_host_event(host *hst){ char *temp_buffer=NULL; char *processed_buffer=NULL; unsigned long log_options=0L; /* grab the host macros */ clear_volatile_macros(); grab_host_macros(hst); /* 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; asprintf(&temp_buffer,"HOST ALERT: %s;$HOSTSTATE$;$HOSTSTATETYPE$;$HOSTATTEMPT$;%s\n",hst->name,(hst->plugin_output==NULL)?"":hst->plugin_output); process_macros(temp_buffer,&processed_buffer,0); write_to_all_logs(processed_buffer,log_options); my_free(temp_buffer); my_free(processed_buffer); return OK; }
/* 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; }
/* write a host problem/recovery to the log file */ int log_host_event(host *hst) { char *temp_buffer = NULL; unsigned long log_options = 0L; /* 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; asprintf(&temp_buffer, "HOST ALERT: %s;%s;%s;%d;%s\n", hst->name, host_state_name(hst->current_state), state_type_name(hst->state_type), hst->current_attempt, (hst->plugin_output == NULL) ? "" : hst->plugin_output); write_to_all_logs(temp_buffer, log_options); my_free(temp_buffer); return OK; }
void logger(int priority, const char *loginfo, ...) { va_list ap; va_start(ap, loginfo); /* Only the main process may use the Nagios log methods */ if (!g_logfile || g_mainthread_id == pthread_self()) { char buffer[8192]; snprintf(buffer, 20, "livestatus: "); vsnprintf(buffer + strlen(buffer), sizeof(buffer) - strlen(buffer), loginfo, ap); write_to_all_logs(buffer, priority); } else { if (g_logfile) { /* write date/time */ char timestring[64]; time_t now_t = time(0); struct tm now; localtime_r(&now_t, &now); strftime(timestring, 64, "%F %T ", &now); fputs(timestring, g_logfile); /* write log message */ vfprintf(g_logfile, loginfo, ap); fputc('\n', g_logfile); fflush(g_logfile); } } va_end(ap); }
/* writes a string to Nagios logs */ int altinity_set_initial_state_write_to_logs(char *buf, int flags){ if(buf==NULL) return NDO_ERROR; return write_to_all_logs(buf,flags); }
/* 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; }
int open_sock(){ int tosocket; /* the socket descriptor*/ char temp_buffer[BUFFER]; /* description of struct sockaddr_in is mentioned in netinet/in.h */ struct sockaddr_in toaddr; /* store address of server here */ /* create tcp socket */ tosocket = socket(PF_INET,SOCK_STREAM,0); if(tosocket == -1){ snprintf(temp_buffer,sizeof(temp_buffer)-1,"modpnpsender: Unable to create socket. Aborting...\n"); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_all_logs(temp_buffer,NSLOG_INFO_MESSAGE); return(-1); } /* else { snprintf(temp_buffer,sizeof(temp_buffer)-1,"modpnpsender: Socket is OK....\n"); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_all_logs(temp_buffer,NSLOG_INFO_MESSAGE); } */ /* define server address */ toaddr.sin_family = PF_INET; toaddr.sin_addr.s_addr = inet_addr(serverip); toaddr.sin_port = htons(serverport); /* connect to server */ if(connect(tosocket, (struct sockaddr *)&toaddr, sizeof(toaddr)) == -1){ snprintf(temp_buffer,sizeof(temp_buffer)-1,"modpnpsender: Unable to connect to server '%s' on port %d. Aborting...\n", serverip, serverport); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_all_logs(temp_buffer,NSLOG_INFO_MESSAGE); // write_to_all_logs("modpnpsender: Connect failed... closing the socket...",NSLOG_INFO_MESSAGE); close (tosocket); // write_to_all_logs("modpnpsender: Socket closed...",NSLOG_INFO_MESSAGE); return(-1); } else { socket_status=OPEN; return tosocket; } return (-1); }
/* 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 */ modpnpsender_module_handle=handle; /* log module info to the Nagios log file */ write_to_all_logs("modpnpsender: Copyright (c)2007 Hendrik Baecker ([email protected])",NSLOG_INFO_MESSAGE); /* log a message to the Nagios log file */ snprintf(temp_buffer,sizeof(temp_buffer)-1,"modpnpsender: PNPSender module starting the engines!\n"); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_all_logs(temp_buffer,NSLOG_INFO_MESSAGE); if(args == NULL) { write_to_all_logs("modpnpsender: WARNING assuming '127.0.0.1' as destination IP Address)",NSLOG_INFO_MESSAGE); } else { if((serverip = strtok_r(args, " ", &saveptr1))!=NULL){ serverip = serverip; } if((port = strtok_r(NULL, " ", &saveptr1))!=NULL){ serverport=atoi(port); } } snprintf(temp_buffer,sizeof(temp_buffer)-1,"modpnpsender: Arguments are %s - %d",serverip,serverport); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_all_logs(temp_buffer,NSLOG_INFO_MESSAGE); /* register to be notified of certain events... */ neb_register_callback(NEBCALLBACK_SERVICE_CHECK_DATA,modpnpsender_module_handle,0,modpnpsender_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; }
/* 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_SERVICE_CHECK_DATA,modpnpsender_handle_data); /* log a message to the Nagios log file */ snprintf(temp_buffer,sizeof(temp_buffer)-1,"modpnpsender: Exiting - Thanks for for the flight!\n"); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_all_logs(temp_buffer,NSLOG_INFO_MESSAGE); return 0; }
/* handle data from Nagios daemon */ int modpnpsender_handle_data(int event_type, void *data){ nebstruct_service_check_data *scdata=NULL; char temp_buffer[1024]; /* what type of event/data do we have? */ switch(event_type){ case NEBCALLBACK_SERVICE_CHECK_DATA: /* a service check event occurs */ if((scdata=(nebstruct_service_check_data *)data)!=NULL){ if (scdata->type==NEBTYPE_SERVICECHECK_INITIATE) { /* Check if this service check has performance data */ if (scdata->perf_data != NULL) { snprintf(temp_buffer,sizeof(temp_buffer)-1,"modpnpsender: Processing PNP for %s / %s with perfdata %s",scdata->host_name,scdata->service_description,scdata->perf_data); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_all_logs(temp_buffer,NSLOG_INFO_MESSAGE); if(send_data(scdata)!=0) { write_to_all_logs("modpnpsender: An error occured while sending data!",NSLOG_INFO_MESSAGE); } else { write_to_all_logs("modpnpsender: Message sent - finish for now.",NSLOG_INFO_MESSAGE); return 0; } } } } break; default: break; } 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_HOST_CHECK_DATA,npcdmod_handle_data); neb_deregister_callback(NEBCALLBACK_SERVICE_CHECK_DATA,npcdmod_handle_data); /* log a message to the Nagios log file */ snprintf(temp_buffer, sizeof(temp_buffer) - 1, "npcdmod: If you don't like me, I will go out! Bye.\n"); temp_buffer[sizeof(temp_buffer) - 1] = '\x0'; write_to_all_logs(temp_buffer, NSLOG_INFO_MESSAGE); return 0; }
void n2a_logger (int priority, const char *loginfo, ...) { if (priority == 1 && g_options.log_level <= 0) return; else priority = LG_INFO; char buffer[8192]; snprintf (buffer, 20, "neb2amqp: "); va_list ap; va_start (ap, loginfo); vsnprintf (buffer + strlen (buffer), sizeof (buffer) - strlen (buffer), loginfo, ap); va_end (ap); write_to_all_logs (buffer, priority); }
void n2a_logger (int priority, const char *loginfo, ...) { char *format = NULL; char *buffer = NULL; va_list ap; if (priority != 1 || g_options.log_level > 0) { priority = LG_INFO; } asprintf (&format, "neb2amqp: %s", loginfo); va_start (ap, loginfo); vasprintf (&buffer, format, ap); va_end (ap); write_to_all_logs (buffer, priority); }
/* gets one line of input from an mmap()'ed file */ char *pnp_mmap_fgets(pnp_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; x < temp_mmapfile->file_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) { write_to_all_logs("could not allocate a new buf", NSLOG_INFO_MESSAGE); 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; }
/* write a service problem/recovery to the nagios log file */ int log_service_event(service *svc){ char *temp_buffer=NULL; char *processed_buffer=NULL; unsigned long log_options=0L; host *temp_host=NULL; /* 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 */ if((temp_host=svc->host_ptr)==NULL) return ERROR; /* grab service macros */ clear_volatile_macros(); grab_host_macros(temp_host); grab_service_macros(svc); asprintf(&temp_buffer,"SERVICE ALERT: %s;%s;$SERVICESTATE$;$SERVICESTATETYPE$;$SERVICEATTEMPT$;%s\n",svc->host_name,svc->description,(svc->plugin_output==NULL)?"":svc->plugin_output); process_macros(temp_buffer,&processed_buffer,0); write_to_all_logs(processed_buffer,log_options); my_free(temp_buffer); my_free(processed_buffer); return OK; }
/* write a host problem/recovery to the log file */ int log_host_event(host *hst) { char *temp_buffer = NULL; unsigned long log_options = 0L; /* 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; /* either log only the output, or if enabled, add long_output */ if (log_long_plugin_output == TRUE && hst->long_plugin_output != NULL) { dummy = asprintf(&temp_buffer, "HOST ALERT: %s;%s;%s;%d;%s\\n%s\n", hst->name, host_state_name(hst->current_state), state_type_name(hst->state_type), hst->current_attempt, (hst->plugin_output == NULL) ? "" : hst->plugin_output, hst->long_plugin_output ); } else { dummy = asprintf(&temp_buffer, "HOST ALERT: %s;%s;%s;%d;%s\n", hst->name, host_state_name(hst->current_state), state_type_name(hst->state_type), hst->current_attempt, (hst->plugin_output == NULL) ? "" : hst->plugin_output ); } write_to_all_logs(temp_buffer, log_options); my_free(temp_buffer); return OK; }
/* core log wrapper */ void write_core_log(char *data) { write_to_all_logs( data, NSLOG_INFO_MESSAGE ); return; }
int main(int argc, char **argv, char **env) { int result; int error = FALSE; char *buffer = NULL; int display_license = FALSE; int display_help = FALSE; int c = 0; struct tm *tm, tm_s; time_t now; char datestring[256]; nagios_macros *mac; const char *worker_socket = NULL; int i; #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-config", no_argument, 0, 'v'}, {"daemon", no_argument, 0, 'd'}, {"test-scheduling", no_argument, 0, 's'}, {"precache-objects", no_argument, 0, 'p'}, {"use-precached-objects", no_argument, 0, 'u'}, {"enable-timing-point", no_argument, 0, 'T'}, {"worker", required_argument, 0, 'W'}, {0, 0, 0, 0} }; #define getopt(argc, argv, o) getopt_long(argc, argv, o, long_options, &option_index) #endif memset(&loadctl, 0, sizeof(loadctl)); mac = get_global_macros(); /* make sure we have the correct number of command line arguments */ if(argc < 2) error = TRUE; /* get all command line arguments */ while(1) { c = getopt(argc, argv, "+hVvdspuxTW"); 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++; break; case 's': /* scheduling check */ test_scheduling = TRUE; break; case 'd': /* daemon mode */ daemon_mode = TRUE; break; case 'p': /* precache object config */ precache_objects = TRUE; break; case 'u': /* use precached object config */ use_precached_objects = TRUE; break; case 'T': enable_timing_point = TRUE; break; case 'W': worker_socket = optarg; break; case 'x': printf("Warning: -x is deprecated and will be removed\n"); break; default: break; } } #ifdef DEBUG_MEMORY mtrace(); #endif /* if we're a worker we can skip everything below */ if(worker_socket) { exit(nagios_core_worker(worker_socket)); } if(daemon_mode == FALSE) { printf("\nNagios Core %s\n", PROGRAM_VERSION); printf("Copyright (c) 2009-present Nagios Core Development Team and Community Contributors\n"); printf("Copyright (c) 1999-2009 Ethan Galstad\n"); printf("Last Modified: %s\n", PROGRAM_MODIFICATION_DATE); printf("License: GPL\n\n"); printf("Website: http://www.nagios.org\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 [options] <main_config_file>\n", argv[0]); printf("\n"); printf("Options:\n"); printf("\n"); printf(" -v, --verify-config Verify all configuration data (-v -v for more info)\n"); printf(" -s, --test-scheduling Shows projected/recommended check scheduling and other\n"); printf(" diagnostic info based on the current configuration files.\n"); printf(" -T, --enable-timing-point Enable timed commentary on initialization\n"); printf(" -x, --dont-verify-paths Deprecated (Don't check for circular object paths)\n"); printf(" -p, --precache-objects Precache object configuration\n"); printf(" -u, --use-precached-objects Use precached object config file\n"); printf(" -d, --daemon Starts Nagios in daemon mode, instead of as a foreground process\n"); printf(" -W, --worker /path/to/socket Act as a worker for an already running daemon\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 support options for Nagios.\n"); printf("\n"); exit(ERROR); } /* * config file is last argument specified. * Make sure it uses an absolute path */ config_file = nspath_absolute(argv[optind], NULL); if(config_file == NULL) { printf("Error allocating memory.\n"); exit(ERROR); } /* make sure the config file uses an absolute path */ buffer = strdup(config_file); config_file_dir = strdup(dirname(buffer)); free(buffer); /* * let's go to town. We'll be noisy if we're verifying config * or running scheduling tests. */ if(verify_config || test_scheduling || precache_objects) { reset_variables(); /* * if we don't beef up our resource limits as much as * we can, it's quite possible we'll run headlong into * EAGAIN due to too many processes when we try to * drop privileges later. */ set_loadctl_defaults(); if(verify_config) printf("Reading configuration data...\n"); /* read our config file */ result = read_main_config_file(config_file); if(result != OK) { printf(" Error processing main config file!\n\n"); exit(EXIT_FAILURE); } if(verify_config) printf(" Read main config file okay...\n"); /* drop privileges */ if((result = drop_privileges(nagios_user, nagios_group)) == ERROR) { printf(" Failed to drop privileges. Aborting."); exit(EXIT_FAILURE); } /* read object config files */ result = read_all_object_data(config_file); if(result != OK) { printf(" Error processing object config files!\n\n"); /* 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 '%s'\n", DEFAULT_CONFIG_FILE); } 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"); exit(EXIT_FAILURE); } if(verify_config) { printf(" Read object config files okay...\n\n"); 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("\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"); exit(EXIT_FAILURE); } if(verify_config) { printf("\nThings look okay - No serious problems were detected during the pre-flight check\n"); } /* scheduling tests need a bit more than config verifications */ if(test_scheduling == TRUE) { /* we'll need the event queue here so we can time insertions */ init_event_queue(); timing_point("Done initializing event queue\n"); /* read initial service and host state information */ initialize_retention_data(config_file); read_initial_state_information(); timing_point("Retention data and initial state parsed\n"); /* initialize the event timing loop */ init_timing_loop(); timing_point("Timing loop initialized\n"); /* display scheduling information */ display_scheduling_info(); } if(precache_objects) { result = fcache_objects(object_precache_file); timing_point("Done precaching objects\n"); if(result == OK) { printf("Object precache file created:\n%s\n", object_precache_file); } else { printf("Failed to precache objects to '%s': %s\n", object_precache_file, strerror(errno)); } } /* clean up after ourselves */ cleanup(); /* exit */ timing_point("Exiting\n"); exit(result); } /* else start to monitor things... */ else { /* * if we're called with a relative path we must make * it absolute so we can launch our workers. * If not, we needn't bother, as we're using execvp() */ if (strchr(argv[0], '/')) { nagios_binary_path = nspath_absolute(argv[0], NULL); if (access(nagios_binary_path, X_OK) < 0) { logit(NSLOG_RUNTIME_ERROR, TRUE, "Error: failed to access() %s: %s\n", nagios_binary_path, strerror(errno)); logit(NSLOG_RUNTIME_ERROR, TRUE, "Error: Spawning workers will be impossible. Aborting.\n"); exit(EXIT_FAILURE); } } else { nagios_binary_path = strdup(argv[0]); } nagios_iobs = iobroker_create(); /* keep monitoring things until we get a shutdown command */ do { /* reset program variables */ reset_variables(); timing_point("Variables reset\n"); /* get PID */ nagios_pid = (int)getpid(); /* read in the configuration files (main and resource config files) */ result = read_main_config_file(config_file); timing_point("Main config file read\n"); /* NOTE 11/06/07 EG moved to after we read config files, as user may have overridden timezone offset */ /* get program (re)start time and save as macro */ program_start = time(NULL); my_free(mac->x[MACRO_PROCESSSTARTTIME]); asprintf(&mac->x[MACRO_PROCESSSTARTTIME], "%lu", (unsigned long)program_start); /* open debug log */ open_debug_log(); /* drop privileges */ if(drop_privileges(nagios_user, nagios_group) == ERROR) { logit(NSLOG_PROCESS_INFO | NSLOG_RUNTIME_ERROR | NSLOG_CONFIG_ERROR, TRUE, "Failed to drop privileges. Aborting."); cleanup(); exit(ERROR); } #ifdef USE_EVENT_BROKER /* initialize modules */ neb_init_modules(); neb_init_callback_list(); #endif timing_point("NEB module API initialized\n"); /* this must be logged after we read config data, as user may have changed location of main log file */ logit(NSLOG_PROCESS_INFO, TRUE, "Nagios %s starting... (PID=%d)\n", PROGRAM_VERSION, (int)getpid()); /* log the local time - may be different than clock time due to timezone offset */ now = time(NULL); tm = localtime_r(&now, &tm_s); strftime(datestring, sizeof(datestring), "%a %b %d %H:%M:%S %Z %Y", tm); logit(NSLOG_PROCESS_INFO, TRUE, "Local time is %s", datestring); /* write log version/info */ write_log_file_info(NULL); /* handle signals (interrupts) before we do any socket I/O */ setup_sighandler(); /* * Initialize query handler and event subscription service. * This must be done before modules are initialized, so * the modules can use our in-core stuff properly */ qh_init(qh_socket_path ? qh_socket_path : DEFAULT_QUERY_SOCKET); timing_point("Query handler initialized\n"); nerd_init(); timing_point("NERD initialized\n"); /* initialize check workers */ if(init_workers(num_check_workers) < 0) { logit(NSLOG_RUNTIME_ERROR, TRUE, "Failed to spawn workers. Aborting\n"); exit(EXIT_FAILURE); } timing_point("%u workers spawned\n", wproc_num_workers_spawned); i = 0; while (i < 50 && wproc_num_workers_online < wproc_num_workers_spawned) { iobroker_poll(nagios_iobs, 50); i++; } timing_point("%u workers connected\n", wproc_num_workers_online); /* now that workers have arrived we can set the defaults */ set_loadctl_defaults(); #ifdef USE_EVENT_BROKER /* load modules */ neb_load_all_modules(); timing_point("Modules loaded\n"); /* send program data to broker */ broker_program_state(NEBTYPE_PROCESS_PRELAUNCH, NEBFLAG_NONE, NEBATTR_NONE, NULL); timing_point("First callback made\n"); #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) logit(NSLOG_PROCESS_INFO | NSLOG_RUNTIME_ERROR | NSLOG_CONFIG_ERROR, TRUE, "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)", (int)getpid()); else { /* run the pre-flight check to make sure everything looks okay*/ if((result = pre_flight_check()) != OK) logit(NSLOG_PROCESS_INFO | NSLOG_RUNTIME_ERROR | NSLOG_VERIFICATION_ERROR, TRUE, "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()); } /* an error occurred that prevented us from (re)starting */ if(result != OK) { /* if we were restarting, we need to cleanup from the previous run */ if(sigrestart == TRUE) { /* clean up the status data */ cleanup_status_data(config_file, 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); } timing_point("Object configuration parsed and understood\n"); /* write the objects.cache file */ fcache_objects(object_cache_file); timing_point("Objects cached\n"); init_event_queue(); timing_point("Event queue initialized\n"); #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) { result = daemon_init(); /* we had an error daemonizing, so bail... */ if(result == ERROR) { logit(NSLOG_PROCESS_INFO | NSLOG_RUNTIME_ERROR, TRUE, "Bailing out due to failure to daemonize. (PID=%d)", (int)getpid()); #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); } asprintf(&buffer, "Finished daemonizing... (New PID=%d)\n", (int)getpid()); write_to_all_logs(buffer, NSLOG_PROCESS_INFO); my_free(buffer); /* get new PID */ nagios_pid = (int)getpid(); } /* initialize status data unless we're starting */ if(sigrestart == FALSE) { initialize_status_data(config_file); timing_point("Status data initialized\n"); } /* read initial service and host state information */ initialize_retention_data(config_file); timing_point("Retention data initialized\n"); read_initial_state_information(); timing_point("Initial state information read\n"); /* initialize comment data */ initialize_comment_data(config_file); timing_point("Comment data initialized\n"); /* initialize scheduled downtime data */ initialize_downtime_data(config_file); timing_point("Downtime data initialized\n"); /* initialize performance data */ initialize_performance_data(config_file); timing_point("Performance data initialized\n"); /* initialize the event timing loop */ init_timing_loop(); timing_point("Event timing loop initialized\n"); /* initialize check statistics */ init_check_stats(); timing_point("check stats initialized\n"); /* check for updates */ check_for_nagios_updates(FALSE, TRUE); timing_point("Update check concluded\n"); /* update all status data (with retained information) */ update_all_status_data(); timing_point("Status data updated\n"); /* log initial host and service state */ log_host_states(INITIAL_STATES, NULL); log_service_states(INITIAL_STATES, NULL); timing_point("Initial states logged\n"); /* reset the restart flag */ sigrestart = FALSE; /* fire up command file worker */ launch_command_file_worker(); timing_point("Command file worker launched\n"); #ifdef USE_EVENT_BROKER /* send program data to broker */ broker_program_state(NEBTYPE_PROCESS_EVENTLOOPSTART, NEBFLAG_NONE, NEBATTR_NONE, NULL); #endif /* get event start time and save as macro */ event_start = time(NULL); my_free(mac->x[MACRO_EVENTSTARTTIME]); asprintf(&mac->x[MACRO_EVENTSTARTTIME], "%lu", (unsigned long)event_start); timing_point("Entering event execution loop\n"); /***** start monitoring all services *****/ /* (doesn't return until a restart or shutdown signal is encountered) */ event_execution_loop(); /* 03/01/2007 EG Moved from sighandler() to prevent FUTEX locking problems under NPTL */ /* 03/21/2007 EG SIGSEGV signals are still logged in sighandler() so we don't loose them */ /* did we catch a signal? */ if(caught_signal == TRUE) { if(sig_id == SIGHUP) logit(NSLOG_PROCESS_INFO, TRUE, "Caught SIGHUP, restarting...\n"); } #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(FALSE); cleanup_retention_data(config_file); /* clean up performance data */ cleanup_performance_data(config_file); /* clean up the scheduled downtime data */ cleanup_downtime_data(config_file); /* clean up the status data unless we're restarting */ if(sigrestart == FALSE) { cleanup_status_data(config_file, TRUE); } /* shutdown stuff... */ if(sigshutdown == TRUE) { free_worker_memory(WPROC_FORCE); iobroker_destroy(nagios_iobs, IOBROKER_CLOSE_SOCKETS); nagios_iobs = NULL; /* 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 */ logit(NSLOG_PROCESS_INFO, TRUE, "Successfully shutdown... (PID=%d)\n", (int)getpid()); } /* clean up after ourselves */ cleanup(); /* close debug log */ close_debug_log(); } while(sigrestart == TRUE && sigshutdown == FALSE); /* free misc memory */ my_free(config_file); } return OK; }
int send_data(nebstruct_service_check_data *data){ char temp_buffer[1024]; char *message; int socket; int message_length = 1024; char cmd[1024]; time_t t; if (socket_status == CLOSE) { socket = open_sock(); if (socket == -1) { write_to_all_logs("modpnpsender: Arg! Socket is -1",NSLOG_INFO_MESSAGE); return (-1); } } if (!(message = (char *) malloc(message_length))) { snprintf(temp_buffer,sizeof(temp_buffer)-1,"modpnpsender: cannot allocate memory for message. Aborting...\n"); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_all_logs(temp_buffer,NSLOG_INFO_MESSAGE); return (-1); } bzero((void *)message, message_length); strcat(message,"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n"); strcat(message,"<NAGIOS>\n<NAGIOS_DATATYPE>serviceperfdata</NAGIOS_DATATYPE>\n"); strcat(message,"<NAGIOS_HOSTNAME>"); strcat(message,data->host_name); strcat(message,"</NAGIOS_HOSTNAME>\n"); strcat(message,"<NAGIOS_SERVICEDESC>"); strcat(message,data->service_description); strcat(message,"</NAGIOS_SERVICEDESC>\n"); strcat(message,"<NAGIOS_SERVICEPERFDATA>"); strcat(message,data->perf_data); strcat(message,"</NAGIOS_SERVICEPERFDATA>\n"); strcat(message,"<NAGIOS_SERVICECHECKCOMMAND>"); if (data->command_name != NULL) { strcat(message,data->command_name); } strcat(message,"</NAGIOS_SERVICECHECKCOMMAND>\n"); strcat(message,"<NAGIOS_SERVICECHECKCOMMAND_ARGS>"); if (data->command_args != NULL) strcat(message,data->command_args); strcat(message,"</NAGIOS_SERVICECHECKCOMMAND>\n"); strcat(message,"<NAGIOS_SERVICECHECKCOMMAND_LINE>"); if (data->command_line != NULL) strcat(message,data->command_line); strcat(message,"</NAGIOS_SERVICECHECKCOMMAND>\n"); strcat(message,"<NAGIOS_SERVICEOUTPUT>"); if (data->output != NULL) strcat(message,data->output); strcat(message,"</NAGIOS_SERVICEOUTPUT>\n"); time(&t); snprintf(temp_buffer, sizeof(temp_buffer)-1,"%ld",t); temp_buffer[sizeof(temp_buffer)-1]='\x0'; strcat(message,"<NAGIOS_TIMET>"); strcat(message, temp_buffer); strcat(message,"</NAGIOS_TIMET>\n"); bzero((void *)temp_buffer,sizeof(temp_buffer)-1); strcat(message,"</NAGIOS>\n"); if(send(socket, message, strlen(message), 0) == -1) { snprintf(temp_buffer,sizeof(temp_buffer)-1,"modpnpsender: error while sending message to server. - %s\n",strerror(errno)); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_all_logs(temp_buffer,NSLOG_INFO_MESSAGE); } close (socket); socket_status = CLOSE; snprintf(temp_buffer,sizeof(temp_buffer)-1,"modpnpsender: Sending perfdata for %s / %s with perfdata %s",data->host_name,data->service_description,data->perf_data); temp_buffer[sizeof(temp_buffer)-1]='\x0'; write_to_all_logs(temp_buffer,NSLOG_INFO_MESSAGE); return 0; }
/* Following main() declaration required by older versions of Perl ut 5.00503 */ int main(int argc, char **argv, char **env) { int result; int error = FALSE; char *buffer = NULL; int display_license = FALSE; int display_help = FALSE; int c = 0; struct tm *tm, tm_s; time_t now; char datestring[256]; nagios_macros *mac; mac = get_global_macros(); #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-config", no_argument, 0, 'v'}, {"daemon", no_argument, 0, 'd'}, {"test-scheduling", no_argument, 0, 's'}, {"dont-verify-objects", no_argument, 0, 'o'}, {"dont-verify-paths", no_argument, 0, 'x'}, {"precache-objects", no_argument, 0, 'p'}, {"use-precached-objects", no_argument, 0, 'u'}, {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, "+hVvdsoxpu", long_options, &option_index); #else c = getopt(argc, argv, "+hVvdsoxpu"); #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; case 'o': /* don't verify objects */ /* verify_object_relationships=FALSE; */ break; case 'x': /* don't verify circular paths */ verify_circular_paths = FALSE; break; case 'p': /* precache object config */ precache_objects = TRUE; break; case 'u': /* use precached object config */ use_precached_objects = TRUE; break; default: break; } } /* make sure we have the right combination of arguments */ if(precache_objects == TRUE && (test_scheduling == FALSE && verify_config == FALSE)) { error = TRUE; display_help = TRUE; } #ifdef DEBUG_MEMORY mtrace(); #endif if(daemon_mode == FALSE) { printf("\nNagios Core %s\n", PROGRAM_VERSION); printf("Copyright (c) 2009-2011 Nagios Core Development Team and Community Contributors\n"); printf("Copyright (c) 1999-2009 Ethan Galstad\n"); printf("Last Modified: %s\n", PROGRAM_MODIFICATION_DATE); printf("License: GPL\n\n"); printf("Website: http://www.nagios.org\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 [options] <main_config_file>\n", argv[0]); printf("\n"); printf("Options:\n"); printf("\n"); printf(" -v, --verify-config Verify all configuration data\n"); printf(" -s, --test-scheduling Shows projected/recommended check scheduling and other\n"); printf(" diagnostic info based on the current configuration files.\n"); /*printf(" -o, --dont-verify-objects Don't verify object relationships - USE WITH CAUTION!\n");*/ printf(" -x, --dont-verify-paths Don't check for circular object paths - USE WITH CAUTION!\n"); printf(" -p, --precache-objects Precache object configuration - use with -v or -s options\n"); printf(" -u, --use-precached-objects Use precached object config file\n"); printf(" -d, --daemon Starts Nagios in daemon mode, instead of as a foreground process\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 support options for Nagios.\n"); printf("\n"); exit(ERROR); } /* * Set the signal handler for the SIGXFSZ signal here because * we may encounter this signal before the other signal handlers * are set. */ signal(SIGXFSZ, handle_sigxfsz); /* 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 */ buffer = (char *)strdup(config_file); /* 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, "/", 1); 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'; my_free(buffer); } /* we're just verifying the configuration... */ if(verify_config == TRUE) { /* reset program variables */ reset_variables(); printf("Reading configuration data...\n"); /* read in the configuration files (main config file, resource and object config files) */ if((result = read_main_config_file(config_file)) == OK) { printf(" Read main config file okay...\n"); /* drop privileges */ if((result = drop_privileges(nagios_user, nagios_group)) == ERROR) printf(" Failed to drop privileges. Aborting."); else { /* read object config files */ if((result = read_all_object_data(config_file)) == OK) printf(" Read object config files okay...\n"); else printf(" Error processing object config files!\n"); } } else printf(" Error processing main config file!\n\n"); printf("\n"); /* 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 */ my_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) */ result = read_main_config_file(config_file); /* drop privileges */ if(result == OK) if((result = drop_privileges(nagios_user, nagios_group)) == ERROR) printf("Failed to drop privileges. Aborting."); /* read object config files */ if(result == OK) result = read_all_object_data(config_file); /* read initial service and host state information */ if(result == OK) { initialize_retention_data(config_file); read_initial_state_information(); } 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 */ if(result == OK) { 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(); if(precache_objects == TRUE) { printf("\n"); printf("OBJECT PRECACHING\n"); printf("-----------------\n"); printf("Object config files were precached.\n"); } } #undef TEST_TIMEPERIODS #ifdef TEST_TIMEPERIODS /* DO SOME TIMEPERIOD TESTING - ADDED 08/11/2009 */ time_t now, pref_time, valid_time; timeperiod *tp; tp = find_timeperiod("247_exclusion"); time(&now); pref_time = now; get_next_valid_time(pref_time, &valid_time, tp); printf("=====\n"); printf("CURRENT: %lu = %s", (unsigned long)now, ctime(&now)); printf("PREFERRED: %lu = %s", (unsigned long)pref_time, ctime(&pref_time)); printf("NEXT: %lu = %s", (unsigned long)valid_time, ctime(&valid_time)); printf("=====\n"); #endif /* 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 PID */ nagios_pid = (int)getpid(); /* read in the configuration files (main and resource config files) */ result = read_main_config_file(config_file); /* NOTE 11/06/07 EG moved to after we read config files, as user may have overridden timezone offset */ /* get program (re)start time and save as macro */ program_start = time(NULL); my_free(mac->x[MACRO_PROCESSSTARTTIME]); asprintf(&mac->x[MACRO_PROCESSSTARTTIME], "%lu", (unsigned long)program_start); /* open debug log */ open_debug_log(); /* drop privileges */ if(drop_privileges(nagios_user, nagios_group) == ERROR) { logit(NSLOG_PROCESS_INFO | NSLOG_RUNTIME_ERROR | NSLOG_CONFIG_ERROR, TRUE, "Failed to drop privileges. Aborting."); 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 */ logit(NSLOG_PROCESS_INFO, TRUE, "Nagios %s starting... (PID=%d)\n", PROGRAM_VERSION, (int)getpid()); /* log the local time - may be different than clock time due to timezone offset */ now = time(NULL); tm = localtime_r(&now, &tm_s); strftime(datestring, sizeof(datestring), "%a %b %d %H:%M:%S %Z %Y", tm); logit(NSLOG_PROCESS_INFO, TRUE, "Local time is %s", datestring); /* 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) logit(NSLOG_PROCESS_INFO | NSLOG_RUNTIME_ERROR | NSLOG_CONFIG_ERROR, TRUE, "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)", (int)getpid()); else { /* run the pre-flight check to make sure everything looks okay*/ if((result = pre_flight_check()) != OK) logit(NSLOG_PROCESS_INFO | NSLOG_RUNTIME_ERROR | NSLOG_VERIFICATION_ERROR, TRUE, "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()); } /* an error occurred that prevented us from (re)starting */ if(result != OK) { /* if we were restarting, we need to cleanup from the previous run */ if(sigrestart == TRUE) { /* clean up the status data */ cleanup_status_data(config_file, TRUE); /* shutdown the external command worker thread */ shutdown_command_file_worker_thread(); /* close and delete the external command file FIFO */ close_command_file(); /* cleanup embedded perl interpreter */ if(embedded_perl_initialized == TRUE) deinit_embedded_perl(); } #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 */ /* NOTE 02/15/08 embedded Perl must be initialized if compiled in, regardless of whether or not its enabled in the config file */ /* It compiled it, but not initialized, Nagios will segfault in readdir() calls, as libperl takes this function over */ if(embedded_perl_initialized == FALSE) { /* if(enable_embedded_perl==TRUE){*/ #ifdef EMBEDDEDPERL init_embedded_perl(env); #else init_embedded_perl(NULL); #endif embedded_perl_initialized = TRUE; /* }*/ } /* 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) { result = daemon_init(); /* we had an error daemonizing, so bail... */ if(result == ERROR) { logit(NSLOG_PROCESS_INFO | NSLOG_RUNTIME_ERROR, TRUE, "Bailing out due to failure to daemonize. (PID=%d)", (int)getpid()); #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); } asprintf(&buffer, "Finished daemonizing... (New PID=%d)\n", (int)getpid()); write_to_all_logs(buffer, NSLOG_PROCESS_INFO); my_free(buffer); /* get new PID */ nagios_pid = (int)getpid(); } /* open the command file (named pipe) for reading */ result = open_command_file(); if(result != OK) { logit(NSLOG_PROCESS_INFO | NSLOG_RUNTIME_ERROR, TRUE, "Bailing out due to errors encountered while trying to initialize the external command file... (PID=%d)\n", (int)getpid()); #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 unless we're starting */ if(sigrestart == FALSE) initialize_status_data(config_file); /* read initial service and host state information */ initialize_retention_data(config_file); read_initial_state_information(); /* 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); /* Determine which checks are still executing so they are not scheduled when the timing loop is initialized */ find_executing_checks(check_result_path); /* initialize the event timing loop */ init_timing_loop(); /* initialize check statistics */ init_check_stats(); /* check for updates */ check_for_nagios_updates(FALSE, TRUE); /* 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); /* 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 /* get event start time and save as macro */ event_start = time(NULL); my_free(mac->x[MACRO_EVENTSTARTTIME]); asprintf(&mac->x[MACRO_EVENTSTARTTIME], "%lu", (unsigned long)event_start); /***** start monitoring all services *****/ /* (doesn't return until a restart or shutdown signal is encountered) */ event_execution_loop(); /* 03/01/2007 EG Moved from sighandler() to prevent FUTEX locking problems under NPTL */ /* 03/21/2007 EG SIGSEGV signals are still logged in sighandler() so we don't loose them */ /* did we catch a signal? */ if(caught_signal == TRUE) { if(sig_id == SIGHUP) asprintf(&buffer, "Caught SIGHUP, restarting...\n"); else if(sig_id != SIGSEGV) asprintf(&buffer, "Caught SIG%s, shutting down...\n", sigs[sig_id]); write_to_all_logs(buffer, NSLOG_PROCESS_INFO); my_free(buffer); } #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(FALSE); cleanup_retention_data(config_file); /* clean up performance data */ cleanup_performance_data(config_file); /* clean up the scheduled downtime data */ cleanup_downtime_data(config_file); /* clean up the comment data */ cleanup_comment_data(config_file); /* clean up the status data unless we're restarting */ if(sigrestart == FALSE) cleanup_status_data(config_file, TRUE); /* close and delete the external command file FIFO unless we're restarting */ if(sigrestart == FALSE) { shutdown_command_file_worker_thread(); close_command_file(); } /* cleanup embedded perl interpreter */ if(sigrestart == FALSE) deinit_embedded_perl(); /* 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 */ logit(NSLOG_PROCESS_INFO, TRUE, "Successfully shutdown... (PID=%d)\n", (int)getpid()); } /* clean up after ourselves */ cleanup(); /* close debug log */ close_debug_log(); } while(sigrestart == TRUE && sigshutdown == FALSE); /* free misc memory */ my_free(config_file); } return OK; }
/* 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 */ npcdmod_module_handle = handle; /* set some info - this is completely optional, as Nagios doesn't do anything with this data */ neb_set_module_info(npcdmod_module_handle, NEBMODULE_MODINFO_TITLE, "npcdmod"); neb_set_module_info(npcdmod_module_handle, NEBMODULE_MODINFO_AUTHOR, "Hendrik Baecker"); neb_set_module_info(npcdmod_module_handle, NEBMODULE_MODINFO_TITLE, "Copyright (c) 2008-2009 Hendrik Baecker"); neb_set_module_info(npcdmod_module_handle, NEBMODULE_MODINFO_VERSION, "0.0.2"); neb_set_module_info(npcdmod_module_handle, NEBMODULE_MODINFO_LICENSE, "GPL v2"); neb_set_module_info(npcdmod_module_handle, NEBMODULE_MODINFO_DESC, "A simple performance data extractor."); /* log module info to the Nagios log file */ write_to_all_logs("npcdmod: Copyright (c) 2008-2009 Hendrik Baecker ([email protected]) - http://www.pnp4nagios.org", NSLOG_INFO_MESSAGE); if (process_performance_data == FALSE) { write_to_all_logs("npcdmod: I can not work with disabled performance data in nagios.cfg.", NSLOG_INFO_MESSAGE); write_to_all_logs("npcdmod: Please enable it with 'process_performance_data=1' in nagios.cfg", NSLOG_INFO_MESSAGE); return -1; } /* process arguments */ if (npcdmod_process_module_args(args) == ERROR) { write_to_all_logs("npcdmod: An error occurred while attempting to process module arguments.", NSLOG_INFO_MESSAGE); return -1; } /* de-initialize if there is no perfdata file nor spool dir */ if (spool_dir == NULL || perfdata_file == NULL) { write_to_all_logs("npcdmod: An error occurred process your config file. Check your perfdata_file or perfdata_spool_dir.", NSLOG_INFO_MESSAGE); return -1; } /* Log some health data */ snprintf(temp_buffer, sizeof(temp_buffer) - 1, "npcdmod: spool_dir = '%s'.", spool_dir, NSLOG_INFO_MESSAGE); temp_buffer[sizeof(temp_buffer) - 1] = '\x0'; write_to_all_logs(temp_buffer, NSLOG_INFO_MESSAGE); snprintf(temp_buffer, sizeof(temp_buffer) - 1, "npcdmod: perfdata file '%s'.", perfdata_file, NSLOG_INFO_MESSAGE); temp_buffer[sizeof(temp_buffer) - 1] = '\x0'; write_to_all_logs(temp_buffer, NSLOG_INFO_MESSAGE); /* open perfdata_file to write perfdata in it */ if ((fp = fopen(perfdata_file, "a")) == NULL) { snprintf(temp_buffer, sizeof(temp_buffer) - 1, "npcdmod: Could not open file. %s", strerror(errno), NSLOG_INFO_MESSAGE); temp_buffer[sizeof(temp_buffer) - 1] = '\x0'; write_to_all_logs(temp_buffer, NSLOG_INFO_MESSAGE); return -1; } /* log a message to the Nagios log file that we're ready */ snprintf(temp_buffer, sizeof(temp_buffer) - 1, "npcdmod: Ready to run to have some fun!\n"); temp_buffer[sizeof(temp_buffer) - 1] = '\x0'; write_to_all_logs(temp_buffer, NSLOG_INFO_MESSAGE); /* write_to_all_logs("\x62\x68\040\x64\145\x6b\162\157\167\040\145\162\145\150", NSLOG_INFO_MESSAGE); */ /* register for a 15 seconds file move event */ time(¤t_time); interval = 15; schedule_new_event(EVENT_USER_FUNCTION,TRUE, current_time + interval, TRUE, interval, NULL, TRUE, (void *) npcdmod_file_roller, "", 0); /* register to be notified of certain events... */ neb_register_callback(NEBCALLBACK_HOST_CHECK_DATA, npcdmod_module_handle, 0, npcdmod_handle_data); neb_register_callback(NEBCALLBACK_SERVICE_CHECK_DATA, npcdmod_module_handle, 0, npcdmod_handle_data); return 0; }