nagcon-0.0.30/0000755000175000017500000000000011044324253012733 5ustar folkertfolkertnagcon-0.0.30/error.h0000644000175000017500000000137611044324253014244 0ustar folkertfolkert/* * Copyright (C) 2006 Folkert van Heusden * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * */ void error_exit(char *format, ...); nagcon-0.0.30/nc.cpp0000644000175000017500000003054411044324253014045 0ustar folkertfolkert/* * Copyright (C) 2006 Folkert van Heusden * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef __sun__ #include #include #endif extern "C" { #include "error.h" } #include "utils.h" #include "pl.h" #define MY_RED 1 #define MY_GREEN 2 #define MY_YELLOW 3 #define MY_BLUE 4 #define MY_MAGENTA 5 #define MY_CYAN 6 #define MY_DRAW 7 char *state_str[4] = { "OK", "WA", "CR", "??" }; int terminal_resized = 0; int max_sort_order = 2; int sort_order = 0; int group_by_state = 1; void init_curses(void) { initscr(); start_color(); keypad(stdscr, TRUE); cbreak(); intrflush(stdscr, FALSE); leaveok(stdscr, TRUE); noecho(); nonl(); refresh(); nodelay(stdscr, FALSE); meta(stdscr, TRUE); /* enable 8-bit input */ idlok(stdscr, TRUE); /* may give a little clunky screenredraw */ raw(); use_default_colors(); init_pair(MY_RED, COLOR_RED, -1); init_pair(MY_GREEN, COLOR_GREEN, -1); init_pair(MY_YELLOW, COLOR_YELLOW, -1); init_pair(MY_BLUE, COLOR_BLUE, -1); init_pair(MY_MAGENTA, COLOR_MAGENTA, -1); init_pair(MY_CYAN, COLOR_CYAN, -1); init_pair(MY_DRAW, -1, -1); } void determine_terminal_size(int *max_y, int *max_x) { struct winsize size; *max_x = *max_y = 0; /* changed from 'STDIN_FILENO' as that is incorrect: we're * outputting to stdout! */ if (ioctl(1, TIOCGWINSZ, &size) == 0) { *max_y = size.ws_row; *max_x = size.ws_col; } if (!*max_x || !*max_y) { char *dummy = getenv("COLUMNS"); if (dummy) *max_x = atoi(dummy); else *max_x = 80; dummy = getenv("LINES"); if (dummy) *max_x = atoi(dummy); else *max_x = 24; } } void wrong_key(void) { flash(); flushinp(); } char *limit_str(char *str, int max_len) { char *out = (char *)mymalloc(max_len + 1, "limit_str"); int len = str?strlen(str):0; int copy_len = min(max_len, len); memset(out, ' ', max_len); if (copy_len) memcpy(out, str, copy_len); out[max_len] = 0x00; return out; } void online_help(int max_x, int max_y) { WINDOW *win = newwin(15, 45, (max_y / 2) - (12 / 2), (max_x / 2) - (45 / 2)); if (!win) error_exit("failed to create window"); werase(win); box(win, 0, 0); mvwprintw(win, 1, 2, "The following keys will toggle a setting:"); mvwprintw(win, 2, 2, "a list all problems"); mvwprintw(win, 3, 2, "n always notify"); mvwprintw(win, 4, 2, "k also acknowlegded"); mvwprintw(win, 5, 2, "o hide ok"); mvwprintw(win, 6, 2, "g turn off grouping by status"); mvwprintw(win, 7, 2, "s change sort order"); mvwprintw(win, 8, 2, "h this help"); mvwprintw(win, 10, 2, "[]{} resize host/service fields"); mvwprintw(win, 11, 2, "q exit"); mvwprintw(win, 13, 2, "Press any key to exit this help"); wnoutrefresh(win); doupdate(); (void)getch(); delwin(win); } void version(void) { printf("nagcon v" VERSION ", (C) 2005 by folkert@vanheusden.com\n\n"); } void help(void) { version(); printf("-f file what file to monitor (usuallly:\n"); printf("-F host:port connect to a host for retrieving the status.log information\n"); printf(" /usr/local/nagios/var/status.log, look for status_file in\n"); printf(" the nagios.cfg file\n"); printf("-i x check interval (in seconds)\n"); printf("-a list also the services for hosts that are down\n"); printf("-n also display services for which notify has been switched off\n"); printf("-k also display problems that already have been acknowledged\n"); printf("-g turn off grouping by status\n"); printf("-s change sort order\n"); printf("-e/-o suppress services with ok status\n"); printf("-x status.log-file is in Nagios 1.0 format\n"); printf("-X status.log-file is in Nagios 2.0 format\n"); printf("-1 x set width of hostname column\n"); printf("-2 x set width of service description column\n"); printf("-h this help\n"); printf("-V display version\n"); } void do_resize(int sig) { terminal_resized = 1; } int main(int argc, char *argv[]) { struct stats *pstats = NULL; struct stat statstruct; int n_stats = 0; int n_critical = 0, n_warning = 0, n_ok = 0, n_up = 0, n_down = 0, n_unreachable = 0, n_pending = 0; int max_x = 80, max_y = 25; WINDOW *win; int sw; char *status_log = "/usr/local/nagios/var/status.log"; int interval = 5; char list_all_problems = 0; char always_notify = 0; char also_acknowledged = 0; char hide_ok = 0; int host_width = 8; int service_width = 6; char nagios_version = 2; char file_mode = 0; while ((sw = getopt (argc, argv, "xXoeankF:f:i:1:2:hVgs:")) != EOF) { switch(sw) { case 'x': nagios_version = 1; break; case 'X': nagios_version = 2; break; case 'f': status_log = optarg; file_mode = 0; break; case 'F': status_log = optarg; file_mode = 1; break; case 'i': interval = atoi(optarg); break; case 'a': list_all_problems = 1; break; case 'n': always_notify = 1; break; case 'k': also_acknowledged = 1; break; case 'o': case 'e': hide_ok = 1; break; case 's': sort_order = atoi(optarg); if(sort_order < 0 || sort_order > max_sort_order) error_exit("invalid sort-order"); break; case 'g': group_by_state = 1; break; case '1': host_width = atoi(optarg); if (host_width < 1 || host_width > (max_x - (22 + service_width))) error_exit("invalid host-column width"); break; case '2': service_width = atoi(optarg); if (service_width < 1 || service_width > (max_x - (22 + host_width))) error_exit("invalid service-column width"); break; case 'V': version(); return 0; default: help(); return 0; } } if (file_mode == 0 && stat(status_log, &statstruct) == -1) error_exit("error accessing nagios status.log file! (%s)", status_log); init_curses(); signal(SIGWINCH, do_resize); getmaxyx(stdscr, max_y, max_x); win = newwin(max_y, max_x, 0, 0); for(;;) { fd_set rfds; struct timeval tm; int disp_index = 0; time_t now = time(NULL); char *time_str = ctime(&now); char *dummy = strchr(time_str, '\n'); if (dummy) *dummy = 0x00; int fd; werase(win); wattron(win, COLOR_PAIR(MY_DRAW)); box(win, 0, 0); wattroff(win, COLOR_PAIR(MY_DRAW)); if (file_mode == 0) /* file */ fd = open64(status_log, O_RDONLY); else fd = connect_to(status_log); if (fd != -1) { if (nagios_version == 2) parse_2_0_statuslog(fd, &pstats, &n_stats); else if (nagios_version == 1) parse_1_0_statuslog(fd, &pstats, &n_stats); else error_exit("internal error: nagios version %d is unknown\n", nagios_version); calc_stats_stats(pstats, n_stats, list_all_problems, always_notify, also_acknowledged, hide_ok, &n_critical, &n_warning, &n_ok, &n_up, &n_down, &n_unreachable, &n_pending); sort_stats_array(pstats, n_stats); mvwprintw(win, 1, 1, "Hosts: "); wattron(win, COLOR_PAIR(MY_RED)); mvwprintw(win, 1, 8, "down: %-4d", n_down); wattroff(win, COLOR_PAIR(MY_RED)); wattron(win, COLOR_PAIR(MY_YELLOW)); mvwprintw(win, 1, 19, "unreachable: %-4d", n_unreachable); wattroff(win, COLOR_PAIR(MY_YELLOW)); wattron(win, COLOR_PAIR(MY_DRAW)); mvwprintw(win, 1, 38, "pending: %-4d", n_pending); wattroff(win, COLOR_PAIR(MY_DRAW)); wattron(win, COLOR_PAIR(MY_GREEN)); mvwprintw(win, 1, 53, "up: %-4d", n_up); wattroff(win, COLOR_PAIR(MY_GREEN)); mvwprintw(win, 2, 1, "Services: "); wattron(win, COLOR_PAIR(MY_RED)); mvwprintw(win, 2, 11, "critical: %-4d", n_critical); wattroff(win, COLOR_PAIR(MY_RED)); wattron(win, COLOR_PAIR(MY_YELLOW)); mvwprintw(win, 2, 25, "warning: %-4d", n_warning); wattroff(win, COLOR_PAIR(MY_YELLOW)); wattron(win, COLOR_PAIR(MY_GREEN)); mvwprintw(win, 2, 39, "ok: %-4d", n_ok); wattroff(win, COLOR_PAIR(MY_GREEN)); wmove(win, 3, 1); wattron(win, COLOR_PAIR(MY_DRAW)); whline(win, 0, max_x - 2); mvwprintw(win, 3, max_x - (strlen(time_str) + 6), "[ %s ]", time_str); mvwprintw(win, 3, 2, "[ Press 'h' for help ]"); wattroff(win, COLOR_PAIR(MY_DRAW)); for(int loop=0; disp_index tm_year + 1900, ptm -> tm_mon + 1, ptm -> tm_mday, ptm -> tm_hour, ptm -> tm_min, host_name, service_d, state_str[pstats[loop].current_state], plugin_ou); wattroff(win, COLOR_PAIR(color)); myfree(host_name, "hostname"); myfree(service_d, "service description"); myfree(plugin_ou, "plugin output"); disp_index++; } wnoutrefresh(win); doupdate(); free_stats_array(pstats, n_stats); close(fd); } FD_ZERO(&rfds); FD_SET(0, &rfds); tm.tv_sec = interval; tm.tv_usec = 0; if (select(1, &rfds, NULL, NULL, &tm) == -1) { if (errno != EAGAIN && errno != EINTR) error_exit("select failed"); } if (FD_ISSET(0, &rfds)) { int c = getch(); int cu = toupper(c); if (c == KEY_RESIZE || c == KEY_F(5)) terminal_resized = 1; else if (c == 3 || c == 7 || cu == 'Q') break; else if (cu == 'A') list_all_problems = 1 - list_all_problems; else if (cu == 'N') always_notify = 1 - always_notify; else if (cu == 'K') also_acknowledged = 1 - also_acknowledged; else if (cu == 'S') sort_order = (sort_order + 1) % (max_sort_order + 1); else if (cu == 'G') group_by_state = 1 - group_by_state; else if (cu == 'O') hide_ok = 1 - hide_ok; else if (cu == 'H') online_help(max_x, max_y); else if (cu == '[') { if (host_width > 0) host_width--; else wrong_key(); } else if (cu == ']') { if (host_width < (max_x - (22 + service_width + 1))) host_width++; else wrong_key(); } else if (cu == '{') { if (service_width > 0) service_width--; else wrong_key(); } else if (cu == '}') { if (service_width < (max_x - (22 + host_width + 1))) service_width++; else wrong_key(); } else { wrong_key(); } } if (terminal_resized) { determine_terminal_size(&max_y, &max_x); delwin(win); wresize(stdscr, max_y, max_x); win = newwin(max_y, max_x, 0, 0); wclear(win); terminal_resized = 0; } } endwin(); return 0; } nagcon-0.0.30/br.h0000644000175000017500000000275611044324253013521 0ustar folkertfolkert/* * Copyright (C) 2006 Folkert van Heusden * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * */ /* code taken from linux kernel */ #if __GNUC__ == 2 && __GNUC_MINOR__ < 96 #define __builtin_expect(x, expected_value) (x) #endif #ifndef __builtin_expect #define __builtin_expect(x, expected_value) (x) #endif #define likely(x) __builtin_expect((x),1) #define unlikely(x) __builtin_expect((x),0) class buffered_reader { private: int fd, block_size; char *buffer; long long int buffer_length, buffer_pointer; char *mmap_addr, *cur_offset; off64_t size_of_file; int number_of_bytes_in_buffer(void); int read_into_buffer(void); public: buffered_reader(int fd, int block_size=4096); ~buffered_reader(); int garbage_collect(char shrink_buffer=0); char * read_line(void); off64_t file_offset(void); }; nagcon-0.0.30/Makefile0000644000175000017500000000110511044324253014370 0ustar folkertfolkertVERSION=0.0.30 DEBUG= -g # -D_DEBUG -g -fprofile-arcs -ftest-coverage # -pg -g CXXFLAGS+=-Wall -g -O2 -DVERSION=\"${VERSION}\" $(DEBUG) CFLAGS+=${CXXFLAGS} LDFLAGS+=$(DEBUG) -lncurses -lstdc++ OBJS=error.o utils.o br.o nc.o pl.o all: nagcon nagcon: $(OBJS) $(CC) -Wall -W $(OBJS) $(LDFLAGS) -o nagcon install: nagcon cp nagcon /usr/local/bin clean: rm -f $(OBJS) nagcon core *.da *.gcov *.bb* package: clean mkdir nagcon-$(VERSION) cp *.c* *.h Makefile readme.txt license.txt nagcon-$(VERSION) tar czf nagcon-$(VERSION).tgz nagcon-$(VERSION) rm -rf nagcon-$(VERSION) nagcon-0.0.30/utils.h0000644000175000017500000000242311044324253014245 0ustar folkertfolkert/* * Copyright (C) 2006 Folkert van Heusden * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * */ void * mymalloc(int size, char *what); void * myrealloc(void *oldp, int newsize, char *what); char * mystrdup(char *in); char * mtstrndup(char *in, int len); void myfree(void *p, char *what); ssize_t WRITE(int fd, char *whereto, size_t len); int get_filesize(char *filename); time_t get_filechanged(char *filename); void resolve_host(char *host, struct sockaddr_in *addr); int connect_to(char *hoststr); int write_pidfile(char *fname); #define incopy(a) *((struct in_addr *)a) #define max(x, y) ((x) > (y) ? (x) : (y)) #define min(x, y) ((x) < (y) ? (x) : (y)) nagcon-0.0.30/error.c0000644000175000017500000000210111044324253014222 0ustar folkertfolkert/* * Copyright (C) 2006 Folkert van Heusden * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include #include #include #include #include void error_exit(char *format, ...) { va_list ap; endwin(); va_start(ap, format); (void)vfprintf(stderr, format, ap); va_end(ap); fprintf(stderr, "errno=%d (if applicable)\n", errno); exit(EXIT_FAILURE); } nagcon-0.0.30/pl.h0000644000175000017500000001001711044324253013516 0ustar folkertfolkert/* * Copyright (C) 2006 Folkert van Heusden * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * */ #define TYPE_IGNORE 0 #define TYPE_HOST 1 #define TYPE_SERVICE 2 #define V1_0_MAX_ELEMENTS 32 #define VARTYPE_PCHAR 0 #define VARTYPE_INT 1 #define VARTYPE_TIMET 2 #define VARTYPE_DOUBLE 3 #define STATS_OFFSET(x) (int)(offsetof(struct stats, x)) #define ST_HARD 1 #define ST_SOFT 0 struct v2_0_config { char *str; int offset; int type; }; struct stats { int type; char *host_name; int current_state; char *service_description; char *plugin_output; time_t last_state_change; int active_checks_enabled; int passive_checks_enabled; int notifications_enabled; int problem_has_been_acknowledged; double scheduled_downtime_depth; int state_type; int last_hard_state; double percent_state_change; double check_execution_time; double check_latency; int modified_attributes; int event_handler; int has_been_checked; int should_be_scheduled; int current_attempt; int max_attempts; int last_hard_state_change; int last_time_ok; int last_time_warning; int last_time_unknown; int last_time_critical; time_t last_check; time_t next_check; int check_type; double current_notification_number; int last_notification; int next_notification; int no_more_notifications; int event_handler_enabled; int acknowledgement_type; int flap_detection_enabled; int failure_prediction_enabled; int process_performance_data; int obsess_over_service; int obsess_over_host; time_t last_update; int is_flapping; char * performance_data; char * check_command; int last_time_up; int last_time_down; int last_time_unreachable; /* newly added in 3.0 */ char *author; double check_interval; int check_options; char *check_period; char *comment_data; int comment_id; int current_event_id; int current_notification_id; int current_problem_id; time_t entry_time; int entry_type; int expires; time_t expire_time; char *host_notification_period; int last_event_id; int last_problem_id; char *long_plugin_output; int next_comment_id; char *notification_period; int persistent; double retry_interval; char *service_notification_period; int source; int downtime_id; time_t start_time, end_time; int triggered_by; int fixed; int duration; char *comment; }; void parse_1_0_statuslog(int fd, struct stats **pstats, int *n_stats); void parse_2_0_statuslog(int fd, struct stats **pstats, int *n_stats); void free_stats_array(struct stats *pstats, int n_stats); void sort_stats_array(struct stats *pstats, int n_stats); int host_is_down(struct stats *pstats, int n_stats, char *host_name); int should_i_show_entry(struct stats *pstats, int n_stats, int cur_index, char list_all_problems, char always_notify, char also_acknowledged, char hide_ok); int find_index_by_host_and_service(struct stats *pstats, int n_stats, char *host_name, char *service_description); int check_max_age_last_check(struct stats *pstats, int n_stats, int max_time_last_host_update, int max_time_oldest_host_update, int max_time_last_host_check, int max_time_oldest_host_check, int max_time_last_service_check, int max_time_oldest_service_check, int max_time_oldest_next_service_check, char **message); void calc_stats_stats(struct stats *pstats, int n_stats, char list_all_problems, char always_notify, char also_acknowledged, char hide_ok, int *n_critical, int *n_warning, int *n_ok, int *n_up, int *n_down, int *n_unreachable, int *n_pending); nagcon-0.0.30/pl.cpp0000644000175000017500000007246011044324253014063 0ustar folkertfolkert/* * Copyright (C) 2006 Folkert van Heusden * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include extern "C" { #include "error.h" } #include "utils.h" #include "br.h" #include "pl.h" static struct v2_0_config v2_0_config_elements[] = { {"acknowledgement_type", STATS_OFFSET(acknowledgement_type), VARTYPE_INT}, {"active_checks_enabled", STATS_OFFSET(active_checks_enabled), VARTYPE_INT}, {"author", STATS_OFFSET(author), VARTYPE_PCHAR}, {"check_command", STATS_OFFSET(check_command), VARTYPE_PCHAR}, {"check_execution_time", STATS_OFFSET(check_execution_time), VARTYPE_DOUBLE}, {"check_interval", STATS_OFFSET(check_interval), VARTYPE_DOUBLE}, {"check_latency", STATS_OFFSET(check_latency), VARTYPE_DOUBLE}, {"check_options", STATS_OFFSET(check_options), VARTYPE_INT}, {"check_period", STATS_OFFSET(check_period), VARTYPE_PCHAR}, {"check_type", STATS_OFFSET(check_type), VARTYPE_INT}, {"comment", STATS_OFFSET(comment), VARTYPE_PCHAR}, {"comment_data", STATS_OFFSET(comment_data), VARTYPE_PCHAR}, {"comment_id", STATS_OFFSET(comment_id), VARTYPE_INT}, {"current_attempt", STATS_OFFSET(current_attempt), VARTYPE_INT}, {"current_event_id", STATS_OFFSET(current_event_id), VARTYPE_INT}, {"current_notification_id", STATS_OFFSET(current_notification_id), VARTYPE_INT}, {"current_notification_number", STATS_OFFSET(current_notification_number), VARTYPE_DOUBLE}, {"current_problem_id", STATS_OFFSET(current_problem_id), VARTYPE_INT}, {"current_state", STATS_OFFSET(current_state), VARTYPE_INT}, {"downtime_id", STATS_OFFSET(downtime_id), VARTYPE_INT}, {"duration", STATS_OFFSET(duration), VARTYPE_INT}, {"end_time", STATS_OFFSET(end_time), VARTYPE_TIMET}, {"entry_time", STATS_OFFSET(entry_time), VARTYPE_TIMET}, {"entry_type", STATS_OFFSET(entry_type), VARTYPE_INT}, {"event_handler", STATS_OFFSET(event_handler), VARTYPE_INT}, {"event_handler_enabled", STATS_OFFSET(event_handler_enabled), VARTYPE_INT}, {"expire_time", STATS_OFFSET(expire_time), VARTYPE_TIMET}, {"expires", STATS_OFFSET(expires), VARTYPE_INT}, {"failure_prediction_enabled", STATS_OFFSET(failure_prediction_enabled), VARTYPE_INT}, {"fixed", STATS_OFFSET(fixed), VARTYPE_INT}, {"flap_detection_enabled", STATS_OFFSET(flap_detection_enabled), VARTYPE_INT}, {"has_been_checked", STATS_OFFSET(has_been_checked), VARTYPE_INT}, {"host_name", STATS_OFFSET(host_name), VARTYPE_PCHAR}, {"host_notification_period", STATS_OFFSET(host_notification_period), VARTYPE_PCHAR}, {"is_flapping", STATS_OFFSET(is_flapping), VARTYPE_INT}, {"last_check", STATS_OFFSET(last_check), VARTYPE_TIMET}, {"last_event_id", STATS_OFFSET(last_event_id), VARTYPE_INT}, {"last_hard_state", STATS_OFFSET(last_hard_state), VARTYPE_INT}, {"last_hard_state_change", STATS_OFFSET(last_hard_state_change), VARTYPE_INT}, {"last_notification", STATS_OFFSET(last_notification), VARTYPE_INT}, {"last_problem_id", STATS_OFFSET(last_problem_id), VARTYPE_INT}, {"last_state_change", STATS_OFFSET(last_state_change), VARTYPE_TIMET}, {"last_time_critical", STATS_OFFSET(last_time_critical), VARTYPE_INT}, {"last_time_down", STATS_OFFSET(last_time_down), VARTYPE_INT}, {"last_time_ok", STATS_OFFSET(last_time_ok), VARTYPE_INT}, {"last_time_unknown", STATS_OFFSET(last_time_unknown), VARTYPE_INT}, {"last_time_unreachable", STATS_OFFSET(last_time_unreachable), VARTYPE_INT}, {"last_time_up", STATS_OFFSET(last_time_up), VARTYPE_INT}, {"last_time_warning", STATS_OFFSET(last_time_warning), VARTYPE_INT}, {"last_update", STATS_OFFSET(last_update), VARTYPE_TIMET}, {"long_plugin_output", STATS_OFFSET(long_plugin_output), VARTYPE_PCHAR}, {"max_attempts", STATS_OFFSET(max_attempts), VARTYPE_INT}, {"modified_attributes", STATS_OFFSET(modified_attributes), VARTYPE_INT}, {"next_check", STATS_OFFSET(next_check), VARTYPE_TIMET}, {"next_comment_id", STATS_OFFSET(next_comment_id), VARTYPE_INT}, {"next_notification", STATS_OFFSET(next_notification), VARTYPE_INT}, {"no_more_notifications", STATS_OFFSET(no_more_notifications), VARTYPE_INT}, {"notification_period", STATS_OFFSET(notification_period), VARTYPE_PCHAR}, {"notifications_enabled", STATS_OFFSET(notifications_enabled), VARTYPE_INT}, {"obsess_over_host", STATS_OFFSET(obsess_over_host), VARTYPE_INT}, {"obsess_over_service", STATS_OFFSET(obsess_over_service), VARTYPE_INT}, {"passive_checks_enabled", STATS_OFFSET(passive_checks_enabled), VARTYPE_INT}, {"percent_state_change", STATS_OFFSET(percent_state_change), VARTYPE_DOUBLE}, {"performance_data", STATS_OFFSET(performance_data), VARTYPE_PCHAR}, {"persistent", STATS_OFFSET(persistent), VARTYPE_INT}, {"plugin_output", STATS_OFFSET(plugin_output), VARTYPE_PCHAR}, {"problem_has_been_acknowledged", STATS_OFFSET(problem_has_been_acknowledged), VARTYPE_INT}, {"process_performance_data", STATS_OFFSET(process_performance_data), VARTYPE_INT}, {"retry_interval", STATS_OFFSET(retry_interval), VARTYPE_DOUBLE}, {"scheduled_downtime_depth", STATS_OFFSET(scheduled_downtime_depth), VARTYPE_DOUBLE}, {"service_description", STATS_OFFSET(service_description), VARTYPE_PCHAR}, {"should_be_scheduled", STATS_OFFSET(should_be_scheduled), VARTYPE_INT}, {"source", STATS_OFFSET(source), VARTYPE_INT}, {"start_time", STATS_OFFSET(start_time), VARTYPE_TIMET}, {"state_type", STATS_OFFSET(state_type), VARTYPE_INT}, {"triggered_by", STATS_OFFSET(triggered_by), VARTYPE_INT}, {"type", STATS_OFFSET(type), VARTYPE_INT} }; /* service { host_name=ap service_description=HTTP modified_attributes=0 check_command=check_tcp!80 event_handler= has_been_checked=1 should_be_scheduled=1 check_execution_time=0.009 check_latency=0.712 current_state=0 last_hard_state=0 current_attempt=1 max_attempts=3 state_type=1 last_state_change=1128634047 last_hard_state_change=1128633828 last_time_ok=1129101510 last_time_warning=0 last_time_unknown=1128633828 last_time_critical=1126954624 plugin_output=TCP OK - 0.001 second response time on port 80 performance_data=time=0.001121s;0.000000;0.000000;0.000000;10.000000 last_check=1129101510 next_check=1129101630 check_type=0 current_notification_number=0 last_notification=0 next_notification=0 no_more_notifications=0 notifications_enabled=1 active_checks_enabled=1 passive_checks_enabled=1 event_handler_enabled=1 problem_has_been_acknowledged=0 acknowledgement_type=0 flap_detection_enabled=1 failure_prediction_enabled=1 process_performance_data=1 obsess_over_service=1 last_update=1129101556 is_flapping=0 percent_state_change=0.00 scheduled_downtime_depth=0 } host { host_name=ap modified_attributes=0 check_command=check-host-alive event_handler= has_been_checked=1 should_be_scheduled=0 check_execution_time=0.012 check_latency=0.000 current_state=0 last_hard_state=0 check_type=0 plugin_output=PING OK - Packet loss = 0%, RTA = 1.54 ms performance_data= last_check=1128863442 next_check=0 current_attempt=1 max_attempts=10 state_type=1 last_state_change=1128634057 last_hard_state_change=1128634057 last_time_up=1128863442 last_time_down=1128633868 last_time_unreachable=0 last_notification=1128634057 next_notification=0 no_more_notifications=0 current_notification_number=0 notifications_enabled=1 problem_has_been_acknowledged=0 acknowledgement_type=0 active_checks_enabled=1 passive_checks_enabled=1 event_handler_enabled=1 flap_detection_enabled=1 failure_prediction_enabled=1 process_performance_data=1 obsess_over_host=1 last_update=1129101556 is_flapping=0 percent_state_change=0.00 scheduled_downtime_depth=0 } */ int v2_0_find_entry_type(char *field_name) { int left = 0; int right = (sizeof(v2_0_config_elements) / sizeof(struct v2_0_config)) - 1; while(left <= right) { int mid = (left + right) / 2; int compare = strcmp(field_name, v2_0_config_elements[mid].str); if (compare > 0) left = mid + 1; else if (compare < 0) right = mid - 1; else return mid; } return -1; } void parse_2_0_statuslog(int fd, struct stats **pstats, int *n_stats) { int n_alloc = 0; int type = TYPE_IGNORE; /* start up buffered reader */ buffered_reader bf(fd); *pstats = NULL; *n_stats = 0; for(;;) { char *line = bf.read_line(); if (!line) break; if (strchr(line, '{')) { /* init */ type = TYPE_IGNORE; if (*n_stats == n_alloc) { if (n_alloc) n_alloc *= 2; else n_alloc = 128; *pstats = (struct stats *)myrealloc(*pstats, n_alloc * sizeof(struct stats), "stats array"); if (!*pstats) error_exit("Error allocating memory"); memset(&(*pstats)[*n_stats], 0x00, sizeof(struct stats) * (n_alloc - *n_stats)); } else { memset(&(*pstats)[*n_stats], 0x00, sizeof(struct stats)); } if (strncmp(line, "host", 4) == 0) { type = TYPE_HOST; } else if (strncmp(line, "service", 7) == 0) { type = TYPE_SERVICE; } else { type = TYPE_IGNORE; } } else if (type != TYPE_IGNORE) { char *cmd = line, *is; while(*cmd == ' ' || *cmd == '\t') cmd++; is = strchr(cmd, '='); if (is == NULL) { if (strchr(cmd, '}') != NULL) /* end of definition, store in array */ { if (type == TYPE_HOST && (*pstats)[*n_stats].current_state == 1) /* HOSTS: 0=ok, 1=down, 2=unreachable */ (*pstats)[*n_stats].current_state = 2; (*pstats)[*n_stats].type = type; (*n_stats)++; } } else { int index; char *record = (char *)(&(*pstats)[*n_stats]); char *par = is + 1; *is = 0x00; if ((index = v2_0_find_entry_type(cmd)) != -1) { switch(v2_0_config_elements[index].type) { case VARTYPE_PCHAR: *((char **)(&record[v2_0_config_elements[index].offset])) = mystrdup(par); break; case VARTYPE_INT: *((int *)(&record[v2_0_config_elements[index].offset])) = atoi(par); break; case VARTYPE_TIMET: *((time_t *)(&record[v2_0_config_elements[index].offset])) = atol(par); break; case VARTYPE_DOUBLE: *((double *)(&record[v2_0_config_elements[index].offset])) = atof(par); break; } } else { printf("{%s} ???\n", cmd); } } } /* this one does not use myfree() as the buffered reader does not * use mymalloc() and friends */ free(line); } } int split_1_0_line(char *line, char **out) { int out_index = 0; memset(out, 0x00, sizeof(char *) * V1_0_MAX_ELEMENTS); for(;out_index < V1_0_MAX_ELEMENTS;) { out[out_index++] = line; line = strchr(line, ';'); if (!line) break; *line = 0x00; /* replace ';' with 0x00 */ line++; } return out_index; } void parse_1_0_statuslog(int fd, struct stats **pstats, int *n_stats) { /* start up buffered reader */ buffered_reader bf(fd); *pstats = NULL; *n_stats = 0; for(;;) { int type = TYPE_IGNORE; char *host_name = NULL; int current_state = -1; char *service_description = NULL; char *plugin_output = NULL; time_t last_state_change = 0; char active_checks_enabled = 0; char passive_checks_enabled = 0; char notifications_enabled = 0; char problem_has_been_acknowledged = 0; int scheduled_downtime_depth = 0; char state_type = 0; char last_hard_state = 0; int modified_attributes = 0; int event_handler = 0; int has_been_checked = 0; int should_be_scheduled = 0; int current_attempt = 0; int max_attempts = 0; int last_hard_state_change = 0; int last_time_ok = 0; int last_time_warning = 0; int last_time_unknown = 0; int last_time_critical = 0; time_t last_check = 0; time_t next_check = 0; int check_type = 0; int current_notification_number = 0; int last_notification = 0; int next_notification = 0; int no_more_notifications = 0; int event_handler_enabled = 0; int acknowledgement_type = 0; int flap_detection_enabled = 0; int failure_prediction_enabled = 0; int process_performance_data = 0; int obsess_over_service = 0; time_t last_update = 0; int is_flapping = 0; double percent_state_change = 0; double check_execution_time = 0; double check_latency = 0; char * performance_data = NULL; char * check_command = NULL; int last_time_up = 0; int last_time_down = 0; int last_time_unreachable = 0; char *dummy; char *elements[V1_0_MAX_ELEMENTS]; int n_elem; char *line = bf.read_line(); if (!line) break; if (line[0] == '#') goto skip_line; n_elem = split_1_0_line(line, elements); *pstats = (struct stats *)myrealloc(*pstats, ((*n_stats) + 1) * sizeof(struct stats), "stats array"); if (!*pstats) error_exit("Error allocating memory"); memset(&(*pstats)[*n_stats], 0x00, sizeof(struct stats)); /* [Time of last update] HOST; Host Name (string); Status (OK/DOWN/UNREACHABLE); Last Check Time (long time); Last State Change (long time); Acknowledged (0/1); Time Up (long time); Time Down (long time); Time Unreachable (long time); Last Notification Time (long time); Current Notification Number (#); Notifications Enabled (0/1); Event Handlers Enabled (0/1); Checks Enabled (0/1); Flap Detection Enabled (0/1); Host is Flapping (0/1); Percent State Change (###.##); Scheduled downtime depth (#); Failure Prediction Enabled (0/1); Process Performance Data(0/1); Plugin Output (string) */ /* [Time of last update] SERVICE; Host Name (string); Service Description (string); Status (OK/WARNING/CRITICAL/UNKNOWN); Retry number (#/#); State Type (SOFT/HARD); Last check time (long time); Next check time (long time); Check type (ACTIVE/PASSIVE); Checks enabled (0/1); Accept Passive Checks (0/1); Event Handlers Enabled (0/1); Last state change (long time); Problem acknowledged (0/1); Last Hard State (OK/WARNING/CRITICAL/UNKNOWN); Time OK (long time); Time Unknown (long time); Time Warning (long time); Time Critical (long time); Last Notification Time (long time); Current Notification Number (#); Notifications Enabled (0/1); Latency (#); Execution Time (#); Flap Detection Enabled (0/1); Service is Flapping (0/1); Percent State Change (###.##); Scheduled Downtime Depth (#); Failure Prediction Enabled (0/1); Process Performance Date (0/1); Obsess Over Service (0/1); Plugin Output (string) */ dummy = strchr(elements[0], ' '); if (!dummy) goto skip_line; dummy++; if (strcmp(dummy, "HOST") == 0) type = TYPE_HOST; else if (strcmp(dummy, "SERVICE") == 0) type = TYPE_SERVICE; else if (strcmp(dummy, "PROGRAM") == 0) goto skip_line; else goto skip_line; last_update = atol(elements[0] + 1); if (type == TYPE_HOST) { if (n_elem != 21) goto skip_line; host_name = mystrdup(elements[1]); if (strcmp(elements[2], "UP") == 0) current_state = 0; else current_state = 2; last_check = atol(elements[3]); last_state_change = atol(elements[4]); problem_has_been_acknowledged = atoi(elements[5]); last_time_up = atol(elements[6]); last_time_down = atol(elements[7]); last_time_unreachable = atol(elements[8]); last_notification = atol(elements[9]); current_notification_number = atoi(elements[10]); notifications_enabled = atoi(elements[11]); event_handler_enabled = atoi(elements[12]); active_checks_enabled = atoi(elements[13]); /* in 2.0 it has been split up in passive and active */ flap_detection_enabled = atoi(elements[14]); is_flapping = atoi(elements[15]); percent_state_change = atof(elements[16]); scheduled_downtime_depth = atoi(elements[17]); failure_prediction_enabled = atoi(elements[18]); /* process_performance_data = atoi(elements[19]); */ plugin_output = mystrdup(elements[20]); } else if (type == TYPE_SERVICE) { if (n_elem != 32) goto skip_line; host_name = mystrdup(elements[1]); service_description = mystrdup(elements[2]); if (strcmp(elements[3], "OK") == 0) current_state = 0; else if (strcmp(elements[3], "WARNING") == 0) current_state = 1; else if (strcmp(elements[3], "CRITICAL") == 0) current_state = 2; else if (strcmp(elements[3], "UNKNOWN") == 0 || strcmp(elements[3], "PENDING") == 0) current_state = 3; /* retry_number = atoi(elements[4]); */ if (strcmp(elements[5], "SOFT") == 0) state_type = 0; else state_type = 1; last_check = atol(elements[6]); next_check = atol(elements[7]); if (strcmp(elements[8], "ACTIVE") == 0) check_type = 1; else check_type = 0; active_checks_enabled = atoi(elements[9]); /* accept_passive_checks = atoi(elements[10]); */ event_handler_enabled = atoi(elements[11]); last_state_change = atol(elements[12]); problem_has_been_acknowledged = atoi(elements[13]); if (strcmp(elements[14], "OK") == 0) last_hard_state = 0; else if (strcmp(elements[14], "WARNING") == 0) last_hard_state = 1; else if (strcmp(elements[14], "CRITICAL") == 0) last_hard_state = 2; else if (strcmp(elements[14], "UNKNOWN") == 0) last_hard_state = 3; last_time_ok = atol(elements[15]); last_time_unknown = atol(elements[16]); last_time_warning = atol(elements[17]); last_time_critical = atol(elements[18]); last_notification = atol(elements[19]); current_notification_number = atoi(elements[20]); notifications_enabled = atoi(elements[21]); check_latency = atof(elements[22]); check_execution_time = atof(elements[23]); flap_detection_enabled = atoi(elements[24]); is_flapping = atoi(elements[25]); percent_state_change = atof(elements[26]); scheduled_downtime_depth = atoi(elements[27]); failure_prediction_enabled = atoi(elements[28]); /* process_performance_date = atoi(elements[29]); */ obsess_over_service = atoi(elements[30]); plugin_output = mystrdup(elements[31]); } else error_exit("internal error: type %d unexpected\n", type); (*pstats)[*n_stats].type = type; (*pstats)[*n_stats].host_name = host_name?host_name:mystrdup(""); if (type == TYPE_HOST && current_state == 1) /* HOSTS: 0=ok, 1=down, 2=unreachable */ current_state = 2; (*pstats)[*n_stats].current_state = current_state; (*pstats)[*n_stats].service_description = service_description?service_description:mystrdup(""); (*pstats)[*n_stats].plugin_output = plugin_output?plugin_output:mystrdup(""); (*pstats)[*n_stats].last_state_change = last_state_change; (*pstats)[*n_stats].active_checks_enabled = active_checks_enabled; (*pstats)[*n_stats].passive_checks_enabled = passive_checks_enabled; (*pstats)[*n_stats].notifications_enabled = notifications_enabled; (*pstats)[*n_stats].problem_has_been_acknowledged = problem_has_been_acknowledged; (*pstats)[*n_stats].scheduled_downtime_depth = scheduled_downtime_depth; (*pstats)[*n_stats].state_type = state_type; (*pstats)[*n_stats].last_hard_state = last_hard_state; (*pstats)[*n_stats].modified_attributes = modified_attributes; (*pstats)[*n_stats].event_handler = event_handler; (*pstats)[*n_stats].has_been_checked = has_been_checked; (*pstats)[*n_stats].should_be_scheduled = should_be_scheduled; (*pstats)[*n_stats].current_attempt = current_attempt; (*pstats)[*n_stats].max_attempts = max_attempts; (*pstats)[*n_stats].last_hard_state_change = last_hard_state_change; (*pstats)[*n_stats].last_time_ok = last_time_ok; (*pstats)[*n_stats].last_time_warning = last_time_warning; (*pstats)[*n_stats].last_time_unknown = last_time_unknown; (*pstats)[*n_stats].last_time_critical = last_time_critical; (*pstats)[*n_stats].last_check = last_check; (*pstats)[*n_stats].next_check = next_check; (*pstats)[*n_stats].check_type = check_type; (*pstats)[*n_stats].current_notification_number = current_notification_number; (*pstats)[*n_stats].last_notification = last_notification; (*pstats)[*n_stats].next_notification = next_notification; (*pstats)[*n_stats].no_more_notifications = no_more_notifications; (*pstats)[*n_stats].event_handler_enabled = event_handler_enabled; (*pstats)[*n_stats].acknowledgement_type = acknowledgement_type; (*pstats)[*n_stats].flap_detection_enabled = flap_detection_enabled; (*pstats)[*n_stats].failure_prediction_enabled = failure_prediction_enabled; (*pstats)[*n_stats].process_performance_data = process_performance_data; (*pstats)[*n_stats].obsess_over_service = obsess_over_service; (*pstats)[*n_stats].last_update = last_update; (*pstats)[*n_stats].is_flapping = is_flapping; (*pstats)[*n_stats].percent_state_change = percent_state_change; (*pstats)[*n_stats].check_execution_time = check_execution_time; (*pstats)[*n_stats].check_latency = check_latency; (*pstats)[*n_stats].performance_data = performance_data; (*pstats)[*n_stats].check_command = check_command; (*pstats)[*n_stats].last_time_up = last_time_up; (*pstats)[*n_stats].last_time_down = last_time_down; (*pstats)[*n_stats].last_time_unreachable = last_time_unreachable; (*n_stats)++; skip_line: free(line); } close(fd); } void free_stats_array(struct stats *pstats, int n_stats) { if (pstats) { for(int loop=0; loop current_state < p2 -> current_state) return 1; else if (p1 -> current_state == p2 -> current_state) { if (p1 -> last_state_change < p2 -> last_state_change) return 1; return p2 -> last_state_change - p1 -> last_state_change; } return -1; } void sort_stats_array(struct stats *pstats, int n_stats) { if (n_stats > 1) qsort(pstats, n_stats, sizeof(struct stats), sort_compare_func); } int host_is_down(struct stats *pstats, int n_stats, char *host_name) { for(int loop=0; loop 3) error_exit("internal error: state %d not known", pstats[cur_index].current_state); return 1; } int find_index_by_host_and_service(struct stats *pstats, int n_stats, char *host_name, char *service_description) { int loop; static int last = 0; if (service_description) { for(loop=0; loop max_diff) { char *time_str = ctime(&check_time); char *dummy = strchr(time_str, '\n'); *dummy = 0x00; snprintf(buffer, sizeof(buffer), "limit reached of \"%s\" for %s: %d seconds (last check: %s (%d), max diff: %d)", descr, what?what:"?", cur_diff, time_str, (int)check_time, max_diff); *message = strdup(buffer); return -1; } return 0; } int check_max_age_last_check(struct stats *pstats, int n_stats, int max_time_last_host_update, int max_time_oldest_host_update, int max_time_last_host_check, int max_time_oldest_host_check, int max_time_last_service_check, int max_time_oldest_service_check, int max_time_oldest_next_service_check, char **message) { time_t now = time(NULL); int index; time_t most_recent_host_update = 0; time_t most_recent_host_check = 0; time_t most_recent_last_service_check = 0; time_t oldest_next_service_check = now; for(index=0; index * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include #include #include #include #include #include #include #include #include #include #include extern "C" { #include "error.h" } #include "utils.h" #ifdef _DEBUG typedef struct { void *p; char *descr; int size; } memlist; memlist *pm = NULL; int n_pm = 0; void LOG(char *s, ...) { va_list ap; FILE *fh = fopen("log.log", "a+"); if (!fh) error_exit("can't access log.log"); va_start(ap, s); vfprintf(fh, s, ap); va_end(ap); fclose(fh); } void dump_mem(int sig) { int loop; signal(SIGHUP, dump_mem); if (sig != SIGHUP) error_exit("unexpected signal %d for dump_mem\n", sig); LOG("%d elements of memory used\n", n_pm); for(loop=0; loop then configurable * via configurationfile with number of retries and/or * sleep * ---------------------------------------------------- */ void *dummy = realloc(oldp, newsize); if (!dummy) error_exit("failed to reallocate to %d bytes for %s\n", newsize, what); #endif return dummy; } void * mymalloc(int size, char *what) { void *dummy = myrealloc(NULL, size, what); if (!dummy) error_exit("failed to allocate %d bytes for %s\n", size, what); return dummy; } char * mystrndup(char *in, int len) { #ifdef _DEBUG char *dummy = (char *)mymalloc(len + 1, in); if (!dummy) error_exit("failed to copy string '%s': out of memory?\n", in); memcpy(dummy, in, len + 1); return dummy; #else char *dummy = strndup(in, len); if (!dummy) error_exit("failed to copy string '%s': out of memory?\n", in); return dummy; #endif } char * mystrdup(char *in) { return mystrndup(in, strlen(in)); } ssize_t WRITE(int fd, char *whereto, size_t len) { ssize_t cnt=0; while(len>0) { ssize_t rc; rc = write(fd, whereto, len); if (rc == -1) { if (errno != EINTR && errno != EINPROGRESS && errno != EAGAIN) { syslog(LOG_INFO, "Error sending to IRC server: %m"); return -1; } } else if (rc == 0) { return -1; } else { whereto += rc; len -= rc; cnt += rc; } } return cnt; } int get_filesize(char *filename) { struct stat buf; if (stat(filename, &buf) == -1) { if (errno != ENOENT) error_exit("stat failed for %s", filename); return -1; } return buf.st_size; } time_t get_filechanged(char *filename) { struct stat buf; if (stat(filename, &buf) == -1) { if (errno != ENOENT) error_exit("stat failed for %s", filename); return -1; } return buf.st_mtime; } void resolve_host(char *host, struct sockaddr_in *addr) { struct hostent *hostdnsentries; hostdnsentries = gethostbyname(host); if (hostdnsentries == NULL) { switch(h_errno) { case HOST_NOT_FOUND: error_exit("The specified host is unknown.\n"); break; case NO_ADDRESS: error_exit("The requested name is valid but does not have an IP address.\n"); break; case NO_RECOVERY: error_exit("A non-recoverable name server error occurred.\n"); break; case TRY_AGAIN: error_exit("A temporary error occurred on an authoritative name server. Try again later.\n"); break; default: error_exit("Could not resolve %s for an unknown reason (%d)\n", host, h_errno); } } /* create address structure */ addr -> sin_family = hostdnsentries -> h_addrtype; addr -> sin_addr = incopy(hostdnsentries -> h_addr_list[0]); } int connect_to(char *h) { char *hoststr = mystrdup(h); int fd; char *colon = strchr(hoststr, ':'); int portnr = 33333; struct sockaddr_in addr; int keep_alive = 1; if (colon) { *colon = 0x00; portnr = atoi(colon + 1); } /* resolve */ memset(&addr, 0x00, sizeof(addr)); resolve_host(hoststr, &addr); addr.sin_port = htons(portnr); myfree(hoststr, "connect_to"); /* connect */ fd = socket(AF_INET, SOCK_STREAM, 0); if (fd == -1) error_exit("problem creating socket"); if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (char *)&keep_alive, sizeof(keep_alive)) == -1) error_exit("problem setting KEEPALIVE"); /* connect to peer */ if (connect(fd, (struct sockaddr *)&addr, sizeof(struct sockaddr)) == 0) { /* connection made, return */ return fd; } close(fd); return -1; } int write_pidfile(char *fname) { FILE *fh = fopen(fname, "w"); if (!fh) error_exit("write_pidfile::fopen: failed creating file %s", fname); fprintf(fh, "%i", getpid()); fclose(fh); return 0; } nagcon-0.0.30/license.txt0000644000175000017500000000017711044324253015123 0ustar folkertfolkertThe license of this program can be obtained from: http://www.vanheusden.com/license.txt It is actually the GNU Public License. nagcon-0.0.30/readme.txt0000644000175000017500000000061711044324253014735 0ustar folkertfolkertInstallation: make install Need help? nagcon -h will give you a list of possible switches. For everything more or less related to 'nagcon', please feel free to contact me on: folkert@vanheusden.com Consider using PGP. My PGP key-id is: 0x1f28d8ae Thanks to Niels van Sluis for fixes to make it run under Solaris. Please support my opensource development: http://www.vanheusden.com/wishlist.php nagcon-0.0.30/br.cpp0000644000175000017500000001271211044324253014045 0ustar folkertfolkert/* * Copyright (C) 2006 Folkert van Heusden * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * */ #define _LARGEFILE64_SOURCE #include #include #include #include #include #include #include #include #include #include #include #include "br.h" buffered_reader::buffered_reader(int cur_fd, int cur_block_size) { #ifdef USE_MMAP struct stat64 finfo; #endif fd = cur_fd; block_size = cur_block_size; buffer = NULL; buffer_length = buffer_pointer = 0; mmap_addr = NULL; /* try do mmap */ #ifdef USE_MMAP if (fstat64(cur_fd, &finfo) == 0) { if (!S_ISFIFO(finfo.st_mode)) { /* mmap */ size_of_file = finfo.st_size; cur_offset = mmap_addr = (char *)mmap64(NULL, size_of_file, PROT_READ, MAP_SHARED, cur_fd, 0); if (!mmap_addr) { fprintf(stderr, "mmap64 failed: %d/%s\n", errno, strerror(errno)); } /* advise the kernel how to treat the mmaped region */ /* FIXME: change to madvise64 as soon as it comes available */ (void)madvise(mmap_addr, size_of_file, MADV_SEQUENTIAL); // fprintf(stderr, "*using mmap*\n"); } } else { fprintf(stderr, "Error obtaining information on fd %d: %d/%s\n", cur_fd, errno, strerror(errno)); } #endif if (!mmap_addr) { #if (_XOPEN_VERSION >= 600) (void)posix_fadvise(cur_fd, 0, 0, POSIX_FADV_SEQUENTIAL); // or POSIX_FADV_NOREUSE? #endif } } buffered_reader::~buffered_reader() { free(buffer); if (mmap_addr) munmap(mmap_addr, size_of_file); } int buffered_reader::number_of_bytes_in_buffer(void) { return buffer_length - buffer_pointer; } int buffered_reader::garbage_collect(char shrink_buffer) { if (buffer_pointer) { int n_to_move = number_of_bytes_in_buffer(); if (n_to_move > 0) { memmove(&buffer[0], &buffer[buffer_pointer], n_to_move); buffer_length -= buffer_pointer; buffer_pointer = 0; if (shrink_buffer) { char *dummy = (char *)realloc(buffer, buffer_length + 1); if (!dummy) { fprintf(stderr, "buffered_reader::garbage_collect: realloc failed\n"); syslog(LOG_EMERG, "buffered_reader::garbage_collect: realloc failed"); exit(1); } buffer = dummy; } buffer[buffer_length] = 0x00; } } return 0; } int buffered_reader::read_into_buffer(void) { char *dummy; int n_read = 0; garbage_collect(); dummy = (char *)realloc(buffer, buffer_length + block_size + 1); if (!dummy) { fprintf(stderr, "buffered_reader::read_into_buffer: realloc failed\n"); syslog(LOG_EMERG, "buffered_reader::read_into_buffer: realloc failed"); exit(1); } buffer = dummy; for(;;) { n_read = read(fd, &buffer[buffer_length], block_size); if (n_read == -1) { if (errno == EINTR || errno == EAGAIN) continue; fprintf(stderr, "buffered_reader::read_into_buffer: read failed (%s)\n", strerror(errno)); syslog(LOG_EMERG, "buffered_reader::read_into_buffer: read failed: %m"); exit(1); } buffer_length += n_read; break; } buffer[buffer_length] = 0x00; return n_read; } char * buffered_reader::read_line(void) { char *out = NULL; #ifdef USE_MMAP if (mmap_addr) { long long int n_bytes; char *lf; char *virtual_0x00 = &mmap_addr[size_of_file]; /* EOF reached? */ if (!cur_offset) return NULL; /* determine length of current line */ lf = (char *)memchr(cur_offset, '\n', (virtual_0x00 - cur_offset)); if (lf) n_bytes = lf - cur_offset; else n_bytes = virtual_0x00 - cur_offset; /* allocate memory & copy string */ out = (char *)malloc(n_bytes + 1); if (!out) { fprintf(stderr, "buffered_reader::read_line: malloc(%lld) failed\n", n_bytes + 1); syslog(LOG_EMERG, "buffered_reader::read_line: malloc(%lld) failed", n_bytes + 1); exit(1); } memcpy(out, cur_offset, n_bytes); out[n_bytes] = 0x00; if (lf) cur_offset = lf + 1; else cur_offset = NULL; } else #endif { long long int lf_offset = -1; long long int n_bytes, search_start; if (number_of_bytes_in_buffer() <= 0) { garbage_collect(); if (read_into_buffer() == 0) { // EOF return NULL; } } search_start = buffer_pointer; for(;;) { char *dummy = strchr(&buffer[buffer_pointer], '\n'); if (dummy) lf_offset = (long long int)(dummy - buffer); if (lf_offset != -1) break; if (read_into_buffer() == 0) { lf_offset = buffer_length; break; } } n_bytes = lf_offset - buffer_pointer; out = strndup(&buffer[buffer_pointer], n_bytes); if (!out) { fprintf(stderr, "buffered_reader::read_line: malloc(%lld) failed\n", n_bytes + 1); syslog(LOG_EMERG, "buffered_reader::read_line: malloc(%lld) failed", n_bytes + 1); exit(1); } buffer_pointer = lf_offset + 1; } return out; } off64_t buffered_reader::file_offset(void) { if (mmap_addr) return cur_offset - mmap_addr; else return lseek64(fd, 0, SEEK_CUR); }