/************************************************************************** * * AVAIL.C - Nagios Availability CGI * * * License: * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. *************************************************************************/ #include "../include/config.h" #include "../include/common.h" #include "../include/objects.h" #include "../include/comments.h" #include "../include/statusdata.h" #include "../include/cgiutils.h" #include "../include/cgiauth.h" #include "../include/getcgi.h" extern char main_config_file[MAX_FILENAME_LENGTH]; extern char url_html_path[MAX_FILENAME_LENGTH]; extern char url_images_path[MAX_FILENAME_LENGTH]; extern char url_stylesheets_path[MAX_FILENAME_LENGTH]; #ifndef max #define max(a,b) (((a) > (b)) ? (a) : (b)) #endif #ifndef min #define min(a,b) (((a) < (b)) ? (a) : (b)) #endif /* output types */ #define HTML_OUTPUT 0 #define CSV_OUTPUT 1 /* archived state types */ #define AS_CURRENT_STATE -1 /* special case for initial assumed state */ #define AS_NO_DATA 0 #define AS_PROGRAM_END 1 #define AS_PROGRAM_START 2 #define AS_HOST_UP 3 #define AS_HOST_DOWN 4 #define AS_HOST_UNREACHABLE 5 #define AS_SVC_OK 6 #define AS_SVC_UNKNOWN 7 #define AS_SVC_WARNING 8 #define AS_SVC_CRITICAL 9 #define AS_SVC_DOWNTIME_START 10 #define AS_SVC_DOWNTIME_END 11 #define AS_HOST_DOWNTIME_START 12 #define AS_HOST_DOWNTIME_END 13 #define AS_SOFT_STATE 1 #define AS_HARD_STATE 2 /* display types */ #define DISPLAY_NO_AVAIL 0 #define DISPLAY_HOSTGROUP_AVAIL 1 #define DISPLAY_HOST_AVAIL 2 #define DISPLAY_SERVICE_AVAIL 3 #define DISPLAY_SERVICEGROUP_AVAIL 4 /* subject types */ #define HOST_SUBJECT 0 #define SERVICE_SUBJECT 1 /* standard report times */ #define TIMEPERIOD_CUSTOM 0 #define TIMEPERIOD_TODAY 1 #define TIMEPERIOD_YESTERDAY 2 #define TIMEPERIOD_THISWEEK 3 #define TIMEPERIOD_LASTWEEK 4 #define TIMEPERIOD_THISMONTH 5 #define TIMEPERIOD_LASTMONTH 6 #define TIMEPERIOD_THISQUARTER 7 #define TIMEPERIOD_LASTQUARTER 8 #define TIMEPERIOD_THISYEAR 9 #define TIMEPERIOD_LASTYEAR 10 #define TIMEPERIOD_LAST24HOURS 11 #define TIMEPERIOD_LAST7DAYS 12 #define TIMEPERIOD_LAST31DAYS 13 #define MIN_TIMESTAMP_SPACING 10 #define MAX_ARCHIVE_SPREAD 65 #define MAX_ARCHIVE 65 #define MAX_ARCHIVE_BACKTRACKS 60 authdata current_authdata; typedef struct archived_state_struct { time_t time_stamp; int entry_type; int state_type; char *state_info; int processed_state; struct archived_state_struct *misc_ptr; struct archived_state_struct *next; } archived_state; typedef struct avail_subject_struct { int type; char *host_name; char *service_description; archived_state *as_list; /* archived state list */ archived_state *as_list_tail; archived_state *sd_list; /* scheduled downtime list */ int last_known_state; time_t earliest_time; time_t latest_time; int earliest_state; int latest_state; unsigned long time_up; unsigned long time_down; unsigned long time_unreachable; unsigned long time_ok; unsigned long time_warning; unsigned long time_unknown; unsigned long time_critical; unsigned long scheduled_time_up; unsigned long scheduled_time_down; unsigned long scheduled_time_unreachable; unsigned long scheduled_time_ok; unsigned long scheduled_time_warning; unsigned long scheduled_time_unknown; unsigned long scheduled_time_critical; unsigned long scheduled_time_indeterminate; unsigned long time_indeterminate_nodata; unsigned long time_indeterminate_notrunning; struct avail_subject_struct *next; } avail_subject; avail_subject *subject_list = NULL; time_t t1; time_t t2; int display_type = DISPLAY_NO_AVAIL; int timeperiod_type = TIMEPERIOD_LAST24HOURS; int show_log_entries = FALSE; int full_log_entries = FALSE; int show_scheduled_downtime = TRUE; int start_second = 0; int start_minute = 0; int start_hour = 0; int start_day = 1; int start_month = 1; int start_year = 2000; int end_second = 0; int end_minute = 0; int end_hour = 24; int end_day = 1; int end_month = 1; int end_year = 2000; int get_date_parts = FALSE; int select_hostgroups = FALSE; int select_hosts = FALSE; int select_servicegroups = FALSE; int select_services = FALSE; int select_output_format = FALSE; int compute_time_from_parts = FALSE; int show_all_hostgroups = FALSE; int show_all_hosts = FALSE; int show_all_servicegroups = FALSE; int show_all_services = FALSE; int assume_initial_states = TRUE; int assume_state_retention = TRUE; int assume_states_during_notrunning = TRUE; int initial_assumed_host_state = AS_NO_DATA; int initial_assumed_service_state = AS_NO_DATA; int include_soft_states = FALSE; char *hostgroup_name = ""; char *host_name = ""; char *servicegroup_name = ""; char *svc_description = ""; void create_subject_list(void); void add_subject(int, char *, char *); avail_subject *find_subject(int, char *, char *); void compute_availability(void); void compute_subject_availability(avail_subject *, time_t); void compute_subject_availability_times(int, int, time_t, time_t, time_t, avail_subject *, archived_state *); void compute_subject_downtime(avail_subject *, time_t); void compute_subject_downtime_times(time_t, time_t, avail_subject *, archived_state *); void compute_subject_downtime_part_times(time_t, time_t, int, avail_subject *); void display_hostgroup_availability(void); void display_specific_hostgroup_availability(hostgroup *); void display_servicegroup_availability(void); void display_specific_servicegroup_availability(servicegroup *); void display_host_availability(void); void display_service_availability(void); void write_log_entries(avail_subject *); void get_running_average(double *, double, int); void host_report_url(const char *, const char *); void service_report_url(const char *, const char *, const char *); void compute_report_times(void); int convert_host_state_to_archived_state(int); int convert_service_state_to_archived_state(int); void add_global_archived_state(int, int, time_t, const char *); void add_archived_state(int, int, time_t, const char *, avail_subject *); void add_scheduled_downtime(int, time_t, avail_subject *); void free_availability_data(void); void free_archived_state_list(archived_state *); void read_archived_state_data(void); void scan_log_file_for_archived_state_data(char *); void convert_timeperiod_to_times(int); unsigned long calculate_total_time(time_t, time_t); void document_header(int); void document_footer(void); int process_cgivars(void); int backtrack_archives = 2; int earliest_archive = 0; int embedded = FALSE; int display_header = TRUE; timeperiod *current_timeperiod = NULL; int output_format = HTML_OUTPUT; int main(int argc, char **argv) { char temp_buffer[MAX_INPUT_BUFFER]; char start_timestring[MAX_DATETIME_LENGTH]; char end_timestring[MAX_DATETIME_LENGTH]; host *temp_host; service *temp_service; int is_authorized = TRUE; time_t report_start_time; time_t report_end_time; int days, hours, minutes, seconds; hostgroup *temp_hostgroup; servicegroup *temp_servicegroup; timeperiod *temp_timeperiod; time_t t3; time_t current_time; struct tm *t; char *firsthostpointer; /* reset internal CGI variables */ reset_cgi_vars(); cgi_init(document_header, document_footer, READ_ALL_OBJECT_DATA, READ_ALL_STATUS_DATA); /* initialize time period to last 24 hours */ time(¤t_time); t2 = current_time; t1 = (time_t)(current_time - (60 * 60 * 24)); /* default number of backtracked archives */ switch (log_rotation_method) { case LOG_ROTATION_MONTHLY: backtrack_archives = 1; break; case LOG_ROTATION_WEEKLY: backtrack_archives = 2; break; case LOG_ROTATION_DAILY: backtrack_archives = 4; break; case LOG_ROTATION_HOURLY: backtrack_archives = 8; break; default: backtrack_archives = 2; break; } /* get the arguments passed in the URL */ process_cgivars(); document_header(TRUE); /* get authentication information */ get_authentication_information(¤t_authdata); if (compute_time_from_parts == TRUE) compute_report_times(); /* make sure times are sane, otherwise swap them */ if (t2 < t1) { t3 = t2; t2 = t1; t1 = t3; } /* don't let user create reports in the future */ if (t2 > current_time) { t2 = current_time; if (t1 > t2) t1 = t2 - (60 * 60 * 24); } if (display_header == TRUE) { /* begin top table */ printf("\n"); printf("\n"); /* left column of the first row */ printf("\n"); /* center column of top row */ printf("\n"); /* right hand column of top row */ printf("\n"); /* end of top table */ printf("\n"); printf("
\n"); switch (display_type) { case DISPLAY_HOST_AVAIL: snprintf(temp_buffer, sizeof(temp_buffer) - 1, "Host Availability Report"); break; case DISPLAY_SERVICE_AVAIL: snprintf(temp_buffer, sizeof(temp_buffer) - 1, "Service Availability Report"); break; case DISPLAY_HOSTGROUP_AVAIL: snprintf(temp_buffer, sizeof(temp_buffer) - 1, "Hostgroup Availability Report"); break; case DISPLAY_SERVICEGROUP_AVAIL: snprintf(temp_buffer, sizeof(temp_buffer) - 1, "Servicegroup Availability Report"); break; default: snprintf(temp_buffer, sizeof(temp_buffer) - 1, "Availability Report"); break; } temp_buffer[sizeof(temp_buffer) - 1] = '\x0'; display_info_table(temp_buffer, FALSE, ¤t_authdata); if (((display_type == DISPLAY_HOST_AVAIL && show_all_hosts == FALSE) || (display_type == DISPLAY_SERVICE_AVAIL && show_all_services == FALSE)) && get_date_parts == FALSE) { printf("\n"); printf("\n"); printf("\n"); } printf("\n"); if (display_type != DISPLAY_NO_AVAIL && get_date_parts == FALSE) { printf("
\n"); if (display_type == DISPLAY_HOST_AVAIL) { if (show_all_hosts == TRUE) printf("All Hosts"); else printf("Host '%s'", host_name); } else if (display_type == DISPLAY_SERVICE_AVAIL) { if (show_all_services == TRUE) printf("All Services"); else printf("Service '%s' On Host '%s'", svc_description, host_name); } else if (display_type == DISPLAY_HOSTGROUP_AVAIL) { if (show_all_hostgroups == TRUE) printf("All Hostgroups"); else printf("Hostgroup '%s'", hostgroup_name); } else if (display_type == DISPLAY_SERVICEGROUP_AVAIL) { if (show_all_servicegroups == TRUE) printf("All Servicegroups"); else printf("Servicegroup '%s'", servicegroup_name); } printf("
\n"); printf("
\n"); printf("Availability Report\n", url_images_path, TRENDS_ICON); printf("
\n"); get_time_string(&t1, start_timestring, sizeof(start_timestring) - 1, SHORT_DATE_TIME); get_time_string(&t2, end_timestring, sizeof(end_timestring) - 1, SHORT_DATE_TIME); printf("
%s to %s
\n", start_timestring, end_timestring); get_time_breakdown((time_t)(t2 - t1), &days, &hours, &minutes, &seconds); printf("
Duration: %dd %dh %dm %ds", days, hours, minutes, seconds); if (current_timeperiod) printf("
(using timeperiod %s)", current_timeperiod->name); printf("
\n"); } printf("
\n"); printf("
\n", AVAIL_CGI); printf("\n"); if (display_type != DISPLAY_NO_AVAIL && get_date_parts == FALSE) { printf("\n", (display_type == DISPLAY_SERVICE_AVAIL) ? "service" : "host", (display_type == DISPLAY_HOST_AVAIL || display_type == DISPLAY_HOSTGROUP_AVAIL || display_type == DISPLAY_SERVICEGROUP_AVAIL) ? "First assumed service state" : ""); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); } /* display context-sensitive help */ printf("\n"); printf("
First assumed %s state:%s
\n"); printf("\n", (unsigned long)t1); printf("\n", (unsigned long)t2); if (show_log_entries == TRUE) printf("\n"); if (full_log_entries == TRUE) printf("\n"); if (display_type == DISPLAY_HOSTGROUP_AVAIL) printf("\n", escape_string(hostgroup_name)); if (display_type == DISPLAY_HOST_AVAIL || display_type == DISPLAY_SERVICE_AVAIL) printf("\n", escape_string(host_name)); if (display_type == DISPLAY_SERVICE_AVAIL) printf("\n", escape_string(svc_description)); if (display_type == DISPLAY_SERVICEGROUP_AVAIL) printf("\n", escape_string(servicegroup_name)); printf("\n", (assume_initial_states == TRUE) ? "yes" : "no"); printf("\n", (assume_state_retention == TRUE) ? "yes" : "no"); printf("\n", (assume_states_during_notrunning == TRUE) ? "yes" : "no"); printf("\n", (include_soft_states == TRUE) ? "yes" : "no"); if (display_type == DISPLAY_HOST_AVAIL || display_type == DISPLAY_HOSTGROUP_AVAIL || display_type == DISPLAY_SERVICEGROUP_AVAIL) { printf("\n"); } else { printf("", initial_assumed_host_state); printf("\n"); } printf("\n"); if (display_type == DISPLAY_HOST_AVAIL || display_type == DISPLAY_HOSTGROUP_AVAIL || display_type == DISPLAY_SERVICEGROUP_AVAIL) { printf("\n"); } printf("
Report period:Backtracked archives:
\n"); printf("\n"); printf("\n"); printf("\n", backtrack_archives); printf("
\n"); printf("\n"); printf("
\n"); if (get_date_parts == TRUE) display_context_help(CONTEXTHELP_AVAIL_MENU5); else if (select_hostgroups == TRUE) display_context_help(CONTEXTHELP_AVAIL_MENU2); else if (select_hosts == TRUE) display_context_help(CONTEXTHELP_AVAIL_MENU3); else if (select_services == TRUE) display_context_help(CONTEXTHELP_AVAIL_MENU4); else if (display_type == DISPLAY_HOSTGROUP_AVAIL) display_context_help(CONTEXTHELP_AVAIL_HOSTGROUP); else if (display_type == DISPLAY_HOST_AVAIL) display_context_help(CONTEXTHELP_AVAIL_HOST); else if (display_type == DISPLAY_SERVICE_AVAIL) display_context_help(CONTEXTHELP_AVAIL_SERVICE); else if (display_type == DISPLAY_SERVICEGROUP_AVAIL) display_context_help(CONTEXTHELP_AVAIL_SERVICEGROUP); else display_context_help(CONTEXTHELP_AVAIL_MENU1); printf("
\n"); printf("
\n"); printf("
\n"); } /* step 3 - ask user for report date range */ if (get_date_parts == TRUE) { time(¤t_time); t = localtime(¤t_time); start_day = 1; start_year = t->tm_year + 1900; end_day = t->tm_mday; end_year = t->tm_year + 1900; printf("

Step 3: Select Report Options

\n"); printf("

\n"); printf("
\n", AVAIL_CGI); printf("\n"); if (display_type == DISPLAY_HOSTGROUP_AVAIL) printf("\n", escape_string(hostgroup_name)); if (display_type == DISPLAY_HOST_AVAIL || display_type == DISPLAY_SERVICE_AVAIL) printf("\n", escape_string(host_name)); if (display_type == DISPLAY_SERVICE_AVAIL) printf("\n", escape_string(svc_description)); if (display_type == DISPLAY_SERVICEGROUP_AVAIL) printf("\n", escape_string(servicegroup_name)); printf("\n"); printf(""); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf(""); printf("\n"); printf("\n"); printf("\n"); printf(""); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf(""); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); if (display_type != DISPLAY_SERVICE_AVAIL) { printf("\n"); printf("\n"); } printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf(""); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("
Report Period:\n"); printf("\n"); printf("
If Custom Report Period...
Start Date (Inclusive):"); printf("\n "); printf(" ", start_day); printf("", start_year); printf("\n"); printf("\n"); printf("\n"); printf("
End Date (Inclusive):"); printf("\n "); printf(" ", end_day); printf("", end_year); printf("\n"); printf("\n"); printf("\n"); printf("

Report time Period:\n"); printf("\n"); printf("

Assume Initial States:\n"); printf("\n"); printf("
Assume State Retention:\n"); printf("\n"); printf("
Assume States During Program Downtime:\n"); printf("\n"); printf("
Include Soft States:\n"); printf("\n"); printf("
First Assumed Host State:\n"); printf("\n"); printf("
First Assumed Service State:\n"); printf("\n"); printf("
Backtracked Archives (To Scan For Initial States):\n"); printf("\n", backtrack_archives); printf("
Output in CSV Format:"); printf("\n"); printf("
\n"); printf("
\n"); printf("

\n"); } /* step 2 - the user wants to select a hostgroup */ else if (select_hostgroups == TRUE) { printf("

Step 2: Select Hostgroup

\n"); printf("

\n"); printf("
\n", AVAIL_CGI); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("
Hostgroup(s):\n"); printf("\n"); printf("
\n"); printf("
\n"); printf("

\n"); } /* step 2 - the user wants to select a host */ else if (select_hosts == TRUE) { printf("

Step 2: Select Host

\n"); printf("

\n"); printf("
\n", AVAIL_CGI); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("
Host(s):\n"); printf("\n"); printf("
\n"); printf("
\n"); printf("

\n"); printf("
Tip: If you want to have the option of getting the availability data in CSV format, select '** ALL HOSTS **' from the pull-down menu.\n"); } /* step 2 - the user wants to select a servicegroup */ else if (select_servicegroups == TRUE) { printf("

Step 2: Select Servicegroup

\n"); printf("

\n"); printf("
\n", AVAIL_CGI); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("
Servicegroup(s):\n"); printf("\n"); printf("
\n"); printf("
\n"); printf("

\n"); } /* step 2 - the user wants to select a service */ else if (select_services == TRUE) { printf("\n"); printf("

Step 2: Select Service

\n"); printf("

\n"); printf("
\n", AVAIL_CGI); printf("\n"); printf("\n", (firsthostpointer == NULL) ? "unknown" : (char *)escape_string(firsthostpointer)); printf("\n"); printf("\n"); printf("\n"); printf("
Service(s):\n"); printf("\n"); printf("
\n"); printf("
\n"); printf("

\n"); printf("
Tip: If you want to have the option of getting the availability data in CSV format, select '** ALL SERVICES **' from the pull-down menu.\n"); } /* generate availability report */ else if (display_type != DISPLAY_NO_AVAIL) { /* check authorization */ is_authorized = TRUE; if ((display_type == DISPLAY_HOST_AVAIL && show_all_hosts == FALSE) || (display_type == DISPLAY_SERVICE_AVAIL && show_all_services == FALSE)) { if (display_type == DISPLAY_HOST_AVAIL && show_all_hosts == FALSE) is_authorized = is_authorized_for_host(find_host(host_name), ¤t_authdata); else is_authorized = is_authorized_for_service(find_service(host_name, svc_description), ¤t_authdata); } if (is_authorized == FALSE) printf("

It appears as though you are not authorized to view information for the specified %s...

\n", (display_type == DISPLAY_HOST_AVAIL) ? "host" : "service"); else { time(&report_start_time); /* create list of subjects to collect availability data for */ create_subject_list(); /* read in all necessary archived state data */ read_archived_state_data(); /* compute availability data */ compute_availability(); time(&report_end_time); if (output_format == HTML_OUTPUT) { get_time_breakdown((time_t)(report_end_time - report_start_time), &days, &hours, &minutes, &seconds); printf("
[ Availability report completed in %d min %d sec ]
\n", minutes, seconds); printf("

\n"); } /* display availability data */ if (display_type == DISPLAY_HOST_AVAIL) display_host_availability(); else if (display_type == DISPLAY_SERVICE_AVAIL) display_service_availability(); else if (display_type == DISPLAY_HOSTGROUP_AVAIL) display_hostgroup_availability(); else if (display_type == DISPLAY_SERVICEGROUP_AVAIL) display_servicegroup_availability(); /* free memory allocated to availability data */ free_availability_data(); } } /* step 1 - ask the user what kind of report they want */ else { printf("

Step 1: Select Report Type

\n"); printf("

\n"); printf("
\n", AVAIL_CGI); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("
Type:\n"); printf("\n"); printf("
\n"); printf("
\n"); printf("

\n"); } document_footer(); /* free all other allocated memory */ free_memory(); return OK; } void document_header(int use_stylesheet) { char date_time[MAX_DATETIME_LENGTH]; time_t current_time; time_t expire_time; printf("Cache-Control: no-store\r\n"); printf("Pragma: no-cache\r\n"); time(¤t_time); get_time_string(¤t_time, date_time, sizeof(date_time), HTTP_DATE_TIME); printf("Last-Modified: %s\r\n", date_time); expire_time = (time_t)0; get_time_string(&expire_time, date_time, sizeof(date_time), HTTP_DATE_TIME); printf("Expires: %s\r\n", date_time); if (output_format == HTML_OUTPUT) printf("Content-type: text/html; charset=utf-8\r\n\r\n"); else { printf("Content-type: text/csv\r\n"); printf("Content-Disposition: attachment; filename=\"avail.csv\"\r\n\r\n"); return; } if (embedded == TRUE || output_format == CSV_OUTPUT) return; printf("\n"); printf("\n"); printf("\n", url_images_path); printf("\n"); printf("Nagios Availability\n"); printf("\n"); if (use_stylesheet == TRUE) { printf("\n", url_stylesheets_path, COMMON_CSS); printf("\n", url_stylesheets_path, AVAIL_CSS); } printf("\n"); printf("\n"); /* include user SSI header */ include_ssi_files(AVAIL_CGI, SSI_HEADER); return; } void document_footer(void) { if (output_format != HTML_OUTPUT) return; if (embedded == TRUE) return; /* include user SSI footer */ include_ssi_files(AVAIL_CGI, SSI_FOOTER); printf("\n"); printf("\n"); return; } int process_cgivars(void) { char **variables; int error = FALSE; int x; variables = getcgivars(); for (x = 0; variables[x]; x++) { /* do some basic length checking on the variable identifier to prevent buffer overflows */ if (strlen(variables[x]) >= MAX_INPUT_BUFFER - 1) { continue; } /* we found the hostgroup argument */ else if (!strcmp(variables[x], "hostgroup")) { x++; if (variables[x] == NULL) { error = TRUE; break; } if ((hostgroup_name = (char *)strdup(variables[x])) == NULL) hostgroup_name = ""; strip_html_brackets(hostgroup_name); display_type = DISPLAY_HOSTGROUP_AVAIL; show_all_hostgroups = (strcmp(hostgroup_name, "all")) ? FALSE : TRUE; } /* we found the servicegroup argument */ else if (!strcmp(variables[x], "servicegroup")) { x++; if (variables[x] == NULL) { error = TRUE; break; } if ((servicegroup_name = (char *)strdup(variables[x])) == NULL) servicegroup_name = ""; strip_html_brackets(servicegroup_name); display_type = DISPLAY_SERVICEGROUP_AVAIL; show_all_servicegroups = (strcmp(servicegroup_name, "all")) ? FALSE : TRUE; } /* we found the host argument */ else if (!strcmp(variables[x], "host")) { x++; if (variables[x] == NULL) { error = TRUE; break; } if ((host_name = (char *)strdup(variables[x])) == NULL) host_name = ""; strip_html_brackets(host_name); display_type = DISPLAY_HOST_AVAIL; show_all_hosts = (strcmp(host_name, "all")) ? FALSE : TRUE; } /* we found the service description argument */ else if (!strcmp(variables[x], "service")) { x++; if (variables[x] == NULL) { error = TRUE; break; } if ((svc_description = (char *)strdup(variables[x])) == NULL) svc_description = ""; strip_html_brackets(svc_description); display_type = DISPLAY_SERVICE_AVAIL; show_all_services = (strcmp(svc_description, "all")) ? FALSE : TRUE; } /* we found first time argument */ else if (!strcmp(variables[x], "t1")) { x++; if (variables[x] == NULL) { error = TRUE; break; } t1 = (time_t)strtoul(variables[x], NULL, 10); timeperiod_type = TIMEPERIOD_CUSTOM; compute_time_from_parts = FALSE; } /* we found first time argument */ else if (!strcmp(variables[x], "t2")) { x++; if (variables[x] == NULL) { error = TRUE; break; } t2 = (time_t)strtoul(variables[x], NULL, 10); timeperiod_type = TIMEPERIOD_CUSTOM; compute_time_from_parts = FALSE; } /* we found the assume initial states option */ else if (!strcmp(variables[x], "assumeinitialstates")) { x++; if (variables[x] == NULL) { error = TRUE; break; } if (!strcmp(variables[x], "yes")) assume_initial_states = TRUE; else assume_initial_states = FALSE; } /* we found the assume state during program not running option */ else if (!strcmp(variables[x], "assumestatesduringnotrunning")) { x++; if (variables[x] == NULL) { error = TRUE; break; } if (!strcmp(variables[x], "yes")) assume_states_during_notrunning = TRUE; else assume_states_during_notrunning = FALSE; } /* we found the initial assumed host state option */ else if (!strcmp(variables[x], "initialassumedhoststate")) { x++; if (variables[x] == NULL) { error = TRUE; break; } initial_assumed_host_state = atoi(variables[x]); } /* we found the initial assumed service state option */ else if (!strcmp(variables[x], "initialassumedservicestate")) { x++; if (variables[x] == NULL) { error = TRUE; break; } initial_assumed_service_state = atoi(variables[x]); } /* we found the assume state retention option */ else if (!strcmp(variables[x], "assumestateretention")) { x++; if (variables[x] == NULL) { error = TRUE; break; } if (!strcmp(variables[x], "yes")) assume_state_retention = TRUE; else assume_state_retention = FALSE; } /* we found the include soft states option */ else if (!strcmp(variables[x], "includesoftstates")) { x++; if (variables[x] == NULL) { error = TRUE; break; } if (!strcmp(variables[x], "yes")) include_soft_states = TRUE; else include_soft_states = FALSE; } /* we found the backtrack archives argument */ else if (!strcmp(variables[x], "backtrack")) { x++; if (variables[x] == NULL) { error = TRUE; break; } backtrack_archives = atoi(variables[x]); if (backtrack_archives < 0) backtrack_archives = 0; if (backtrack_archives > MAX_ARCHIVE_BACKTRACKS) backtrack_archives = MAX_ARCHIVE_BACKTRACKS; #ifdef DEBUG printf("BACKTRACK ARCHIVES: %d\n", backtrack_archives); #endif } /* we found the standard timeperiod argument */ else if (!strcmp(variables[x], "timeperiod")) { x++; if (variables[x] == NULL) { error = TRUE; break; } if (!strcmp(variables[x], "today")) timeperiod_type = TIMEPERIOD_TODAY; else if (!strcmp(variables[x], "yesterday")) timeperiod_type = TIMEPERIOD_YESTERDAY; else if (!strcmp(variables[x], "thisweek")) timeperiod_type = TIMEPERIOD_THISWEEK; else if (!strcmp(variables[x], "lastweek")) timeperiod_type = TIMEPERIOD_LASTWEEK; else if (!strcmp(variables[x], "thismonth")) timeperiod_type = TIMEPERIOD_THISMONTH; else if (!strcmp(variables[x], "lastmonth")) timeperiod_type = TIMEPERIOD_LASTMONTH; else if (!strcmp(variables[x], "thisquarter")) timeperiod_type = TIMEPERIOD_THISQUARTER; else if (!strcmp(variables[x], "lastquarter")) timeperiod_type = TIMEPERIOD_LASTQUARTER; else if (!strcmp(variables[x], "thisyear")) timeperiod_type = TIMEPERIOD_THISYEAR; else if (!strcmp(variables[x], "lastyear")) timeperiod_type = TIMEPERIOD_LASTYEAR; else if (!strcmp(variables[x], "last24hours")) timeperiod_type = TIMEPERIOD_LAST24HOURS; else if (!strcmp(variables[x], "last7days")) timeperiod_type = TIMEPERIOD_LAST7DAYS; else if (!strcmp(variables[x], "last31days")) timeperiod_type = TIMEPERIOD_LAST31DAYS; else if (!strcmp(variables[x], "custom")) timeperiod_type = TIMEPERIOD_CUSTOM; else continue; convert_timeperiod_to_times(timeperiod_type); compute_time_from_parts = FALSE; } /* we found the embed option */ else if (!strcmp(variables[x], "embedded")) embedded = TRUE; /* we found the noheader option */ else if (!strcmp(variables[x], "noheader")) display_header = FALSE; /* we found the CSV output option */ else if (!strcmp(variables[x], "csvoutput")) { display_header = FALSE; output_format = CSV_OUTPUT; } /* we found the log entries option */ else if (!strcmp(variables[x], "show_log_entries")) show_log_entries = TRUE; /* we found the full log entries option */ else if (!strcmp(variables[x], "full_log_entries")) full_log_entries = TRUE; /* we found the get date parts option */ else if (!strcmp(variables[x], "get_date_parts")) get_date_parts = TRUE; /* we found the report type selection option */ else if (!strcmp(variables[x], "report_type")) { x++; if (variables[x] == NULL) { error = TRUE; break; } if (!strcmp(variables[x], "hostgroups")) select_hostgroups = TRUE; else if (!strcmp(variables[x], "servicegroups")) select_servicegroups = TRUE; else if (!strcmp(variables[x], "hosts")) select_hosts = TRUE; else select_services = TRUE; } /* we found time argument */ else if (!strcmp(variables[x], "smon")) { x++; if (variables[x] == NULL) { error = TRUE; break; } if (timeperiod_type != TIMEPERIOD_CUSTOM) continue; start_month = atoi(variables[x]); timeperiod_type = TIMEPERIOD_CUSTOM; compute_time_from_parts = TRUE; } /* we found time argument */ else if (!strcmp(variables[x], "sday")) { x++; if (variables[x] == NULL) { error = TRUE; break; } if (timeperiod_type != TIMEPERIOD_CUSTOM) continue; start_day = atoi(variables[x]); timeperiod_type = TIMEPERIOD_CUSTOM; compute_time_from_parts = TRUE; } /* we found time argument */ else if (!strcmp(variables[x], "syear")) { x++; if (variables[x] == NULL) { error = TRUE; break; } if (timeperiod_type != TIMEPERIOD_CUSTOM) continue; start_year = atoi(variables[x]); timeperiod_type = TIMEPERIOD_CUSTOM; compute_time_from_parts = TRUE; } /* we found time argument */ else if (!strcmp(variables[x], "smin")) { x++; if (variables[x] == NULL) { error = TRUE; break; } if (timeperiod_type != TIMEPERIOD_CUSTOM) continue; start_minute = atoi(variables[x]); timeperiod_type = TIMEPERIOD_CUSTOM; compute_time_from_parts = TRUE; } /* we found time argument */ else if (!strcmp(variables[x], "ssec")) { x++; if (variables[x] == NULL) { error = TRUE; break; } if (timeperiod_type != TIMEPERIOD_CUSTOM) continue; start_second = atoi(variables[x]); timeperiod_type = TIMEPERIOD_CUSTOM; compute_time_from_parts = TRUE; } /* we found time argument */ else if (!strcmp(variables[x], "shour")) { x++; if (variables[x] == NULL) { error = TRUE; break; } if (timeperiod_type != TIMEPERIOD_CUSTOM) continue; start_hour = atoi(variables[x]); timeperiod_type = TIMEPERIOD_CUSTOM; compute_time_from_parts = TRUE; } /* we found time argument */ else if (!strcmp(variables[x], "emon")) { x++; if (variables[x] == NULL) { error = TRUE; break; } if (timeperiod_type != TIMEPERIOD_CUSTOM) continue; end_month = atoi(variables[x]); timeperiod_type = TIMEPERIOD_CUSTOM; compute_time_from_parts = TRUE; } /* we found time argument */ else if (!strcmp(variables[x], "eday")) { x++; if (variables[x] == NULL) { error = TRUE; break; } if (timeperiod_type != TIMEPERIOD_CUSTOM) continue; end_day = atoi(variables[x]); timeperiod_type = TIMEPERIOD_CUSTOM; compute_time_from_parts = TRUE; } /* we found time argument */ else if (!strcmp(variables[x], "eyear")) { x++; if (variables[x] == NULL) { error = TRUE; break; } if (timeperiod_type != TIMEPERIOD_CUSTOM) continue; end_year = atoi(variables[x]); timeperiod_type = TIMEPERIOD_CUSTOM; compute_time_from_parts = TRUE; } /* we found time argument */ else if (!strcmp(variables[x], "emin")) { x++; if (variables[x] == NULL) { error = TRUE; break; } if (timeperiod_type != TIMEPERIOD_CUSTOM) continue; end_minute = atoi(variables[x]); timeperiod_type = TIMEPERIOD_CUSTOM; compute_time_from_parts = TRUE; } /* we found time argument */ else if (!strcmp(variables[x], "esec")) { x++; if (variables[x] == NULL) { error = TRUE; break; } if (timeperiod_type != TIMEPERIOD_CUSTOM) continue; end_second = atoi(variables[x]); timeperiod_type = TIMEPERIOD_CUSTOM; compute_time_from_parts = TRUE; } /* we found time argument */ else if (!strcmp(variables[x], "ehour")) { x++; if (variables[x] == NULL) { error = TRUE; break; } if (timeperiod_type != TIMEPERIOD_CUSTOM) continue; end_hour = atoi(variables[x]); timeperiod_type = TIMEPERIOD_CUSTOM; compute_time_from_parts = TRUE; } /* we found the show scheduled downtime option */ else if (!strcmp(variables[x], "showscheduleddowntime")) { x++; if (variables[x] == NULL) { error = TRUE; break; } if (!strcmp(variables[x], "yes")) show_scheduled_downtime = TRUE; else show_scheduled_downtime = FALSE; } /* we found the report timeperiod option */ else if (!strcmp(variables[x], "rpttimeperiod")) { timeperiod *temp_timeperiod; x++; if (variables[x] == NULL) { error = TRUE; break; } for (temp_timeperiod = timeperiod_list; temp_timeperiod != NULL; temp_timeperiod = temp_timeperiod->next) { if (!strcmp(temp_timeperiod->name, variables[x])) { current_timeperiod = temp_timeperiod; break; } } } } /* free memory allocated to the CGI variables */ free_cgivars(variables); return error; } /* computes availability data for all subjects */ void compute_availability(void) { avail_subject *temp_subject; time_t current_time; time(¤t_time); for (temp_subject = subject_list; temp_subject != NULL; temp_subject = temp_subject->next) { compute_subject_availability(temp_subject, current_time); compute_subject_downtime(temp_subject, current_time); } return; } /* computes availability data for a given subject */ void compute_subject_availability(avail_subject *subject, time_t current_time) { archived_state *temp_as; archived_state *last_as; time_t a; time_t b; int current_state = AS_NO_DATA; int have_some_real_data = FALSE; hoststatus *hststatus = NULL; servicestatus *svcstatus = NULL; time_t initial_assumed_time; int initial_assumed_state = AS_NO_DATA; int error; /* if left hand of graph is after current time, we can't do anything at all.... */ if (t1 > current_time) return; /* get current state of host or service if possible */ if (subject->type == HOST_SUBJECT) hststatus = find_hoststatus(subject->host_name); else svcstatus = find_servicestatus(subject->host_name, subject->service_description); /************************************/ /* INSERT CURRENT STATE (IF WE CAN) */ /************************************/ /* if current time DOES NOT fall within graph bounds, so we can't do anything as far as assuming current state */ /* if we don't have any data, assume current state (if possible) */ if (subject->as_list == NULL && current_time > t1 && current_time <= t2) { /* we don't have any historical information, but the current time falls within the reporting period, so use */ /* the current status of the host/service as the starting data */ if (subject->type == HOST_SUBJECT) { if (hststatus != NULL) { if (hststatus->status == SD_HOST_DOWN) subject->last_known_state = AS_HOST_DOWN; else if (hststatus->status == SD_HOST_UNREACHABLE) subject->last_known_state = AS_HOST_UNREACHABLE; else if (hststatus->status == SD_HOST_UP) subject->last_known_state = AS_HOST_UP; else subject->last_known_state = AS_NO_DATA; if (subject->last_known_state != AS_NO_DATA) { /* add a dummy archived state item, so something can get graphed */ add_archived_state(subject->last_known_state, AS_HARD_STATE, t1, "Current Host State Assumed (Faked Log Entry)", subject); } } } else { if (svcstatus != NULL) { if (svcstatus->status == SERVICE_OK) subject->last_known_state = AS_SVC_OK; else if (svcstatus->status == SERVICE_WARNING) subject->last_known_state = AS_SVC_WARNING; else if (svcstatus->status == SERVICE_CRITICAL) subject->last_known_state = AS_SVC_CRITICAL; else if (svcstatus->status == SERVICE_UNKNOWN) subject->last_known_state = AS_SVC_UNKNOWN; else subject->last_known_state = AS_NO_DATA; if (subject->last_known_state != AS_NO_DATA) { /* add a dummy archived state item, so something can get graphed */ add_archived_state(subject->last_known_state, AS_HARD_STATE, t1, "Current Service State Assumed (Faked Log Entry)", subject); } } } } /******************************************/ /* INSERT FIRST ASSUMED STATE (IF WE CAN) */ /******************************************/ if ((subject->type == HOST_SUBJECT && initial_assumed_host_state != AS_NO_DATA) || (subject->type == SERVICE_SUBJECT && initial_assumed_service_state != AS_NO_DATA)) { /* see if its okay to assume initial state for this subject */ error = FALSE; if (subject->type == SERVICE_SUBJECT) { if (initial_assumed_service_state != AS_SVC_OK && initial_assumed_service_state != AS_SVC_WARNING && initial_assumed_service_state != AS_SVC_UNKNOWN && initial_assumed_service_state != AS_SVC_CRITICAL && initial_assumed_service_state != AS_CURRENT_STATE) error = TRUE; else initial_assumed_state = initial_assumed_service_state; if (initial_assumed_service_state == AS_CURRENT_STATE && svcstatus == NULL) error = TRUE; } else { if (initial_assumed_host_state != AS_HOST_UP && initial_assumed_host_state != AS_HOST_DOWN && initial_assumed_host_state != AS_HOST_UNREACHABLE && initial_assumed_host_state != AS_CURRENT_STATE) error = TRUE; else initial_assumed_state = initial_assumed_host_state; if (initial_assumed_host_state == AS_CURRENT_STATE && hststatus == NULL) error = TRUE; } /* get the current state if applicable */ if (((subject->type == HOST_SUBJECT && initial_assumed_host_state == AS_CURRENT_STATE) || (subject->type == SERVICE_SUBJECT && initial_assumed_service_state == AS_CURRENT_STATE)) && error == FALSE) { if (subject->type == SERVICE_SUBJECT) { switch (svcstatus->status) { case SERVICE_OK: initial_assumed_state = AS_SVC_OK; break; case SERVICE_WARNING: initial_assumed_state = AS_SVC_WARNING; break; case SERVICE_UNKNOWN: initial_assumed_state = AS_SVC_UNKNOWN; break; case SERVICE_CRITICAL: initial_assumed_state = AS_SVC_CRITICAL; break; default: error = TRUE; break; } } else { switch (hststatus->status) { case SD_HOST_DOWN: initial_assumed_state = AS_HOST_DOWN; break; case SD_HOST_UNREACHABLE: initial_assumed_state = AS_HOST_UNREACHABLE; break; case SD_HOST_UP: initial_assumed_state = AS_HOST_UP; break; default: error = TRUE; break; } } } if (error == FALSE) { /* add this assumed state entry before any entries in the list and <= t1 */ if (subject->as_list == NULL) initial_assumed_time = t1; else if (subject->as_list->time_stamp > t1) initial_assumed_time = t1; else initial_assumed_time = subject->as_list->time_stamp - 1; if (subject->type == HOST_SUBJECT) add_archived_state(initial_assumed_state, AS_HARD_STATE, initial_assumed_time, "First Host State Assumed (Faked Log Entry)", subject); else add_archived_state(initial_assumed_state, AS_HARD_STATE, initial_assumed_time, "First Service State Assumed (Faked Log Entry)", subject); } } /**************************************/ /* BAIL OUT IF WE DON'T HAVE ANYTHING */ /**************************************/ have_some_real_data = FALSE; for (temp_as = subject->as_list; temp_as != NULL; temp_as = temp_as->next) { if (temp_as->entry_type != AS_NO_DATA && temp_as->entry_type != AS_PROGRAM_START && temp_as->entry_type != AS_PROGRAM_END) { have_some_real_data = TRUE; break; } } if (have_some_real_data == FALSE) return; last_as = NULL; subject->earliest_time = t2; subject->latest_time = t1; #ifdef DEBUG printf("--- BEGINNING/MIDDLE SECTION ---
\n"); #endif /**********************************/ /* BEGINNING/MIDDLE SECTION */ /**********************************/ for (temp_as = subject->as_list; temp_as != NULL; temp_as = temp_as->next) { /* keep this as last known state if this is the first entry or if it occurs before the starting point of the graph */ if ((temp_as->time_stamp <= t1 || temp_as == subject->as_list) && (temp_as->entry_type != AS_NO_DATA && temp_as->entry_type != AS_PROGRAM_END && temp_as->entry_type != AS_PROGRAM_START)) { subject->last_known_state = temp_as->entry_type; #ifdef DEBUG printf("SETTING LAST KNOWN STATE=%d
\n", subject->last_known_state); #endif } /* skip this entry if it occurs before the starting point of the graph */ if (temp_as->time_stamp <= t1) { #ifdef DEBUG printf("SKIPPING PRE-EVENT: %d @ %lu
\n", temp_as->entry_type, temp_as->time_stamp); #endif last_as = temp_as; continue; } /* graph this span if we're not on the first item */ if (last_as != NULL) { a = last_as->time_stamp; b = temp_as->time_stamp; /* we've already passed the last time displayed in the graph */ if (a > t2) break; /* only graph this data if its on the graph */ else if (b > t1) { /* clip last time if it exceeds graph limits */ if (b > t2) b = t2; /* clip first time if it precedes graph limits */ if (a < t1) a = t1; /* save this time if its the earliest we've graphed */ if (a < subject->earliest_time) { subject->earliest_time = a; subject->earliest_state = last_as->entry_type; } /* save this time if its the latest we've graphed */ if (b > subject->latest_time) { subject->latest_time = b; subject->latest_state = last_as->entry_type; } /* compute availability times for this chunk */ compute_subject_availability_times(last_as->entry_type, temp_as->entry_type, last_as->time_stamp, a, b, subject, temp_as); /* return if we've reached the end of the graph limits */ if (b >= t2) { last_as = temp_as; break; } } } /* keep track of the last item */ last_as = temp_as; } #ifdef DEBUG printf("--- END SECTION ---
\n"); #endif /**********************************/ /* END SECTION */ /**********************************/ if (last_as != NULL) { /* don't process an entry that is beyond the limits of the graph */ if (last_as->time_stamp < t2) { time(¤t_time); b = current_time; if (b > t2) b = t2; a = last_as->time_stamp; if (a < t1) a = t1; /* fake the current state (it doesn't really matter for graphing) */ if (subject->type == HOST_SUBJECT) current_state = AS_HOST_UP; else current_state = AS_SVC_OK; /* compute availability times for last state */ compute_subject_availability_times(last_as->entry_type, current_state, last_as->time_stamp, a, b, subject, last_as); } } return; } /* computes availability times */ void compute_subject_availability_times(int first_state, int last_state, time_t real_start_time, time_t start_time, time_t end_time, avail_subject *subject, archived_state *as) { int start_state = 0; unsigned long state_duration = 0L; struct tm *t = NULL; time_t midnight_today = 0L; int weekday = 0; timerange *temp_timerange = NULL; unsigned long temp_duration = 0L; unsigned long temp_end = 0L; unsigned long temp_start = 0L; unsigned long start = 0L; unsigned long end = 0L; #ifdef DEBUG if (subject->type == HOST_SUBJECT) { printf("HOST '%s'...\n", subject->host_name); } else { printf("SERVICE '%s' ON HOST '%s'...\n", subject->service_description, subject->host_name); } printf("COMPUTING %d->%d FROM %lu to %lu (%lu seconds) FOR %s
\n", first_state, last_state, start_time, end_time, (end_time - start_time), (subject->type == HOST_SUBJECT) ? "HOST" : "SERVICE"); #endif /* clip times if necessary */ if (start_time < t1) { start_time = t1; } if (end_time > t2) { end_time = t2; } /* make sure this is a valid time */ if (start_time > t2) { return; } if (end_time < t1) { return; } /* MickeM - attempt to handle the current time_period (if any) */ if (current_timeperiod != NULL) { t = localtime((time_t *)&start_time); state_duration = 0; /* calculate the start of the day (midnight, 00:00 hours) */ t->tm_sec = 0; t->tm_min = 0; t->tm_hour = 0; t->tm_isdst = -1; midnight_today = (unsigned long)mktime(t); weekday = t->tm_wday; while (midnight_today < end_time) { temp_duration = 0; temp_end = min(86400, end_time - midnight_today); temp_start = 0; if (start_time > midnight_today) { temp_start = start_time - midnight_today; } #ifdef DEBUG printf("Matching: %ld -> %ld. (%ld -> %ld)
\n", temp_start, temp_end, midnight_today + temp_start, midnight_today + temp_end); #endif /* check all time ranges for this day of the week */ for (temp_timerange = current_timeperiod->days[weekday]; temp_timerange != NULL; temp_timerange = temp_timerange->next) { #ifdef DEBUG printf("
  • Matching in timerange[%d]: %d -> %d (%ld -> %ld)
    \n", weekday, temp_timerange->range_start, temp_timerange->range_end, temp_start, temp_end); #endif start = max(temp_timerange->range_start, temp_start); end = min(temp_timerange->range_end, temp_end); if (start < end) { temp_duration += end - start; #ifdef DEBUG printf("
  • Matched time: %ld -> %ld = %d
    \n", start, end, temp_duration); #endif } #ifdef DEBUG else { printf("
  • Ignored time: %ld -> %ld
    \n", start, end); } #endif } state_duration += temp_duration; temp_start = 0; midnight_today += 86400; if (++weekday > 6) { weekday = 0; } } } /* no report timeperiod was selected (assume 24x7) */ else { /* calculate time in this state */ state_duration = (unsigned long)(end_time - start_time); } /* can't graph if we don't have data... */ if (first_state == AS_NO_DATA || last_state == AS_NO_DATA) { subject->time_indeterminate_nodata += state_duration; return; } if (first_state == AS_PROGRAM_START && (last_state == AS_PROGRAM_END || last_state == AS_PROGRAM_START)) { if (assume_initial_states == FALSE) { subject->time_indeterminate_nodata += state_duration; return; } } if (first_state == AS_PROGRAM_END) { if (assume_states_during_notrunning == TRUE) { first_state = subject->last_known_state; } else { subject->time_indeterminate_notrunning += state_duration; return; } } /* special case if first entry was program start */ if (first_state == AS_PROGRAM_START) { if (assume_initial_states == TRUE) { if (assume_state_retention == TRUE) { start_state = subject->last_known_state; } else { if (subject->type == HOST_SUBJECT) { start_state = AS_HOST_UP; } else { start_state = AS_SVC_OK; } } } else { return; } } else { start_state = first_state; subject->last_known_state = first_state; } /* save "processed state" info */ as->processed_state = start_state; #ifdef DEBUG printf("PASSED TIME CHECKS, CLIPPED VALUES: START=%lu, END=%lu\n", start_time, end_time); #endif /* add time in this state to running totals */ switch (start_state) { case AS_HOST_UP: subject->time_up += state_duration; break; case AS_HOST_DOWN: subject->time_down += state_duration; break; case AS_HOST_UNREACHABLE: subject->time_unreachable += state_duration; break; case AS_SVC_OK: subject->time_ok += state_duration; break; case AS_SVC_WARNING: subject->time_warning += state_duration; break; case AS_SVC_UNKNOWN: subject->time_unknown += state_duration; break; case AS_SVC_CRITICAL: subject->time_critical += state_duration; break; default: break; } } /* computes downtime data for a given subject */ void compute_subject_downtime(avail_subject *subject, time_t current_time) { archived_state *temp_sd = NULL; time_t start_time = 0L; time_t end_time = 0L; int host_downtime_state = 0; int service_downtime_state = 0; int process_chunk = FALSE; #ifdef DEBUG2 printf("COMPUTE_SUBJECT_DOWNTIME\n"); #endif /* if left hand of graph is after current time, we can't do anything at all.... */ if (t1 > current_time) { return; } /* no scheduled downtime data for subject... */ if (subject->sd_list == NULL) { return; } /* all data we have occurs after last time on graph... */ if (subject->sd_list->time_stamp >= t2) { return; } /* initialize pointer */ temp_sd = subject->sd_list; /* special case if first entry is the end of scheduled downtime */ if ((temp_sd->entry_type == AS_HOST_DOWNTIME_END || temp_sd->entry_type == AS_SVC_DOWNTIME_END) && temp_sd->time_stamp > t1) { #ifdef DEBUG2 printf("\tSPECIAL DOWNTIME CASE\n"); #endif start_time = t1; end_time = (temp_sd->time_stamp > t2) ? t2 : temp_sd->time_stamp; compute_subject_downtime_times(start_time, end_time, subject, NULL); temp_sd = temp_sd->next; } /* process all periods of scheduled downtime */ for (; temp_sd != NULL; temp_sd = temp_sd->next) { /* we've passed graph bounds... */ if (temp_sd->time_stamp >= t2) { break; } if (temp_sd->entry_type == AS_HOST_DOWNTIME_START) { host_downtime_state = 1; } else if (temp_sd->entry_type == AS_HOST_DOWNTIME_END) { host_downtime_state = 0; } else if (temp_sd->entry_type == AS_SVC_DOWNTIME_START) { service_downtime_state = 1; } else if (temp_sd->entry_type == AS_SVC_DOWNTIME_END) { service_downtime_state = 0; } else { continue; } process_chunk = FALSE; if (temp_sd->entry_type == AS_HOST_DOWNTIME_START || temp_sd->entry_type == AS_SVC_DOWNTIME_START) { process_chunk = TRUE; } else if (subject->type == SERVICE_SUBJECT && (host_downtime_state == 1 || service_downtime_state == 1)) { process_chunk = TRUE; } /* process this specific "chunk" of scheduled downtime */ if (process_chunk == TRUE) { start_time = temp_sd->time_stamp; end_time = (temp_sd->next == NULL) ? current_time : temp_sd->next->time_stamp; /* check time sanity */ if (end_time <= t1) { continue; } if (start_time >= t2) { continue; } if (start_time >= end_time) { continue; } /* clip time values */ if (start_time < t1) { start_time = t1; } if (end_time > t2) { end_time = t2; } compute_subject_downtime_times(start_time, end_time, subject, temp_sd); } } } /* computes downtime times */ void compute_subject_downtime_times(time_t start_time, time_t end_time, avail_subject *subject, archived_state *sd) { archived_state *temp_as = NULL; time_t part_subject_state = 0L; int saved_status = 0; time_t saved_stamp = 0; int count = 0; archived_state *temp_before = NULL; archived_state *last = NULL; #ifdef DEBUG2 printf("

    ENTERING COMPUTE_SUBJECT_DOWNTIME_TIMES: start=%lu, end=%lu, t1=%lu, t2=%lu

    ", start_time, end_time, t1, t2); #endif /* times are weird, so bail out... */ if (start_time > end_time) { return; } if (start_time < t1 || end_time > t2) { return; } /* find starting point in archived state list */ if (sd == NULL) { #ifdef DEBUG2 printf("

    TEMP_AS=SUBJECT->AS_LIST

    "); #endif temp_as = subject->as_list; } else if (sd->misc_ptr == NULL) { #ifdef DEBUG2 printf("

    TEMP_AS=SUBJECT->AS_LIST

    "); #endif temp_as = subject->as_list; } else if (sd->misc_ptr->next == NULL) { #ifdef DEBUG2 printf("

    TEMP_AS=SD->MISC_PTR

    "); #endif temp_as = sd->misc_ptr; } else { #ifdef DEBUG2 printf("

    TEMP_AS=SD->MISC_PTR->NEXT

    "); #endif temp_as = sd->misc_ptr->next; } /* initialize values */ if (temp_as == NULL) { part_subject_state = AS_NO_DATA; } else if (temp_as->processed_state == AS_PROGRAM_START || temp_as->processed_state == AS_PROGRAM_END || temp_as->processed_state == AS_NO_DATA) { #ifdef DEBUG2 printf("

    ENTRY TYPE #1: %d

    ", temp_as->entry_type); #endif part_subject_state = AS_NO_DATA; } else { #ifdef DEBUG2 printf("

    ENTRY TYPE #2: %d

    ", temp_as->entry_type); #endif part_subject_state = temp_as->processed_state; } #ifdef DEBUG2 printf("

    TEMP_AS=%s

    ", (temp_as == NULL) ? "NULL" : "Not NULL"); printf("

    SD=%s

    ", (sd == NULL) ? "NULL" : "Not NULL"); #endif /* temp_as now points to first event to possibly "break" this chunk */ for (; temp_as != NULL; temp_as = temp_as->next) { count++; last = temp_as; if (temp_before == NULL) { if (last->time_stamp > start_time) { if (last->time_stamp > end_time) { compute_subject_downtime_part_times(start_time, end_time, part_subject_state, subject); } else { compute_subject_downtime_part_times(start_time, last->time_stamp, part_subject_state, subject); } } temp_before = temp_as; saved_status = temp_as->entry_type; saved_stamp = temp_as->time_stamp; /* check if first time is before schedule downtime */ if (saved_stamp < start_time) { saved_stamp = start_time; } continue; } /* if status changed, we have to calculate */ if (saved_status != temp_as->entry_type) { /* is outside schedule time, use end schdule downtime */ if (temp_as->time_stamp > end_time) { if (saved_stamp < start_time) { compute_subject_downtime_part_times(start_time, end_time, saved_status, subject); } else { compute_subject_downtime_part_times(saved_stamp, end_time, saved_status, subject); } } else { if (saved_stamp < start_time) { compute_subject_downtime_part_times(start_time, temp_as->time_stamp, saved_status, subject); } else { compute_subject_downtime_part_times(saved_stamp, temp_as->time_stamp, saved_status, subject); } } saved_status = temp_as->entry_type; saved_stamp = temp_as->time_stamp; /* check if first time is before schedule downtime */ if (saved_stamp < start_time) { saved_stamp = start_time; } } } /* just one entry inside the scheduled downtime */ if (count == 0) { compute_subject_downtime_part_times(start_time, end_time, part_subject_state, subject); } else { /* is outside scheduled time, use end schdule downtime */ if (last->time_stamp > end_time) { compute_subject_downtime_part_times(saved_stamp, end_time, saved_status, subject); } else { compute_subject_downtime_part_times(saved_stamp, last->time_stamp, saved_status, subject); } } } /* computes downtime times */ void compute_subject_downtime_part_times(time_t start_time, time_t end_time, int subject_state, avail_subject *subject) { unsigned long state_duration = 0L; #ifdef DEBUG2 printf("ENTERING COMPUTE_SUBJECT_DOWNTIME_PART_TIMES\n"); #endif /* times are weird */ if (start_time > end_time) { return; } state_duration = (unsigned long)(end_time - start_time); switch (subject_state) { case AS_HOST_UP: subject->scheduled_time_up += state_duration; break; case AS_HOST_DOWN: subject->scheduled_time_down += state_duration; break; case AS_HOST_UNREACHABLE: subject->scheduled_time_unreachable += state_duration; break; case AS_SVC_OK: subject->scheduled_time_ok += state_duration; break; case AS_SVC_WARNING: subject->scheduled_time_warning += state_duration; break; case AS_SVC_UNKNOWN: subject->scheduled_time_unknown += state_duration; break; case AS_SVC_CRITICAL: subject->scheduled_time_critical += state_duration; break; default: subject->scheduled_time_indeterminate += state_duration; break; } #ifdef DEBUG2 printf("\tSUBJECT DOWNTIME: Host '%s', Service '%s', State=%d, Duration=%lu, Start=%lu\n", subject->host_name, (subject->service_description == NULL) ? "NULL" : subject->service_description, subject_state, state_duration, start_time); #endif } /* convert current host state to archived state value */ int convert_host_state_to_archived_state(int current_status) { if (current_status == SD_HOST_UP) { return AS_HOST_UP; } if (current_status == SD_HOST_DOWN) { return AS_HOST_DOWN; } if (current_status == SD_HOST_UNREACHABLE) { return AS_HOST_UNREACHABLE; } return AS_NO_DATA; } /* convert current service state to archived state value */ int convert_service_state_to_archived_state(int current_status) { if (current_status == SERVICE_OK) { return AS_SVC_OK; } if (current_status == SERVICE_UNKNOWN) { return AS_SVC_UNKNOWN; } if (current_status == SERVICE_WARNING) { return AS_SVC_WARNING; } if (current_status == SERVICE_CRITICAL) { return AS_SVC_CRITICAL; } return AS_NO_DATA; } /* create list of subjects to collect availability data for */ void create_subject_list(void) { hostgroup *temp_hostgroup = NULL; hostsmember *temp_hgmember = NULL; servicegroup *temp_servicegroup = NULL; servicesmember *temp_sgmember = NULL; host *temp_host = NULL; service *temp_service = NULL; const char *last_host_name = ""; /* we're displaying one or more hosts */ if (display_type == DISPLAY_HOST_AVAIL && host_name && strcmp(host_name, "")) { /* we're only displaying a specific host (and summaries for all services associated with it) */ if (show_all_hosts == FALSE) { add_subject(HOST_SUBJECT, host_name, NULL); for (temp_service = service_list; temp_service != NULL; temp_service = temp_service->next) { if (!strcmp(temp_service->host_name, host_name)) { add_subject(SERVICE_SUBJECT, host_name, temp_service->description); } } } /* we're displaying all hosts */ else { for (temp_host = host_list; temp_host != NULL; temp_host = temp_host->next) { add_subject(HOST_SUBJECT, temp_host->name, NULL); } } } /* we're displaying a specific service */ else if (display_type == DISPLAY_SERVICE_AVAIL && svc_description && strcmp(svc_description, "")) { /* we're only displaying a specific service */ if (show_all_services == FALSE) { add_subject(SERVICE_SUBJECT, host_name, svc_description); } /* we're displaying all services */ else { for (temp_service = service_list; temp_service != NULL; temp_service = temp_service->next) { add_subject(SERVICE_SUBJECT, temp_service->host_name, temp_service->description); } } } /* we're displaying one or more hostgroups (the host members of the groups) */ else if (display_type == DISPLAY_HOSTGROUP_AVAIL && hostgroup_name && strcmp(hostgroup_name, "")) { /* we're displaying all hostgroups */ if (show_all_hostgroups == TRUE) { for (temp_hostgroup = hostgroup_list; temp_hostgroup != NULL; temp_hostgroup = temp_hostgroup->next) { for (temp_hgmember = temp_hostgroup->members; temp_hgmember != NULL; temp_hgmember = temp_hgmember->next) { add_subject(HOST_SUBJECT, temp_hgmember->host_name, NULL); } } } /* we're only displaying a specific hostgroup */ else { temp_hostgroup = find_hostgroup(hostgroup_name); if (temp_hostgroup != NULL) { for (temp_hgmember = temp_hostgroup->members; temp_hgmember != NULL; temp_hgmember = temp_hgmember->next) { add_subject(HOST_SUBJECT, temp_hgmember->host_name, NULL); } } } } /* we're displaying one or more servicegroups (the host and service members of the groups) */ else if (display_type == DISPLAY_SERVICEGROUP_AVAIL && servicegroup_name && strcmp(servicegroup_name, "")) { /* we're displaying all servicegroups */ if (show_all_servicegroups == TRUE) { for (temp_servicegroup = servicegroup_list; temp_servicegroup != NULL; temp_servicegroup = temp_servicegroup->next) { for (temp_sgmember = temp_servicegroup->members; temp_sgmember != NULL; temp_sgmember = temp_sgmember->next) { add_subject(SERVICE_SUBJECT, temp_sgmember->host_name, temp_sgmember->service_description); if (strcmp(last_host_name, temp_sgmember->host_name)) { add_subject(HOST_SUBJECT, temp_sgmember->host_name, NULL); } last_host_name = temp_sgmember->host_name; } } } /* we're only displaying a specific servicegroup */ else { temp_servicegroup = find_servicegroup(servicegroup_name); if (temp_servicegroup != NULL) { for (temp_sgmember = temp_servicegroup->members; temp_sgmember != NULL; temp_sgmember = temp_sgmember->next) { add_subject(SERVICE_SUBJECT, temp_sgmember->host_name, temp_sgmember->service_description); if (strcmp(last_host_name, temp_sgmember->host_name)) { add_subject(HOST_SUBJECT, temp_sgmember->host_name, NULL); } last_host_name = temp_sgmember->host_name; } } } } } /* adds a subject */ void add_subject(int subject_type, char *hn, char *sd) { avail_subject *last_subject = NULL; avail_subject *temp_subject = NULL; avail_subject *new_subject = NULL; int is_authorized = FALSE; /* bail if we've already added the subject */ if (find_subject(subject_type, hn, sd)) { return; } /* see if the user is authorized to see data for this host or service */ if (subject_type == HOST_SUBJECT) { is_authorized = is_authorized_for_host(find_host(hn), ¤t_authdata); } else { is_authorized = is_authorized_for_service(find_service(hn, sd), ¤t_authdata); } if (is_authorized == FALSE) { return; } /* allocate memory for the new entry */ new_subject = (avail_subject *)malloc(sizeof(avail_subject)); if (new_subject == NULL) { return; } /* allocate memory for the host name */ if (hn != NULL) { new_subject->host_name = (char *)malloc(strlen(hn) + 1); if (new_subject->host_name != NULL) { strcpy(new_subject->host_name, hn); } } else { new_subject->host_name = NULL; } /* allocate memory for the service description */ if (sd != NULL) { new_subject->service_description = (char *)malloc(strlen(sd) + 1); if (new_subject->service_description != NULL) { strcpy(new_subject->service_description, sd); } } else { new_subject->service_description = NULL; } new_subject->type = subject_type; new_subject->earliest_state = AS_NO_DATA; new_subject->latest_state = AS_NO_DATA; new_subject->time_up = 0L; new_subject->time_down = 0L; new_subject->time_unreachable = 0L; new_subject->time_ok = 0L; new_subject->time_warning = 0L; new_subject->time_unknown = 0L; new_subject->time_critical = 0L; new_subject->scheduled_time_up = 0L; new_subject->scheduled_time_down = 0L; new_subject->scheduled_time_unreachable = 0L; new_subject->scheduled_time_ok = 0L; new_subject->scheduled_time_warning = 0L; new_subject->scheduled_time_unknown = 0L; new_subject->scheduled_time_critical = 0L; new_subject->scheduled_time_indeterminate = 0L; new_subject->time_indeterminate_nodata = 0L; new_subject->time_indeterminate_notrunning = 0L; new_subject->as_list = NULL; new_subject->as_list_tail = NULL; new_subject->sd_list = NULL; new_subject->last_known_state = AS_NO_DATA; /* add the new entry to the list in memory, sorted by host name */ last_subject = subject_list; for (temp_subject = subject_list; temp_subject != NULL; temp_subject = temp_subject->next) { if (strcmp(new_subject->host_name, temp_subject->host_name) < 0) { new_subject->next = temp_subject; if (temp_subject == subject_list) { subject_list = new_subject; } else { last_subject->next = new_subject; } break; } else { last_subject = temp_subject; } } if (subject_list == NULL) { new_subject->next = NULL; subject_list = new_subject; } else if (temp_subject == NULL) { new_subject->next = NULL; last_subject->next = new_subject; } } /* finds a specific subject */ avail_subject *find_subject(int type, char *hn, char *sd) { avail_subject *temp_subject = NULL; if (hn == NULL) { return NULL; } if (type == SERVICE_SUBJECT && sd == NULL) { return NULL; } for (temp_subject = subject_list; temp_subject != NULL; temp_subject = temp_subject->next) { if (temp_subject->type != type) { continue; } if (strcmp(hn, temp_subject->host_name)) { continue; } if (type == SERVICE_SUBJECT && strcmp(sd, temp_subject->service_description)) { continue; } return temp_subject; } return NULL; } /* adds an archived state entry to all subjects */ void add_global_archived_state(int entry_type, int state_type, time_t time_stamp, const char *state_info) { avail_subject *temp_subject = NULL; for (temp_subject = subject_list; temp_subject != NULL; temp_subject = temp_subject->next) { add_archived_state(entry_type, state_type, time_stamp, state_info, temp_subject); } return; } /* adds an archived state entry to a specific subject */ void add_archived_state(int entry_type, int state_type, time_t time_stamp, const char *state_info, avail_subject *subject) { archived_state *last_as = NULL; archived_state *temp_as = NULL; archived_state *new_as = NULL; /* allocate memory for the new entry */ new_as = (archived_state *)malloc(sizeof(archived_state)); if (new_as == NULL) return; /* allocate memory for the state info */ if (state_info != NULL) { new_as->state_info = (char *)malloc(strlen(state_info) + 1); if (new_as->state_info != NULL) strcpy(new_as->state_info, state_info); } else new_as->state_info = NULL; /* initialize the "processed state" value - this gets modified later for most entries */ if (entry_type != AS_PROGRAM_START && entry_type != AS_PROGRAM_END && entry_type != AS_NO_DATA) new_as->processed_state = entry_type; else new_as->processed_state = AS_NO_DATA; new_as->entry_type = entry_type; new_as->state_type = state_type; new_as->time_stamp = time_stamp; new_as->misc_ptr = NULL; /* add the new entry to the list in memory, sorted by time (more recent entries should appear towards end of list) */ last_as = subject->as_list; for (temp_as = subject->as_list; temp_as != NULL; temp_as = temp_as->next) { if (new_as->time_stamp < temp_as->time_stamp) { new_as->next = temp_as; if (temp_as == subject->as_list) subject->as_list = new_as; else last_as->next = new_as; break; } else last_as = temp_as; } if (subject->as_list == NULL) { new_as->next = NULL; subject->as_list = new_as; } else if (temp_as == NULL) { new_as->next = NULL; last_as->next = new_as; } /* update "tail" of the list - not really the tail, just last item added */ subject->as_list_tail = new_as; return; } /* adds a scheduled downtime entry to a specific subject */ void add_scheduled_downtime(int state_type, time_t time_stamp, avail_subject *subject) { archived_state *last_sd = NULL; archived_state *temp_sd = NULL; archived_state *new_sd = NULL; /* allocate memory for the new entry */ new_sd = (archived_state *)malloc(sizeof(archived_state)); if (new_sd == NULL) return; new_sd->state_info = NULL; new_sd->processed_state = state_type; new_sd->entry_type = state_type; new_sd->time_stamp = time_stamp; new_sd->misc_ptr = subject->as_list_tail; /* add the new entry to the list in memory, sorted by time (more recent entries should appear towards end of list) */ last_sd = subject->sd_list; for (temp_sd = subject->sd_list; temp_sd != NULL; temp_sd = temp_sd->next) { if (new_sd->time_stamp <= temp_sd->time_stamp) { new_sd->next = temp_sd; if (temp_sd == subject->sd_list) subject->sd_list = new_sd; else last_sd->next = new_sd; break; } else last_sd = temp_sd; } if (subject->sd_list == NULL) { new_sd->next = NULL; subject->sd_list = new_sd; } else if (temp_sd == NULL) { new_sd->next = NULL; last_sd->next = new_sd; } return; } /* frees memory allocated to all availability data */ void free_availability_data(void) { avail_subject *this_subject; avail_subject *next_subject; for (this_subject = subject_list; this_subject != NULL;) { next_subject = this_subject->next; if (this_subject->host_name != NULL) free(this_subject->host_name); if (this_subject->service_description != NULL) free(this_subject->service_description); free_archived_state_list(this_subject->as_list); free_archived_state_list(this_subject->sd_list); free(this_subject); this_subject = next_subject; } return; } /* frees memory allocated to the archived state list */ void free_archived_state_list(archived_state *as_list) { archived_state *this_as = NULL; archived_state *next_as = NULL; for (this_as = as_list; this_as != NULL;) { next_as = this_as->next; if (this_as->state_info != NULL) free(this_as->state_info); free(this_as); this_as = next_as; } as_list = NULL; return; } /* reads log files for archived state data */ void read_archived_state_data(void) { char filename[MAX_FILENAME_LENGTH]; int oldest_archive = 0; int newest_archive = 0; int current_archive = 0; /* determine oldest archive to use when scanning for data (include backtracked archives as well) */ oldest_archive = determine_archive_to_use_from_time(t1); if (log_rotation_method != LOG_ROTATION_NONE) oldest_archive += backtrack_archives; /* determine most recent archive to use when scanning for data */ newest_archive = determine_archive_to_use_from_time(t2); if (oldest_archive < newest_archive) oldest_archive = newest_archive; /* read in all the necessary archived logs (from most recent to earliest) */ for (current_archive = newest_archive; current_archive <= oldest_archive; current_archive++) { #ifdef DEBUG printf("Reading archive #%d\n", current_archive); #endif /* get the name of the log file that contains this archive */ get_log_archive_to_use(current_archive, filename, sizeof(filename) - 1); #ifdef DEBUG printf("Archive name: '%s'\n", filename); #endif /* scan the log file for archived state data */ scan_log_file_for_archived_state_data(filename); } return; } /* grabs archives state data from a log file */ void scan_log_file_for_archived_state_data(char *filename) { char *input = NULL; char *input2 = NULL; char entry_host_name[MAX_INPUT_BUFFER]; char entry_svc_description[MAX_INPUT_BUFFER]; char *plugin_output = NULL; char *temp_buffer = NULL; time_t time_stamp; mmapfile *thefile = NULL; avail_subject *temp_subject = NULL; int state_type = 0; if ((thefile = mmap_fopen(filename)) == NULL) return; while(1) { /* free memory */ free(input); free(input2); input = NULL; input2 = NULL; /* read the next line */ if ((input = mmap_fgets(thefile)) == NULL) break; strip(input); if ((input2 = strdup(input)) == NULL) continue; temp_buffer = my_strtok(input2, "]"); time_stamp = (temp_buffer == NULL) ? (time_t)0 : (time_t)strtoul(temp_buffer + 1, NULL, 10); /* program starts/restarts */ if (strstr(input, " starting...")) add_global_archived_state(AS_PROGRAM_START, AS_NO_DATA, time_stamp, "Program start"); if (strstr(input, " restarting...")) add_global_archived_state(AS_PROGRAM_START, AS_NO_DATA, time_stamp, "Program restart"); /* program stops */ if (strstr(input, " shutting down...")) add_global_archived_state(AS_PROGRAM_END, AS_NO_DATA, time_stamp, "Normal program termination"); if (strstr(input, "Bailing out")) add_global_archived_state(AS_PROGRAM_END, AS_NO_DATA, time_stamp, "Abnormal program termination"); if (display_type == DISPLAY_HOST_AVAIL || display_type == DISPLAY_HOSTGROUP_AVAIL || display_type == DISPLAY_SERVICEGROUP_AVAIL) { /* normal host alerts and initial/current states */ if (strstr(input, "HOST ALERT:") || strstr(input, "INITIAL HOST STATE:") || strstr(input, "CURRENT HOST STATE:")) { /* get host name */ temp_buffer = my_strtok(NULL, ":"); temp_buffer = my_strtok(NULL, ";"); strncpy(entry_host_name, (temp_buffer == NULL) ? "" : temp_buffer + 1, sizeof(entry_host_name)); entry_host_name[sizeof(entry_host_name) - 1] = '\x0'; /* see if there is a corresponding subject for this host */ temp_subject = find_subject(HOST_SUBJECT, entry_host_name, NULL); if (temp_subject == NULL) continue; /* state types */ if (strstr(input, ";SOFT;")) { if (include_soft_states == FALSE) continue; state_type = AS_SOFT_STATE; } if (strstr(input, ";HARD;")) state_type = AS_HARD_STATE; /* get the plugin output */ temp_buffer = my_strtok(NULL, ";"); temp_buffer = my_strtok(NULL, ";"); temp_buffer = my_strtok(NULL, ";"); plugin_output = my_strtok(NULL, "\n"); if (strstr(input, ";DOWN;")) add_archived_state(AS_HOST_DOWN, state_type, time_stamp, plugin_output, temp_subject); else if (strstr(input, ";UNREACHABLE;")) add_archived_state(AS_HOST_UNREACHABLE, state_type, time_stamp, plugin_output, temp_subject); else if (strstr(input, ";RECOVERY") || strstr(input, ";UP;")) add_archived_state(AS_HOST_UP, state_type, time_stamp, plugin_output, temp_subject); else add_archived_state(AS_NO_DATA, AS_NO_DATA, time_stamp, plugin_output, temp_subject); } /* scheduled downtime notices */ else if (strstr(input, "HOST DOWNTIME ALERT:")) { /* get host name */ temp_buffer = my_strtok(NULL, ":"); temp_buffer = my_strtok(NULL, ";"); strncpy(entry_host_name, (temp_buffer == NULL) ? "" : temp_buffer + 1, sizeof(entry_host_name)); entry_host_name[sizeof(entry_host_name) - 1] = '\x0'; /* see if there is a corresponding subject for this host */ temp_subject = find_subject(HOST_SUBJECT, entry_host_name, NULL); if (temp_subject == NULL) continue; if (show_scheduled_downtime == FALSE) continue; if (strstr(input, ";STARTED;")) add_scheduled_downtime(AS_HOST_DOWNTIME_START, time_stamp, temp_subject); else add_scheduled_downtime(AS_HOST_DOWNTIME_END, time_stamp, temp_subject); } } if (display_type == DISPLAY_SERVICE_AVAIL || display_type == DISPLAY_HOST_AVAIL || display_type == DISPLAY_SERVICEGROUP_AVAIL) { /* normal service alerts and initial/current states */ if (strstr(input, "SERVICE ALERT:") || strstr(input, "INITIAL SERVICE STATE:") || strstr(input, "CURRENT SERVICE STATE:")) { /* get host name */ temp_buffer = my_strtok(NULL, ":"); temp_buffer = my_strtok(NULL, ";"); strncpy(entry_host_name, (temp_buffer == NULL) ? "" : temp_buffer + 1, sizeof(entry_host_name)); entry_host_name[sizeof(entry_host_name) - 1] = '\x0'; /* get service description */ temp_buffer = my_strtok(NULL, ";"); strncpy(entry_svc_description, (temp_buffer == NULL) ? "" : temp_buffer, sizeof(entry_svc_description)); entry_svc_description[sizeof(entry_svc_description) - 1] = '\x0'; /* see if there is a corresponding subject for this service */ temp_subject = find_subject(SERVICE_SUBJECT, entry_host_name, entry_svc_description); if (temp_subject == NULL) continue; /* state types */ if (strstr(input, ";SOFT;")) { if (include_soft_states == FALSE) continue; state_type = AS_SOFT_STATE; } if (strstr(input, ";HARD;")) state_type = AS_HARD_STATE; /* get the plugin output */ temp_buffer = my_strtok(NULL, ";"); temp_buffer = my_strtok(NULL, ";"); temp_buffer = my_strtok(NULL, ";"); plugin_output = my_strtok(NULL, "\n"); if (strstr(input, ";CRITICAL;")) add_archived_state(AS_SVC_CRITICAL, state_type, time_stamp, plugin_output, temp_subject); else if (strstr(input, ";WARNING;")) add_archived_state(AS_SVC_WARNING, state_type, time_stamp, plugin_output, temp_subject); else if (strstr(input, ";UNKNOWN;")) add_archived_state(AS_SVC_UNKNOWN, state_type, time_stamp, plugin_output, temp_subject); else if (strstr(input, ";RECOVERY;") || strstr(input, ";OK;")) add_archived_state(AS_SVC_OK, state_type, time_stamp, plugin_output, temp_subject); else add_archived_state(AS_NO_DATA, AS_NO_DATA, time_stamp, plugin_output, temp_subject); } /* scheduled service downtime notices */ else if (strstr(input, "SERVICE DOWNTIME ALERT:")) { /* get host name */ temp_buffer = my_strtok(NULL, ":"); temp_buffer = my_strtok(NULL, ";"); strncpy(entry_host_name, (temp_buffer == NULL) ? "" : temp_buffer + 1, sizeof(entry_host_name)); entry_host_name[sizeof(entry_host_name) - 1] = '\x0'; /* get service description */ temp_buffer = my_strtok(NULL, ";"); strncpy(entry_svc_description, (temp_buffer == NULL) ? "" : temp_buffer, sizeof(entry_svc_description)); entry_svc_description[sizeof(entry_svc_description) - 1] = '\x0'; /* see if there is a corresponding subject for this service */ temp_subject = find_subject(SERVICE_SUBJECT, entry_host_name, entry_svc_description); if (temp_subject == NULL) continue; if (show_scheduled_downtime == FALSE) continue; if (strstr(input, ";STARTED;")) add_scheduled_downtime(AS_SVC_DOWNTIME_START, time_stamp, temp_subject); else add_scheduled_downtime(AS_SVC_DOWNTIME_END, time_stamp, temp_subject); } /* scheduled host downtime notices */ else if (strstr(input, "HOST DOWNTIME ALERT:")) { /* get host name */ temp_buffer = my_strtok(NULL, ":"); temp_buffer = my_strtok(NULL, ";"); strncpy(entry_host_name, (temp_buffer == NULL) ? "" : temp_buffer + 1, sizeof(entry_host_name)); entry_host_name[sizeof(entry_host_name) - 1] = '\x0'; /* this host downtime entry must be added to all service subjects associated with the host! */ for (temp_subject = subject_list; temp_subject != NULL; temp_subject = temp_subject->next) { if (temp_subject->type != SERVICE_SUBJECT) continue; if (strcmp(temp_subject->host_name, entry_host_name)) continue; if (show_scheduled_downtime == FALSE) continue; if (strstr(input, ";STARTED;")) add_scheduled_downtime(AS_HOST_DOWNTIME_START, time_stamp, temp_subject); else add_scheduled_downtime(AS_HOST_DOWNTIME_END, time_stamp, temp_subject); } } } } /* free memory and close the file */ free(input); free(input2); mmap_fclose(thefile); return; } void convert_timeperiod_to_times(int type) { time_t current_time; struct tm *t; /* get the current time */ time(¤t_time); t = localtime(¤t_time); t->tm_sec = 0; t->tm_min = 0; t->tm_hour = 0; t->tm_isdst = -1; switch (type) { case TIMEPERIOD_LAST24HOURS: t1 = current_time - (60 * 60 * 24); t2 = current_time; break; case TIMEPERIOD_TODAY: t1 = mktime(t); t2 = current_time; break; case TIMEPERIOD_YESTERDAY: t1 = (time_t)(mktime(t) - (60 * 60 * 24)); t2 = (time_t)mktime(t); break; case TIMEPERIOD_THISWEEK: t1 = (time_t)(mktime(t) - (60 * 60 * 24 * t->tm_wday)); t2 = current_time; break; case TIMEPERIOD_LASTWEEK: t1 = (time_t)(mktime(t) - (60 * 60 * 24 * t->tm_wday) - (60 * 60 * 24 * 7)); t2 = (time_t)(mktime(t) - (60 * 60 * 24 * t->tm_wday)); break; case TIMEPERIOD_THISMONTH: t->tm_mday = 1; t1 = mktime(t); t2 = current_time; break; case TIMEPERIOD_LASTMONTH: t->tm_mday = 1; t2 = mktime(t); if (t->tm_mon == 0) { t->tm_mon = 11; t->tm_year--; } else t->tm_mon--; t1 = mktime(t); break; case TIMEPERIOD_THISQUARTER: /* not implemented */ break; case TIMEPERIOD_LASTQUARTER: /* not implemented */ break; case TIMEPERIOD_THISYEAR: t->tm_mon = 0; t->tm_mday = 1; t1 = mktime(t); t2 = current_time; break; case TIMEPERIOD_LASTYEAR: t->tm_mon = 0; t->tm_mday = 1; t2 = mktime(t); t->tm_year--; t1 = mktime(t); break; case TIMEPERIOD_LAST7DAYS: t2 = current_time; t1 = current_time - (7 * 24 * 60 * 60); break; case TIMEPERIOD_LAST31DAYS: t2 = current_time; t1 = current_time - (31 * 24 * 60 * 60); break; default: break; } } void compute_report_times(void) { time_t current_time = 0L; struct tm *st = NULL; struct tm *et = NULL; /* get the current time */ time(¤t_time); st = localtime(¤t_time); st->tm_sec = start_second; st->tm_min = start_minute; st->tm_hour = start_hour; st->tm_mday = start_day; st->tm_mon = start_month - 1; st->tm_year = start_year - 1900; st->tm_isdst = -1; t1 = mktime(st); et = localtime(¤t_time); et->tm_sec = end_second; et->tm_min = end_minute; et->tm_hour = end_hour; et->tm_mday = end_day; et->tm_mon = end_month - 1; et->tm_year = end_year - 1900; et->tm_isdst = -1; t2 = mktime(et); } /* writes log entries to screen */ void write_log_entries(avail_subject *subject) { archived_state *temp_as = NULL; archived_state *temp_sd = NULL; time_t current_time = 0L; char start_date_time[MAX_DATETIME_LENGTH] = { 0 }; char end_date_time[MAX_DATETIME_LENGTH] = { 0 }; char duration[20] = { 0 }; const char *bgclass = ""; const char *ebgclass = ""; const char *entry_type = ""; const char *state_type = ""; int days = 0; int hours = 0; int minutes = 0; int seconds = 0; int odd = 0; if (output_format != HTML_OUTPUT) { return; } if (show_log_entries == FALSE) { return; } if (subject == NULL) { return; } time(¤t_time); /* inject all scheduled downtime entries into the main list for display purposes */ for (temp_sd = subject->sd_list; temp_sd != NULL; temp_sd = temp_sd->next) { switch (temp_sd->entry_type) { case AS_SVC_DOWNTIME_START: case AS_HOST_DOWNTIME_START: entry_type = "Start of scheduled downtime"; break; case AS_SVC_DOWNTIME_END: case AS_HOST_DOWNTIME_END: entry_type = "End of scheduled downtime"; break; default: entry_type = "?"; break; } add_archived_state(temp_sd->entry_type, AS_NO_DATA, temp_sd->time_stamp, entry_type, subject); } printf("

    \n"); printf("
    %s Log Entries:
    \n", (subject->type == HOST_SUBJECT) ? "Host" : "Service"); printf("
    "); if (full_log_entries == TRUE) { full_log_entries = FALSE; if (subject->type == HOST_SUBJECT) { host_report_url(subject->host_name, "[ View condensed log entries ]"); } else { service_report_url(subject->host_name, subject->service_description, "[ View condensed log entries ]"); } full_log_entries = TRUE; } else { full_log_entries = TRUE; if (subject->type == HOST_SUBJECT) { host_report_url(subject->host_name, "[ View full log entries ]"); } else { service_report_url(subject->host_name, subject->service_description, "[ View full log entries ]"); } full_log_entries = FALSE; } printf("
    \n"); printf("
    \n"); printf("\n"); printf(""); printf(""); printf(""); printf(""); printf("\n"); /* write all archived state entries */ for (temp_as = subject->as_list; temp_as != NULL; temp_as = temp_as->next) { if (temp_as->state_type == AS_HARD_STATE) { state_type = " (HARD)"; } else if (temp_as->state_type == AS_SOFT_STATE) { state_type = " (SOFT)"; } else { state_type = ""; } switch (temp_as->entry_type) { case AS_NO_DATA: if (full_log_entries == FALSE) { continue; } entry_type = "NO DATA"; ebgclass = "INDETERMINATE"; break; case AS_PROGRAM_END: if (full_log_entries == FALSE) { continue; } entry_type = "PROGRAM END"; ebgclass = "INDETERMINATE"; break; case AS_PROGRAM_START: if (full_log_entries == FALSE) { continue; } entry_type = "PROGRAM (RE)START"; ebgclass = "INDETERMINATE"; break; case AS_HOST_UP: entry_type = "HOST UP"; ebgclass = "UP"; break; case AS_HOST_DOWN: entry_type = "HOST DOWN"; ebgclass = "DOWN"; break; case AS_HOST_UNREACHABLE: entry_type = "HOST UNREACHABLE"; ebgclass = "UNREACHABLE"; break; case AS_SVC_OK: entry_type = "SERVICE OK"; ebgclass = "OK"; break; case AS_SVC_UNKNOWN: entry_type = "SERVICE UNKNOWN"; ebgclass = "UNKNOWN"; break; case AS_SVC_WARNING: entry_type = "SERVICE WARNING"; ebgclass = "WARNING"; break; case AS_SVC_CRITICAL: entry_type = "SERVICE CRITICAL"; ebgclass = "CRITICAL"; break; case AS_SVC_DOWNTIME_START: entry_type = "SERVICE DOWNTIME START"; ebgclass = "INDETERMINATE"; break; case AS_SVC_DOWNTIME_END: entry_type = "SERVICE DOWNTIME END"; ebgclass = "INDETERMINATE"; break; case AS_HOST_DOWNTIME_START: entry_type = "HOST DOWNTIME START"; ebgclass = "INDETERMINATE"; break; case AS_HOST_DOWNTIME_END: entry_type = "HOST DOWNTIME END"; ebgclass = "INDETERMINATE"; break; default: if (full_log_entries == FALSE) { continue; } entry_type = "?"; ebgclass = "INDETERMINATE"; } get_time_string(&(temp_as->time_stamp), start_date_time, sizeof(start_date_time) - 1, SHORT_DATE_TIME); if (temp_as->next == NULL) { get_time_string(&t2, end_date_time, sizeof(end_date_time) - 1, SHORT_DATE_TIME); get_time_breakdown((time_t)(t2 - temp_as->time_stamp), &days, &hours, &minutes, &seconds); snprintf(duration, sizeof(duration) - 1, "%dd %dh %dm %ds+", days, hours, minutes, seconds); } else { get_time_string(&(temp_as->next->time_stamp), end_date_time, sizeof(end_date_time) - 1, SHORT_DATE_TIME); get_time_breakdown((time_t)(temp_as->next->time_stamp - temp_as->time_stamp), &days, &hours, &minutes, &seconds); snprintf(duration, sizeof(duration) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds); } if (odd) { bgclass = "Odd"; odd = 0; } else { bgclass = "Even"; odd = 1; } printf("", bgclass); printf("", bgclass, start_date_time); printf("", bgclass, end_date_time); printf("", bgclass, duration); printf("", ebgclass, entry_type, state_type); printf("", bgclass, (temp_as->state_info == NULL) ? "" : html_encode(temp_as->state_info, FALSE)); printf("\n"); } printf("
    Event Start TimeEvent End TimeEvent DurationEvent/State TypeEvent/State Information
    %s%s%s%s%s%s
    \n"); printf("
    \n"); } /* display hostgroup availability */ void display_hostgroup_availability(void) { hostgroup *temp_hostgroup = NULL; if (output_format == CSV_OUTPUT) { printf("HOSTGROUP_NAME, HOST_NAME, "); printf("TIME_UP, PERCENT_TIME_UP, PERCENT_KNOWN_TIME_UP, "); printf("TIME_DOWN, PERCENT_TIME_DOWN, PERCENT_KNOWN_TIME_DOWN, "); printf("TIME_UNREACHABLE, PERCENT_TIME_UNREACHABLE, PERCENT_KNOWN_TIME_UNREACHABLE, "); printf("TIME_UNDETERMINED, PERCENT_TIME_UNDETERMINED\n"); } /* display data for a specific hostgroup */ if (show_all_hostgroups == FALSE) { temp_hostgroup = find_hostgroup(hostgroup_name); display_specific_hostgroup_availability(temp_hostgroup); } /* display data for all hostgroups */ else { for (temp_hostgroup = hostgroup_list; temp_hostgroup != NULL; temp_hostgroup = temp_hostgroup->next) { display_specific_hostgroup_availability(temp_hostgroup); } } } /* display availability for a specific hostgroup */ void display_specific_hostgroup_availability(hostgroup *hg) { unsigned long total_time = 0L; unsigned long time_determinate = 0L; unsigned long time_indeterminate = 0L; avail_subject *temp_subject = NULL; double percent_time_up = 0.0; double percent_time_down = 0.0; double percent_time_unreachable = 0.0; double percent_time_up_known = 0.0; double percent_time_down_known = 0.0; double percent_time_unreachable_known = 0.0; double percent_time_indeterminate = 0.0; double average_percent_time_up = 0.0; double average_percent_time_up_known = 0.0; double average_percent_time_down = 0.0; double average_percent_time_down_known = 0.0; double average_percent_time_unreachable = 0.0; double average_percent_time_unreachable_known = 0.0; double average_percent_time_indeterminate = 0.0; int current_subject = 0; const char *bgclass = ""; int odd = 1; host *temp_host = NULL; if (hg == NULL) { return; } /* the user isn't authorized to view this hostgroup */ if (is_authorized_for_hostgroup(hg, ¤t_authdata) == FALSE) { return; } /* calculate total time during period based on timeperiod used for reporting */ total_time = calculate_total_time(t1, t2); if (output_format == HTML_OUTPUT) { printf("

    \n"); printf("
    Hostgroup '%s' Host State Breakdowns:
    \n", hg->group_name); printf("
    \n"); printf("\n"); printf(""); printf(""); printf(""); printf(""); printf("\n"); } for (temp_subject = subject_list; temp_subject != NULL; temp_subject = temp_subject->next) { if (temp_subject->type != HOST_SUBJECT) { continue; } temp_host = find_host(temp_subject->host_name); if (temp_host == NULL) { continue; } if (is_host_member_of_hostgroup(hg, temp_host) == FALSE) { continue; } current_subject++; /* reset variables */ percent_time_up = 0.0; percent_time_down = 0.0; percent_time_unreachable = 0.0; percent_time_indeterminate = 0.0; percent_time_up_known = 0.0; percent_time_down_known = 0.0; percent_time_unreachable_known = 0.0; time_determinate = temp_subject->time_up + temp_subject->time_down + temp_subject->time_unreachable; time_indeterminate = total_time - time_determinate; if (total_time > 0) { percent_time_up = (double) (((double) temp_subject->time_up * 100.0) / (double) total_time); percent_time_down = (double) (((double) temp_subject->time_down * 100.0) / (double) total_time); percent_time_unreachable = (double) (((double) temp_subject->time_unreachable * 100.0) / (double) total_time); percent_time_indeterminate = (double) (((double) time_indeterminate * 100.0) / (double) total_time); if (time_determinate > 0) { percent_time_up_known = (double) (((double) temp_subject->time_up * 100.0) / (double) time_determinate); percent_time_down_known = (double) (((double) temp_subject->time_down * 100.0) / (double) time_determinate); percent_time_unreachable_known = (double) (((double) temp_subject->time_unreachable * 100.0) / (double) time_determinate); } } if (odd) { odd = 0; bgclass = "Odd"; } else { odd = 1; bgclass = "Even"; } if (output_format == HTML_OUTPUT) { printf("", percent_time_up, percent_time_up_known); printf("", percent_time_down, percent_time_down_known); printf("", percent_time_unreachable, percent_time_unreachable_known); printf("\n", bgclass, percent_time_indeterminate); get_running_average(&average_percent_time_up, percent_time_up, current_subject); get_running_average(&average_percent_time_up_known, percent_time_up_known, current_subject); get_running_average(&average_percent_time_down, percent_time_down, current_subject); get_running_average(&average_percent_time_down_known, percent_time_down_known, current_subject); get_running_average(&average_percent_time_unreachable, percent_time_unreachable, current_subject); get_running_average(&average_percent_time_unreachable_known, percent_time_unreachable_known, current_subject); get_running_average(&average_percent_time_indeterminate, percent_time_indeterminate, current_subject); } else if (output_format == CSV_OUTPUT) { /* hostgroup/host name */ printf("\"%s\", \"%s\", ", hg->group_name, temp_subject->host_name); /* time up */ printf("%lu, %2.3f%%, %2.3f%%, ", temp_subject->time_up, percent_time_up, percent_time_up_known); /* time down */ printf("%lu, %2.3f%%, %2.3f%%, ", temp_subject->time_down, percent_time_down, percent_time_down_known); /* time unreachable */ printf("%lu, %2.3f%%, %2.3f%%, ", temp_subject->time_unreachable, percent_time_unreachable, percent_time_unreachable_known); /* time undetermined */ printf("%lu, %2.3f%%\n", time_indeterminate, percent_time_indeterminate); } } /* average statistics */ if (output_format == HTML_OUTPUT) { if (odd) { odd = 0; bgclass = "Odd"; } else { odd = 1; bgclass = "Even"; } printf("", bgclass, bgclass); printf("", average_percent_time_up, average_percent_time_up_known); printf("", average_percent_time_down, average_percent_time_down_known); printf("", average_percent_time_unreachable, average_percent_time_unreachable_known); printf("", bgclass, average_percent_time_indeterminate); printf("
    Host%% Time Up%% Time Down%% Time Unreachable%% Time Undetermined
    ", bgclass, bgclass); host_report_url(temp_subject->host_name, temp_subject->host_name); printf("%2.3f%% (%2.3f%%)%2.3f%% (%2.3f%%)%2.3f%% (%2.3f%%)%2.3f%%
    Average%2.3f%% (%2.3f%%)%2.3f%% (%2.3f%%)%2.3f%% (%2.3f%%)%2.3f%%
    \n"); printf("
    \n"); } } /* display servicegroup availability */ void display_servicegroup_availability(void) { servicegroup *temp_servicegroup = NULL; if (output_format == CSV_OUTPUT) { printf("SERVICEGROUP_NAME, HOST_NAME, SERVICE_DESCRIPTION, "); /* it would be nice to include all of the host information as well but this would require re-writing the way the loops work in display_specific_servicegroup_availability() and i don't think that's appropriate for a bug-fix issue (TODO) */ /* printf("HOST_TIME_UP, HOST_PERCENT_TIME_UP, HOST_PERCENT_KNOWN_TIME_UP, "); printf("HOST_TIME_DOWN, HOST_PERCENT_TIME_DOWN, HOST_PERCENT_KNOWN_TIME_DOWN, "); printf("HOST_TIME_UNREACHABLE, HOST_PERCENT_TIME_UNREACHABLE, HOST_PERCENT_KNOWN_TIME_UNREACHABLE, "); printf("HOST_TIME_UNDETERMINED, HOST_PERCENT_TIME_UNDETERMINED, "); */ printf("SERVICE_TIME_OK, SERVICE_PERCENT_TIME_OK, SERVICE_PERCENT_KNOWN_TIME_OK, "); printf("SERVICE_TIME_WARNING, SERVICE_PERCENT_TIME_WARNING, SERVICE_PERCENT_KNOWN_TIME_WARNING, "); printf("SERVICE_TIME_CRITICAL, SERVICE_PERCENT_TIME_CRITICAL, SERVICE_PERCENT_KNOWN_TIME_CRITICAL, "); printf("SERVICE_TIME_UNKNOWN, SERVICE_PERCENT_TIME_UNKNOWN, SERVICE_PERCENT_KNOWN_TIME_UNKNOWN, "); printf("SERVICE_TIME_UNDETERMINED, SERVICE_PERCENT_TIME_UNDETERMINED\n"); } /* display data for a specific servicegroup */ if (show_all_servicegroups == FALSE) { temp_servicegroup = find_servicegroup(servicegroup_name); display_specific_servicegroup_availability(temp_servicegroup); } /* display data for all servicegroups */ else { for (temp_servicegroup = servicegroup_list; temp_servicegroup != NULL; temp_servicegroup = temp_servicegroup->next) { display_specific_servicegroup_availability(temp_servicegroup); } } } /* display availability for a specific servicegroup */ void display_specific_servicegroup_availability(servicegroup *sg) { unsigned long total_time = 0L; unsigned long time_determinate = 0L; unsigned long time_indeterminate = 0L; avail_subject *temp_subject = NULL; double percent_time_up = 0.0; double percent_time_down = 0.0; double percent_time_unreachable = 0.0; double percent_time_up_known = 0.0; double percent_time_down_known = 0.0; double percent_time_unreachable_known = 0.0; double percent_time_indeterminate = 0.0; double percent_time_ok = 0.0; double percent_time_warning = 0.0; double percent_time_unknown = 0.0; double percent_time_critical = 0.0; double percent_time_ok_known = 0.0; double percent_time_warning_known = 0.0; double percent_time_unknown_known = 0.0; double percent_time_critical_known = 0.0; double average_percent_time_up = 0.0; double average_percent_time_up_known = 0.0; double average_percent_time_down = 0.0; double average_percent_time_down_known = 0.0; double average_percent_time_unreachable = 0.0; double average_percent_time_unreachable_known = 0.0; double average_percent_time_ok = 0.0; double average_percent_time_ok_known = 0.0; double average_percent_time_unknown = 0.0; double average_percent_time_unknown_known = 0.0; double average_percent_time_warning = 0.0; double average_percent_time_warning_known = 0.0; double average_percent_time_critical = 0.0; double average_percent_time_critical_known = 0.0; double average_percent_time_indeterminate = 0.0; const char *bgclass = ""; int current_subject = 0; int odd = 1; host *temp_host = NULL; service *temp_service = NULL; /* Initialize to empty string for initial strcmp() below */ char last_host[MAX_INPUT_BUFFER] = { 0 }; if (sg == NULL) { return; } /* the user isn't authorized to view this servicegroup */ if (is_authorized_for_servicegroup(sg, ¤t_authdata) == FALSE) { return; } /* calculate total time during period based on timeperiod used for reporting */ total_time = calculate_total_time(t1, t2); if (output_format == HTML_OUTPUT) { printf("

    \n"); printf("
    Servicegroup '%s' Host State Breakdowns:
    \n", sg->group_name); printf("
    \n"); printf("\n"); printf(""); printf(""); printf(""); printf(""); printf("\n"); } for (temp_subject = subject_list; temp_subject != NULL; temp_subject = temp_subject->next) { if (temp_subject->type != HOST_SUBJECT) { continue; } temp_host = find_host(temp_subject->host_name); if (temp_host == NULL) { continue; } if (is_host_member_of_servicegroup(sg, temp_host) == FALSE) { continue; } current_subject++; /* reset variables */ percent_time_up = 0.0; percent_time_down = 0.0; percent_time_unreachable = 0.0; percent_time_indeterminate = 0.0; percent_time_up_known = 0.0; percent_time_down_known = 0.0; percent_time_unreachable_known = 0.0; time_determinate = temp_subject->time_up + temp_subject->time_down + temp_subject->time_unreachable; time_indeterminate = total_time - time_determinate; if (total_time > 0) { percent_time_up = (double) (((double) temp_subject->time_up * 100.0) / (double) total_time); percent_time_down = (double) (((double) temp_subject->time_down * 100.0) / (double) total_time); percent_time_unreachable = (double) (((double) temp_subject->time_unreachable * 100.0) / (double) total_time); percent_time_indeterminate = (double) (((double) time_indeterminate * 100.0) / (double) total_time); if (time_determinate > 0) { percent_time_up_known = (double) (((double) temp_subject->time_up * 100.0) / (double) time_determinate); percent_time_down_known = (double) (((double) temp_subject->time_down * 100.0) / (double) time_determinate); percent_time_unreachable_known = (double) (((double) temp_subject->time_unreachable * 100.0) / (double) time_determinate); } } if (output_format == HTML_OUTPUT) { if (odd) { odd = 0; bgclass = "Odd"; } else { odd = 1; bgclass = "Even"; } printf("", percent_time_up, percent_time_up_known); printf("", percent_time_down, percent_time_down_known); printf("", percent_time_unreachable, percent_time_unreachable_known); printf("\n", bgclass, percent_time_indeterminate); get_running_average(&average_percent_time_up, percent_time_up, current_subject); get_running_average(&average_percent_time_up_known, percent_time_up_known, current_subject); get_running_average(&average_percent_time_down, percent_time_down, current_subject); get_running_average(&average_percent_time_down_known, percent_time_down_known, current_subject); get_running_average(&average_percent_time_unreachable, percent_time_unreachable, current_subject); get_running_average(&average_percent_time_unreachable_known, percent_time_unreachable_known, current_subject); get_running_average(&average_percent_time_indeterminate, percent_time_indeterminate, current_subject); } } /* average statistics */ if (output_format == HTML_OUTPUT) { if (odd) { odd = 0; bgclass = "Odd"; } else { odd = 1; bgclass = "Even"; } printf("", bgclass, bgclass); printf("", average_percent_time_up, average_percent_time_up_known); printf("", average_percent_time_down, average_percent_time_down_known); printf("", average_percent_time_unreachable, average_percent_time_unreachable_known); printf("", bgclass, average_percent_time_indeterminate); printf("
    Host%% Time Up%% Time Down%% Time Unreachable%% Time Undetermined
    ", bgclass, bgclass); host_report_url(temp_subject->host_name, temp_subject->host_name); printf("%2.3f%% (%2.3f%%)%2.3f%% (%2.3f%%)%2.3f%% (%2.3f%%)%2.3f%%
    Average%2.3f%% (%2.3f%%)%2.3f%% (%2.3f%%)%2.3f%% (%2.3f%%)%2.3f%%
    \n"); printf("
    \n"); printf("
    \n"); printf("
    Servicegroup '%s' Service State Breakdowns:
    \n", sg->group_name); printf("
    \n"); printf("\n"); printf(""); printf(""); printf(""); printf(""); printf(""); printf(""); printf("\n"); } current_subject = 0; average_percent_time_indeterminate = 0.0; for (temp_subject = subject_list; temp_subject != NULL; temp_subject = temp_subject->next) { if (temp_subject->type != SERVICE_SUBJECT) { continue; } temp_service = find_service(temp_subject->host_name, temp_subject->service_description); if (temp_service == NULL) { continue; } if (is_service_member_of_servicegroup(sg, temp_service) == FALSE) { continue; } current_subject++; time_determinate = temp_subject->time_ok + temp_subject->time_warning + temp_subject->time_unknown + temp_subject->time_critical; time_indeterminate = total_time - time_determinate; /* adjust indeterminate time due to insufficient data (not all was caught) */ temp_subject->time_indeterminate_nodata = time_indeterminate - temp_subject->time_indeterminate_notrunning; /* initialize values */ percent_time_ok = 0.0; percent_time_warning = 0.0; percent_time_unknown = 0.0; percent_time_critical = 0.0; percent_time_indeterminate = 0.0; percent_time_ok_known = 0.0; percent_time_warning_known = 0.0; percent_time_unknown_known = 0.0; percent_time_critical_known = 0.0; if (total_time > 0) { percent_time_ok = (double) (((double) temp_subject->time_ok * 100.0) / (double) total_time); percent_time_warning = (double) (((double) temp_subject->time_warning * 100.0) / (double) total_time); percent_time_unknown = (double) (((double) temp_subject->time_unknown * 100.0) / (double) total_time); percent_time_critical = (double) (((double) temp_subject->time_critical * 100.0) / (double) total_time); percent_time_indeterminate = (double) (((double) time_indeterminate * 100.0) / (double) total_time); if (time_determinate > 0) { percent_time_ok_known = (double) (((double) temp_subject->time_ok * 100.0) / (double) time_determinate); percent_time_warning_known = (double) (((double) temp_subject->time_warning * 100.0) / (double) time_determinate); percent_time_unknown_known = (double) (((double) temp_subject->time_unknown * 100.0) / (double) time_determinate); percent_time_critical_known = (double) (((double) temp_subject->time_critical * 100.0) / (double) time_determinate); } } if (output_format == HTML_OUTPUT) { if (odd) { odd = 0; bgclass = "Odd"; } else { odd = 1; bgclass = "Even"; } printf("", percent_time_ok, percent_time_ok_known); printf("", percent_time_warning, percent_time_warning_known); printf("", percent_time_unknown, percent_time_unknown_known); printf("", percent_time_critical, percent_time_critical_known); printf("\n", bgclass, percent_time_indeterminate); strncpy(last_host, temp_subject->host_name, sizeof(last_host) - 1); last_host[sizeof(last_host) - 1] = '\x0'; get_running_average(&average_percent_time_ok, percent_time_ok, current_subject); get_running_average(&average_percent_time_ok_known, percent_time_ok_known, current_subject); get_running_average(&average_percent_time_unknown, percent_time_unknown, current_subject); get_running_average(&average_percent_time_unknown_known, percent_time_unknown_known, current_subject); get_running_average(&average_percent_time_warning, percent_time_warning, current_subject); get_running_average(&average_percent_time_warning_known, percent_time_warning_known, current_subject); get_running_average(&average_percent_time_critical, percent_time_critical, current_subject); get_running_average(&average_percent_time_critical_known, percent_time_critical_known, current_subject); get_running_average(&average_percent_time_indeterminate, percent_time_indeterminate, current_subject); } else if (output_format == CSV_OUTPUT) { /* servicegroup name, host name, service description */ printf("\"%s\", \"%s\", \"%s\", ", sg->group_name, temp_subject->host_name, temp_subject->service_description); /* time ok */ printf("%lu, %2.3f%%, %2.3f%%, ", temp_subject->time_ok, percent_time_ok, percent_time_ok_known); /* time warning */ printf("%lu, %2.3f%%, %2.3f%%, ", temp_subject->time_warning, percent_time_warning, percent_time_warning_known); /* time critical */ printf("%lu, %2.3f%%, %2.3f%%, ", temp_subject->time_critical, percent_time_critical, percent_time_critical_known); /* time unknown */ printf("%lu, %2.3f%%, %2.3f%%, ", temp_subject->time_unknown, percent_time_unknown, percent_time_unknown_known); /* time undetermined */ printf("%lu, %2.3f%%\n", time_indeterminate, percent_time_indeterminate); } } if (output_format == HTML_OUTPUT) { /* display average stats */ if (odd) { odd = 0; bgclass = "Odd"; } else { odd = 1; bgclass = "Even"; } printf("", bgclass, bgclass); printf("", average_percent_time_ok, average_percent_time_ok_known); printf("", average_percent_time_warning, average_percent_time_warning_known); printf("", average_percent_time_unknown, average_percent_time_unknown_known); printf("", average_percent_time_critical, average_percent_time_critical_known); printf("\n", bgclass, average_percent_time_indeterminate); printf("
    HostService%% Time OK%% Time Warning%% Time Unknown%% Time Critical%% Time Undetermined
    ", bgclass, bgclass); if (strcmp(temp_subject->host_name, last_host)) { host_report_url(temp_subject->host_name, temp_subject->host_name); } printf("", bgclass); service_report_url(temp_subject->host_name, temp_subject->service_description, temp_subject->service_description); printf("%2.3f%% (%2.3f%%)%2.3f%% (%2.3f%%)%2.3f%% (%2.3f%%)%2.3f%% (%2.3f%%)%2.3f%%
    Average%2.3f%% (%2.3f%%)%2.3f%% (%2.3f%%)%2.3f%% (%2.3f%%)%2.3f%% (%2.3f%%)%2.3f%%
    \n"); printf("
    \n"); } } /* display host availability */ void display_host_availability(void) { unsigned long total_time = 0L; unsigned long time_determinate = 0L; unsigned long time_indeterminate = 0L; avail_subject *temp_subject = NULL; host *temp_host = NULL; service *temp_service = NULL; int days = 0; int hours = 0; int minutes = 0; int seconds = 0; char time_indeterminate_string[48] = { 0 }; char time_determinate_string[48] = { 0 }; char total_time_string[48] = { 0 }; double percent_time_ok = 0.0; double percent_time_warning = 0.0; double percent_time_unknown = 0.0; double percent_time_critical = 0.0; double percent_time_indeterminate = 0.0; double percent_time_ok_known = 0.0; double percent_time_warning_known = 0.0; double percent_time_unknown_known = 0.0; double percent_time_critical_known = 0.0; char time_up_string[48] = { 0 }; char time_down_string[48] = { 0 }; char time_unreachable_string[48] = { 0 }; double percent_time_up = 0.0; double percent_time_down = 0.0; double percent_time_unreachable = 0.0; double percent_time_up_known = 0.0; double percent_time_down_known = 0.0; double percent_time_unreachable_known = 0.0; double percent_time_up_scheduled = 0.0; double percent_time_up_unscheduled = 0.0; double percent_time_down_scheduled = 0.0; double percent_time_down_unscheduled = 0.0; double percent_time_unreachable_scheduled = 0.0; double percent_time_unreachable_unscheduled = 0.0; double percent_time_up_scheduled_known = 0.0; double percent_time_up_unscheduled_known = 0.0; double percent_time_down_scheduled_known = 0.0; double percent_time_down_unscheduled_known = 0.0; double percent_time_unreachable_scheduled_known = 0.0; double percent_time_unreachable_unscheduled_known = 0.0; char time_up_scheduled_string[48] = { 0 }; char time_up_unscheduled_string[48] = { 0 }; char time_down_scheduled_string[48] = { 0 }; char time_down_unscheduled_string[48] = { 0 }; char time_unreachable_scheduled_string[48] = { 0 }; char time_unreachable_unscheduled_string[48] = { 0 }; char time_indeterminate_scheduled_string[48] = { 0 }; char time_indeterminate_unscheduled_string[48] = { 0 }; char time_indeterminate_notrunning_string[48] = { 0 }; char time_indeterminate_nodata_string[48] = { 0 }; double percent_time_indeterminate_notrunning = 0.0; double percent_time_indeterminate_nodata = 0.0; double average_percent_time_up = 0.0; double average_percent_time_up_known = 0.0; double average_percent_time_down = 0.0; double average_percent_time_down_known = 0.0; double average_percent_time_unreachable = 0.0; double average_percent_time_unreachable_known = 0.0; double average_percent_time_indeterminate = 0.0; double average_percent_time_ok = 0.0; double average_percent_time_ok_known = 0.0; double average_percent_time_unknown = 0.0; double average_percent_time_unknown_known = 0.0; double average_percent_time_warning = 0.0; double average_percent_time_warning_known = 0.0; double average_percent_time_critical = 0.0; double average_percent_time_critical_known = 0.0; const char *bgclass = ""; int current_subject = 0; int odd = 1; /* calculate total time during period based on timeperiod used for reporting */ total_time = calculate_total_time(t1, t2); #ifdef DEBUG printf("Total time: '%ld' seconds
    \n", total_time); #endif /* its the same header for all CSV outputs */ if (output_format == CSV_OUTPUT) { printf("HOST_NAME, "); printf("TIME_UP_SCHEDULED, PERCENT_TIME_UP_SCHEDULED, PERCENT_KNOWN_TIME_UP_SCHEDULED, "); printf("TIME_UP_UNSCHEDULED, PERCENT_TIME_UP_UNSCHEDULED, PERCENT_KNOWN_TIME_UP_UNSCHEDULED, "); printf("TOTAL_TIME_UP, PERCENT_TOTAL_TIME_UP, PERCENT_KNOWN_TIME_UP, "); printf("TIME_DOWN_SCHEDULED, PERCENT_TIME_DOWN_SCHEDULED, PERCENT_KNOWN_TIME_DOWN_SCHEDULED, "); printf("TIME_DOWN_UNSCHEDULED, PERCENT_TIME_DOWN_UNSCHEDULED, PERCENT_KNOWN_TIME_DOWN_UNSCHEDULED, "); printf("TOTAL_TIME_DOWN, PERCENT_TOTAL_TIME_DOWN, PERCENT_KNOWN_TIME_DOWN, "); printf("TIME_UNREACHABLE_SCHEDULED, PERCENT_TIME_UNREACHABLE_SCHEDULED, "); printf("PERCENT_KNOWN_TIME_UNREACHABLE_SCHEDULED, TIME_UNREACHABLE_UNSCHEDULED, "); printf("PERCENT_TIME_UNREACHABLE_UNSCHEDULED, PERCENT_KNOWN_TIME_UNREACHABLE_UNSCHEDULED, "); printf("TOTAL_TIME_UNREACHABLE, PERCENT_TOTAL_TIME_UNREACHABLE, PERCENT_KNOWN_TIME_UNREACHABLE, "); printf("TIME_UNDETERMINED_NOT_RUNNING, PERCENT_TIME_UNDETERMINED_NOT_RUNNING, "); printf("TIME_UNDETERMINED_NO_DATA, PERCENT_TIME_UNDETERMINED_NO_DATA, "); printf("TOTAL_TIME_UNDETERMINED, PERCENT_TOTAL_TIME_UNDETERMINED\n"); } /* show data for a specific host */ if (show_all_hosts == FALSE) { temp_subject = find_subject(HOST_SUBJECT, host_name, NULL); if (temp_subject == NULL) { return; } temp_host = find_host(temp_subject->host_name); if (temp_host == NULL) { return; } /* the user isn't authorized to view this host */ if (is_authorized_for_host(temp_host, ¤t_authdata) == FALSE) { return; } time_determinate = temp_subject->time_up + temp_subject->time_down + temp_subject->time_unreachable; time_indeterminate = total_time - time_determinate; /* adjust indeterminate time due to insufficient data (not all was caught) */ temp_subject->time_indeterminate_nodata = time_indeterminate - temp_subject->time_indeterminate_notrunning; /* up times */ get_time_breakdown(temp_subject->time_up, &days, &hours, &minutes, &seconds); snprintf(time_up_string, sizeof(time_up_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds); get_time_breakdown(temp_subject->scheduled_time_up, &days, &hours, &minutes, &seconds); snprintf(time_up_scheduled_string, sizeof(time_up_scheduled_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds); get_time_breakdown(temp_subject->time_up - temp_subject->scheduled_time_up, &days, &hours, &minutes, &seconds); snprintf(time_up_unscheduled_string, sizeof(time_up_unscheduled_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds); /* down times */ get_time_breakdown(temp_subject->time_down, &days, &hours, &minutes, &seconds); snprintf(time_down_string, sizeof(time_down_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds); get_time_breakdown(temp_subject->scheduled_time_down, &days, &hours, &minutes, &seconds); snprintf(time_down_scheduled_string, sizeof(time_down_scheduled_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds); get_time_breakdown(temp_subject->time_down - temp_subject->scheduled_time_down, &days, &hours, &minutes, &seconds); snprintf(time_down_unscheduled_string, sizeof(time_down_unscheduled_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds); /* unreachable times */ get_time_breakdown(temp_subject->time_unreachable, &days, &hours, &minutes, &seconds); snprintf(time_unreachable_string, sizeof(time_unreachable_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds); get_time_breakdown(temp_subject->scheduled_time_unreachable, &days, &hours, &minutes, &seconds); snprintf(time_unreachable_scheduled_string, sizeof(time_unreachable_scheduled_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds); get_time_breakdown(temp_subject->time_unreachable - temp_subject->scheduled_time_unreachable, &days, &hours, &minutes, &seconds); snprintf(time_unreachable_unscheduled_string, sizeof(time_unreachable_unscheduled_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds); /* indeterminate times */ get_time_breakdown(time_indeterminate, &days, &hours, &minutes, &seconds); snprintf(time_indeterminate_string, sizeof(time_indeterminate_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds); get_time_breakdown(temp_subject->scheduled_time_indeterminate, &days, &hours, &minutes, &seconds); snprintf(time_indeterminate_scheduled_string, sizeof(time_indeterminate_scheduled_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds); get_time_breakdown(time_indeterminate - temp_subject->scheduled_time_indeterminate, &days, &hours, &minutes, &seconds); snprintf(time_indeterminate_unscheduled_string, sizeof(time_indeterminate_unscheduled_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds); get_time_breakdown(temp_subject->time_indeterminate_notrunning, &days, &hours, &minutes, &seconds); snprintf(time_indeterminate_notrunning_string, sizeof(time_indeterminate_notrunning_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds); get_time_breakdown(temp_subject->time_indeterminate_nodata, &days, &hours, &minutes, &seconds); snprintf(time_indeterminate_nodata_string, sizeof(time_indeterminate_nodata_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds); get_time_breakdown(time_determinate, &days, &hours, &minutes, &seconds); snprintf(time_determinate_string, sizeof(time_determinate_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds); get_time_breakdown(total_time, &days, &hours, &minutes, &seconds); snprintf(total_time_string, sizeof(total_time_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds); if (total_time > 0) { percent_time_up = (double) (((double) temp_subject->time_up * 100.0) / (double) total_time); percent_time_up_scheduled = (double) (((double) temp_subject->scheduled_time_up * 100.0) / (double) total_time); percent_time_up_unscheduled = percent_time_up - percent_time_up_scheduled; percent_time_down = (double) (((double) temp_subject->time_down * 100.0) / (double) total_time); percent_time_down_scheduled = (double) (((double) temp_subject->scheduled_time_down * 100.0) / (double) total_time); percent_time_down_unscheduled = percent_time_down - percent_time_down_scheduled; percent_time_unreachable = (double) (((double) temp_subject->time_unreachable * 100.0) / (double) total_time); percent_time_unreachable_scheduled = (double) (((double) temp_subject->scheduled_time_unreachable * 100.0) / (double) total_time); percent_time_unreachable_unscheduled = percent_time_unreachable - percent_time_unreachable_scheduled; percent_time_indeterminate = (double) (((double) time_indeterminate * 100.0) / (double) total_time); percent_time_indeterminate_notrunning = (double) (((double) temp_subject->time_indeterminate_notrunning * 100.0) / (double) total_time); percent_time_indeterminate_nodata = (double) (((double) temp_subject->time_indeterminate_nodata * 100.0) / (double) total_time); if (time_determinate > 0) { percent_time_up_known = (double) (((double) temp_subject->time_up * 100.0) / (double) time_determinate); percent_time_up_scheduled_known = (double) (((double) temp_subject->scheduled_time_up * 100.0) / (double) time_determinate); percent_time_up_unscheduled_known = percent_time_up_known - percent_time_up_scheduled_known; percent_time_down_known = (double) (((double) temp_subject->time_down * 100.0) / (double) time_determinate); percent_time_down_scheduled_known = (double) (((double) temp_subject->scheduled_time_down * 100.0) / (double) time_determinate); percent_time_down_unscheduled_known = percent_time_down_known - percent_time_down_scheduled_known; percent_time_unreachable_known = (double) (((double) temp_subject->time_unreachable * 100.0) / (double) time_determinate); percent_time_unreachable_scheduled_known = (double) (((double) temp_subject->scheduled_time_unreachable * 100.0) / (double) time_determinate); percent_time_unreachable_unscheduled_known = percent_time_unreachable_known - percent_time_unreachable_scheduled_known; } } if (output_format == HTML_OUTPUT) { printf("
    Host State Breakdowns:
    \n"); #ifdef USE_TRENDS printf("

    \n"); printf("", backtrack_archives); #ifdef LEGACY_GRAPHICAL_CGIS printf("Host State Trends"); printf("
    \n"); printf("

    \n"); #endif printf("
    \n"); printf("\n"); printf(""); printf(""); printf(""); printf(""); printf("\n"); /* up times */ printf(""); printf(""); printf(""); printf("", time_up_unscheduled_string); printf("", percent_time_up); printf("\n", percent_time_up_known); printf(""); printf(""); printf("", time_up_scheduled_string); printf("", percent_time_up_scheduled); printf("\n", percent_time_up_scheduled_known); printf(""); printf(""); printf("", time_up_string); printf("", percent_time_up); printf("\n", percent_time_up_known); /* down times */ printf(""); printf(""); printf(""); printf("", time_down_unscheduled_string); printf("", percent_time_down_unscheduled); printf("\n", percent_time_down_unscheduled_known); printf(""); printf(""); printf("", time_down_scheduled_string); printf("", percent_time_down_scheduled); printf("\n", percent_time_down_scheduled_known); printf(""); printf(""); printf("", time_down_string); printf("", percent_time_down); printf("\n", percent_time_down_known); /* unreachable times */ printf(""); printf(""); printf(""); printf("", time_unreachable_unscheduled_string); printf("", percent_time_unreachable); printf("\n", percent_time_unreachable_known); printf(""); printf(""); printf("", time_unreachable_scheduled_string); printf("", percent_time_unreachable_scheduled); printf("\n", percent_time_unreachable_scheduled_known); printf(""); printf(""); printf("", time_unreachable_string); printf("", percent_time_unreachable); printf("\n", percent_time_unreachable_known); /* indeterminate times */ printf(""); printf(""); printf(""); printf("", time_indeterminate_notrunning_string); printf("", percent_time_indeterminate_notrunning); printf("\n"); printf(""); printf(""); printf("", time_indeterminate_nodata_string); printf("", percent_time_indeterminate_nodata); printf("\n"); printf(""); printf(""); printf("", time_indeterminate_string); printf("", percent_time_indeterminate); printf("\n"); printf("\n"); printf("\n", total_time_string); printf("
    StateType / ReasonTime%% Total Time%% Known Time
    UPUnscheduled%s%2.3f%%%2.3f%%
    Scheduled%s%2.3f%%%2.3f%%
    Total%s%2.3f%%%2.3f%%
    DOWNUnscheduled%s%2.3f%%%2.3f%%
    Scheduled%s%2.3f%%%2.3f%%
    Total%s%2.3f%%%2.3f%%
    UNREACHABLEUnscheduled%s%2.3f%%%2.3f%%
    Scheduled%s%2.3f%%%2.3f%%
    Total%s%2.3f%%%2.3f%%
    UndeterminedNagios Not Running%s%2.3f%%
    Insufficient Data%s%2.3f%%
    Total%s%2.3f%%
    AllTotal%s100.000%%100.000%%
    \n"); printf("
    \n"); /* display state breakdowns for all services on this host (only HTML output) */ printf("

    \n"); printf("
    State Breakdowns For Host Services:
    \n"); printf("
    \n"); printf("\n"); printf("\n"); for (temp_subject = subject_list; temp_subject != NULL; temp_subject = temp_subject->next) { if (temp_subject->type != SERVICE_SUBJECT) { continue; } temp_service = find_service(temp_subject->host_name, temp_subject->service_description); if (temp_service == NULL) { continue; } /* the user isn't authorized to view this service */ if (is_authorized_for_service(temp_service, ¤t_authdata) == FALSE) { continue; } current_subject++; if (odd) { odd = 0; bgclass = "Odd"; } else { odd = 1; bgclass = "Even"; } /* reset variables */ percent_time_ok = 0.0; percent_time_warning = 0.0; percent_time_unknown = 0.0; percent_time_critical = 0.0; percent_time_indeterminate = 0.0; percent_time_ok_known = 0.0; percent_time_warning_known = 0.0; percent_time_unknown_known = 0.0; percent_time_critical_known = 0.0; time_determinate = temp_subject->time_ok + temp_subject->time_warning + temp_subject->time_unknown + temp_subject->time_critical; time_indeterminate = total_time - time_determinate; if (total_time > 0) { percent_time_ok = (double) (((double) temp_subject->time_ok * 100.0) / (double) total_time); percent_time_warning = (double) (((double) temp_subject->time_warning * 100.0) / (double) total_time); percent_time_unknown = (double) (((double) temp_subject->time_unknown * 100.0) / (double) total_time); percent_time_critical = (double) (((double) temp_subject->time_critical * 100.0) / (double) total_time); percent_time_indeterminate = (double) (((double) time_indeterminate * 100.0) / (double) total_time); if (time_determinate > 0) { percent_time_ok_known = (double) (((double) temp_subject->time_ok * 100.0) / (double) time_determinate); percent_time_warning_known = (double) (((double) temp_subject->time_warning * 100.0) / (double) time_determinate); percent_time_unknown_known = (double) (((double) temp_subject->time_unknown * 100.0) / (double) time_determinate); percent_time_critical_known = (double) (((double) temp_subject->time_critical * 100.0) / (double) time_determinate); } } printf("", percent_time_ok, percent_time_ok_known); printf("", percent_time_warning, percent_time_warning_known); printf("", percent_time_unknown, percent_time_unknown_known); printf("", percent_time_critical, percent_time_critical_known); printf("\n", bgclass, percent_time_indeterminate); get_running_average(&average_percent_time_ok, percent_time_ok, current_subject); get_running_average(&average_percent_time_ok_known, percent_time_ok_known, current_subject); get_running_average(&average_percent_time_unknown, percent_time_unknown, current_subject); get_running_average(&average_percent_time_unknown_known, percent_time_unknown_known, current_subject); get_running_average(&average_percent_time_warning, percent_time_warning, current_subject); get_running_average(&average_percent_time_warning_known, percent_time_warning_known, current_subject); get_running_average(&average_percent_time_critical, percent_time_critical, current_subject); get_running_average(&average_percent_time_critical_known, percent_time_critical_known, current_subject); get_running_average(&average_percent_time_indeterminate, percent_time_indeterminate, current_subject); } /* display average stats */ if (odd) { odd = 0; bgclass = "Odd"; } else { odd = 1; bgclass = "Even"; } printf("", bgclass, bgclass); printf("", average_percent_time_ok, average_percent_time_ok_known); printf("", average_percent_time_warning, average_percent_time_warning_known); printf("", average_percent_time_unknown, average_percent_time_unknown_known); printf("", average_percent_time_critical, average_percent_time_critical_known); printf("\n", bgclass, average_percent_time_indeterminate); printf("
    Service%% Time OK%% Time Warning%% Time Unknown%% Time Critical%% Time Undetermined
    ", bgclass, bgclass); service_report_url(temp_subject->host_name, temp_subject->service_description, temp_subject->service_description); printf("%2.3f%% (%2.3f%%)%2.3f%% (%2.3f%%)%2.3f%% (%2.3f%%)%2.3f%% (%2.3f%%)%2.3f%%
    Average%2.3f%% (%2.3f%%)%2.3f%% (%2.3f%%)%2.3f%% (%2.3f%%)%2.3f%% (%2.3f%%)%2.3f%%
    \n"); printf("
    \n"); /* write log entries for the host */ temp_subject = find_subject(HOST_SUBJECT, host_name, NULL); write_log_entries(temp_subject); } else if (output_format == CSV_OUTPUT) { /* host name */ printf("\"%s\", ", temp_subject->host_name); /* up times */ printf("%lu, %2.3f%%, %2.3f%%, ", temp_subject->scheduled_time_up, percent_time_up_scheduled, percent_time_up_scheduled_known); printf("%lu, %2.3f%%, %2.3f%%, ", temp_subject->time_up - temp_subject->scheduled_time_up, percent_time_up_unscheduled, percent_time_up_unscheduled_known); printf("%lu, %2.3f%%, %2.3f%%, ", temp_subject->time_up, percent_time_up, percent_time_up_known); /* down times */ printf("%lu, %2.3f%%, %2.3f%%, ", temp_subject->scheduled_time_down, percent_time_down_scheduled, percent_time_down_scheduled_known); printf("%lu, %2.3f%%, %2.3f%%, ", temp_subject->time_down - temp_subject->scheduled_time_down, percent_time_down_unscheduled, percent_time_down_unscheduled_known); printf("%lu, %2.3f%%, %2.3f%%, ", temp_subject->time_down, percent_time_down, percent_time_down_known); /* unreachable times */ printf("%lu, %2.3f%%, ", temp_subject->scheduled_time_unreachable, percent_time_unreachable_scheduled); printf("%2.3f%%, %lu, ", percent_time_unreachable_scheduled_known, temp_subject->time_unreachable - temp_subject->scheduled_time_unreachable); printf("%2.3f%%, %2.3f%%, ", percent_time_unreachable_unscheduled, percent_time_unreachable_unscheduled_known); printf("%lu, %2.3f%%, %2.3f%%, ", temp_subject->time_unreachable, percent_time_unreachable, percent_time_unreachable_known); /* indeterminate times */ printf("%lu, %2.3f%%, ", temp_subject->time_indeterminate_notrunning, percent_time_indeterminate_notrunning); printf("%lu, %2.3f%%, ", temp_subject->time_indeterminate_nodata, percent_time_indeterminate_nodata); printf("%lu, %2.3f%%\n", time_indeterminate, percent_time_indeterminate); } } /* display data for all hosts */ else { if (output_format == HTML_OUTPUT) { printf("

    \n"); printf("
    Host State Breakdowns:
    \n"); printf("
    \n"); printf("\n"); printf(""); printf(""); printf(""); printf(""); printf("\n"); } for (temp_subject = subject_list; temp_subject != NULL; temp_subject = temp_subject->next) { if (temp_subject->type != HOST_SUBJECT) { continue; } temp_host = find_host(temp_subject->host_name); if (temp_host == NULL) { continue; } /* the user isn't authorized to view this host */ if (is_authorized_for_host(temp_host, ¤t_authdata) == FALSE) { continue; } current_subject++; time_determinate = temp_subject->time_up + temp_subject->time_down + temp_subject->time_unreachable; time_indeterminate = total_time - time_determinate; /* adjust indeterminate time due to insufficient data (not all was caught) */ temp_subject->time_indeterminate_nodata = time_indeterminate - temp_subject->time_indeterminate_notrunning; /* initialize values */ percent_time_up = 0.0; percent_time_up_scheduled = 0.0; percent_time_up_unscheduled = 0.0; percent_time_down = 0.0; percent_time_down_scheduled = 0.0; percent_time_down_unscheduled = 0.0; percent_time_unreachable = 0.0; percent_time_unreachable_scheduled = 0.0; percent_time_unreachable_unscheduled = 0.0; percent_time_indeterminate = 0.0; percent_time_indeterminate_notrunning = 0.0; percent_time_indeterminate_nodata = 0.0; percent_time_up_known = 0.0; percent_time_up_scheduled_known = 0.0; percent_time_up_unscheduled_known = 0.0; percent_time_down_known = 0.0; percent_time_down_scheduled_known = 0.0; percent_time_down_unscheduled_known = 0.0; percent_time_unreachable_known = 0.0; percent_time_unreachable_scheduled_known = 0.0; percent_time_unreachable_unscheduled_known = 0.0; if (total_time > 0) { percent_time_up = (double) (((double) temp_subject->time_up * 100.0) / (double) total_time); percent_time_up_scheduled = (double) (((double) temp_subject->scheduled_time_up * 100.0) / (double) total_time); percent_time_up_unscheduled = percent_time_up - percent_time_up_scheduled; percent_time_down = (double) (((double) temp_subject->time_down * 100.0) / (double) total_time); percent_time_down_scheduled = (double) (((double) temp_subject->scheduled_time_down * 100.0) / (double) total_time); percent_time_down_unscheduled = percent_time_down - percent_time_down_scheduled; percent_time_unreachable = (double) (((double) temp_subject->time_unreachable * 100.0) / (double) total_time); percent_time_unreachable_scheduled = (double) (((double) temp_subject->scheduled_time_unreachable * 100.0) / (double) total_time); percent_time_unreachable_unscheduled = percent_time_unreachable - percent_time_unreachable_scheduled; percent_time_indeterminate = (double) (((double) time_indeterminate * 100.0) / (double) total_time); percent_time_indeterminate_notrunning = (double) (((double) temp_subject->time_indeterminate_notrunning * 100.0) / (double) total_time); percent_time_indeterminate_nodata = (double) (((double) temp_subject->time_indeterminate_nodata * 100.0) / (double) total_time); if (time_determinate > 0) { percent_time_up_known = (double) (((double) temp_subject->time_up * 100.0) / (double) time_determinate); percent_time_up_scheduled_known = (double) (((double) temp_subject->scheduled_time_up * 100.0) / (double) time_determinate); percent_time_up_unscheduled_known = percent_time_up_known - percent_time_up_scheduled_known; percent_time_down_known = (double) (((double) temp_subject->time_down * 100.0) / (double) time_determinate); percent_time_down_scheduled_known = (double) (((double) temp_subject->scheduled_time_down * 100.0) / (double) time_determinate); percent_time_down_unscheduled_known = percent_time_down_known - percent_time_down_scheduled_known; percent_time_unreachable_known = (double) (((double) temp_subject->time_unreachable * 100.0) / (double) time_determinate); percent_time_unreachable_scheduled_known = (double) (((double) temp_subject->scheduled_time_unreachable * 100.0) / (double) time_determinate); percent_time_unreachable_unscheduled_known = percent_time_unreachable_known - percent_time_unreachable_scheduled_known; } } if (output_format == HTML_OUTPUT) { if (odd) { odd = 0; bgclass = "Odd"; } else { odd = 1; bgclass = "Even"; } printf("", percent_time_up, percent_time_up_known); printf("", percent_time_down, percent_time_down_known); printf("", percent_time_unreachable, percent_time_unreachable_known); printf("\n", bgclass, percent_time_indeterminate); /* we only print the averages for html output */ get_running_average(&average_percent_time_up, percent_time_up, current_subject); get_running_average(&average_percent_time_up_known, percent_time_up_known, current_subject); get_running_average(&average_percent_time_down, percent_time_down, current_subject); get_running_average(&average_percent_time_down_known, percent_time_down_known, current_subject); get_running_average(&average_percent_time_unreachable, percent_time_unreachable, current_subject); get_running_average(&average_percent_time_unreachable_known, percent_time_unreachable_known, current_subject); get_running_average(&average_percent_time_indeterminate, percent_time_indeterminate, current_subject); } else if (output_format == CSV_OUTPUT) { /* host name */ printf("\"%s\", ", temp_subject->host_name); /* up times */ printf("%lu, %2.3f%%, %2.3f%%, ", temp_subject->scheduled_time_up, percent_time_up_scheduled, percent_time_up_scheduled_known); printf("%lu, %2.3f%%, %2.3f%%, ", temp_subject->time_up - temp_subject->scheduled_time_up, percent_time_up_unscheduled, percent_time_up_unscheduled_known); printf("%lu, %2.3f%%, %2.3f%%, ", temp_subject->time_up, percent_time_up, percent_time_up_known); /* down times */ printf("%lu, %2.3f%%, %2.3f%%, ", temp_subject->scheduled_time_down, percent_time_down_scheduled, percent_time_down_scheduled_known); printf("%lu, %2.3f%%, %2.3f%%, ", temp_subject->time_down - temp_subject->scheduled_time_down, percent_time_down_unscheduled, percent_time_down_unscheduled_known); printf("%lu, %2.3f%%, %2.3f%%, ", temp_subject->time_down, percent_time_down, percent_time_down_known); /* unreachable times */ printf("%lu, %2.3f%%, ", temp_subject->scheduled_time_unreachable, percent_time_unreachable_scheduled); printf("%2.3f%%, %lu, ", percent_time_unreachable_scheduled_known, temp_subject->time_unreachable - temp_subject->scheduled_time_unreachable); printf("%2.3f%%, %2.3f%%, ", percent_time_unreachable_unscheduled, percent_time_unreachable_unscheduled_known); printf("%lu, %2.3f%%, %2.3f%%, ", temp_subject->time_unreachable, percent_time_unreachable, percent_time_unreachable_known); /* indeterminate times */ printf("%lu, %2.3f%%, ", temp_subject->time_indeterminate_notrunning, percent_time_indeterminate_notrunning); printf("%lu, %2.3f%%, ", temp_subject->time_indeterminate_nodata, percent_time_indeterminate_nodata); printf("%lu, %2.3f%%\n", time_indeterminate, percent_time_indeterminate); } } if (output_format == HTML_OUTPUT) { /* average statistics */ if (odd) { odd = 0; bgclass = "Odd"; } else { odd = 1; bgclass = "Even"; } printf("", bgclass, bgclass); printf("", average_percent_time_up, average_percent_time_up_known); printf("", average_percent_time_down, average_percent_time_down_known); printf("", average_percent_time_unreachable, average_percent_time_unreachable_known); printf("", bgclass, average_percent_time_indeterminate); printf("
    Host%% Time Up%% Time Down%% Time Unreachable%% Time Undetermined
    ", bgclass, bgclass); host_report_url(temp_subject->host_name, temp_subject->host_name); printf("%2.3f%% (%2.3f%%)%2.3f%% (%2.3f%%)%2.3f%% (%2.3f%%)%2.3f%%
    Average%2.3f%% (%2.3f%%)%2.3f%% (%2.3f%%)%2.3f%% (%2.3f%%)%2.3f%%
    \n"); printf("
    \n"); } } } /* display service availability */ void display_service_availability(void) { unsigned long total_time = 0L; unsigned long time_determinate = 0L; unsigned long time_indeterminate = 0L; avail_subject *temp_subject = NULL; service *temp_service = NULL; int days = 0; int hours = 0; int minutes = 0; int seconds = 0; char time_ok_string[48] = { 0 }; char time_warning_string[48] = { 0 }; char time_unknown_string[48] = { 0 }; char time_critical_string[48] = { 0 }; char time_indeterminate_string[48] = { 0 }; char time_determinate_string[48] = { 0 }; char total_time_string[48] = { 0 }; double percent_time_ok = 0.0; double percent_time_warning = 0.0; double percent_time_unknown = 0.0; double percent_time_critical = 0.0; double percent_time_indeterminate = 0.0; double percent_time_ok_known = 0.0; double percent_time_warning_known = 0.0; double percent_time_unknown_known = 0.0; double percent_time_critical_known = 0.0; char time_critical_scheduled_string[48] = { 0 }; char time_critical_unscheduled_string[48] = { 0 }; double percent_time_critical_scheduled = 0.0; double percent_time_critical_unscheduled = 0.0; double percent_time_critical_scheduled_known = 0.0; double percent_time_critical_unscheduled_known = 0.0; char time_unknown_scheduled_string[48] = { 0 }; char time_unknown_unscheduled_string[48] = { 0 }; double percent_time_unknown_scheduled = 0.0; double percent_time_unknown_unscheduled = 0.0; double percent_time_unknown_scheduled_known = 0.0; double percent_time_unknown_unscheduled_known = 0.0; char time_warning_scheduled_string[48] = { 0 }; char time_warning_unscheduled_string[48] = { 0 }; double percent_time_warning_scheduled = 0.0; double percent_time_warning_unscheduled = 0.0; double percent_time_warning_scheduled_known = 0.0; double percent_time_warning_unscheduled_known = 0.0; char time_ok_scheduled_string[48] = { 0 }; char time_ok_unscheduled_string[48] = { 0 }; double percent_time_ok_scheduled = 0.0; double percent_time_ok_unscheduled = 0.0; double percent_time_ok_scheduled_known = 0.0; double percent_time_ok_unscheduled_known = 0.0; double average_percent_time_ok = 0.0; double average_percent_time_ok_known = 0.0; double average_percent_time_unknown = 0.0; double average_percent_time_unknown_known = 0.0; double average_percent_time_warning = 0.0; double average_percent_time_warning_known = 0.0; double average_percent_time_critical = 0.0; double average_percent_time_critical_known = 0.0; double average_percent_time_indeterminate = 0.0; int current_subject = 0; char time_indeterminate_scheduled_string[48] = { 0 }; char time_indeterminate_unscheduled_string[48] = { 0 }; char time_indeterminate_notrunning_string[48] = { 0 }; char time_indeterminate_nodata_string[48] = { 0 }; double percent_time_indeterminate_notrunning = 0.0; double percent_time_indeterminate_nodata = 0.0; int odd = 1; const char *bgclass = ""; char last_host[128] = ""; /* calculate total time during period based on timeperiod used for reporting */ total_time = calculate_total_time(t1, t2); #ifdef DEBUG printf("Total time: '%ld' seconds
    \n", total_time); #endif /* its the same header for all CSV outputs */ if (output_format == CSV_OUTPUT) { printf("HOST_NAME, SERVICE_DESCRIPTION, "); printf("TIME_OK_SCHEDULED, PERCENT_TIME_OK_SCHEDULED, PERCENT_KNOWN_TIME_OK_SCHEDULED, "); printf("TIME_OK_UNSCHEDULED, PERCENT_TIME_OK_UNSCHEDULED, PERCENT_KNOWN_TIME_OK_UNSCHEDULED, "); printf("TOTAL_TIME_OK, PERCENT_TOTAL_TIME_OK, PERCENT_KNOWN_TIME_OK, "); printf("TIME_WARNING_SCHEDULED, PERCENT_TIME_WARNING_SCHEDULED, PERCENT_KNOWN_TIME_WARNING_SCHEDULED, "); printf("TIME_WARNING_UNSCHEDULED, PERCENT_TIME_WARNING_UNSCHEDULED, PERCENT_KNOWN_TIME_WARNING_UNSCHEDULED, "); printf("TOTAL_TIME_WARNING, PERCENT_TOTAL_TIME_WARNING, PERCENT_KNOWN_TIME_WARNING, "); printf("TIME_UNKNOWN_SCHEDULED, PERCENT_TIME_UNKNOWN_SCHEDULED, PERCENT_KNOWN_TIME_UNKNOWN_SCHEDULED, "); printf("TIME_UNKNOWN_UNSCHEDULED, PERCENT_TIME_UNKNOWN_UNSCHEDULED, PERCENT_KNOWN_TIME_UNKNOWN_UNSCHEDULED, "); printf("TOTAL_TIME_UNKNOWN, PERCENT_TOTAL_TIME_UNKNOWN, PERCENT_KNOWN_TIME_UNKNOWN, "); printf("TIME_CRITICAL_SCHEDULED, PERCENT_TIME_CRITICAL_SCHEDULED, PERCENT_KNOWN_TIME_CRITICAL_SCHEDULED, "); printf("TIME_CRITICAL_UNSCHEDULED, PERCENT_TIME_CRITICAL_UNSCHEDULED, PERCENT_KNOWN_TIME_CRITICAL_UNSCHEDULED, "); printf("TOTAL_TIME_CRITICAL, PERCENT_TOTAL_TIME_CRITICAL, PERCENT_KNOWN_TIME_CRITICAL, "); printf("TIME_UNDETERMINED_NOT_RUNNING, PERCENT_TIME_UNDETERMINED_NOT_RUNNING, TIME_UNDETERMINED_NO_DATA, "); printf("PERCENT_TIME_UNDETERMINED_NO_DATA, TOTAL_TIME_UNDETERMINED, PERCENT_TOTAL_TIME_UNDETERMINED\n"); } /* we're only getting data for one service */ if (show_all_services == FALSE) { temp_subject = find_subject(SERVICE_SUBJECT, host_name, svc_description); if (temp_subject == NULL) { return; } temp_service = find_service(temp_subject->host_name, temp_subject->service_description); if (temp_service == NULL) { return; } /* the user isn't authorized to view this service */ if (is_authorized_for_service(temp_service, ¤t_authdata) == FALSE) { return; } time_determinate = temp_subject->time_ok + temp_subject->time_warning + temp_subject->time_unknown + temp_subject->time_critical; time_indeterminate = total_time - time_determinate; /* adjust indeterminate time due to insufficient data (not all was caught) */ temp_subject->time_indeterminate_nodata = time_indeterminate - temp_subject->time_indeterminate_notrunning; /* ok states */ get_time_breakdown(temp_subject->time_ok, &days, &hours, &minutes, &seconds); snprintf(time_ok_string, sizeof(time_ok_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds); get_time_breakdown(temp_subject->scheduled_time_ok, &days, &hours, &minutes, &seconds); snprintf(time_ok_scheduled_string, sizeof(time_ok_scheduled_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds); get_time_breakdown(temp_subject->time_ok - temp_subject->scheduled_time_ok, &days, &hours, &minutes, &seconds); snprintf(time_ok_unscheduled_string, sizeof(time_ok_unscheduled_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds); /* warning states */ get_time_breakdown(temp_subject->time_warning, &days, &hours, &minutes, &seconds); snprintf(time_warning_string, sizeof(time_warning_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds); get_time_breakdown(temp_subject->scheduled_time_warning, &days, &hours, &minutes, &seconds); snprintf(time_warning_scheduled_string, sizeof(time_warning_scheduled_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds); get_time_breakdown(temp_subject->time_warning - temp_subject->scheduled_time_warning, &days, &hours, &minutes, &seconds); snprintf(time_warning_unscheduled_string, sizeof(time_warning_unscheduled_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds); /* unknown states */ get_time_breakdown(temp_subject->time_unknown, &days, &hours, &minutes, &seconds); snprintf(time_unknown_string, sizeof(time_unknown_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds); get_time_breakdown(temp_subject->scheduled_time_unknown, &days, &hours, &minutes, &seconds); snprintf(time_unknown_scheduled_string, sizeof(time_unknown_scheduled_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds); get_time_breakdown(temp_subject->time_unknown - temp_subject->scheduled_time_unknown, &days, &hours, &minutes, &seconds); snprintf(time_unknown_unscheduled_string, sizeof(time_unknown_unscheduled_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds); /* critical states */ get_time_breakdown(temp_subject->time_critical, &days, &hours, &minutes, &seconds); snprintf(time_critical_string, sizeof(time_critical_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds); get_time_breakdown(temp_subject->scheduled_time_critical, &days, &hours, &minutes, &seconds); snprintf(time_critical_scheduled_string, sizeof(time_critical_scheduled_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds); get_time_breakdown(temp_subject->time_critical - temp_subject->scheduled_time_critical, &days, &hours, &minutes, &seconds); snprintf(time_critical_unscheduled_string, sizeof(time_critical_unscheduled_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds); /* indeterminate time */ get_time_breakdown(time_indeterminate, &days, &hours, &minutes, &seconds); snprintf(time_indeterminate_string, sizeof(time_indeterminate_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds); get_time_breakdown(temp_subject->scheduled_time_indeterminate, &days, &hours, &minutes, &seconds); snprintf(time_indeterminate_scheduled_string, sizeof(time_indeterminate_scheduled_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds); get_time_breakdown(time_indeterminate - temp_subject->scheduled_time_indeterminate, &days, &hours, &minutes, &seconds); snprintf(time_indeterminate_unscheduled_string, sizeof(time_indeterminate_unscheduled_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds); get_time_breakdown(temp_subject->time_indeterminate_notrunning, &days, &hours, &minutes, &seconds); snprintf(time_indeterminate_notrunning_string, sizeof(time_indeterminate_notrunning_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds); get_time_breakdown(temp_subject->time_indeterminate_nodata, &days, &hours, &minutes, &seconds); snprintf(time_indeterminate_nodata_string, sizeof(time_indeterminate_nodata_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds); get_time_breakdown(time_determinate, &days, &hours, &minutes, &seconds); snprintf(time_determinate_string, sizeof(time_determinate_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds); get_time_breakdown(total_time, &days, &hours, &minutes, &seconds); snprintf(total_time_string, sizeof(total_time_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds); if (total_time > 0) { percent_time_ok = (double) (((double) temp_subject->time_ok * 100.0) / (double) total_time); percent_time_ok_scheduled = (double) (((double) temp_subject->scheduled_time_ok * 100.0) / (double) total_time); percent_time_ok_unscheduled = percent_time_ok - percent_time_ok_scheduled; percent_time_warning = (double) (((double) temp_subject->time_warning * 100.0) / (double) total_time); percent_time_warning_scheduled = (double) (((double) temp_subject->scheduled_time_warning * 100.0) / (double) total_time); percent_time_warning_unscheduled = percent_time_warning - percent_time_warning_scheduled; percent_time_unknown = (double) (((double) temp_subject->time_unknown * 100.0) / (double) total_time); percent_time_unknown_scheduled = (double) (((double) temp_subject->scheduled_time_unknown * 100.0) / (double) total_time); percent_time_unknown_unscheduled = percent_time_unknown - percent_time_unknown_scheduled; percent_time_critical = (double) (((double) temp_subject->time_critical * 100.0) / (double) total_time); percent_time_critical_scheduled = (double) (((double) temp_subject->scheduled_time_critical * 100.0) / (double) total_time); percent_time_critical_unscheduled = percent_time_critical - percent_time_critical_scheduled; percent_time_indeterminate = (double) (((double) time_indeterminate * 100.0) / (double) total_time); percent_time_indeterminate_notrunning = (double) (((double) temp_subject->time_indeterminate_notrunning * 100.0) / (double) total_time); percent_time_indeterminate_nodata = (double) (((double) temp_subject->time_indeterminate_nodata * 100.0) / (double) total_time); if (time_determinate > 0) { percent_time_ok_known = (double) (((double) temp_subject->time_ok * 100.0) / (double) time_determinate); percent_time_ok_scheduled_known = (double) (((double) temp_subject->scheduled_time_ok * 100.0) / (double) time_determinate); percent_time_ok_unscheduled_known = percent_time_ok_known - percent_time_ok_scheduled_known; percent_time_warning_known = (double) (((double) temp_subject->time_warning * 100.0) / (double) time_determinate); percent_time_warning_scheduled_known = (double) (((double) temp_subject->scheduled_time_warning * 100.0) / (double) time_determinate); percent_time_warning_unscheduled_known = percent_time_warning_known - percent_time_warning_scheduled_known; percent_time_unknown_known = (double) (((double) temp_subject->time_unknown * 100.0) / (double) time_determinate); percent_time_unknown_scheduled_known = (double) (((double) temp_subject->scheduled_time_unknown * 100.0) / (double) time_determinate); percent_time_unknown_unscheduled_known = percent_time_unknown_known - percent_time_unknown_scheduled_known; percent_time_critical_known = (double) (((double) temp_subject->time_critical * 100.0) / (double) time_determinate); percent_time_critical_scheduled_known = (double) (((double) temp_subject->scheduled_time_critical * 100.0) / (double) time_determinate); percent_time_critical_unscheduled_known = percent_time_critical_known - percent_time_critical_scheduled_known; } } if (output_format == HTML_OUTPUT) { printf("
    Service State Breakdowns:
    \n"); #ifdef USE_TRENDS printf("

    \n"); printf("", backtrack_archives); #ifdef LEGACY_GRAPHICAL_CGIS printf("Service State Trends"); printf("
    \n"); printf("

    \n"); #endif printf("
    \n"); printf("\n"); printf(""); printf(""); printf(""); printf(""); printf("\n"); /* ok states */ printf(""); printf(""); printf("", time_ok_unscheduled_string); printf("", percent_time_ok_unscheduled); printf("\n", percent_time_ok_unscheduled_known); printf(""); printf("", time_ok_scheduled_string); printf("", percent_time_ok_scheduled); printf("\n", percent_time_ok_scheduled_known); printf(""); printf("", time_ok_string); printf("", percent_time_ok); printf("\n", percent_time_ok_known); /* warning states */ printf(""); printf(""); printf("", time_warning_unscheduled_string); printf("", percent_time_warning_unscheduled); printf("\n", percent_time_warning_unscheduled_known); printf(""); printf("", time_warning_scheduled_string); printf("", percent_time_warning_scheduled); printf("\n", percent_time_warning_scheduled_known); printf(""); printf("", time_warning_string); printf("", percent_time_warning); printf("\n", percent_time_warning_known); /* unknown states */ printf(""); printf(""); printf("", time_unknown_unscheduled_string); printf("", percent_time_unknown_unscheduled); printf("\n", percent_time_unknown_unscheduled_known); printf(""); printf("", time_unknown_scheduled_string); printf("", percent_time_unknown_scheduled); printf("\n", percent_time_unknown_scheduled_known); printf(""); printf("", time_unknown_string); printf("", percent_time_unknown); printf("\n", percent_time_unknown_known); /* critical states */ printf(""); printf(""); printf("", time_critical_unscheduled_string); printf("", percent_time_critical_unscheduled); printf("\n", percent_time_critical_unscheduled_known); printf(""); printf("", time_critical_scheduled_string); printf("", percent_time_critical_scheduled); printf("\n", percent_time_critical_scheduled_known); printf(""); printf("", time_critical_string); printf("", percent_time_critical); printf("\n", percent_time_critical_known); printf(""); printf(""); printf("", time_indeterminate_notrunning_string); printf("", percent_time_indeterminate_notrunning); printf("\n"); printf(""); printf("", time_indeterminate_nodata_string); printf("", percent_time_indeterminate_nodata); printf("\n"); printf(""); printf("", time_indeterminate_string); printf("", percent_time_indeterminate); printf("\n"); printf("\n"); printf(""); printf(""); printf("", total_time_string); printf(""); printf("\n"); printf("
    StateType / ReasonTime%% Total Time%% Known Time
    OKUnscheduled%s%2.3f%%%2.3f%%
    Scheduled%s%2.3f%%%2.3f%%
    Total%s%2.3f%%%2.3f%%
    WARNINGUnscheduled%s%2.3f%%%2.3f%%
    Scheduled%s%2.3f%%%2.3f%%
    Total%s%2.3f%%%2.3f%%
    UNKNOWNUnscheduled%s%2.3f%%%2.3f%%
    Scheduled%s%2.3f%%%2.3f%%
    Total%s%2.3f%%%2.3f%%
    CRITICALUnscheduled%s%2.3f%%%2.3f%%
    Scheduled%s%2.3f%%%2.3f%%
    Total%s%2.3f%%%2.3f%%
    UndeterminedNagios Not Running%s%2.3f%%
    Insufficient Data%s%2.3f%%
    Total%s%2.3f%%
    AllTotal%s100.000%%100.000%%
    \n"); printf("
    \n"); write_log_entries(temp_subject); } else if (output_format == CSV_OUTPUT) { /* host name and service description */ printf("\"%s\", \"%s\", ", temp_subject->host_name, temp_subject->service_description); /* ok times */ printf("%lu, %2.3f%%, %2.3f%%, ", temp_subject->scheduled_time_ok, percent_time_ok_scheduled, percent_time_ok_scheduled_known); printf("%lu, %2.3f%%, %2.3f%%, ", temp_subject->time_ok - temp_subject->scheduled_time_ok, percent_time_ok_unscheduled, percent_time_ok_unscheduled_known); printf("%lu, %2.3f%%, %2.3f%%, ", temp_subject->time_ok, percent_time_ok, percent_time_ok_known); /* warning times */ printf("%lu, %2.3f%%, %2.3f%%, ", temp_subject->scheduled_time_warning, percent_time_warning_scheduled, percent_time_warning_scheduled_known); printf("%lu, %2.3f%%, %2.3f%%, ", temp_subject->time_warning - temp_subject->scheduled_time_warning, percent_time_warning_unscheduled, percent_time_warning_unscheduled_known); printf("%lu, %2.3f%%, %2.3f%%, ", temp_subject->time_warning, percent_time_warning, percent_time_warning_known); /* unknown times */ printf("%lu, %2.3f%%, %2.3f%%, ", temp_subject->scheduled_time_unknown, percent_time_unknown_scheduled, percent_time_unknown_scheduled_known); printf("%lu, %2.3f%%, %2.3f%%, ", temp_subject->time_unknown - temp_subject->scheduled_time_unknown, percent_time_unknown_unscheduled, percent_time_unknown_unscheduled_known); printf("%lu, %2.3f%%, %2.3f%%, ", temp_subject->time_unknown, percent_time_unknown, percent_time_unknown_known); /* critical times */ printf("%lu, %2.3f%%, %2.3f%%, ", temp_subject->scheduled_time_critical, percent_time_critical_scheduled, percent_time_critical_scheduled_known); printf("%lu, %2.3f%%, %2.3f%%, ", temp_subject->time_critical - temp_subject->scheduled_time_critical, percent_time_critical_unscheduled, percent_time_critical_unscheduled_known); printf("%lu, %2.3f%%, %2.3f%%, ", temp_subject->time_critical, percent_time_critical, percent_time_critical_known); /* indeterminate times */ printf("%lu, %2.3f%%, ", temp_subject->time_indeterminate_notrunning, percent_time_indeterminate_notrunning); printf("%lu, %2.3f%%, ", temp_subject->time_indeterminate_nodata, percent_time_indeterminate_nodata); printf("%lu, %2.3f%%\n", time_indeterminate, percent_time_indeterminate); } } /* display data for all services */ else { if (output_format == HTML_OUTPUT) { printf("
    Service State Breakdowns:
    \n"); printf("
    \n"); printf("\n"); printf("\n"); } for (temp_subject = subject_list; temp_subject != NULL; temp_subject = temp_subject->next) { if (temp_subject->type != SERVICE_SUBJECT) { continue; } temp_service = find_service(temp_subject->host_name, temp_subject->service_description); if (temp_service == NULL) { continue; } /* the user isn't authorized to view this service */ if (is_authorized_for_service(temp_service, ¤t_authdata) == FALSE) { continue; } current_subject++; time_determinate = temp_subject->time_ok + temp_subject->time_warning + temp_subject->time_unknown + temp_subject->time_critical; time_indeterminate = total_time - time_determinate; /* adjust indeterminate time due to insufficient data (not all was caught) */ temp_subject->time_indeterminate_nodata = time_indeterminate - temp_subject->time_indeterminate_notrunning; /* initialize values */ percent_time_ok = 0.0; percent_time_ok_scheduled = 0.0; percent_time_ok_unscheduled = 0.0; percent_time_warning = 0.0; percent_time_warning_scheduled = 0.0; percent_time_warning_unscheduled = 0.0; percent_time_unknown = 0.0; percent_time_unknown_scheduled = 0.0; percent_time_unknown_unscheduled = 0.0; percent_time_critical = 0.0; percent_time_critical_scheduled = 0.0; percent_time_critical_unscheduled = 0.0; percent_time_indeterminate = 0.0; percent_time_indeterminate_notrunning = 0.0; percent_time_indeterminate_nodata = 0.0; percent_time_ok_known = 0.0; percent_time_ok_scheduled_known = 0.0; percent_time_ok_unscheduled_known = 0.0; percent_time_warning_known = 0.0; percent_time_warning_scheduled_known = 0.0; percent_time_warning_unscheduled_known = 0.0; percent_time_unknown_known = 0.0; percent_time_unknown_scheduled_known = 0.0; percent_time_unknown_unscheduled_known = 0.0; percent_time_critical_known = 0.0; percent_time_critical_scheduled_known = 0.0; percent_time_critical_unscheduled_known = 0.0; if (total_time > 0) { percent_time_ok = (double) (((double) temp_subject->time_ok * 100.0) / (double) total_time); percent_time_ok_scheduled = (double) (((double) temp_subject->scheduled_time_ok * 100.0) / (double) total_time); percent_time_ok_unscheduled = percent_time_ok - percent_time_ok_scheduled; percent_time_warning = (double) (((double) temp_subject->time_warning * 100.0) / (double) total_time); percent_time_warning_scheduled = (double) (((double) temp_subject->scheduled_time_warning * 100.0) / (double) total_time); percent_time_warning_unscheduled = percent_time_warning - percent_time_warning_scheduled; percent_time_unknown = (double) (((double) temp_subject->time_unknown * 100.0) / (double) total_time); percent_time_unknown_scheduled = (double) (((double) temp_subject->scheduled_time_unknown * 100.0) / (double) total_time); percent_time_unknown_unscheduled = percent_time_unknown - percent_time_unknown_scheduled; percent_time_critical = (double) (((double) temp_subject->time_critical * 100.0) / (double) total_time); percent_time_critical_scheduled = (double) (((double) temp_subject->scheduled_time_critical * 100.0) / (double) total_time); percent_time_critical_unscheduled = percent_time_critical - percent_time_critical_scheduled; percent_time_indeterminate = (double) (((double) time_indeterminate * 100.0) / (double) total_time); percent_time_indeterminate_notrunning = (double) (((double) temp_subject->time_indeterminate_notrunning * 100.0) / (double) total_time); percent_time_indeterminate_nodata = (double) (((double) temp_subject->time_indeterminate_nodata * 100.0) / (double) total_time); if (time_determinate > 0) { percent_time_ok_known = (double) (((double) temp_subject->time_ok * 100.0) / (double) time_determinate); percent_time_ok_scheduled_known = (double) (((double) temp_subject->scheduled_time_ok * 100.0) / (double) time_determinate); percent_time_ok_unscheduled_known = percent_time_ok_known - percent_time_ok_scheduled_known; percent_time_warning_known = (double) (((double) temp_subject->time_warning * 100.0) / (double) time_determinate); percent_time_warning_scheduled_known = (double) (((double) temp_subject->scheduled_time_warning * 100.0) / (double) time_determinate); percent_time_warning_unscheduled_known = percent_time_warning_known - percent_time_warning_scheduled_known; percent_time_unknown_known = (double) (((double) temp_subject->time_unknown * 100.0) / (double) time_determinate); percent_time_unknown_scheduled_known = (double) (((double) temp_subject->scheduled_time_unknown * 100.0) / (double) time_determinate); percent_time_unknown_unscheduled_known = percent_time_unknown_known - percent_time_unknown_scheduled_known; percent_time_critical_known = (double) (((double) temp_subject->time_critical * 100.0) / (double) time_determinate); percent_time_critical_scheduled_known = (double) (((double) temp_subject->scheduled_time_critical * 100.0) / (double) time_determinate); percent_time_critical_unscheduled_known = percent_time_critical_known - percent_time_critical_scheduled_known; } } if (output_format == HTML_OUTPUT) { if (odd) { odd = 0; bgclass = "Odd"; } else { odd = 1; bgclass = "Even"; } printf("", percent_time_ok, percent_time_ok_known); printf("", percent_time_warning, percent_time_warning_known); printf("", percent_time_unknown, percent_time_unknown_known); printf("", percent_time_critical, percent_time_critical_known); printf("\n", bgclass, percent_time_indeterminate); /* we only print the averages for html output */ get_running_average(&average_percent_time_ok, percent_time_ok, current_subject); get_running_average(&average_percent_time_ok_known, percent_time_ok_known, current_subject); get_running_average(&average_percent_time_unknown, percent_time_unknown, current_subject); get_running_average(&average_percent_time_unknown_known, percent_time_unknown_known, current_subject); get_running_average(&average_percent_time_warning, percent_time_warning, current_subject); get_running_average(&average_percent_time_warning_known, percent_time_warning_known, current_subject); get_running_average(&average_percent_time_critical, percent_time_critical, current_subject); get_running_average(&average_percent_time_critical_known, percent_time_critical_known, current_subject); get_running_average(&average_percent_time_indeterminate, percent_time_indeterminate, current_subject); strncpy(last_host, temp_subject->host_name, sizeof(last_host) - 1); last_host[sizeof(last_host) - 1] = '\x0'; } else if (output_format == CSV_OUTPUT) { /* host name and service description */ printf("\"%s\", \"%s\", ", temp_subject->host_name, temp_subject->service_description); /* ok times */ printf("%lu, %2.3f%%, %2.3f%%, ", temp_subject->scheduled_time_ok, percent_time_ok_scheduled, percent_time_ok_scheduled_known); printf("%lu, %2.3f%%, %2.3f%%, ", temp_subject->time_ok - temp_subject->scheduled_time_ok, percent_time_ok_unscheduled, percent_time_ok_unscheduled_known); printf("%lu, %2.3f%%, %2.3f%%, ", temp_subject->time_ok, percent_time_ok, percent_time_ok_known); /* warning times */ printf("%lu, %2.3f%%, %2.3f%%, ", temp_subject->scheduled_time_warning, percent_time_warning_scheduled, percent_time_warning_scheduled_known); printf("%lu, %2.3f%%, %2.3f%%, ", temp_subject->time_warning - temp_subject->scheduled_time_warning, percent_time_warning_unscheduled, percent_time_warning_unscheduled_known); printf("%lu, %2.3f%%, %2.3f%%, ", temp_subject->time_warning, percent_time_warning, percent_time_warning_known); /* unknown times */ printf("%lu, %2.3f%%, %2.3f%%, ", temp_subject->scheduled_time_unknown, percent_time_unknown_scheduled, percent_time_unknown_scheduled_known); printf("%lu, %2.3f%%, %2.3f%%, ", temp_subject->time_unknown - temp_subject->scheduled_time_unknown, percent_time_unknown_unscheduled, percent_time_unknown_unscheduled_known); printf("%lu, %2.3f%%, %2.3f%%, ", temp_subject->time_unknown, percent_time_unknown, percent_time_unknown_known); /* critical times */ printf("%lu, %2.3f%%, %2.3f%%, ", temp_subject->scheduled_time_critical, percent_time_critical_scheduled, percent_time_critical_scheduled_known); printf("%lu, %2.3f%%, %2.3f%%, ", temp_subject->time_critical - temp_subject->scheduled_time_critical, percent_time_critical_unscheduled, percent_time_critical_unscheduled_known); printf("%lu, %2.3f%%, %2.3f%%, ", temp_subject->time_critical, percent_time_critical, percent_time_critical_known); /* indeterminate times */ printf("%lu, %2.3f%%, ", temp_subject->time_indeterminate_notrunning, percent_time_indeterminate_notrunning); printf("%lu, %2.3f%%, ", temp_subject->time_indeterminate_nodata, percent_time_indeterminate_nodata); printf("%lu, %2.3f%%\n", time_indeterminate, percent_time_indeterminate); } } if (output_format == HTML_OUTPUT) { /* average statistics */ if (odd) { odd = 0; bgclass = "Odd"; } else { odd = 1; bgclass = "Even"; } printf("", bgclass, bgclass); printf("", average_percent_time_ok, average_percent_time_ok_known); printf("", average_percent_time_warning, average_percent_time_warning_known); printf("", average_percent_time_unknown, average_percent_time_unknown_known); printf("", average_percent_time_critical, average_percent_time_critical_known); printf("\n", bgclass, average_percent_time_indeterminate); printf("
    HostService%% Time OK%% Time Warning%% Time Unknown%% Time Critical%% Time Undetermined
    ", bgclass, bgclass); if (strcmp(temp_subject->host_name, last_host)) { host_report_url(temp_subject->host_name, temp_subject->host_name); } printf("", bgclass); service_report_url(temp_subject->host_name, temp_subject->service_description, temp_subject->service_description); printf("%2.3f%% (%2.3f%%)%2.3f%% (%2.3f%%)%2.3f%% (%2.3f%%)%2.3f%% (%2.3f%%)%2.3f%%
    Average%2.3f%% (%2.3f%%)%2.3f%% (%2.3f%%)%2.3f%% (%2.3f%%)%2.3f%% (%2.3f%%)%2.3f%%
    \n"); printf("
    \n"); } } } void host_report_url(const char *hn, const char *label) { printf("%s", label); return; } void service_report_url(const char *hn, const char *sd, const char *label) { printf("%s", label); return; } /* calculates running average */ void get_running_average(double *running_average, double new_value, int current_item) { *running_average = (((*running_average * ((double)current_item - 1.0)) + new_value) / (double)current_item); return; } /* used in reports where a timeperiod is selected */ unsigned long calculate_total_time(time_t start_time, time_t end_time) { struct tm *t; time_t midnight_today; int weekday; unsigned long total_time; timerange *temp_timerange; unsigned long temp_duration; unsigned long temp_end; unsigned long temp_start; unsigned long start; unsigned long end; /* attempt to handle the current time_period */ if (current_timeperiod != NULL) { /* "A day" is 86400 seconds */ t = localtime(&start_time); /* calculate the start of the day (midnight, 00:00 hours) */ t->tm_sec = 0; t->tm_min = 0; t->tm_hour = 0; t->tm_isdst = -1; midnight_today = mktime(t); weekday = t->tm_wday; total_time = 0; while(midnight_today < end_time) { temp_duration = 0; temp_end = min(86400, t2 - midnight_today); temp_start = 0; if (t1 > midnight_today) temp_start = t1 - midnight_today; /* check all time ranges for this day of the week */ for (temp_timerange = current_timeperiod->days[weekday]; temp_timerange != NULL; temp_timerange = temp_timerange->next) { start = max(temp_timerange->range_start, temp_start); end = min(temp_timerange->range_end, temp_end); #ifdef DEBUG printf("
  • Matching in timerange[%d]: %d -> %d (%ld -> %ld) %d -> %d = %ld
    \n", weekday, temp_timerange->range_start, temp_timerange->range_end, temp_start, temp_end, start, end, end - start); #endif if (end > start) temp_duration += end - start; } total_time += temp_duration; temp_start = 0; midnight_today += 86400; if (++weekday > 6) weekday = 0; } return total_time; } /* no timeperiod was selected */ return end_time - start_time; }