int main(int argc, char **argv) { int result; int error = FALSE; char *buffer = NULL; int display_license = FALSE; int display_help = FALSE; int c = 0; struct tm *tm; time_t now; char datestring[256]; host *temp_host = NULL; hostgroup *temp_hostgroup = NULL; hostsmember *temp_member = NULL; plan(4); /* reset program variables */ reset_variables(); printf("Reading configuration data...\n"); config_file = strdup("smallconfig/icinga.cfg"); /* read in the configuration files (main config file, resource and object config files) */ result = read_main_config_file(config_file); ok(result == OK, "Read main configuration file okay - if fails, use icinga -v to check"); result = read_all_object_data(config_file); ok(result == OK, "Read all object config files"); result = pre_flight_check(); ok(result == OK, "Preflight check okay"); for (temp_hostgroup = hostgroup_list; temp_hostgroup != NULL; temp_hostgroup = temp_hostgroup->next) { c++; //printf("Hostgroup=%s\n", temp_hostgroup->group_name); } ok(c == 2, "Found all hostgroups"); temp_hostgroup = find_hostgroup("hostgroup1"); for (temp_member = temp_hostgroup->members; temp_member != NULL; temp_member = temp_member->next) { //printf("host pointer=%d\n", temp_member->host_ptr); } temp_hostgroup = find_hostgroup("hostgroup2"); for (temp_member = temp_hostgroup->members; temp_member != NULL; temp_member = temp_member->next) { //printf("host pointer=%d\n", temp_member->host_ptr); } cleanup(); my_free(config_file); return exit_status(); }
int main(int /*@unused@*/ argc, char /*@unused@*/ **arv) { const char *test_config_file = TESTDIR "naemon.cfg"; plan_tests(489); init_event_queue(); config_file_dir = nspath_absolute_dirname(test_config_file, NULL); assert(OK == read_main_config_file(test_config_file)); assert(OK == read_all_object_data(test_config_file)); assert(OK == initialize_downtime_data()); assert(OK == initialize_retention_data()); test_register(); test_parsing(); test_core_commands(); return exit_status(); }
int main(int argc, char **argv) { int result, warnings = 0, errors = 0; int c = 0; char *outfile = NULL; char *groups = NULL; char *cache_file = NULL; #ifdef HAVE_GETOPT_H int option_index; struct option long_options[] = { {"help", no_argument, 0, 'h' }, {"version", no_argument, 0, 'v' }, {"quiet", no_argument, 0, 'q' }, {"groups", required_argument, 0, 'g' }, {"include", required_argument, 0, 'i' }, {"outfile", required_argument, 0, 'o' }, {"naemon-cfg", required_argument, 0, 'c' }, {"force", no_argument, 0, 'f' }, { 0, 0, 0, 0 } }; #define getopt(a, b, c) getopt_long(a, b, c, long_options, &option_index) #endif self_name = strdup(basename(argv[0])); /* make sure we have the correct number of command line arguments */ if (argc < 2) { usage("Not enough arguments.\n"); } reset_variables(); enable_timing_point = 1; for (;;) { c = getopt(argc, argv, "hVqvfg:i:o:O:"); if (c < 0 || c == EOF) break; switch (c) { case 'v': case 'V': printf("oconfsplit version %s", PROGRAM_VERSION); break; case 'h': case '?': usage(NULL); break; case 'o': outfile = optarg; break; case 'c': config_file = optarg; break; case 'g': groups = optarg; break; case 'q': verbose = 0; enable_timing_point = 0; break; case 'O': cache_file = optarg; break; case 'f': /* force = 1;, but ignored for now */ break; default: usage("Unknown argument\n"); exit(EXIT_FAILURE); } } if (outfile) { fp = fopen(outfile, "w"); if (!fp) { printf("Failed to open '%s' for writing: %m\n", outfile); exit(EXIT_FAILURE); } } else if (groups) { usage("Can't cache groups without an outfile. Try again, will ya?\n"); } if (!groups && !cache_file) { usage("No groups specified. Redo from start\n"); } if (!config_file) { if (optind >= argc) config_file = strdup(get_default_config_file()); else config_file = argv[optind]; } if (!config_file) { printf("Something went horribly wrong there. What the hells...\n"); exit(EXIT_FAILURE); } timing_point("Loading configuration...\n"); /* * config file is last argument specified. * Make sure it uses an absolute path */ config_file = nspath_absolute(config_file, NULL); if (config_file == NULL) { printf("Error allocating memory.\n"); exit(EXIT_FAILURE); } config_file_dir = nspath_absolute_dirname(config_file, NULL); /* never log anything anywhere */ use_syslog = FALSE; log_file = NULL; close_log_file(); /* we ignore errors from here */ if (!cache_file) read_main_config_file(config_file); /* order: named cache > cache > precache > "raw" config */ use_precached_objects = FALSE; if (cache_file && !access(cache_file, R_OK)) { use_precached_objects = TRUE; object_precache_file = cache_file; } else if (object_cache_file && !access(object_cache_file, R_OK)) { /* use the right one but prevent double free */ object_precache_file = object_cache_file; object_cache_file = NULL; use_precached_objects = TRUE; } else if (object_precache_file && !access(object_precache_file, R_OK)) { use_precached_objects = TRUE; } if (verbose && use_precached_objects) { printf("Using cached objects from %s\n", object_precache_file); } /* read object config files */ result = read_all_object_data(config_file); if (result != OK) { printf(" Error processing object config files. Bailing out\n"); exit(EXIT_FAILURE); } timing_point("Config data read\n"); /* run object pre-flight checks only */ if (pre_flight_object_check(&warnings, &errors) != OK) { printf("Pre-flight check failed. Bailing out\n"); exit(EXIT_FAILURE); } if (pre_flight_circular_check(&warnings, &errors) != OK) { printf("Pre-flight circular check failed. Bailing out\n"); exit(EXIT_FAILURE); } if (cache_file && !groups) { if (verbose || !outfile) printf("%u objects check out ok\n", ocount_total(&num_objects)); if (outfile) { fcache_objects(outfile); printf("%u objects sorted and cached to %s\n", ocount_total(&num_objects), outfile); } exit(EXIT_SUCCESS); } /* create our tracker maps */ htrack = bitmap_create(num_objects.hosts); map.hosts = bitmap_create(num_objects.hosts); map.commands = bitmap_create(num_objects.commands); map.timeperiods = bitmap_create(num_objects.timeperiods); map.contacts = bitmap_create(num_objects.contacts); map.contactgroups = bitmap_create(num_objects.contactgroups); map.hostgroups = bitmap_create(num_objects.hostgroups); /* global commands are always included */ nsplit_cache_command(ochp_command_ptr); nsplit_cache_command(ocsp_command_ptr); nsplit_cache_command(global_host_event_handler_ptr); nsplit_cache_command(global_service_event_handler_ptr); nsplit_cache_command(find_command(host_perfdata_command)); nsplit_cache_command(find_command(service_perfdata_command)); nsplit_cache_command(find_command(host_perfdata_file_processing_command)); nsplit_cache_command(find_command(service_perfdata_file_processing_command)); if (nsplit_cache_stuff(groups) < 0) { printf("Caching failed. Bailing out\n"); return EXIT_FAILURE; } timing_point("Done caching essentials\n"); nsplit_partial_groups(); timing_point("Done caching partial groups\n"); fflush(fp); if (fp != stdout) fclose(fp); /* valgrind shush factor 1000 */ cleanup(); timing_point("Done cleaning up. Exiting\n"); /* exit */ printf("%u objects cached to %s\n", ocount_total(&cached) + ocount_total(&partial), outfile); return EXIT_SUCCESS; }
int main(int argc, char **argv) { int result; int error = FALSE; 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; } } /* if we're a worker we can skip everything below */ if (worker_socket) { exit(nagios_core_worker(worker_socket)); } if (daemon_mode == FALSE) { printf("\nNaemon Core %s\n", PROGRAM_VERSION); printf("Copyright (c) 2013-present Naemon Core Development Team and Community Contributors\n"); printf("Copyright (c) 2009-2013 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.naemon.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 Naemon 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 Naemon website at http://www.naemon.org/ for bug fixes, new\n"); printf("releases, online documentation, FAQs and more...\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); } config_file_dir = nspath_absolute_dirname(config_file, NULL); /* * 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); /* * 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(naemon_user, naemon_group)) == ERROR) { printf(" Failed to drop privileges. Aborting."); exit(EXIT_FAILURE); } /* * this must come after dropping privileges, so we make * sure to test access permissions as the right user. */ if (test_configured_paths() == ERROR) { printf(" One or more path problems detected. Aborting.\n"); 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, "naemon.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 Naemon, 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 Naemon, 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"); /* make valgrind shut up about still reachable memory */ neb_free_module_list(); free(config_file_dir); free(config_file); exit(result); } /* start to monitor things... */ /* * 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], '/')) naemon_binary_path = nspath_absolute(argv[0], NULL); else naemon_binary_path = strdup(argv[0]); if (!naemon_binary_path) { logit(NSLOG_RUNTIME_ERROR, TRUE, "Error: Unable to allocate memory for naemon_binary_path\n"); exit(EXIT_FAILURE); } if (!(nagios_iobs = iobroker_create())) { logit(NSLOG_RUNTIME_ERROR, TRUE, "Error: Failed to create IO broker set: %s\n", strerror(errno)); exit(EXIT_FAILURE); } /* keep monitoring things until we get a shutdown command */ do { /* reset internal book-keeping (in case we're restarting) */ wproc_num_workers_spawned = wproc_num_workers_online = 0; caught_signal = sigshutdown = sigrestart = FALSE; sig_id = 0; /* 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); if (result != OK) { logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Failed to process config file '%s'. Aborting\n", config_file); exit(EXIT_FAILURE); } 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); /* drop privileges */ if (drop_privileges(naemon_user, naemon_group) == ERROR) { logit(NSLOG_PROCESS_INFO | NSLOG_RUNTIME_ERROR | NSLOG_CONFIG_ERROR, TRUE, "Failed to drop privileges. Aborting."); cleanup(); exit(ERROR); } if (test_path_access(naemon_binary_path, X_OK)) { logit(NSLOG_RUNTIME_ERROR, TRUE, "Error: failed to access() %s: %s\n", naemon_binary_path, strerror(errno)); logit(NSLOG_RUNTIME_ERROR, TRUE, "Error: Spawning workers will be impossible. Aborting.\n"); exit(EXIT_FAILURE); } if (test_configured_paths() == ERROR) { /* error has already been logged */ exit(EXIT_FAILURE); } /* 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()); cleanup(); exit(EXIT_FAILURE); } /* get new PID */ nagios_pid = (int)getpid(); } /* this must be logged after we read config data, as user may have changed location of main log file */ logit(NSLOG_PROCESS_INFO, TRUE, "Naemon %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); /* open debug log now that we're the right user */ open_debug_log(); #ifdef USE_EVENT_BROKER /* initialize modules */ neb_init_modules(); neb_init_callback_list(); #endif timing_point("NEB module API initialized\n"); /* 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 */ if (qh_init(qh_socket_path ? qh_socket_path : DEFAULT_QUERY_SOCKET) != OK) { logit(NSLOG_RUNTIME_ERROR, TRUE, "Error: Failed to initialize query handler. Aborting\n"); exit(EXIT_FAILURE); } 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(); /* read in all object config data */ if (result == OK) result = read_all_object_data(config_file); /* * the queue has to be initialized befor loading the neb modules * to give them the chance to register user events. * (initializing event queue requires number of objects, so do * this after parsing the objects) */ init_event_queue(); timing_point("Event queue initialized\n"); #ifdef USE_EVENT_BROKER /* load modules */ if (neb_load_all_modules() != OK) { logit(NSLOG_CONFIG_ERROR, ERROR, "Error: Module loading failed. Aborting.\n"); /* if we're dumping core, we must remove all dl-files */ if (daemon_dumps_core) neb_unload_all_modules(NEBMODULE_FORCE_UNLOAD, NEBMODULE_NEB_SHUTDOWN); exit(EXIT_FAILURE); } 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 /* 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 Naemon 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 Naemon 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(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"); #ifdef USE_EVENT_BROKER /* send program data to broker */ broker_program_state(NEBTYPE_PROCESS_START, NEBFLAG_NONE, NEBATTR_NONE, NULL); #endif /* initialize status data unless we're starting */ if (sigrestart == FALSE) { initialize_status_data(config_file); timing_point("Status data initialized\n"); } /* initialize scheduled downtime data */ initialize_downtime_data(); timing_point("Downtime 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(); timing_point("Comment 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"); /* 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(); /* * immediately deinitialize the query handler so it * can remove modules that have stashed data with it */ qh_deinit(qh_socket_path ? qh_socket_path : DEFAULT_QUERY_SOCKET); /* 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 disconnect_command_file_worker(); /* save service and host state information */ save_state_information(FALSE); cleanup_retention_data(); /* clean up performance data */ cleanup_performance_data(); /* clean up the scheduled downtime data */ cleanup_downtime_data(); /* clean up the status data unless we're restarting */ if (sigrestart == FALSE) { cleanup_status_data(TRUE); } free_worker_memory(WPROC_FORCE); /* shutdown stuff... */ if (sigshutdown == TRUE) { iobroker_destroy(nagios_iobs, IOBROKER_CLOSE_SOCKETS); nagios_iobs = NULL; /* 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); if (daemon_mode == TRUE) unlink(lock_file); /* free misc memory */ my_free(lock_file); my_free(config_file); my_free(config_file_dir); my_free(naemon_binary_path); return OK; }
int main(int argc, char **argv) { int result; int error = FALSE; char *buffer = NULL; int display_license = FALSE; int display_help = FALSE; int c = 0; struct tm *tm; time_t current_time; time_t test_time; time_t saved_test_time; time_t next_valid_time = 0L; time_t chosen_valid_time = 0L; char datestring[256]; host *temp_host = NULL; hostgroup *temp_hostgroup = NULL; hostsmember *temp_member = NULL; timeperiod *temp_timeperiod = NULL; int is_valid_time = 0; int iterations = 1000; plan_tests(6043); /* reset program variables */ reset_variables(); printf("Reading configuration data...\n"); config_file = strdup("smallconfig/icinga.cfg"); /* read in the configuration files (main config file, resource and object config files) */ result = read_main_config_file(config_file); ok(result == OK, "Read main configuration file okay - if fails, use icinga -v to check"); result = read_all_object_data(config_file); ok(result == OK, "Read all object config files"); result = pre_flight_check(); ok(result == OK, "Preflight check okay"); time(¤t_time); test_time = current_time; saved_test_time = current_time; temp_timeperiod = find_timeperiod("none"); is_valid_time = check_time_against_period(test_time, temp_timeperiod); ok(is_valid_time == ERROR, "No valid time because time period is empty"); get_next_valid_time(current_time, &next_valid_time, temp_timeperiod); ok((next_valid_time - current_time) <= 2, "Next valid time should be the current_time, but with a 2 second tolerance"); temp_timeperiod = find_timeperiod("24x7"); is_valid_time = check_time_against_period(test_time, temp_timeperiod); ok(is_valid_time == OK, "Fine because 24x7"); get_next_valid_time(current_time, &next_valid_time, temp_timeperiod); ok(current_time == next_valid_time, "Current time should be the next valid time"); /* 2009-10-25 is the day when clocks go back an hour in Europe. Bug happens during 23:00 to 00:00 */ /* This is 23:01:01 */ saved_test_time = 1256511661; saved_test_time = saved_test_time - (24 * 60 * 60); putenv("TZ=UTC"); tzset(); test_time = saved_test_time; c = 0; while (c < iterations) { is_valid_time = check_time_against_period(test_time, temp_timeperiod); ok(is_valid_time == OK, "Always OK for 24x7 with TZ=UTC"); chosen_valid_time = 0L; _get_next_valid_time(test_time, test_time, &chosen_valid_time, temp_timeperiod); ok(test_time == chosen_valid_time, "get_next_valid_time always returns same time"); test_time += 1800; c++; } putenv("TZ=Europe/London"); tzset(); test_time = saved_test_time; c = 0; while (c < iterations) { is_valid_time = check_time_against_period(test_time, temp_timeperiod); ok(is_valid_time == OK, "Always OK for 24x7 with TZ=Europe/London"); _get_next_valid_time(test_time, test_time, &chosen_valid_time, temp_timeperiod); ok(test_time == chosen_valid_time, "get_next_valid_time always returns same time, time_t=%lu", test_time); test_time += 1800; c++; } /* 2009-11-01 is the day when clocks go back an hour in America. Bug happens during 23:00 to 00:00 */ /* This is 23:01:01 */ saved_test_time = 1256511661; saved_test_time = saved_test_time - (24 * 60 * 60); putenv("TZ=America/New_York"); tzset(); test_time = saved_test_time; c = 0; while (c < iterations) { is_valid_time = check_time_against_period(test_time, temp_timeperiod); ok(is_valid_time == OK, "Always OK for 24x7 with TZ=America/New_York"); _get_next_valid_time(test_time, test_time, &chosen_valid_time, temp_timeperiod); ok(test_time == chosen_valid_time, "get_next_valid_time always returns same time, time_t=%lu", test_time); test_time += 1800; c++; } /* Tests around clock change going back for TZ=Europe/London. 1256511661 = Sun Oct 25 23:01:01 2009 */ /* A little trip to Paris*/ putenv("TZ=Europe/Paris"); tzset(); /* Timeperiod exclude tests, from Jean Gabes */ temp_timeperiod = find_timeperiod("Test_exclude"); ok(temp_timeperiod != NULL, "ME: Testing Exclude timeperiod"); test_time = 1278939600; /* printf("Testing at time %s", ctime(&test_time)); */ is_valid_time = check_time_against_period(test_time, temp_timeperiod); ok(is_valid_time == ERROR, "ME: 12 Jul 2010 15:00:00 - false"); _get_next_valid_time(test_time, test_time, &chosen_valid_time, temp_timeperiod); /* printf("JEAN: Got chosent time at %s", ctime(&chosen_valid_time)); */ todo_start("Bug in exclude"); ok(chosen_valid_time == 1288103400, "ME: Next valid time=Tue Oct 26 16:30:00 2010"); todo_end(); temp_timeperiod = find_timeperiod("Test_exclude2"); ok(temp_timeperiod != NULL, "ME: Testing Exclude timeperiod 2"); test_time = 1278939600; /* printf("Testing at time %s", ctime(&test_time)); */ is_valid_time = check_time_against_period(test_time, temp_timeperiod); ok(is_valid_time == ERROR, "ME: 12 Jul 2010 15:00:00 - false"); _get_next_valid_time(test_time, test_time, &chosen_valid_time, temp_timeperiod); /* printf("JEAN: Got chosent time at %s", ctime(&chosen_valid_time)); */ todo_start("Bug in exclude 2"); ok(chosen_valid_time == 1279058340, "ME: Next valid time=Tue Jul 13 23:59:00 2010"); todo_end(); temp_timeperiod = find_timeperiod("Test_exclude3"); ok(temp_timeperiod != NULL, "ME: Testing Exclude timeperiod 3"); test_time = 1278939600; /* printf("Testing at time %s", ctime(&test_time)); */ is_valid_time = check_time_against_period(test_time, temp_timeperiod); ok(is_valid_time == ERROR, "ME: 12 Jul 2010 15:00:00 - false"); _get_next_valid_time(test_time, test_time, &chosen_valid_time, temp_timeperiod); /* printf("JEAN: Got chosent time at %s", ctime(&chosen_valid_time)); */ todo_start("Bug in exclude 3"); ok(chosen_valid_time == 1284474600, "ME: Next valid time=Tue Sep 14 16:30:00 2010"); todo_end(); temp_timeperiod = find_timeperiod("Test_exclude4"); ok(temp_timeperiod != NULL, "ME: Testing Exclude timeperiod 4"); test_time = 1278939600; /* printf("Testing at time %s", ctime(&test_time)); */ is_valid_time = check_time_against_period(test_time, temp_timeperiod); ok(is_valid_time == ERROR, "ME: 12 Jul 2010 15:00:00 - false"); _get_next_valid_time(test_time, test_time, &chosen_valid_time, temp_timeperiod); /* printf("JEAN: Got chosent time at %s", ctime(&chosen_valid_time)); */ todo_start("Bug in exclude 3"); ok(chosen_valid_time == 1283265000, "ME: Next valid time=Tue Aug 31 16:30:00 2010"); todo_end(); /* Back to New york */ putenv("TZ=America/New_York"); tzset(); temp_timeperiod = find_timeperiod("sunday_only"); ok(temp_timeperiod != NULL, "Testing Sunday 00:00-01:15,03:15-22:00"); putenv("TZ=Europe/London"); tzset(); test_time = 1256421000; is_valid_time = check_time_against_period(test_time, temp_timeperiod); ok(is_valid_time == ERROR, "Sat Oct 24 22:50:00 2009 - false"); _get_next_valid_time(test_time, test_time, &chosen_valid_time, temp_timeperiod); ok(chosen_valid_time == 1256425200, "Next valid time=Sun Oct 25 00:00:00 2009"); test_time = 1256421661; is_valid_time = check_time_against_period(test_time, temp_timeperiod); ok(is_valid_time == ERROR, "Sat Oct 24 23:01:01 2009 - false"); _get_next_valid_time(test_time, test_time, &chosen_valid_time, temp_timeperiod); ok(chosen_valid_time == 1256425200, "Next valid time=Sun Oct 25 00:00:00 2009"); test_time = 1256425400; is_valid_time = check_time_against_period(test_time, temp_timeperiod); ok(is_valid_time == OK, "Sun Oct 25 00:03:20 2009 - true"); _get_next_valid_time(test_time, test_time, &chosen_valid_time, temp_timeperiod); ok(chosen_valid_time == test_time, "Next valid time=Sun Oct 25 00:03:20 2009"); test_time = 1256429700; is_valid_time = check_time_against_period(test_time, temp_timeperiod); ok(is_valid_time == OK, "Sun Oct 25 01:15:00 2009 - true"); _get_next_valid_time(test_time, test_time, &chosen_valid_time, temp_timeperiod); ok(chosen_valid_time == test_time, "Next valid time=Sun Oct 25 01:15:00 2009"); test_time = 1256430400; is_valid_time = check_time_against_period(test_time, temp_timeperiod); ok(is_valid_time == ERROR, "Sun Oct 25 01:26:40 2009 - false"); _get_next_valid_time(test_time, test_time, &chosen_valid_time, temp_timeperiod); todo_start("Is a bug in get_next_valid_time for a time that falls in the DST change hour period"); ok(chosen_valid_time == 1256440500, "Next valid time=Sun Oct 25 03:15:00 2009") || printf("chosen_valid_time=%lu\n", chosen_valid_time); todo_end(); test_time = 1256440500; is_valid_time = check_time_against_period(test_time, temp_timeperiod); ok(is_valid_time == OK, "Sun Oct 25 03:15:00 2009 - true"); _get_next_valid_time(test_time, test_time, &chosen_valid_time, temp_timeperiod); ok(chosen_valid_time == test_time, "Next valid time=Sun Oct 25 03:15:00 2009"); test_time = 1256500000; is_valid_time = check_time_against_period(test_time, temp_timeperiod); ok(is_valid_time == OK, "Sun Oct 25 19:46:40 2009 - true"); _get_next_valid_time(test_time, test_time, &chosen_valid_time, temp_timeperiod); ok(chosen_valid_time == 1256500000, "Next valid time=Sun Oct 25 19:46:40 2009"); test_time = 1256508000; is_valid_time = check_time_against_period(test_time, temp_timeperiod); ok(is_valid_time == OK, "Sun Oct 25 22:00:00 2009 - true"); _get_next_valid_time(test_time, test_time, &chosen_valid_time, temp_timeperiod); ok(chosen_valid_time == 1256508000, "Next valid time=Sun Oct 25 22:00:00 2009"); test_time = 1256508001; is_valid_time = check_time_against_period(test_time, temp_timeperiod); ok(is_valid_time == ERROR, "Sun Oct 25 22:00:01 2009 - false"); //_get_next_valid_time(test_time, test_time, &chosen_valid_time, temp_timeperiod); _get_next_valid_time_per_timeperiod(test_time, &chosen_valid_time, test_time, temp_timeperiod); ok(chosen_valid_time == 1257033600, "Next valid time=Sun Nov 1 00:00:00 2009"); test_time = 1256513000; is_valid_time = check_time_against_period(test_time, temp_timeperiod); ok(is_valid_time == ERROR, "Sun Oct 25 23:23:20 2009 - false"); //_get_next_valid_time(test_time, test_time, &chosen_valid_time, temp_timeperiod); _get_next_valid_time_per_timeperiod(test_time, &chosen_valid_time, test_time, temp_timeperiod); ok(chosen_valid_time == 1257033600, "Next valid time=Sun Nov 1 00:00:00 2009"); temp_timeperiod = find_timeperiod("weekly_complex"); ok(temp_timeperiod != NULL, "Testing complex weekly timeperiod definition"); putenv("TZ=America/New_York"); tzset(); test_time = 1268109420; is_valid_time = check_time_against_period(test_time, temp_timeperiod); ok(is_valid_time == ERROR, "Mon Mar 8 23:37:00 2010 - false"); //_get_next_valid_time(test_time, test_time, &chosen_valid_time, temp_timeperiod); _get_next_valid_time_per_timeperiod(test_time, &chosen_valid_time, test_time, temp_timeperiod); ok(chosen_valid_time == 1268115300, "Next valid time=Tue Mar 9 01:15:00 2010"); cleanup(); my_free(config_file); return exit_status(); }
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; #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'}, {0, 0, 0, 0} }; #define getopt(argc, argv, o) getopt_long(argc, argv, o, long_options, &option_index) #endif 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, "+hVvdspuxT"); 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 'x': printf("Warning: -x is deprecated and will be removed\n"); break; default: break; } } #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 (-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(" -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\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); } /* 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); } /* * 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(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 '/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"); 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 { nagios_iobs = iobroker_create(); /* keep monitoring things until we get a shutdown command */ do { init_event_queue(); /* 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); } #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); } /* write the objects.cache file */ fcache_objects(object_cache_file); /* 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(); } /* 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); /* 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; /* fire up command file worker */ launch_command_file_worker(); /* @TODO: get number of workers from config */ init_workers(4); #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) 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); /* 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 main(int argc, char **argv) { int result; int error = FALSE; char *buffer = NULL; int display_license = FALSE; int display_help = FALSE; int c = 0; struct tm *tm; time_t now; char datestring[256]; host *temp_host = NULL; hostgroup *temp_hostgroup = NULL; hostsmember *temp_member = NULL; plan_tests(14); /* reset program variables */ reset_variables(); printf("Reading configuration data...\n"); config_file = strdup("smallconfig/nagios.cfg"); /* read in the configuration files (main config file, resource and object config files) */ result = read_main_config_file(config_file); ok(result == OK, "Read main configuration file okay - if fails, use nagios -v to check"); result = read_all_object_data(config_file); ok(result == OK, "Read all object config files"); result = pre_flight_check(); ok(result == OK, "Preflight check okay"); for(temp_hostgroup = hostgroup_list; temp_hostgroup != NULL; temp_hostgroup = temp_hostgroup->next) { c++; //printf("Hostgroup=%s\n", temp_hostgroup->group_name); } ok(c == 2, "Found all hostgroups"); temp_hostgroup = find_hostgroup("hostgroup1"); for(temp_member = temp_hostgroup->members; temp_member != NULL; temp_member = temp_member->next) { //printf("host pointer=%d\n", temp_member->host_ptr); } temp_hostgroup = find_hostgroup("hostgroup2"); for(temp_member = temp_hostgroup->members; temp_member != NULL; temp_member = temp_member->next) { //printf("host pointer=%d\n", temp_member->host_ptr); } temp_host = find_host("host1"); ok(temp_host->current_state == 0, "State is assumed OK on initial load"); xrddefault_retention_file = strdup("smallconfig/retention.dat"); ok(xrddefault_read_state_information() == OK, "Reading retention data"); ok(temp_host->current_state == 1, "State changed due to retention file settings"); ok(find_host_comment(418) != NULL, "Found host comment id 418"); ok(find_service_comment(419) != NULL, "Found service comment id 419"); ok(find_service_comment(420) == NULL, "Did not find service comment id 420 as not persistent"); ok(find_host_comment(1234567888) == NULL, "No such host comment"); ok(find_host_downtime(1102) != NULL, "Found host downtime id 1102"); ok(find_service_downtime(1110) != NULL, "Found service downtime 1110"); ok(find_host_downtime(1234567888) == NULL, "No such host downtime"); cleanup(); my_free(config_file); return exit_status(); }
/***************************************************************************** * 开始main主函数。**env是为了兼容5.00503版本的perl *****************************************************************************/ 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; /* 获得nagios的宏, 此函数为link ../common/macros.o文件的函数 */ mac = get_global_macros(); /***************************************************************************** * 下面部分处理命令行参数 *****************************************************************************/ /* 如果是设置了HAVE_GETOPT_H这种常量,就创建一个结构体,便于后边的系统调用getopt_long()使用 */ #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 */ /* 如果命令行参数小于2,则标记error */ if(argc < 2) error = TRUE; /* get all command line arguments */ /* 获取所有命令行参数 */ while(1) { #ifdef HAVE_GETOPT_H /* getopt.h 是系统调用,可以man getopt_long */ /* ref: http://blog.163.com/hbu_lijian/blog/static/126129153201276246640/ */ /* ref: http://www.examw.com/linux/all/142179/index-2.html */ c = getopt_long(argc, argv, "+hVvdsoxpu", long_options, &option_index); #else c = getopt(argc, argv, "+hVvdsoxpu"); #endif /* 如果getopt分析完了,没有选项了,就会返回-1,那么就退出这个循环 */ 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 /* 如果采用非daemon模式,那么就先打印一些信息 */ if(daemon_mode == FALSE) { /* DELETE by Henry Ni [email protected] */ /* 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 */ /* 如果是license模式,那么就先打印一些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... */ /* optind 是getopt_long的全局变量,当函数分析完所有参数时,全局变量optind(into argv)会指向第一个‘非选项’的位置 */ if(optind >= argc) error = TRUE; /* if there are no command line options (or if we encountered an error), print usage */ /* 将上面的error,统一打印错误信息,并且退出程序 */ 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); } /* config file is last argument specified */ /* 系统调用string.h里面定义的,他的作用是复制字符串,可以 man strdup*/ /* 这历史argv[optind]来表示最后一个参数,然后赋值这个config文件路径。*/ 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 */ /* config文件必须全路径,下面的程序转换相对路径为全路径。 */ 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 */ /* 重置程序参数, 在nagios.h中声明了此函数. */ reset_variables(); #ifdef CHINESE printf("读取配置文件中...\n"); #else printf("Reading configuration data...\n"); #endif /* read in the configuration files (main config file, resource and object config files) */ /* nagios.h中定义,读取配置文件 */ if((result = read_main_config_file(config_file)) == OK) { #ifdef CHINESE printf("主配置文件读取完毕...\n"); #else printf("Read main config file okay...\n"); #endif /* drop privileges */ /* nagios.h中定义,检查文件的时候采用nagios_user去检查 */ if((result = drop_privileges(nagios_user, nagios_group)) == ERROR) { #ifdef CHINESE printf(" 用户nagios_user无法读取配置文件."); #else printf(" Failed to drop privileges. Aborting."); #endif } else { /* read object config files */ /* nagios.h中声明,config.c中定义 */ if((result = read_all_object_data(config_file)) == OK) { #ifdef CHINESE printf(" 读取对象定义文件成功...\n"); #else printf(" Read object config files okay...\n"); #endif } else { #ifdef CHINESE printf(" 处理对象定义文件失败!\n"); #else printf(" Error processing object config files!\n"); #endif } } } else { #ifdef CHINESE printf(" 主配置文件错误!\n\n"); #else printf(" Error processing main config file!\n\n"); #endif } printf("\n"); /* there was a problem reading the config files */ /* 下面处理结果为错误的情况 */ if(result != OK) { /* if the config filename looks fishy, warn the user */ /* man strstr 在字符串中找到指定的字符串,这里找的是nagios.cfg */ if(!strstr(config_file, "nagios.cfg")) { #ifdef CHINESE printf("\n***> 主配置文件名称错误...\n"); printf("\n"); printf(" 默认的主配置文件位置:'/usr/local/nagios/etc/nagios.cfg'\n"); #else 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"); #endif } #ifdef CHINESE printf("\n***> 主配置文件处理的时候发生错误...\n"); #else 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"); #endif } /* the config files were okay, so run the pre-flight check */ /* 主配置文件检查正确之后,执行预处理检查 */ else { #ifdef CHINESE printf("开始预处理...\n\n"); #else printf("Running pre-flight check on configuration data...\n\n"); #endif /* run the pre-flight check to make sure things look okay... */ /* 开始执行pre_flight_check(),在config.c里面定义函数... */ result = pre_flight_check(); if(result == OK) #ifdef CHINESE printf("\n预处理检查成功。\n"); #else printf("\nThings look okay - No serious problems were detected during the pre-flight check\n"); #endif else { #ifdef CHINESE printf("\n***> 预处理检查发现错误...\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"); #endif } }
int main(int argc, char **argv) { int result; int c = 0; struct host *host1, *host2; hostgroup *temp_hostgroup = NULL; hostsmember *temp_member = NULL; plan_tests(19); /* reset program variables */ reset_variables(); /* * avoid updating the checked-in retention data * file when testing */ retain_state_information = FALSE; printf("Reading configuration data...\n"); config_file = strdup(get_default_config_file()); config_file_dir = nspath_absolute_dirname(config_file, NULL); /* read in the configuration files (main config file, resource and object config files) */ result = read_main_config_file(config_file); ok(result == OK, "Read main configuration file okay - if fails, use nagios -v to check"); result = read_all_object_data(config_file); ok(result == OK, "Read all object config files"); result = pre_flight_check(); ok(result == OK, "Preflight check okay"); for (temp_hostgroup = hostgroup_list; temp_hostgroup != NULL; temp_hostgroup = temp_hostgroup->next) { c++; //printf("Hostgroup=%s\n", temp_hostgroup->group_name); } ok(c == 2, "Found all hostgroups"); temp_hostgroup = find_hostgroup("hostgroup1"); for (temp_member = temp_hostgroup->members; temp_member != NULL; temp_member = temp_member->next) { //printf("host pointer=%d\n", temp_member->host_ptr); } temp_hostgroup = find_hostgroup("hostgroup2"); for (temp_member = temp_hostgroup->members; temp_member != NULL; temp_member = temp_member->next) { //printf("host pointer=%d\n", temp_member->host_ptr); } host1 = find_host("host1"); host2 = find_host("host2"); ok(host1 != NULL && host2 != NULL, "find_host() should work"); ok(host1->current_state == 0, "State is assumed OK on initial load"); ok(host1->notifications_enabled == 1, "host1 notifications_enabled set from config"); ok(host2->notifications_enabled == 1, "host2 notifications_enabled set from config"); initialize_retention_data(NULL); initialize_downtime_data(); init_event_queue(); ok(xrddefault_read_state_information() == OK, "Reading retention data"); ok(host1->current_state == 1, "State changed due to retention file settings"); ok(host1->notifications_enabled == 1, "Config change should override notifications_enabled for host1"); ok(host2->notifications_enabled == 0, "Retention data should win on no config change"); ok(find_host_comment(418) != NULL, "Found host comment id 418"); ok(find_service_comment(419) != NULL, "Found service comment id 419"); ok(find_service_comment(420) == NULL, "Did not find service comment id 420 as not persistent"); ok(find_host_comment(1234567888) == NULL, "No such host comment"); ok(find_host_downtime(1102) != NULL, "Found host downtime id 1102"); ok(find_service_downtime(1110) != NULL, "Found service downtime 1110"); ok(find_host_downtime(1234567888) == NULL, "No such host downtime"); cleanup(); my_free(config_file); return exit_status(); }
/* 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]; icinga_macros *mac; #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'}, {"show-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 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) { #ifdef HAVE_GETOPT_H c = getopt_long(argc, argv, "+hVvdsoxpuS", long_options, &option_index); #else c = getopt(argc, argv, "+hVvdsoxpuS"); #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++; break; case 's': /* scheduling check */ test_scheduling = TRUE; break; case 'S': /* scheduling check and show queue*/ show_schedule = TRUE; 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 == 0)) { error = TRUE; display_help = TRUE; } #ifdef DEBUG_MEMORY mtrace(); #endif if (daemon_mode == FALSE) { printf("\n%s %s\n", PROGRAM_NAME , PROGRAM_VERSION); printf("Copyright (c) 2009-present Icinga Development Team (http://www.icinga.org)\n"); printf("Copyright (c) 2009-2013 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"); } /* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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(" -S, --show-scheduling Same as -s, but also show the scheduling queue\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 %s in daemon mode, instead of as a foreground process\n", PROGRAM_NAME); printf("\n"); printf("Visit the %s website at http://www.icinga.org/ for bug fixes, new\n", PROGRAM_NAME); printf("releases, online documentation, FAQs, information on subscribing to\n"); printf("the mailing lists, and commercial support options for %s.\n", PROGRAM_NAME); 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 */ 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) { /* 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") && !strstr(config_file, "icinga.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/icinga/etc/icinga.cfg'\n"); printf(" or if using packages, most likely '/etc/icinga/icinga.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 definitions. If you are upgrading from a previous\n"); printf(" version of %s, you should be aware that some variables/definitions\n", PROGRAM_NAME); 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 and the Changelog CHANGES section as well to find\n"); printf(" 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 definitions. If you are upgrading from a previous\n"); printf(" version of %s, you should be aware that some variables/definitions\n", PROGRAM_NAME); 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 schedule */ if (show_schedule == TRUE) display_schedule(); /* 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) */ if (read_main_config_file(config_file) == ERROR) { logit(NSLOG_PROCESS_INFO | NSLOG_RUNTIME_ERROR | NSLOG_CONFIG_ERROR, TRUE, "Failed to read main config file. Aborting."); cleanup(); exit(EXIT_FAILURE); } /* we need to read the modules in the first place as object configuration before neb modules are initialized/loaded */ result = read_object_config_data(config_file, READ_MODULES, FALSE, FALSE); /* add modules to neb */ result = add_module_objects_to_neb(); /* 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, "%s %s starting... (PID=%d)\n", PROGRAM_NAME, 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 */ if (neb_load_all_modules() != OK) { logit(NSLOG_CONFIG_ERROR, ERROR, "Error: NEB module loading failed. Aborting.\n"); if (daemon_dumps_core) neb_unload_all_modules(NEBMODULE_FORCE_UNLOAD, NEBMODULE_NEB_SHUTDOWN); exit(EXIT_FAILURE); } /* forcibly send a program status update * for later updates of PROCESS_* */ broker_program_status(NEBTYPE_PROGRAMSTATUS_UPDATE, NEBFLAG_NONE, NEBATTR_NONE, NULL); /* 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 %s from the command line with the -v option to verify your config before restarting. (PID=%d)", PROGRAM_NAME , (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 %s from the command line with the -v option to verify your config before restarting. (PID=%d)\n", PROGRAM_NAME , (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, Icinga 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(); sync_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); /* initialize the event timing loop */ init_timing_loop(); /* initialize check statistics */ init_check_stats(); /* 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); /* print event loop start */ asprintf(&buffer, "Event loop started...\n"); write_to_all_logs(buffer, NSLOG_PROCESS_INFO); my_free(buffer); /***** 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; }