void _lml_handle_signal_if_needed(void) { int signo; if ( ! got_signal ) return; signo = got_signal; got_signal = 0; #if !((defined _WIN32 || defined __WIN32__) && !defined __CYGWIN__) if ( signo == SIGQUIT || signo == SIGUSR1 ) { handle_sigquit(); return; } #endif server_close(); if ( config.lml_client ) prelude_client_destroy(config.lml_client, PRELUDE_CLIENT_EXIT_STATUS_FAILURE); prelude_deinit(); #if !((defined _WIN32 || defined __WIN32__) && !defined __CYGWIN__) if ( signo == SIGHUP ) { prelude_log(PRELUDE_LOG_WARN, "signal %d received, restarting (%s).\n", signo, get_restart_string()); handle_sighup(); } #endif prelude_log(PRELUDE_LOG_WARN, "signal %d received, terminating prelude-lml.\n", signo); exit(2); }
void sig_handler( _SaganSigArgs *args ) { sigset_t signal_set; int sig; for(;;) { /* wait for any and all signals */ sigfillset( &signal_set ); sigwait( &signal_set, &sig ); switch( sig ) { /* exit */ case SIGQUIT: case SIGINT: case SIGTERM: case SIGSEGV: case SIGABRT: sagan_log(args->config, 0, "\n\n[Received signal %d. Sagan version %s shutting down]-------\n", sig, VERSION); sagan_statistics(args->config); #if defined(HAVE_LIBMYSQLCLIENT_R) || defined(HAVE_LIBPQ) /* last_cid != cid (has there been any alerts? */ if ( args->config->dbtype != 0 && counters->last_cid != counters-> cid ) record_last_cid(args->debug, args->config, counters); #endif #ifdef HAVE_LIBPRELUDE /* This comment is from the Snort source code. "Sensor reporting to Prelude shall never go offline, which is why we use the PRELUDE_CLIENT_EXIT_STATUS_FAILURE. */ if ( sagan_prelude_flag != 0 ) { prelude_client_destroy(preludeclient, PRELUDE_CLIENT_EXIT_STATUS_FAILURE); prelude_deinit(); } #endif #ifdef HAVE_LIBDNET if ( sagan_unified2_flag ) Unified2CleanExit(args->config); #endif fflush(args->config->sagan_alert_stream); fclose(args->config->sagan_alert_stream); /* Close Sagan alert file */ fflush(args->config->sagan_log_stream); /* Close the sagan.log */ fclose(args->config->sagan_log_stream); removelockfile(args->config); exit(0); break; case SIGHUP: pthread_mutex_lock(&sig_mutex); sagan_log(args->config, 0, "[Reloading Sagan version %s.]-------", VERSION); /* Reset counters */ counters->refcount=0; counters->classcount=0; counters->rulecount=0; counters->ruletotal=0; /* Re-load everything */ load_config(args->debug, args->config); pthread_mutex_unlock(&sig_mutex); sagan_log(args->config, 0, "Configuration reloaded."); break; /* Signals to ignore */ case 17: /* Child process has exited. */ case 28: /* Terminal 'resize'/alarm. */ break; case SIGUSR1: sagan_statistics(args->config); break; default: sagan_log(args->config, 0, "[Received signal %d. Sagan doesn't know how to deal with]", sig); } } }
int main(int argc, char **argv) { int ret; ev_timer evt; struct timeval end; struct sigaction action; /* * Initialize libev. */ ev_default_loop(EVFLAG_AUTO); /* * make sure we ignore sighup until acceptable. */ #if !((defined _WIN32 || defined __WIN32__) && !defined __CYGWIN__) action.sa_flags = 0; action.sa_handler = SIG_IGN; sigemptyset(&action.sa_mask); sigaction(SIGHUP, &action, NULL); #endif memset(&start, 0, sizeof(start)); memset(&end, 0, sizeof(end)); prelude_init(&argc, argv); global_argv = argv; PRELUDE_PLUGIN_SET_PRELOADED_SYMBOLS(); ret = prelude_option_new_root(&lml_root_optlist); if ( ret < 0 ) return ret; ret = log_plugins_init(LOG_PLUGIN_DIR, lml_root_optlist); if (ret < 0) return ret; prelude_log_debug(1, "Initialized %d logs plugins.\n", ret); ret = lml_options_init(lml_root_optlist, argc, argv); if ( ret < 0 ) exit(1); /* * setup signal handling */ action.sa_flags = 0; sigemptyset(&action.sa_mask); action.sa_handler = sig_handler; #ifdef SA_INTERRUPT action.sa_flags |= SA_INTERRUPT; #endif sigaction(SIGTERM, &action, NULL); sigaction(SIGINT, &action, NULL); sigaction(SIGABRT, &action, NULL); #if !((defined _WIN32 || defined __WIN32__) && !defined __CYGWIN__) sigaction(SIGUSR1, &action, NULL); sigaction(SIGQUIT, &action, NULL); sigaction(SIGHUP, &action, NULL); #endif ret = file_server_start_monitoring(); if ( ret < 0 && ! config.udp_nserver ) { prelude_log(PRELUDE_LOG_WARN, "No file or UDP server available for monitoring: terminating.\n"); return -1; } if ( config.daemon_mode ) { prelude_daemonize(config.pidfile); if ( config.pidfile ) free(config.pidfile); ev_default_fork(); } ev_timer_init(&evt, libev_timer_cb, 1, 1); ev_timer_start(&evt); /* * Whether we are using batch-mode or file notification, we need * to process the currently un-processed entry. */ gettimeofday(&start, NULL); do { ret = file_server_read_once(); prelude_timer_wake_up(); } while ( ret > 0 ); /* * if either FAM or UDP server is enabled, we use polling to know * if there are data available for reading. if batch_mode is set, * then we revert to reading every data at once. */ if ( ! config.batch_mode ) wait_for_event(); else { gettimeofday(&end, NULL); /* * only call prelude_client_destroy in case we are running in batch * mode, causing an heartbeat to be sent to notice of a normal exit. */ if ( ! config.dry_run ) prelude_client_destroy(config.lml_client, PRELUDE_CLIENT_EXIT_STATUS_SUCCESS); print_stats("", &end); } prelude_deinit(); return 0; }