1 /**************************************************************************
2 *
3 * AVAIL.C - Nagios Availability CGI
4 *
5 * Copyright (c) 2000-2010 Ethan Galstad (egalstad@nagios.org)
6 * Last Modified: 08-05-2010
7 *
8 * License:
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 *************************************************************************/
23
24 #include "../include/config.h"
25 #include "../include/common.h"
26 #include "../include/objects.h"
27 #include "../include/comments.h"
28 #include "../include/statusdata.h"
29
30 #include "../include/cgiutils.h"
31 #include "../include/cgiauth.h"
32 #include "../include/getcgi.h"
33
34
35 extern char main_config_file[MAX_FILENAME_LENGTH];
36 extern char url_html_path[MAX_FILENAME_LENGTH];
37 extern char url_images_path[MAX_FILENAME_LENGTH];
38 extern char url_stylesheets_path[MAX_FILENAME_LENGTH];
39
40 extern host *host_list;
41 extern hostgroup *hostgroup_list;
42 extern servicegroup *servicegroup_list;
43 extern service *service_list;
44 extern timeperiod *timeperiod_list;
45
46 extern int log_rotation_method;
47
48 #ifndef max
49 #define max(a,b) (((a) > (b)) ? (a) : (b))
50 #endif
51 #ifndef min
52 #define min(a,b) (((a) < (b)) ? (a) : (b))
53 #endif
54
55
56
57 /* output types */
58 #define HTML_OUTPUT 0
59 #define CSV_OUTPUT 1
60
61
62 /* archived state types */
63 #define AS_CURRENT_STATE -1 /* special case for initial assumed state */
64 #define AS_NO_DATA 0
65 #define AS_PROGRAM_END 1
66 #define AS_PROGRAM_START 2
67 #define AS_HOST_UP 3
68 #define AS_HOST_DOWN 4
69 #define AS_HOST_UNREACHABLE 5
70 #define AS_SVC_OK 6
71 #define AS_SVC_UNKNOWN 7
72 #define AS_SVC_WARNING 8
73 #define AS_SVC_CRITICAL 9
74
75 #define AS_SVC_DOWNTIME_START 10
76 #define AS_SVC_DOWNTIME_END 11
77 #define AS_HOST_DOWNTIME_START 12
78 #define AS_HOST_DOWNTIME_END 13
79
80 #define AS_SOFT_STATE 1
81 #define AS_HARD_STATE 2
82
83
84 /* display types */
85 #define DISPLAY_NO_AVAIL 0
86 #define DISPLAY_HOSTGROUP_AVAIL 1
87 #define DISPLAY_HOST_AVAIL 2
88 #define DISPLAY_SERVICE_AVAIL 3
89 #define DISPLAY_SERVICEGROUP_AVAIL 4
90
91 /* subject types */
92 #define HOST_SUBJECT 0
93 #define SERVICE_SUBJECT 1
94
95
96 /* standard report times */
97 #define TIMEPERIOD_CUSTOM 0
98 #define TIMEPERIOD_TODAY 1
99 #define TIMEPERIOD_YESTERDAY 2
100 #define TIMEPERIOD_THISWEEK 3
101 #define TIMEPERIOD_LASTWEEK 4
102 #define TIMEPERIOD_THISMONTH 5
103 #define TIMEPERIOD_LASTMONTH 6
104 #define TIMEPERIOD_THISQUARTER 7
105 #define TIMEPERIOD_LASTQUARTER 8
106 #define TIMEPERIOD_THISYEAR 9
107 #define TIMEPERIOD_LASTYEAR 10
108 #define TIMEPERIOD_LAST24HOURS 11
109 #define TIMEPERIOD_LAST7DAYS 12
110 #define TIMEPERIOD_LAST31DAYS 13
111
112 #define MIN_TIMESTAMP_SPACING 10
113
114 #define MAX_ARCHIVE_SPREAD 65
115 #define MAX_ARCHIVE 65
116 #define MAX_ARCHIVE_BACKTRACKS 60
117
118 authdata current_authdata;
119
120 typedef struct archived_state_struct {
121 time_t time_stamp;
122 int entry_type;
123 int state_type;
124 char *state_info;
125 int processed_state;
126 struct archived_state_struct *misc_ptr;
127 struct archived_state_struct *next;
128 } archived_state;
129
130 typedef struct avail_subject_struct {
131 int type;
132 char *host_name;
133 char *service_description;
134 archived_state *as_list; /* archived state list */
135 archived_state *as_list_tail;
136 archived_state *sd_list; /* scheduled downtime list */
137 int last_known_state;
138 time_t earliest_time;
139 time_t latest_time;
140 int earliest_state;
141 int latest_state;
142
143 unsigned long time_up;
144 unsigned long time_down;
145 unsigned long time_unreachable;
146 unsigned long time_ok;
147 unsigned long time_warning;
148 unsigned long time_unknown;
149 unsigned long time_critical;
150
151 unsigned long scheduled_time_up;
152 unsigned long scheduled_time_down;
153 unsigned long scheduled_time_unreachable;
154 unsigned long scheduled_time_ok;
155 unsigned long scheduled_time_warning;
156 unsigned long scheduled_time_unknown;
157 unsigned long scheduled_time_critical;
158 unsigned long scheduled_time_indeterminate;
159
160 unsigned long time_indeterminate_nodata;
161 unsigned long time_indeterminate_notrunning;
162
163 struct avail_subject_struct *next;
164 } avail_subject;
165
166 avail_subject *subject_list = NULL;
167
168 time_t t1;
169 time_t t2;
170
171 int display_type = DISPLAY_NO_AVAIL;
172 int timeperiod_type = TIMEPERIOD_LAST24HOURS;
173 int show_log_entries = FALSE;
174 int full_log_entries = FALSE;
175 int show_scheduled_downtime = TRUE;
176
177 int start_second = 0;
178 int start_minute = 0;
179 int start_hour = 0;
180 int start_day = 1;
181 int start_month = 1;
182 int start_year = 2000;
183 int end_second = 0;
184 int end_minute = 0;
185 int end_hour = 24;
186 int end_day = 1;
187 int end_month = 1;
188 int end_year = 2000;
189
190 int get_date_parts = FALSE;
191 int select_hostgroups = FALSE;
192 int select_hosts = FALSE;
193 int select_servicegroups = FALSE;
194 int select_services = FALSE;
195 int select_output_format = FALSE;
196
197 int compute_time_from_parts = FALSE;
198
199 int show_all_hostgroups = FALSE;
200 int show_all_hosts = FALSE;
201 int show_all_servicegroups = FALSE;
202 int show_all_services = FALSE;
203
204 int assume_initial_states = TRUE;
205 int assume_state_retention = TRUE;
206 int assume_states_during_notrunning = TRUE;
207 int initial_assumed_host_state = AS_NO_DATA;
208 int initial_assumed_service_state = AS_NO_DATA;
209 int include_soft_states = FALSE;
210
211 char *hostgroup_name = "";
212 char *host_name = "";
213 char *servicegroup_name = "";
214 char *svc_description = "";
215
216 void create_subject_list(void);
217 void add_subject(int, char *, char *);
218 avail_subject *find_subject(int, char *, char *);
219 void compute_availability(void);
220 void compute_subject_availability(avail_subject *, time_t);
221 void compute_subject_availability_times(int, int, time_t, time_t, time_t, avail_subject *, archived_state *);
222 void compute_subject_downtime(avail_subject *, time_t);
223 void compute_subject_downtime_times(time_t, time_t, avail_subject *, archived_state *);
224 void compute_subject_downtime_part_times(time_t, time_t, int, avail_subject *);
225 void display_hostgroup_availability(void);
226 void display_specific_hostgroup_availability(hostgroup *);
227 void display_servicegroup_availability(void);
228 void display_specific_servicegroup_availability(servicegroup *);
229 void display_host_availability(void);
230 void display_service_availability(void);
231 void write_log_entries(avail_subject *);
232
233 void get_running_average(double *, double, int);
234
235 void host_report_url(char *, char *);
236 void service_report_url(char *, char *, char *);
237 void compute_report_times(void);
238
239 int convert_host_state_to_archived_state(int);
240 int convert_service_state_to_archived_state(int);
241 void add_global_archived_state(int, int, time_t, char *);
242 void add_archived_state(int, int, time_t, char *, avail_subject *);
243 void add_scheduled_downtime(int, time_t, avail_subject *);
244 void free_availability_data(void);
245 void free_archived_state_list(archived_state *);
246 void read_archived_state_data(void);
247 void scan_log_file_for_archived_state_data(char *);
248 void convert_timeperiod_to_times(int);
249 unsigned long calculate_total_time(time_t, time_t);
250
251 void document_header(int);
252 void document_footer(void);
253 int process_cgivars(void);
254
255
256
257 int backtrack_archives = 2;
258 int earliest_archive = 0;
259
260 int embedded = FALSE;
261 int display_header = TRUE;
262
263 timeperiod *current_timeperiod = NULL;
264
265 int output_format = HTML_OUTPUT;
266
267
268
main(int argc,char ** argv)269 int main(int argc, char **argv) {
270 int result = OK;
271 char temp_buffer[MAX_INPUT_BUFFER];
272 char start_timestring[MAX_DATETIME_LENGTH];
273 char end_timestring[MAX_DATETIME_LENGTH];
274 host *temp_host;
275 service *temp_service;
276 int is_authorized = TRUE;
277 time_t report_start_time;
278 time_t report_end_time;
279 int days, hours, minutes, seconds;
280 hostgroup *temp_hostgroup;
281 servicegroup *temp_servicegroup;
282 timeperiod *temp_timeperiod;
283 time_t t3;
284 time_t current_time;
285 struct tm *t;
286 char *firsthostpointer;
287
288 /* reset internal CGI variables */
289 reset_cgi_vars();
290
291 /* read the CGI configuration file */
292 result = read_cgi_config_file(get_cgi_config_location());
293 if(result == ERROR) {
294 document_header(FALSE);
295 cgi_config_file_error(get_cgi_config_location());
296 document_footer();
297 return ERROR;
298 }
299
300 /* read the main configuration file */
301 result = read_main_config_file(main_config_file);
302 if(result == ERROR) {
303 document_header(FALSE);
304 main_config_file_error(main_config_file);
305 document_footer();
306 return ERROR;
307 }
308
309 /* read all object configuration data */
310 result = read_all_object_configuration_data(main_config_file, READ_ALL_OBJECT_DATA);
311 if(result == ERROR) {
312 document_header(FALSE);
313 object_data_error();
314 document_footer();
315 return ERROR;
316 }
317
318 /* read all status data */
319 result = read_all_status_data(get_cgi_config_location(), READ_ALL_STATUS_DATA);
320 if(result == ERROR) {
321 document_header(FALSE);
322 status_data_error();
323 document_footer();
324 return ERROR;
325 }
326
327 /* initialize time period to last 24 hours */
328 time(¤t_time);
329 t2 = current_time;
330 t1 = (time_t)(current_time - (60 * 60 * 24));
331
332 /* default number of backtracked archives */
333 switch(log_rotation_method) {
334 case LOG_ROTATION_MONTHLY:
335 backtrack_archives = 1;
336 break;
337 case LOG_ROTATION_WEEKLY:
338 backtrack_archives = 2;
339 break;
340 case LOG_ROTATION_DAILY:
341 backtrack_archives = 4;
342 break;
343 case LOG_ROTATION_HOURLY:
344 backtrack_archives = 8;
345 break;
346 default:
347 backtrack_archives = 2;
348 break;
349 }
350
351 /* get the arguments passed in the URL */
352 process_cgivars();
353
354 document_header(TRUE);
355
356 /* get authentication information */
357 get_authentication_information(¤t_authdata);
358
359
360 if(compute_time_from_parts == TRUE)
361 compute_report_times();
362
363 /* make sure times are sane, otherwise swap them */
364 if(t2 < t1) {
365 t3 = t2;
366 t2 = t1;
367 t1 = t3;
368 }
369
370 /* don't let user create reports in the future */
371 if(t2 > current_time) {
372 t2 = current_time;
373 if(t1 > t2)
374 t1 = t2 - (60 * 60 * 24);
375 }
376
377 if(display_header == TRUE) {
378
379 /* begin top table */
380 printf("<table border=0 width=100%% cellspacing=0 cellpadding=0>\n");
381 printf("<tr>\n");
382
383 /* left column of the first row */
384 printf("<td align=left valign=top width=33%%>\n");
385
386 switch(display_type) {
387 case DISPLAY_HOST_AVAIL:
388 snprintf(temp_buffer, sizeof(temp_buffer) - 1, "Host Availability Report");
389 break;
390 case DISPLAY_SERVICE_AVAIL:
391 snprintf(temp_buffer, sizeof(temp_buffer) - 1, "Service Availability Report");
392 break;
393 case DISPLAY_HOSTGROUP_AVAIL:
394 snprintf(temp_buffer, sizeof(temp_buffer) - 1, "Hostgroup Availability Report");
395 break;
396 case DISPLAY_SERVICEGROUP_AVAIL:
397 snprintf(temp_buffer, sizeof(temp_buffer) - 1, "Servicegroup Availability Report");
398 break;
399 default:
400 snprintf(temp_buffer, sizeof(temp_buffer) - 1, "Availability Report");
401 break;
402 }
403 temp_buffer[sizeof(temp_buffer) - 1] = '\x0';
404 display_info_table(temp_buffer, FALSE, ¤t_authdata);
405
406 if(((display_type == DISPLAY_HOST_AVAIL && show_all_hosts == FALSE) || (display_type == DISPLAY_SERVICE_AVAIL && show_all_services == FALSE)) && get_date_parts == FALSE) {
407
408 printf("<TABLE BORDER=1 CELLPADDING=0 CELLSPACING=0 CLASS='linkBox'>\n");
409 printf("<TR><TD CLASS='linkBox'>\n");
410
411 if(display_type == DISPLAY_HOST_AVAIL && show_all_hosts == FALSE) {
412 host_report_url("all", "View Availability Report For All Hosts");
413 printf("<BR>\n");
414 #ifdef USE_TRENDS
415 printf("<a href='%s?host=%s&t1=%lu&t2=%lu&assumestateretention=%s&assumeinitialstates=%s&includesoftstates=%s&assumestatesduringnotrunning=%s&initialassumedhoststate=%d&backtrack=%d'>View Trends For This Host</a><BR>\n", TRENDS_CGI, url_encode(host_name), t1, t2, (include_soft_states == TRUE) ? "yes" : "no", (assume_state_retention == TRUE) ? "yes" : "no", (assume_initial_states == TRUE) ? "yes" : "no", (assume_states_during_notrunning == TRUE) ? "yes" : "no", initial_assumed_host_state, backtrack_archives);
416 #endif
417 #ifdef USE_HISTOGRAM
418 printf("<a href='%s?host=%s&t1=%lu&t2=%lu&assumestateretention=%s'>View Alert Histogram For This Host</a><BR>\n", HISTOGRAM_CGI, url_encode(host_name), t1, t2, (assume_state_retention == TRUE) ? "yes" : "no");
419 #endif
420 printf("<a href='%s?host=%s'>View Status Detail For This Host</a><BR>\n", STATUS_CGI, url_encode(host_name));
421 printf("<a href='%s?host=%s'>View Alert History For This Host</a><BR>\n", HISTORY_CGI, url_encode(host_name));
422 printf("<a href='%s?host=%s'>View Notifications For This Host</a><BR>\n", NOTIFICATIONS_CGI, url_encode(host_name));
423 }
424 else if(display_type == DISPLAY_SERVICE_AVAIL && show_all_services == FALSE) {
425 host_report_url(host_name, "View Availability Report For This Host");
426 printf("<BR>\n");
427 service_report_url("null", "all", "View Availability Report For All Services");
428 printf("<BR>\n");
429 #ifdef USE_TRENDS
430 printf("<a href='%s?host=%s", TRENDS_CGI, url_encode(host_name));
431 printf("&service=%s&t1=%lu&t2=%lu&assumestateretention=%s&includesoftstates=%s&assumeinitialstates=%s&assumestatesduringnotrunning=%s&initialassumedservicestate=%d&backtrack=%d'>View Trends For This Service</a><BR>\n", url_encode(svc_description), t1, t2, (include_soft_states == TRUE) ? "yes" : "no", (assume_state_retention == TRUE) ? "yes" : "no", (assume_initial_states == TRUE) ? "yes" : "no", (assume_states_during_notrunning == TRUE) ? "yes" : "no", initial_assumed_service_state, backtrack_archives);
432 #endif
433 #ifdef USE_HISTOGRAM
434 printf("<a href='%s?host=%s", HISTOGRAM_CGI, url_encode(host_name));
435 printf("&service=%s&t1=%lu&t2=%lu&assumestateretention=%s'>View Alert Histogram For This Service</a><BR>\n", url_encode(svc_description), t1, t2, (assume_state_retention == TRUE) ? "yes" : "no");
436 #endif
437 printf("<A HREF='%s?host=%s&", HISTORY_CGI, url_encode(host_name));
438 printf("service=%s'>View Alert History For This Service</A><BR>\n", url_encode(svc_description));
439 printf("<A HREF='%s?host=%s&", NOTIFICATIONS_CGI, url_encode(host_name));
440 printf("service=%s'>View Notifications For This Service</A><BR>\n", url_encode(svc_description));
441 }
442
443 printf("</TD></TR>\n");
444 printf("</TABLE>\n");
445 }
446
447 printf("</td>\n");
448
449 /* center column of top row */
450 printf("<td align=center valign=top width=33%%>\n");
451
452 if(display_type != DISPLAY_NO_AVAIL && get_date_parts == FALSE) {
453
454 printf("<DIV ALIGN=CENTER CLASS='dataTitle'>\n");
455 if(display_type == DISPLAY_HOST_AVAIL) {
456 if(show_all_hosts == TRUE)
457 printf("All Hosts");
458 else
459 printf("Host '%s'", host_name);
460 }
461 else if(display_type == DISPLAY_SERVICE_AVAIL) {
462 if(show_all_services == TRUE)
463 printf("All Services");
464 else
465 printf("Service '%s' On Host '%s'", svc_description, host_name);
466 }
467 else if(display_type == DISPLAY_HOSTGROUP_AVAIL) {
468 if(show_all_hostgroups == TRUE)
469 printf("All Hostgroups");
470 else
471 printf("Hostgroup '%s'", hostgroup_name);
472 }
473 else if(display_type == DISPLAY_SERVICEGROUP_AVAIL) {
474 if(show_all_servicegroups == TRUE)
475 printf("All Servicegroups");
476 else
477 printf("Servicegroup '%s'", servicegroup_name);
478 }
479 printf("</DIV>\n");
480
481 printf("<BR>\n");
482
483 printf("<IMG SRC='%s%s' BORDER=0 ALT='Availability Report' TITLE='Availability Report'>\n", url_images_path, TRENDS_ICON);
484
485 printf("<BR CLEAR=ALL>\n");
486
487 get_time_string(&t1, start_timestring, sizeof(start_timestring) - 1, SHORT_DATE_TIME);
488 get_time_string(&t2, end_timestring, sizeof(end_timestring) - 1, SHORT_DATE_TIME);
489 printf("<div align=center class='reportRange'>%s to %s</div>\n", start_timestring, end_timestring);
490
491 get_time_breakdown((time_t)(t2 - t1), &days, &hours, &minutes, &seconds);
492 printf("<div align=center class='reportDuration'>Duration: %dd %dh %dm %ds</div>\n", days, hours, minutes, seconds);
493 }
494
495 printf("</td>\n");
496
497 /* right hand column of top row */
498 printf("<td align=right valign=bottom width=33%%>\n");
499
500 printf("<form method=\"GET\" action=\"%s\">\n", AVAIL_CGI);
501 printf("<table border=0 CLASS='optBox'>\n");
502
503 if(display_type != DISPLAY_NO_AVAIL && get_date_parts == FALSE) {
504
505 printf("<tr><td valign=top align=left class='optBoxItem'>First assumed %s state:</td><td valign=top align=left class='optBoxItem'>%s</td></tr>\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" : "");
506 printf("<tr>\n");
507 printf("<td valign=top align=left class='optBoxItem'>\n");
508
509 printf("<input type='hidden' name='t1' value='%lu'>\n", (unsigned long)t1);
510 printf("<input type='hidden' name='t2' value='%lu'>\n", (unsigned long)t2);
511 if(show_log_entries == TRUE)
512 printf("<input type='hidden' name='show_log_entries' value=''>\n");
513 if(full_log_entries == TRUE)
514 printf("<input type='hidden' name='full_log_entries' value=''>\n");
515 if(display_type == DISPLAY_HOSTGROUP_AVAIL)
516 printf("<input type='hidden' name='hostgroup' value='%s'>\n", escape_string(hostgroup_name));
517 if(display_type == DISPLAY_HOST_AVAIL || display_type == DISPLAY_SERVICE_AVAIL)
518 printf("<input type='hidden' name='host' value='%s'>\n", escape_string(host_name));
519 if(display_type == DISPLAY_SERVICE_AVAIL)
520 printf("<input type='hidden' name='service' value='%s'>\n", escape_string(svc_description));
521 if(display_type == DISPLAY_SERVICEGROUP_AVAIL)
522 printf("<input type='hidden' name='servicegroup' value='%s'>\n", escape_string(servicegroup_name));
523
524 printf("<input type='hidden' name='assumeinitialstates' value='%s'>\n", (assume_initial_states == TRUE) ? "yes" : "no");
525 printf("<input type='hidden' name='assumestateretention' value='%s'>\n", (assume_state_retention == TRUE) ? "yes" : "no");
526 printf("<input type='hidden' name='assumestatesduringnotrunning' value='%s'>\n", (assume_states_during_notrunning == TRUE) ? "yes" : "no");
527 printf("<input type='hidden' name='includesoftstates' value='%s'>\n", (include_soft_states == TRUE) ? "yes" : "no");
528
529 if(display_type == DISPLAY_HOST_AVAIL || display_type == DISPLAY_HOSTGROUP_AVAIL || display_type == DISPLAY_SERVICEGROUP_AVAIL) {
530 printf("<select name='initialassumedhoststate'>\n");
531 printf("<option value=%d %s>Unspecified\n", AS_NO_DATA, (initial_assumed_host_state == AS_NO_DATA) ? "SELECTED" : "");
532 printf("<option value=%d %s>Current State\n", AS_CURRENT_STATE, (initial_assumed_host_state == AS_CURRENT_STATE) ? "SELECTED" : "");
533 printf("<option value=%d %s>Host Up\n", AS_HOST_UP, (initial_assumed_host_state == AS_HOST_UP) ? "SELECTED" : "");
534 printf("<option value=%d %s>Host Down\n", AS_HOST_DOWN, (initial_assumed_host_state == AS_HOST_DOWN) ? "SELECTED" : "");
535 printf("<option value=%d %s>Host Unreachable\n", AS_HOST_UNREACHABLE, (initial_assumed_host_state == AS_HOST_UNREACHABLE) ? "SELECTED" : "");
536 printf("</select>\n");
537 }
538 else {
539 printf("<input type='hidden' name='initialassumedhoststate' value='%d'>", initial_assumed_host_state);
540 printf("<select name='initialassumedservicestate'>\n");
541 printf("<option value=%d %s>Unspecified\n", AS_NO_DATA, (initial_assumed_service_state == AS_NO_DATA) ? "SELECTED" : "");
542 printf("<option value=%d %s>Current State\n", AS_CURRENT_STATE, (initial_assumed_service_state == AS_CURRENT_STATE) ? "SELECTED" : "");
543 printf("<option value=%d %s>Service Ok\n", AS_SVC_OK, (initial_assumed_service_state == AS_SVC_OK) ? "SELECTED" : "");
544 printf("<option value=%d %s>Service Warning\n", AS_SVC_WARNING, (initial_assumed_service_state == AS_SVC_WARNING) ? "SELECTED" : "");
545 printf("<option value=%d %s>Service Unknown\n", AS_SVC_UNKNOWN, (initial_assumed_service_state == AS_SVC_UNKNOWN) ? "SELECTED" : "");
546 printf("<option value=%d %s>Service Critical\n", AS_SVC_CRITICAL, (initial_assumed_service_state == AS_SVC_CRITICAL) ? "SELECTED" : "");
547 printf("</select>\n");
548 }
549 printf("</td>\n");
550 printf("<td CLASS='optBoxItem'>\n");
551 if(display_type == DISPLAY_HOST_AVAIL || display_type == DISPLAY_HOSTGROUP_AVAIL || display_type == DISPLAY_SERVICEGROUP_AVAIL) {
552 printf("<select name='initialassumedservicestate'>\n");
553 printf("<option value=%d %s>Unspecified\n", AS_NO_DATA, (initial_assumed_service_state == AS_NO_DATA) ? "SELECTED" : "");
554 printf("<option value=%d %s>Current State\n", AS_CURRENT_STATE, (initial_assumed_service_state == AS_CURRENT_STATE) ? "SELECTED" : "");
555 printf("<option value=%d %s>Service Ok\n", AS_SVC_OK, (initial_assumed_service_state == AS_SVC_OK) ? "SELECTED" : "");
556 printf("<option value=%d %s>Service Warning\n", AS_SVC_WARNING, (initial_assumed_service_state == AS_SVC_WARNING) ? "SELECTED" : "");
557 printf("<option value=%d %s>Service Unknown\n", AS_SVC_UNKNOWN, (initial_assumed_service_state == AS_SVC_UNKNOWN) ? "SELECTED" : "");
558 printf("<option value=%d %s>Service Critical\n", AS_SVC_CRITICAL, (initial_assumed_service_state == AS_SVC_CRITICAL) ? "SELECTED" : "");
559 printf("</select>\n");
560 }
561 printf("</td>\n");
562 printf("</tr>\n");
563
564 printf("<tr><td valign=top align=left class='optBoxItem'>Report period:</td><td valign=top align=left class='optBoxItem'>Backtracked archives:</td></tr>\n");
565 printf("<tr>\n");
566 printf("<td valign=top align=left class='optBoxItem'>\n");
567 printf("<select name='timeperiod'>\n");
568 printf("<option SELECTED>[ Current time range ]\n");
569 printf("<option value=today %s>Today\n", (timeperiod_type == TIMEPERIOD_TODAY) ? "SELECTED" : "");
570 printf("<option value=last24hours %s>Last 24 Hours\n", (timeperiod_type == TIMEPERIOD_LAST24HOURS) ? "SELECTED" : "");
571 printf("<option value=yesterday %s>Yesterday\n", (timeperiod_type == TIMEPERIOD_YESTERDAY) ? "SELECTED" : "");
572 printf("<option value=thisweek %s>This Week\n", (timeperiod_type == TIMEPERIOD_THISWEEK) ? "SELECTED" : "");
573 printf("<option value=last7days %s>Last 7 Days\n", (timeperiod_type == TIMEPERIOD_LAST7DAYS) ? "SELECTED" : "");
574 printf("<option value=lastweek %s>Last Week\n", (timeperiod_type == TIMEPERIOD_LASTWEEK) ? "SELECTED" : "");
575 printf("<option value=thismonth %s>This Month\n", (timeperiod_type == TIMEPERIOD_THISMONTH) ? "SELECTED" : "");
576 printf("<option value=last31days %s>Last 31 Days\n", (timeperiod_type == TIMEPERIOD_LAST31DAYS) ? "SELECTED" : "");
577 printf("<option value=lastmonth %s>Last Month\n", (timeperiod_type == TIMEPERIOD_LASTMONTH) ? "SELECTED" : "");
578 printf("<option value=thisyear %s>This Year\n", (timeperiod_type == TIMEPERIOD_THISYEAR) ? "SELECTED" : "");
579 printf("<option value=lastyear %s>Last Year\n", (timeperiod_type == TIMEPERIOD_LASTYEAR) ? "SELECTED" : "");
580 printf("</select>\n");
581 printf("</td>\n");
582 printf("<td valign=top align=left CLASS='optBoxItem'>\n");
583 printf("<input type='text' size='2' maxlength='2' name='backtrack' value='%d'>\n", backtrack_archives);
584 printf("</td>\n");
585 printf("</tr>\n");
586
587 printf("<tr><td valign=top align=left></td>\n");
588 printf("<td valign=top align=left CLASS='optBoxItem'>\n");
589 printf("<input type='submit' value='Update'>\n");
590 printf("</td>\n");
591 printf("</tr>\n");
592 }
593
594 /* display context-sensitive help */
595 printf("<tr><td></td><td align=right valign=bottom>\n");
596 if(get_date_parts == TRUE)
597 display_context_help(CONTEXTHELP_AVAIL_MENU5);
598 else if(select_hostgroups == TRUE)
599 display_context_help(CONTEXTHELP_AVAIL_MENU2);
600 else if(select_hosts == TRUE)
601 display_context_help(CONTEXTHELP_AVAIL_MENU3);
602 else if(select_services == TRUE)
603 display_context_help(CONTEXTHELP_AVAIL_MENU4);
604 else if(display_type == DISPLAY_HOSTGROUP_AVAIL)
605 display_context_help(CONTEXTHELP_AVAIL_HOSTGROUP);
606 else if(display_type == DISPLAY_HOST_AVAIL)
607 display_context_help(CONTEXTHELP_AVAIL_HOST);
608 else if(display_type == DISPLAY_SERVICE_AVAIL)
609 display_context_help(CONTEXTHELP_AVAIL_SERVICE);
610 else if(display_type == DISPLAY_SERVICEGROUP_AVAIL)
611 display_context_help(CONTEXTHELP_AVAIL_SERVICEGROUP);
612 else
613 display_context_help(CONTEXTHELP_AVAIL_MENU1);
614 printf("</td></tr>\n");
615
616 printf("</table>\n");
617 printf("</form>\n");
618
619 printf("</td>\n");
620
621 /* end of top table */
622 printf("</tr>\n");
623 printf("</table>\n");
624 }
625
626
627
628
629 /* step 3 - ask user for report date range */
630 if(get_date_parts == TRUE) {
631
632 time(¤t_time);
633 t = localtime(¤t_time);
634
635 start_day = 1;
636 start_year = t->tm_year + 1900;
637 end_day = t->tm_mday;
638 end_year = t->tm_year + 1900;
639
640 printf("<P><DIV ALIGN=CENTER CLASS='dateSelectTitle'>Step 3: Select Report Options</DIV></p>\n");
641
642 printf("<P><DIV ALIGN=CENTER>\n");
643
644 printf("<form method=\"get\" action=\"%s\">\n", AVAIL_CGI);
645 printf("<input type='hidden' name='show_log_entries' value=''>\n");
646 if(display_type == DISPLAY_HOSTGROUP_AVAIL)
647 printf("<input type='hidden' name='hostgroup' value='%s'>\n", escape_string(hostgroup_name));
648 if(display_type == DISPLAY_HOST_AVAIL || display_type == DISPLAY_SERVICE_AVAIL)
649 printf("<input type='hidden' name='host' value='%s'>\n", escape_string(host_name));
650 if(display_type == DISPLAY_SERVICE_AVAIL)
651 printf("<input type='hidden' name='service' value='%s'>\n", escape_string(svc_description));
652 if(display_type == DISPLAY_SERVICEGROUP_AVAIL)
653 printf("<input type='hidden' name='servicegroup' value='%s'>\n", escape_string(servicegroup_name));
654
655 printf("<table border=0 cellpadding=5>\n");
656
657 printf("<tr>");
658 printf("<td valign=top class='reportSelectSubTitle'>Report Period:</td>\n");
659 printf("<td valign=top align=left class='optBoxItem'>\n");
660 printf("<select name='timeperiod'>\n");
661 printf("<option value=today>Today\n");
662 printf("<option value=last24hours>Last 24 Hours\n");
663 printf("<option value=yesterday>Yesterday\n");
664 printf("<option value=thisweek>This Week\n");
665 printf("<option value=last7days SELECTED>Last 7 Days\n");
666 printf("<option value=lastweek>Last Week\n");
667 printf("<option value=thismonth>This Month\n");
668 printf("<option value=last31days>Last 31 Days\n");
669 printf("<option value=lastmonth>Last Month\n");
670 printf("<option value=thisyear>This Year\n");
671 printf("<option value=lastyear>Last Year\n");
672 printf("<option value=custom>* CUSTOM REPORT PERIOD *\n");
673 printf("</select>\n");
674 printf("</td>\n");
675 printf("</tr>\n");
676
677 printf("<tr><td valign=top class='reportSelectSubTitle'>If Custom Report Period...</td></tr>\n");
678
679 printf("<tr>");
680 printf("<td valign=top class='reportSelectSubTitle'>Start Date (Inclusive):</td>\n");
681 printf("<td align=left valign=top class='reportSelectItem'>");
682 printf("<select name='smon'>\n");
683 printf("<option value='1' %s>January\n", (t->tm_mon == 0) ? "SELECTED" : "");
684 printf("<option value='2' %s>February\n", (t->tm_mon == 1) ? "SELECTED" : "");
685 printf("<option value='3' %s>March\n", (t->tm_mon == 2) ? "SELECTED" : "");
686 printf("<option value='4' %s>April\n", (t->tm_mon == 3) ? "SELECTED" : "");
687 printf("<option value='5' %s>May\n", (t->tm_mon == 4) ? "SELECTED" : "");
688 printf("<option value='6' %s>June\n", (t->tm_mon == 5) ? "SELECTED" : "");
689 printf("<option value='7' %s>July\n", (t->tm_mon == 6) ? "SELECTED" : "");
690 printf("<option value='8' %s>August\n", (t->tm_mon == 7) ? "SELECTED" : "");
691 printf("<option value='9' %s>September\n", (t->tm_mon == 8) ? "SELECTED" : "");
692 printf("<option value='10' %s>October\n", (t->tm_mon == 9) ? "SELECTED" : "");
693 printf("<option value='11' %s>November\n", (t->tm_mon == 10) ? "SELECTED" : "");
694 printf("<option value='12' %s>December\n", (t->tm_mon == 11) ? "SELECTED" : "");
695 printf("</select>\n ");
696 printf("<input type='text' size='2' maxlength='2' name='sday' value='%d'> ", start_day);
697 printf("<input type='text' size='4' maxlength='4' name='syear' value='%d'>", start_year);
698 printf("<input type='hidden' name='shour' value='0'>\n");
699 printf("<input type='hidden' name='smin' value='0'>\n");
700 printf("<input type='hidden' name='ssec' value='0'>\n");
701 printf("</td>\n");
702 printf("</tr>\n");
703
704 printf("<tr>");
705 printf("<td valign=top class='reportSelectSubTitle'>End Date (Inclusive):</td>\n");
706 printf("<td align=left valign=top class='reportSelectItem'>");
707 printf("<select name='emon'>\n");
708 printf("<option value='1' %s>January\n", (t->tm_mon == 0) ? "SELECTED" : "");
709 printf("<option value='2' %s>February\n", (t->tm_mon == 1) ? "SELECTED" : "");
710 printf("<option value='3' %s>March\n", (t->tm_mon == 2) ? "SELECTED" : "");
711 printf("<option value='4' %s>April\n", (t->tm_mon == 3) ? "SELECTED" : "");
712 printf("<option value='5' %s>May\n", (t->tm_mon == 4) ? "SELECTED" : "");
713 printf("<option value='6' %s>June\n", (t->tm_mon == 5) ? "SELECTED" : "");
714 printf("<option value='7' %s>July\n", (t->tm_mon == 6) ? "SELECTED" : "");
715 printf("<option value='8' %s>August\n", (t->tm_mon == 7) ? "SELECTED" : "");
716 printf("<option value='9' %s>September\n", (t->tm_mon == 8) ? "SELECTED" : "");
717 printf("<option value='10' %s>October\n", (t->tm_mon == 9) ? "SELECTED" : "");
718 printf("<option value='11' %s>November\n", (t->tm_mon == 10) ? "SELECTED" : "");
719 printf("<option value='12' %s>December\n", (t->tm_mon == 11) ? "SELECTED" : "");
720 printf("</select>\n ");
721 printf("<input type='text' size='2' maxlength='2' name='eday' value='%d'> ", end_day);
722 printf("<input type='text' size='4' maxlength='4' name='eyear' value='%d'>", end_year);
723 printf("<input type='hidden' name='ehour' value='24'>\n");
724 printf("<input type='hidden' name='emin' value='0'>\n");
725 printf("<input type='hidden' name='esec' value='0'>\n");
726 printf("</td>\n");
727 printf("</tr>\n");
728
729 printf("<tr><td colspan=2><br></td></tr>\n");
730
731 printf("<tr>");
732 printf("<td valign=top class='reportSelectSubTitle'>Report time Period:</td>\n");
733 printf("<td valign=top align=left class='optBoxItem'>\n");
734 printf("<select name='rpttimeperiod'>\n");
735 printf("<option value=\"\">None\n");
736 /* check all the time periods... */
737 for(temp_timeperiod = timeperiod_list; temp_timeperiod != NULL; temp_timeperiod = temp_timeperiod->next)
738 printf("<option value=%s>%s\n", escape_string(temp_timeperiod->name), temp_timeperiod->name);
739 printf("</select>\n");
740 printf("</td>\n");
741 printf("</tr>\n");
742 printf("<tr><td colspan=2><br></td></tr>\n");
743
744 printf("<tr><td class='reportSelectSubTitle' align=right>Assume Initial States:</td>\n");
745 printf("<td class='reportSelectItem'>\n");
746 printf("<select name='assumeinitialstates'>\n");
747 printf("<option value=yes>Yes\n");
748 printf("<option value=no>No\n");
749 printf("</select>\n");
750 printf("</td></tr>\n");
751
752 printf("<tr><td class='reportSelectSubTitle' align=right>Assume State Retention:</td>\n");
753 printf("<td class='reportSelectItem'>\n");
754 printf("<select name='assumestateretention'>\n");
755 printf("<option value=yes>Yes\n");
756 printf("<option value=no>No\n");
757 printf("</select>\n");
758 printf("</td></tr>\n");
759
760 printf("<tr><td class='reportSelectSubTitle' align=right>Assume States During Program Downtime:</td>\n");
761 printf("<td class='reportSelectItem'>\n");
762 printf("<select name='assumestatesduringnotrunning'>\n");
763 printf("<option value=yes>Yes\n");
764 printf("<option value=no>No\n");
765 printf("</select>\n");
766 printf("</td></tr>\n");
767
768 printf("<tr><td class='reportSelectSubTitle' align=right>Include Soft States:</td>\n");
769 printf("<td class='reportSelectItem'>\n");
770 printf("<select name='includesoftstates'>\n");
771 printf("<option value=yes>Yes\n");
772 printf("<option value=no SELECTED>No\n");
773 printf("</select>\n");
774 printf("</td></tr>\n");
775
776 if(display_type != DISPLAY_SERVICE_AVAIL) {
777 printf("<tr><td class='reportSelectSubTitle' align=right>First Assumed Host State:</td>\n");
778 printf("<td class='reportSelectItem'>\n");
779 printf("<select name='initialassumedhoststate'>\n");
780 printf("<option value=%d>Unspecified\n", AS_NO_DATA);
781 printf("<option value=%d>Current State\n", AS_CURRENT_STATE);
782 printf("<option value=%d>Host Up\n", AS_HOST_UP);
783 printf("<option value=%d>Host Down\n", AS_HOST_DOWN);
784 printf("<option value=%d>Host Unreachable\n", AS_HOST_UNREACHABLE);
785 printf("</select>\n");
786 printf("</td></tr>\n");
787 }
788
789 printf("<tr><td class='reportSelectSubTitle' align=right>First Assumed Service State:</td>\n");
790 printf("<td class='reportSelectItem'>\n");
791 printf("<select name='initialassumedservicestate'>\n");
792 printf("<option value=%d>Unspecified\n", AS_NO_DATA);
793 printf("<option value=%d>Current State\n", AS_CURRENT_STATE);
794 printf("<option value=%d>Service Ok\n", AS_SVC_OK);
795 printf("<option value=%d>Service Warning\n", AS_SVC_WARNING);
796 printf("<option value=%d>Service Unknown\n", AS_SVC_UNKNOWN);
797 printf("<option value=%d>Service Critical\n", AS_SVC_CRITICAL);
798 printf("</select>\n");
799 printf("</td></tr>\n");
800
801 printf("<tr><td class='reportSelectSubTitle' align=right>Backtracked Archives (To Scan For Initial States):</td>\n");
802 printf("<td class='reportSelectItem'>\n");
803 printf("<input type='text' name='backtrack' size='2' maxlength='2' value='%d'>\n", backtrack_archives);
804 printf("</td></tr>\n");
805
806 if((display_type == DISPLAY_HOST_AVAIL && show_all_hosts == TRUE) || (display_type == DISPLAY_SERVICE_AVAIL && show_all_services == TRUE)) {
807 printf("<tr>");
808 printf("<td valign=top class='reportSelectSubTitle'>Output in CSV Format:</td>\n");
809 printf("<td valign=top class='reportSelectItem'>");
810 printf("<input type='checkbox' name='csvoutput' value=''>\n");
811 printf("</td>\n");
812 printf("</tr>\n");
813 }
814
815 printf("<tr><td></td><td align=left class='dateSelectItem'><input type='submit' value='Create Availability Report!'></td></tr>\n");
816
817 printf("</table>\n");
818
819 printf("</form>\n");
820 printf("</DIV></P>\n");
821 }
822
823
824 /* step 2 - the user wants to select a hostgroup */
825 else if(select_hostgroups == TRUE) {
826 printf("<p><div align=center class='reportSelectTitle'>Step 2: Select Hostgroup</div></p>\n");
827
828 printf("<p><div align=center>\n");
829
830 printf("<form method=\"get\" action=\"%s\">\n", AVAIL_CGI);
831 printf("<input type='hidden' name='get_date_parts'>\n");
832
833 printf("<table border=0 cellpadding=5>\n");
834
835 printf("<tr><td class='reportSelectSubTitle' valign=center>Hostgroup(s):</td><td align=left valign=center class='reportSelectItem'>\n");
836 printf("<select name='hostgroup'>\n");
837 printf("<option value='all'>** ALL HOSTGROUPS **\n");
838 for(temp_hostgroup = hostgroup_list; temp_hostgroup != NULL; temp_hostgroup = temp_hostgroup->next) {
839 if(is_authorized_for_hostgroup(temp_hostgroup, ¤t_authdata) == TRUE)
840 printf("<option value='%s'>%s\n", escape_string(temp_hostgroup->group_name), temp_hostgroup->group_name);
841 }
842 printf("</select>\n");
843 printf("</td></tr>\n");
844
845 printf("<tr><td></td><td align=left class='dateSelectItem'><input type='submit' value='Continue to Step 3'></td></tr>\n");
846
847 printf("</table>\n");
848
849 printf("</form>\n");
850
851 printf("</div></p>\n");
852 }
853
854 /* step 2 - the user wants to select a host */
855 else if(select_hosts == TRUE) {
856 printf("<p><div align=center class='reportSelectTitle'>Step 2: Select Host</div></p>\n");
857
858 printf("<p><div align=center>\n");
859
860 printf("<form method=\"get\" action=\"%s\">\n", AVAIL_CGI);
861 printf("<input type='hidden' name='get_date_parts'>\n");
862
863 printf("<table border=0 cellpadding=5>\n");
864
865 printf("<tr><td class='reportSelectSubTitle' valign=center>Host(s):</td><td align=left valign=center class='reportSelectItem'>\n");
866 printf("<select name='host'>\n");
867 printf("<option value='all'>** ALL HOSTS **\n");
868 for(temp_host = host_list; temp_host != NULL; temp_host = temp_host->next) {
869 if(is_authorized_for_host(temp_host, ¤t_authdata) == TRUE)
870 printf("<option value='%s'>%s\n", escape_string(temp_host->name), temp_host->name);
871 }
872 printf("</select>\n");
873 printf("</td></tr>\n");
874
875 printf("<tr><td></td><td align=left class='dateSelectItem'><input type='submit' value='Continue to Step 3'></td></tr>\n");
876
877 printf("</table>\n");
878
879 printf("</form>\n");
880
881 printf("</div></p>\n");
882
883 printf("<div align=center class='helpfulHint'>Tip: If you want to have the option of getting the availability data in CSV format, select '<b>** ALL HOSTS **</b>' from the pull-down menu.\n");
884 }
885
886 /* step 2 - the user wants to select a servicegroup */
887 else if(select_servicegroups == TRUE) {
888 printf("<p><div align=center class='reportSelectTitle'>Step 2: Select Servicegroup</div></p>\n");
889
890 printf("<p><div align=center>\n");
891
892 printf("<form method=\"get\" action=\"%s\">\n", AVAIL_CGI);
893 printf("<input type='hidden' name='get_date_parts'>\n");
894
895 printf("<table border=0 cellpadding=5>\n");
896
897 printf("<tr><td class='reportSelectSubTitle' valign=center>Servicegroup(s):</td><td align=left valign=center class='reportSelectItem'>\n");
898 printf("<select name='servicegroup'>\n");
899 printf("<option value='all'>** ALL SERVICEGROUPS **\n");
900 for(temp_servicegroup = servicegroup_list; temp_servicegroup != NULL; temp_servicegroup = temp_servicegroup->next) {
901 if(is_authorized_for_servicegroup(temp_servicegroup, ¤t_authdata) == TRUE)
902 printf("<option value='%s'>%s\n", escape_string(temp_servicegroup->group_name), temp_servicegroup->group_name);
903 }
904 printf("</select>\n");
905 printf("</td></tr>\n");
906
907 printf("<tr><td></td><td align=left class='dateSelectItem'><input type='submit' value='Continue to Step 3'></td></tr>\n");
908
909 printf("</table>\n");
910
911 printf("</form>\n");
912
913 printf("</div></p>\n");
914 }
915
916 /* step 2 - the user wants to select a service */
917 else if(select_services == TRUE) {
918
919 printf("<SCRIPT LANGUAGE='JavaScript'>\n");
920 printf("function gethostname(hostindex){\n");
921 printf("hostnames=[\"all\"");
922
923 firsthostpointer = NULL;
924 for(temp_service = service_list; temp_service != NULL; temp_service = temp_service->next) {
925 if(is_authorized_for_service(temp_service, ¤t_authdata) == TRUE) {
926 if(!firsthostpointer)
927 firsthostpointer = temp_service->host_name;
928 printf(", \"%s\"", temp_service->host_name);
929 }
930 }
931
932 printf(" ]\n");
933 printf("return hostnames[hostindex];\n");
934 printf("}\n");
935 printf("</SCRIPT>\n");
936
937 printf("<p><div align=center class='reportSelectTitle'>Step 2: Select Service</div></p>\n");
938
939 printf("<p><div align=center>\n");
940
941 printf("<form method=\"get\" action=\"%s\" name='serviceform'>\n", AVAIL_CGI);
942 printf("<input type='hidden' name='get_date_parts'>\n");
943 printf("<input type='hidden' name='host' value='%s'>\n", (firsthostpointer == NULL) ? "unknown" : (char *)escape_string(firsthostpointer));
944
945 printf("<table border=0 cellpadding=5>\n");
946
947 printf("<tr><td class='reportSelectSubTitle' valign=center>Service(s):</td><td align=left valign=center class='reportSelectItem'>\n");
948 printf("<select name='service' onFocus='document.serviceform.host.value=gethostname(this.selectedIndex);' onChange='document.serviceform.host.value=gethostname(this.selectedIndex);'>\n");
949 printf("<option value='all'>** ALL SERVICES **\n");
950 for(temp_service = service_list; temp_service != NULL; temp_service = temp_service->next) {
951 if(is_authorized_for_service(temp_service, ¤t_authdata) == TRUE)
952 printf("<option value='%s'>%s;%s\n", escape_string(temp_service->description), temp_service->host_name, temp_service->description);
953 }
954
955 printf("</select>\n");
956 printf("</td></tr>\n");
957
958 printf("<tr><td></td><td align=left class='dateSelectItem'><input type='submit' value='Continue to Step 3'></td></tr>\n");
959
960 printf("</table>\n");
961
962 printf("</form>\n");
963
964 printf("</div></p>\n");
965
966 printf("<div align=center class='helpfulHint'>Tip: If you want to have the option of getting the availability data in CSV format, select '<b>** ALL SERVICES **</b>' from the pull-down menu.\n");
967 }
968
969
970 /* generate availability report */
971 else if(display_type != DISPLAY_NO_AVAIL) {
972
973 /* check authorization */
974 is_authorized = TRUE;
975 if((display_type == DISPLAY_HOST_AVAIL && show_all_hosts == FALSE) || (display_type == DISPLAY_SERVICE_AVAIL && show_all_services == FALSE)) {
976
977 if(display_type == DISPLAY_HOST_AVAIL && show_all_hosts == FALSE)
978 is_authorized = is_authorized_for_host(find_host(host_name), ¤t_authdata);
979 else
980 is_authorized = is_authorized_for_service(find_service(host_name, svc_description), ¤t_authdata);
981 }
982
983 if(is_authorized == FALSE)
984 printf("<P><DIV ALIGN=CENTER CLASS='errorMessage'>It appears as though you are not authorized to view information for the specified %s...</DIV></P>\n", (display_type == DISPLAY_HOST_AVAIL) ? "host" : "service");
985
986 else {
987
988 time(&report_start_time);
989
990 /* create list of subjects to collect availability data for */
991 create_subject_list();
992
993 /* read in all necessary archived state data */
994 read_archived_state_data();
995
996 /* compute availability data */
997 compute_availability();
998
999 time(&report_end_time);
1000
1001 if(output_format == HTML_OUTPUT) {
1002 get_time_breakdown((time_t)(report_end_time - report_start_time), &days, &hours, &minutes, &seconds);
1003 printf("<div align=center class='reportTime'>[ Availability report completed in %d min %d sec ]</div>\n", minutes, seconds);
1004 printf("<BR><BR>\n");
1005 }
1006
1007 /* display availability data */
1008 if(display_type == DISPLAY_HOST_AVAIL)
1009 display_host_availability();
1010 else if(display_type == DISPLAY_SERVICE_AVAIL)
1011 display_service_availability();
1012 else if(display_type == DISPLAY_HOSTGROUP_AVAIL)
1013 display_hostgroup_availability();
1014 else if(display_type == DISPLAY_SERVICEGROUP_AVAIL)
1015 display_servicegroup_availability();
1016
1017 /* free memory allocated to availability data */
1018 free_availability_data();
1019 }
1020 }
1021
1022
1023 /* step 1 - ask the user what kind of report they want */
1024 else {
1025
1026 printf("<p><div align=center class='reportSelectTitle'>Step 1: Select Report Type</div></p>\n");
1027
1028 printf("<p><div align=center>\n");
1029
1030 printf("<form method=\"get\" action=\"%s\">\n", AVAIL_CGI);
1031
1032 printf("<table border=0 cellpadding=5>\n");
1033
1034 printf("<tr><td class='reportSelectSubTitle' align=right>Type:</td>\n");
1035 printf("<td class='reportSelectItem'>\n");
1036 printf("<select name='report_type'>\n");
1037 printf("<option value=hostgroups>Hostgroup(s)\n");
1038 printf("<option value=hosts>Host(s)\n");
1039 printf("<option value=servicegroups>Servicegroup(s)\n");
1040 printf("<option value=services>Service(s)\n");
1041 printf("</select>\n");
1042 printf("</td></tr>\n");
1043
1044 printf("<tr><td></td><td align=left class='dateSelectItem'><input type='submit' value='Continue to Step 2'></td></tr>\n");
1045
1046 printf("</table>\n");
1047
1048 printf("</form>\n");
1049
1050 printf("</div></p>\n");
1051 }
1052
1053
1054 document_footer();
1055
1056 /* free all other allocated memory */
1057 free_memory();
1058
1059 return OK;
1060 }
1061
1062
1063
document_header(int use_stylesheet)1064 void document_header(int use_stylesheet) {
1065 char date_time[MAX_DATETIME_LENGTH];
1066 time_t current_time;
1067 time_t expire_time;
1068
1069 printf("Cache-Control: no-store\r\n");
1070 printf("Pragma: no-cache\r\n");
1071
1072 time(¤t_time);
1073 get_time_string(¤t_time, date_time, sizeof(date_time), HTTP_DATE_TIME);
1074 printf("Last-Modified: %s\r\n", date_time);
1075
1076 expire_time = (time_t)0;
1077 get_time_string(&expire_time, date_time, sizeof(date_time), HTTP_DATE_TIME);
1078 printf("Expires: %s\r\n", date_time);
1079
1080 if(output_format == HTML_OUTPUT)
1081 printf("Content-type: text/html\r\n\r\n");
1082 else {
1083 printf("Content-type: text/csv\r\n\r\n");
1084 return;
1085 }
1086
1087 if(embedded == TRUE || output_format == CSV_OUTPUT)
1088 return;
1089
1090 printf("<html>\n");
1091 printf("<head>\n");
1092 printf("<link rel=\"shortcut icon\" href=\"%sfavicon.ico\" type=\"image/ico\">\n", url_images_path);
1093 printf("<title>\n");
1094 printf("Nagios Availability\n");
1095 printf("</title>\n");
1096
1097 if(use_stylesheet == TRUE) {
1098 printf("<LINK REL='stylesheet' TYPE='text/css' HREF='%s%s'>\n", url_stylesheets_path, COMMON_CSS);
1099 printf("<LINK REL='stylesheet' TYPE='text/css' HREF='%s%s'>\n", url_stylesheets_path, AVAIL_CSS);
1100 }
1101
1102 printf("</head>\n");
1103
1104 printf("<BODY CLASS='avail'>\n");
1105
1106 /* include user SSI header */
1107 include_ssi_files(AVAIL_CGI, SSI_HEADER);
1108
1109 return;
1110 }
1111
1112
1113
document_footer(void)1114 void document_footer(void) {
1115
1116 if(output_format != HTML_OUTPUT)
1117 return;
1118
1119 if(embedded == TRUE)
1120 return;
1121
1122 /* include user SSI footer */
1123 include_ssi_files(AVAIL_CGI, SSI_FOOTER);
1124
1125 printf("</body>\n");
1126 printf("</html>\n");
1127
1128 return;
1129 }
1130
1131
1132
process_cgivars(void)1133 int process_cgivars(void) {
1134 char **variables;
1135 int error = FALSE;
1136 int x;
1137
1138 variables = getcgivars();
1139
1140 for(x = 0; variables[x] != NULL; x++) {
1141
1142 /* do some basic length checking on the variable identifier to prevent buffer overflows */
1143 if(strlen(variables[x]) >= MAX_INPUT_BUFFER - 1) {
1144 continue;
1145 }
1146
1147 /* we found the hostgroup argument */
1148 else if(!strcmp(variables[x], "hostgroup")) {
1149 x++;
1150 if(variables[x] == NULL) {
1151 error = TRUE;
1152 break;
1153 }
1154
1155 if((hostgroup_name = (char *)strdup(variables[x])) == NULL)
1156 hostgroup_name = "";
1157 strip_html_brackets(hostgroup_name);
1158
1159 display_type = DISPLAY_HOSTGROUP_AVAIL;
1160 show_all_hostgroups = (strcmp(hostgroup_name, "all")) ? FALSE : TRUE;
1161 }
1162
1163 /* we found the servicegroup argument */
1164 else if(!strcmp(variables[x], "servicegroup")) {
1165 x++;
1166 if(variables[x] == NULL) {
1167 error = TRUE;
1168 break;
1169 }
1170
1171 if((servicegroup_name = (char *)strdup(variables[x])) == NULL)
1172 servicegroup_name = "";
1173 strip_html_brackets(servicegroup_name);
1174
1175 display_type = DISPLAY_SERVICEGROUP_AVAIL;
1176 show_all_servicegroups = (strcmp(servicegroup_name, "all")) ? FALSE : TRUE;
1177 }
1178
1179 /* we found the host argument */
1180 else if(!strcmp(variables[x], "host")) {
1181 x++;
1182 if(variables[x] == NULL) {
1183 error = TRUE;
1184 break;
1185 }
1186
1187 if((host_name = (char *)strdup(variables[x])) == NULL)
1188 host_name = "";
1189 strip_html_brackets(host_name);
1190
1191 display_type = DISPLAY_HOST_AVAIL;
1192 show_all_hosts = (strcmp(host_name, "all")) ? FALSE : TRUE;
1193 }
1194
1195 /* we found the service description argument */
1196 else if(!strcmp(variables[x], "service")) {
1197 x++;
1198 if(variables[x] == NULL) {
1199 error = TRUE;
1200 break;
1201 }
1202
1203 if((svc_description = (char *)strdup(variables[x])) == NULL)
1204 svc_description = "";
1205 strip_html_brackets(svc_description);
1206
1207 display_type = DISPLAY_SERVICE_AVAIL;
1208 show_all_services = (strcmp(svc_description, "all")) ? FALSE : TRUE;
1209 }
1210
1211 /* we found first time argument */
1212 else if(!strcmp(variables[x], "t1")) {
1213 x++;
1214 if(variables[x] == NULL) {
1215 error = TRUE;
1216 break;
1217 }
1218
1219 t1 = (time_t)strtoul(variables[x], NULL, 10);
1220 timeperiod_type = TIMEPERIOD_CUSTOM;
1221 compute_time_from_parts = FALSE;
1222 }
1223
1224 /* we found first time argument */
1225 else if(!strcmp(variables[x], "t2")) {
1226 x++;
1227 if(variables[x] == NULL) {
1228 error = TRUE;
1229 break;
1230 }
1231
1232 t2 = (time_t)strtoul(variables[x], NULL, 10);
1233 timeperiod_type = TIMEPERIOD_CUSTOM;
1234 compute_time_from_parts = FALSE;
1235 }
1236
1237 /* we found the assume initial states option */
1238 else if(!strcmp(variables[x], "assumeinitialstates")) {
1239 x++;
1240 if(variables[x] == NULL) {
1241 error = TRUE;
1242 break;
1243 }
1244
1245 if(!strcmp(variables[x], "yes"))
1246 assume_initial_states = TRUE;
1247 else
1248 assume_initial_states = FALSE;
1249 }
1250
1251 /* we found the assume state during program not running option */
1252 else if(!strcmp(variables[x], "assumestatesduringnotrunning")) {
1253 x++;
1254 if(variables[x] == NULL) {
1255 error = TRUE;
1256 break;
1257 }
1258
1259 if(!strcmp(variables[x], "yes"))
1260 assume_states_during_notrunning = TRUE;
1261 else
1262 assume_states_during_notrunning = FALSE;
1263 }
1264
1265 /* we found the initial assumed host state option */
1266 else if(!strcmp(variables[x], "initialassumedhoststate")) {
1267 x++;
1268 if(variables[x] == NULL) {
1269 error = TRUE;
1270 break;
1271 }
1272
1273 initial_assumed_host_state = atoi(variables[x]);
1274 }
1275
1276 /* we found the initial assumed service state option */
1277 else if(!strcmp(variables[x], "initialassumedservicestate")) {
1278 x++;
1279 if(variables[x] == NULL) {
1280 error = TRUE;
1281 break;
1282 }
1283
1284 initial_assumed_service_state = atoi(variables[x]);
1285 }
1286
1287 /* we found the assume state retention option */
1288 else if(!strcmp(variables[x], "assumestateretention")) {
1289 x++;
1290 if(variables[x] == NULL) {
1291 error = TRUE;
1292 break;
1293 }
1294
1295 if(!strcmp(variables[x], "yes"))
1296 assume_state_retention = TRUE;
1297 else
1298 assume_state_retention = FALSE;
1299 }
1300
1301 /* we found the include soft states option */
1302 else if(!strcmp(variables[x], "includesoftstates")) {
1303 x++;
1304 if(variables[x] == NULL) {
1305 error = TRUE;
1306 break;
1307 }
1308
1309 if(!strcmp(variables[x], "yes"))
1310 include_soft_states = TRUE;
1311 else
1312 include_soft_states = FALSE;
1313 }
1314
1315 /* we found the backtrack archives argument */
1316 else if(!strcmp(variables[x], "backtrack")) {
1317 x++;
1318 if(variables[x] == NULL) {
1319 error = TRUE;
1320 break;
1321 }
1322
1323 backtrack_archives = atoi(variables[x]);
1324 if(backtrack_archives < 0)
1325 backtrack_archives = 0;
1326 if(backtrack_archives > MAX_ARCHIVE_BACKTRACKS)
1327 backtrack_archives = MAX_ARCHIVE_BACKTRACKS;
1328
1329 #ifdef DEBUG
1330 printf("BACKTRACK ARCHIVES: %d\n", backtrack_archives);
1331 #endif
1332 }
1333
1334 /* we found the standard timeperiod argument */
1335 else if(!strcmp(variables[x], "timeperiod")) {
1336 x++;
1337 if(variables[x] == NULL) {
1338 error = TRUE;
1339 break;
1340 }
1341
1342 if(!strcmp(variables[x], "today"))
1343 timeperiod_type = TIMEPERIOD_TODAY;
1344 else if(!strcmp(variables[x], "yesterday"))
1345 timeperiod_type = TIMEPERIOD_YESTERDAY;
1346 else if(!strcmp(variables[x], "thisweek"))
1347 timeperiod_type = TIMEPERIOD_THISWEEK;
1348 else if(!strcmp(variables[x], "lastweek"))
1349 timeperiod_type = TIMEPERIOD_LASTWEEK;
1350 else if(!strcmp(variables[x], "thismonth"))
1351 timeperiod_type = TIMEPERIOD_THISMONTH;
1352 else if(!strcmp(variables[x], "lastmonth"))
1353 timeperiod_type = TIMEPERIOD_LASTMONTH;
1354 else if(!strcmp(variables[x], "thisquarter"))
1355 timeperiod_type = TIMEPERIOD_THISQUARTER;
1356 else if(!strcmp(variables[x], "lastquarter"))
1357 timeperiod_type = TIMEPERIOD_LASTQUARTER;
1358 else if(!strcmp(variables[x], "thisyear"))
1359 timeperiod_type = TIMEPERIOD_THISYEAR;
1360 else if(!strcmp(variables[x], "lastyear"))
1361 timeperiod_type = TIMEPERIOD_LASTYEAR;
1362 else if(!strcmp(variables[x], "last24hours"))
1363 timeperiod_type = TIMEPERIOD_LAST24HOURS;
1364 else if(!strcmp(variables[x], "last7days"))
1365 timeperiod_type = TIMEPERIOD_LAST7DAYS;
1366 else if(!strcmp(variables[x], "last31days"))
1367 timeperiod_type = TIMEPERIOD_LAST31DAYS;
1368 else if(!strcmp(variables[x], "custom"))
1369 timeperiod_type = TIMEPERIOD_CUSTOM;
1370 else
1371 continue;
1372
1373 convert_timeperiod_to_times(timeperiod_type);
1374 compute_time_from_parts = FALSE;
1375 }
1376
1377 /* we found the embed option */
1378 else if(!strcmp(variables[x], "embedded"))
1379 embedded = TRUE;
1380
1381 /* we found the noheader option */
1382 else if(!strcmp(variables[x], "noheader"))
1383 display_header = FALSE;
1384
1385 /* we found the CSV output option */
1386 else if(!strcmp(variables[x], "csvoutput")) {
1387 display_header = FALSE;
1388 output_format = CSV_OUTPUT;
1389 }
1390
1391 /* we found the log entries option */
1392 else if(!strcmp(variables[x], "show_log_entries"))
1393 show_log_entries = TRUE;
1394
1395 /* we found the full log entries option */
1396 else if(!strcmp(variables[x], "full_log_entries"))
1397 full_log_entries = TRUE;
1398
1399 /* we found the get date parts option */
1400 else if(!strcmp(variables[x], "get_date_parts"))
1401 get_date_parts = TRUE;
1402
1403 /* we found the report type selection option */
1404 else if(!strcmp(variables[x], "report_type")) {
1405 x++;
1406 if(variables[x] == NULL) {
1407 error = TRUE;
1408 break;
1409 }
1410 if(!strcmp(variables[x], "hostgroups"))
1411 select_hostgroups = TRUE;
1412 else if(!strcmp(variables[x], "servicegroups"))
1413 select_servicegroups = TRUE;
1414 else if(!strcmp(variables[x], "hosts"))
1415 select_hosts = TRUE;
1416 else
1417 select_services = TRUE;
1418 }
1419
1420 /* we found time argument */
1421 else if(!strcmp(variables[x], "smon")) {
1422 x++;
1423 if(variables[x] == NULL) {
1424 error = TRUE;
1425 break;
1426 }
1427
1428 if(timeperiod_type != TIMEPERIOD_CUSTOM)
1429 continue;
1430
1431 start_month = atoi(variables[x]);
1432 timeperiod_type = TIMEPERIOD_CUSTOM;
1433 compute_time_from_parts = TRUE;
1434 }
1435
1436 /* we found time argument */
1437 else if(!strcmp(variables[x], "sday")) {
1438 x++;
1439 if(variables[x] == NULL) {
1440 error = TRUE;
1441 break;
1442 }
1443
1444 if(timeperiod_type != TIMEPERIOD_CUSTOM)
1445 continue;
1446
1447 start_day = atoi(variables[x]);
1448 timeperiod_type = TIMEPERIOD_CUSTOM;
1449 compute_time_from_parts = TRUE;
1450 }
1451
1452 /* we found time argument */
1453 else if(!strcmp(variables[x], "syear")) {
1454 x++;
1455 if(variables[x] == NULL) {
1456 error = TRUE;
1457 break;
1458 }
1459
1460 if(timeperiod_type != TIMEPERIOD_CUSTOM)
1461 continue;
1462
1463 start_year = atoi(variables[x]);
1464 timeperiod_type = TIMEPERIOD_CUSTOM;
1465 compute_time_from_parts = TRUE;
1466 }
1467
1468 /* we found time argument */
1469 else if(!strcmp(variables[x], "smin")) {
1470 x++;
1471 if(variables[x] == NULL) {
1472 error = TRUE;
1473 break;
1474 }
1475
1476 if(timeperiod_type != TIMEPERIOD_CUSTOM)
1477 continue;
1478
1479 start_minute = atoi(variables[x]);
1480 timeperiod_type = TIMEPERIOD_CUSTOM;
1481 compute_time_from_parts = TRUE;
1482 }
1483
1484 /* we found time argument */
1485 else if(!strcmp(variables[x], "ssec")) {
1486 x++;
1487 if(variables[x] == NULL) {
1488 error = TRUE;
1489 break;
1490 }
1491
1492 if(timeperiod_type != TIMEPERIOD_CUSTOM)
1493 continue;
1494
1495 start_second = atoi(variables[x]);
1496 timeperiod_type = TIMEPERIOD_CUSTOM;
1497 compute_time_from_parts = TRUE;
1498 }
1499
1500 /* we found time argument */
1501 else if(!strcmp(variables[x], "shour")) {
1502 x++;
1503 if(variables[x] == NULL) {
1504 error = TRUE;
1505 break;
1506 }
1507
1508 if(timeperiod_type != TIMEPERIOD_CUSTOM)
1509 continue;
1510
1511 start_hour = atoi(variables[x]);
1512 timeperiod_type = TIMEPERIOD_CUSTOM;
1513 compute_time_from_parts = TRUE;
1514 }
1515
1516
1517 /* we found time argument */
1518 else if(!strcmp(variables[x], "emon")) {
1519 x++;
1520 if(variables[x] == NULL) {
1521 error = TRUE;
1522 break;
1523 }
1524
1525 if(timeperiod_type != TIMEPERIOD_CUSTOM)
1526 continue;
1527
1528 end_month = atoi(variables[x]);
1529 timeperiod_type = TIMEPERIOD_CUSTOM;
1530 compute_time_from_parts = TRUE;
1531 }
1532
1533 /* we found time argument */
1534 else if(!strcmp(variables[x], "eday")) {
1535 x++;
1536 if(variables[x] == NULL) {
1537 error = TRUE;
1538 break;
1539 }
1540
1541 if(timeperiod_type != TIMEPERIOD_CUSTOM)
1542 continue;
1543
1544 end_day = atoi(variables[x]);
1545 timeperiod_type = TIMEPERIOD_CUSTOM;
1546 compute_time_from_parts = TRUE;
1547 }
1548
1549 /* we found time argument */
1550 else if(!strcmp(variables[x], "eyear")) {
1551 x++;
1552 if(variables[x] == NULL) {
1553 error = TRUE;
1554 break;
1555 }
1556
1557 if(timeperiod_type != TIMEPERIOD_CUSTOM)
1558 continue;
1559
1560 end_year = atoi(variables[x]);
1561 timeperiod_type = TIMEPERIOD_CUSTOM;
1562 compute_time_from_parts = TRUE;
1563 }
1564
1565 /* we found time argument */
1566 else if(!strcmp(variables[x], "emin")) {
1567 x++;
1568 if(variables[x] == NULL) {
1569 error = TRUE;
1570 break;
1571 }
1572
1573 if(timeperiod_type != TIMEPERIOD_CUSTOM)
1574 continue;
1575
1576 end_minute = atoi(variables[x]);
1577 timeperiod_type = TIMEPERIOD_CUSTOM;
1578 compute_time_from_parts = TRUE;
1579 }
1580
1581 /* we found time argument */
1582 else if(!strcmp(variables[x], "esec")) {
1583 x++;
1584 if(variables[x] == NULL) {
1585 error = TRUE;
1586 break;
1587 }
1588
1589 if(timeperiod_type != TIMEPERIOD_CUSTOM)
1590 continue;
1591
1592 end_second = atoi(variables[x]);
1593 timeperiod_type = TIMEPERIOD_CUSTOM;
1594 compute_time_from_parts = TRUE;
1595 }
1596
1597 /* we found time argument */
1598 else if(!strcmp(variables[x], "ehour")) {
1599 x++;
1600 if(variables[x] == NULL) {
1601 error = TRUE;
1602 break;
1603 }
1604
1605 if(timeperiod_type != TIMEPERIOD_CUSTOM)
1606 continue;
1607
1608 end_hour = atoi(variables[x]);
1609 timeperiod_type = TIMEPERIOD_CUSTOM;
1610 compute_time_from_parts = TRUE;
1611 }
1612
1613 /* we found the show scheduled downtime option */
1614 else if(!strcmp(variables[x], "showscheduleddowntime")) {
1615 x++;
1616 if(variables[x] == NULL) {
1617 error = TRUE;
1618 break;
1619 }
1620
1621 if(!strcmp(variables[x], "yes"))
1622 show_scheduled_downtime = TRUE;
1623 else
1624 show_scheduled_downtime = FALSE;
1625 }
1626
1627 /* we found the report timeperiod option */
1628 else if(!strcmp(variables[x], "rpttimeperiod")) {
1629 timeperiod *temp_timeperiod;
1630 x++;
1631 if(variables[x] == NULL) {
1632 error = TRUE;
1633 break;
1634 }
1635
1636 for(temp_timeperiod = timeperiod_list; temp_timeperiod != NULL; temp_timeperiod = temp_timeperiod->next) {
1637 if(!strcmp(url_encode(temp_timeperiod->name), variables[x])) {
1638 current_timeperiod = temp_timeperiod;
1639 break;
1640 }
1641 }
1642 }
1643
1644 }
1645
1646 /* free memory allocated to the CGI variables */
1647 free_cgivars(variables);
1648
1649 return error;
1650 }
1651
1652
1653
1654 /* computes availability data for all subjects */
compute_availability(void)1655 void compute_availability(void) {
1656 avail_subject *temp_subject;
1657 time_t current_time;
1658
1659 time(¤t_time);
1660
1661 for(temp_subject = subject_list; temp_subject != NULL; temp_subject = temp_subject->next) {
1662 compute_subject_availability(temp_subject, current_time);
1663 compute_subject_downtime(temp_subject, current_time);
1664 }
1665
1666 return;
1667 }
1668
1669
1670
1671 /* computes availability data for a given subject */
compute_subject_availability(avail_subject * subject,time_t current_time)1672 void compute_subject_availability(avail_subject *subject, time_t current_time) {
1673 archived_state *temp_as;
1674 archived_state *last_as;
1675 time_t a;
1676 time_t b;
1677 int current_state = AS_NO_DATA;
1678 int have_some_real_data = FALSE;
1679 hoststatus *hststatus = NULL;
1680 servicestatus *svcstatus = NULL;
1681 int first_real_state = AS_NO_DATA;
1682 time_t initial_assumed_time;
1683 int initial_assumed_state = AS_NO_DATA;
1684 int error;
1685
1686
1687 /* if left hand of graph is after current time, we can't do anything at all.... */
1688 if(t1 > current_time)
1689 return;
1690
1691 /* get current state of host or service if possible */
1692 if(subject->type == HOST_SUBJECT)
1693 hststatus = find_hoststatus(subject->host_name);
1694 else
1695 svcstatus = find_servicestatus(subject->host_name, subject->service_description);
1696
1697
1698 /************************************/
1699 /* INSERT CURRENT STATE (IF WE CAN) */
1700 /************************************/
1701
1702 /* if current time DOES NOT fall within graph bounds, so we can't do anything as far as assuming current state */
1703
1704 /* if we don't have any data, assume current state (if possible) */
1705 if(subject->as_list == NULL && current_time > t1 && current_time <= t2) {
1706
1707 /* we don't have any historical information, but the current time falls within the reporting period, so use */
1708 /* the current status of the host/service as the starting data */
1709 if(subject->type == HOST_SUBJECT) {
1710 if(hststatus != NULL) {
1711
1712 if(hststatus->status == HOST_DOWN)
1713 subject->last_known_state = AS_HOST_DOWN;
1714 else if(hststatus->status == HOST_UNREACHABLE)
1715 subject->last_known_state = AS_HOST_UNREACHABLE;
1716 else if(hststatus->status == HOST_UP)
1717 subject->last_known_state = AS_HOST_UP;
1718 else
1719 subject->last_known_state = AS_NO_DATA;
1720
1721 if(subject->last_known_state != AS_NO_DATA) {
1722
1723 /* add a dummy archived state item, so something can get graphed */
1724 add_archived_state(subject->last_known_state, AS_HARD_STATE, t1, "Current Host State Assumed (Faked Log Entry)", subject);
1725
1726 /* use the current state as the last known real state */
1727 first_real_state = subject->last_known_state;
1728 }
1729 }
1730 }
1731 else {
1732 if(svcstatus != NULL) {
1733
1734 if(svcstatus->status == SERVICE_OK)
1735 subject->last_known_state = AS_SVC_OK;
1736 else if(svcstatus->status == SERVICE_WARNING)
1737 subject->last_known_state = AS_SVC_WARNING;
1738 else if(svcstatus->status == SERVICE_CRITICAL)
1739 subject->last_known_state = AS_SVC_CRITICAL;
1740 else if(svcstatus->status == SERVICE_UNKNOWN)
1741 subject->last_known_state = AS_SVC_UNKNOWN;
1742 else
1743 subject->last_known_state = AS_NO_DATA;
1744
1745 if(subject->last_known_state != AS_NO_DATA) {
1746
1747 /* add a dummy archived state item, so something can get graphed */
1748 add_archived_state(subject->last_known_state, AS_HARD_STATE, t1, "Current Service State Assumed (Faked Log Entry)", subject);
1749
1750 /* use the current state as the last known real state */
1751 first_real_state = subject->last_known_state;
1752 }
1753 }
1754 }
1755 }
1756
1757
1758
1759 /******************************************/
1760 /* INSERT FIRST ASSUMED STATE (IF WE CAN) */
1761 /******************************************/
1762
1763 if((subject->type == HOST_SUBJECT && initial_assumed_host_state != AS_NO_DATA) || (subject->type == SERVICE_SUBJECT && initial_assumed_service_state != AS_NO_DATA)) {
1764
1765 /* see if its okay to assume initial state for this subject */
1766 error = FALSE;
1767 if(subject->type == SERVICE_SUBJECT) {
1768 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)
1769 error = TRUE;
1770 else
1771 initial_assumed_state = initial_assumed_service_state;
1772 if(initial_assumed_service_state == AS_CURRENT_STATE && svcstatus == NULL)
1773 error = TRUE;
1774 }
1775 else {
1776 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)
1777 error = TRUE;
1778 else
1779 initial_assumed_state = initial_assumed_host_state;
1780 if(initial_assumed_host_state == AS_CURRENT_STATE && hststatus == NULL)
1781 error = TRUE;
1782 }
1783
1784 /* get the current state if applicable */
1785 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) {
1786 if(subject->type == SERVICE_SUBJECT) {
1787 switch(svcstatus->status) {
1788 case SERVICE_OK:
1789 initial_assumed_state = AS_SVC_OK;
1790 break;
1791 case SERVICE_WARNING:
1792 initial_assumed_state = AS_SVC_WARNING;
1793 break;
1794 case SERVICE_UNKNOWN:
1795 initial_assumed_state = AS_SVC_UNKNOWN;
1796 break;
1797 case SERVICE_CRITICAL:
1798 initial_assumed_state = AS_SVC_CRITICAL;
1799 break;
1800 default:
1801 error = TRUE;
1802 break;
1803 }
1804 }
1805 else {
1806 switch(hststatus->status) {
1807 case HOST_DOWN:
1808 initial_assumed_state = AS_HOST_DOWN;
1809 break;
1810 case HOST_UNREACHABLE:
1811 initial_assumed_state = AS_HOST_UNREACHABLE;
1812 break;
1813 case HOST_UP:
1814 initial_assumed_state = AS_HOST_UP;
1815 break;
1816 default:
1817 error = TRUE;
1818 break;
1819 }
1820 }
1821 }
1822
1823 if(error == FALSE) {
1824
1825 /* add this assumed state entry before any entries in the list and <= t1 */
1826 if(subject->as_list == NULL)
1827 initial_assumed_time = t1;
1828 else if(subject->as_list->time_stamp > t1)
1829 initial_assumed_time = t1;
1830 else
1831 initial_assumed_time = subject->as_list->time_stamp - 1;
1832
1833 if(subject->type == HOST_SUBJECT)
1834 add_archived_state(initial_assumed_state, AS_HARD_STATE, initial_assumed_time, "First Host State Assumed (Faked Log Entry)", subject);
1835 else
1836 add_archived_state(initial_assumed_state, AS_HARD_STATE, initial_assumed_time, "First Service State Assumed (Faked Log Entry)", subject);
1837 }
1838 }
1839
1840
1841
1842
1843 /**************************************/
1844 /* BAIL OUT IF WE DON'T HAVE ANYTHING */
1845 /**************************************/
1846
1847 have_some_real_data = FALSE;
1848 for(temp_as = subject->as_list; temp_as != NULL; temp_as = temp_as->next) {
1849 if(temp_as->entry_type != AS_NO_DATA && temp_as->entry_type != AS_PROGRAM_START && temp_as->entry_type != AS_PROGRAM_END) {
1850 have_some_real_data = TRUE;
1851 break;
1852 }
1853 }
1854 if(have_some_real_data == FALSE)
1855 return;
1856
1857
1858
1859
1860 last_as = NULL;
1861 subject->earliest_time = t2;
1862 subject->latest_time = t1;
1863
1864
1865 #ifdef DEBUG
1866 printf("--- BEGINNING/MIDDLE SECTION ---<BR>\n");
1867 #endif
1868
1869 /**********************************/
1870 /* BEGINNING/MIDDLE SECTION */
1871 /**********************************/
1872
1873 for(temp_as = subject->as_list; temp_as != NULL; temp_as = temp_as->next) {
1874
1875 /* keep this as last known state if this is the first entry or if it occurs before the starting point of the graph */
1876 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)) {
1877 subject->last_known_state = temp_as->entry_type;
1878 #ifdef DEBUG
1879 printf("SETTING LAST KNOWN STATE=%d<br>\n", subject->last_known_state);
1880 #endif
1881 }
1882
1883 /* skip this entry if it occurs before the starting point of the graph */
1884 if(temp_as->time_stamp <= t1) {
1885 #ifdef DEBUG
1886 printf("SKIPPING PRE-EVENT: %d @ %lu<br>\n", temp_as->entry_type, temp_as->time_stamp);
1887 #endif
1888 last_as = temp_as;
1889 continue;
1890 }
1891
1892 /* graph this span if we're not on the first item */
1893 if(last_as != NULL) {
1894
1895 a = last_as->time_stamp;
1896 b = temp_as->time_stamp;
1897
1898 /* we've already passed the last time displayed in the graph */
1899 if(a > t2)
1900 break;
1901
1902 /* only graph this data if its on the graph */
1903 else if(b > t1) {
1904
1905 /* clip last time if it exceeds graph limits */
1906 if(b > t2)
1907 b = t2;
1908
1909 /* clip first time if it precedes graph limits */
1910 if(a < t1)
1911 a = t1;
1912
1913 /* save this time if its the earliest we've graphed */
1914 if(a < subject->earliest_time) {
1915 subject->earliest_time = a;
1916 subject->earliest_state = last_as->entry_type;
1917 }
1918
1919 /* save this time if its the latest we've graphed */
1920 if(b > subject->latest_time) {
1921 subject->latest_time = b;
1922 subject->latest_state = last_as->entry_type;
1923 }
1924
1925 /* compute availability times for this chunk */
1926 compute_subject_availability_times(last_as->entry_type, temp_as->entry_type, last_as->time_stamp, a, b, subject, temp_as);
1927
1928 /* return if we've reached the end of the graph limits */
1929 if(b >= t2) {
1930 last_as = temp_as;
1931 break;
1932 }
1933 }
1934 }
1935
1936
1937 /* keep track of the last item */
1938 last_as = temp_as;
1939 }
1940
1941
1942 #ifdef DEBUG
1943 printf("--- END SECTION ---<BR>\n");
1944 #endif
1945
1946 /**********************************/
1947 /* END SECTION */
1948 /**********************************/
1949
1950 if(last_as != NULL) {
1951
1952 /* don't process an entry that is beyond the limits of the graph */
1953 if(last_as->time_stamp < t2) {
1954
1955 time(¤t_time);
1956 b = current_time;
1957 if(b > t2)
1958 b = t2;
1959
1960 a = last_as->time_stamp;
1961 if(a < t1)
1962 a = t1;
1963
1964 /* fake the current state (it doesn't really matter for graphing) */
1965 if(subject->type == HOST_SUBJECT)
1966 current_state = AS_HOST_UP;
1967 else
1968 current_state = AS_SVC_OK;
1969
1970 /* compute availability times for last state */
1971 compute_subject_availability_times(last_as->entry_type, current_state, last_as->time_stamp, a, b, subject, last_as);
1972 }
1973 }
1974
1975
1976 return;
1977 }
1978
1979
1980 /* computes availability times */
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)1981 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) {
1982 int start_state;
1983 int end_state;
1984 unsigned long state_duration;
1985 struct tm *t;
1986 unsigned long midnight_today;
1987 int weekday;
1988 timerange *temp_timerange;
1989 unsigned long temp_duration;
1990 unsigned long temp_end;
1991 unsigned long temp_start;
1992 unsigned long start;
1993 unsigned long end;
1994
1995 #ifdef DEBUG
1996 if(subject->type == HOST_SUBJECT)
1997 printf("HOST '%s'...\n", subject->host_name);
1998 else
1999 printf("SERVICE '%s' ON HOST '%s'...\n", subject->service_description, subject->host_name);
2000
2001 printf("COMPUTING %d->%d FROM %lu to %lu (%lu seconds) FOR %s<br>\n", first_state, last_state, start_time, end_time, (end_time - start_time), (subject->type == HOST_SUBJECT) ? "HOST" : "SERVICE");
2002 #endif
2003
2004 /* clip times if necessary */
2005 if(start_time < t1)
2006 start_time = t1;
2007 if(end_time > t2)
2008 end_time = t2;
2009
2010 /* make sure this is a valid time */
2011 if(start_time > t2)
2012 return;
2013 if(end_time < t1)
2014 return;
2015
2016 /* MickeM - attempt to handle the current time_period (if any) */
2017 if(current_timeperiod != NULL) {
2018 t = localtime((time_t *)&start_time);
2019 state_duration = 0;
2020
2021 /* calculate the start of the day (midnight, 00:00 hours) */
2022 t->tm_sec = 0;
2023 t->tm_min = 0;
2024 t->tm_hour = 0;
2025 t->tm_isdst = -1;
2026 midnight_today = (unsigned long)mktime(t);
2027 weekday = t->tm_wday;
2028
2029 while(midnight_today < end_time) {
2030 temp_duration = 0;
2031 temp_end = min(86400, end_time - midnight_today);
2032 temp_start = 0;
2033 if(start_time > midnight_today)
2034 temp_start = start_time - midnight_today;
2035 #ifdef DEBUG
2036 printf("<b>Matching: %ld -> %ld. (%ld -> %ld)</b><br>\n", temp_start, temp_end, midnight_today + temp_start, midnight_today + temp_end);
2037 #endif
2038 /* check all time ranges for this day of the week */
2039 for(temp_timerange = current_timeperiod->days[weekday]; temp_timerange != NULL; temp_timerange = temp_timerange->next) {
2040
2041 #ifdef DEBUG
2042 printf("<li>Matching in timerange[%d]: %d -> %d (%ld -> %ld)<br>\n", weekday, temp_timerange->range_start, temp_timerange->range_end, temp_start, temp_end);
2043 #endif
2044 start = max(temp_timerange->range_start, temp_start);
2045 end = min(temp_timerange->range_end, temp_end);
2046
2047 if(start < end) {
2048 temp_duration += end - start;
2049 #ifdef DEBUG
2050 printf("<li>Matched time: %ld -> %ld = %d<br>\n", start, end, temp_duration);
2051 #endif
2052 }
2053 #ifdef DEBUG
2054 else
2055 printf("<li>Ignored time: %ld -> %ld<br>\n", start, end);
2056 #endif
2057 }
2058 state_duration += temp_duration;
2059 temp_start = 0;
2060 midnight_today += 86400;
2061 if(++weekday > 6)
2062 weekday = 0;
2063 }
2064 }
2065
2066 /* no report timeperiod was selected (assume 24x7) */
2067 else {
2068 /* calculate time in this state */
2069 state_duration = (unsigned long)(end_time - start_time);
2070 }
2071
2072 /* can't graph if we don't have data... */
2073 if(first_state == AS_NO_DATA || last_state == AS_NO_DATA) {
2074 subject->time_indeterminate_nodata += state_duration;
2075 return;
2076 }
2077 if(first_state == AS_PROGRAM_START && (last_state == AS_PROGRAM_END || last_state == AS_PROGRAM_START)) {
2078 if(assume_initial_states == FALSE) {
2079 subject->time_indeterminate_nodata += state_duration;
2080 return;
2081 }
2082 }
2083 if(first_state == AS_PROGRAM_END) {
2084
2085 /* added 7/24/03 */
2086 if(assume_states_during_notrunning == TRUE) {
2087 first_state = subject->last_known_state;
2088 }
2089 else {
2090 subject->time_indeterminate_notrunning += state_duration;
2091 return;
2092 }
2093 }
2094
2095 /* special case if first entry was program start */
2096 if(first_state == AS_PROGRAM_START) {
2097
2098 if(assume_initial_states == TRUE) {
2099
2100 if(assume_state_retention == TRUE)
2101 start_state = subject->last_known_state;
2102
2103 else {
2104 if(subject->type == HOST_SUBJECT)
2105 start_state = AS_HOST_UP;
2106 else
2107 start_state = AS_SVC_OK;
2108 }
2109 }
2110 else
2111 return;
2112 }
2113 else {
2114 start_state = first_state;
2115 subject->last_known_state = first_state;
2116 }
2117
2118 /* special case if last entry was program stop */
2119 if(last_state == AS_PROGRAM_END)
2120 end_state = first_state;
2121 else
2122 end_state = last_state;
2123
2124 /* save "processed state" info */
2125 as->processed_state = start_state;
2126
2127 #ifdef DEBUG
2128 printf("PASSED TIME CHECKS, CLIPPED VALUES: START=%lu, END=%lu\n", start_time, end_time);
2129 #endif
2130
2131
2132 /* add time in this state to running totals */
2133 switch(start_state) {
2134 case AS_HOST_UP:
2135 subject->time_up += state_duration;
2136 break;
2137 case AS_HOST_DOWN:
2138 subject->time_down += state_duration;
2139 break;
2140 case AS_HOST_UNREACHABLE:
2141 subject->time_unreachable += state_duration;
2142 break;
2143 case AS_SVC_OK:
2144 subject->time_ok += state_duration;
2145 break;
2146 case AS_SVC_WARNING:
2147 subject->time_warning += state_duration;
2148 break;
2149 case AS_SVC_UNKNOWN:
2150 subject->time_unknown += state_duration;
2151 break;
2152 case AS_SVC_CRITICAL:
2153 subject->time_critical += state_duration;
2154 break;
2155 default:
2156 break;
2157 }
2158
2159 return;
2160 }
2161
2162
2163 /* computes downtime data for a given subject */
compute_subject_downtime(avail_subject * subject,time_t current_time)2164 void compute_subject_downtime(avail_subject *subject, time_t current_time) {
2165 archived_state *temp_sd;
2166 time_t start_time;
2167 time_t end_time;
2168 int host_downtime_depth = 0;
2169 int service_downtime_depth = 0;
2170 int process_chunk = FALSE;
2171
2172 #ifdef DEBUG2
2173 printf("COMPUTE_SUBJECT_DOWNTIME\n");
2174 #endif
2175
2176 /* if left hand of graph is after current time, we can't do anything at all.... */
2177 if(t1 > current_time)
2178 return;
2179
2180 /* no scheduled downtime data for subject... */
2181 if(subject->sd_list == NULL)
2182 return;
2183
2184 /* all data we have occurs after last time on graph... */
2185 if(subject->sd_list->time_stamp >= t2)
2186 return;
2187
2188 /* initialize pointer */
2189 temp_sd = subject->sd_list;
2190
2191 /* special case if first entry is the end of scheduled downtime */
2192 if((temp_sd->entry_type == AS_HOST_DOWNTIME_END || temp_sd->entry_type == AS_SVC_DOWNTIME_END) && temp_sd->time_stamp > t1) {
2193
2194 #ifdef DEBUG2
2195 printf("\tSPECIAL DOWNTIME CASE\n");
2196 #endif
2197 start_time = t1;
2198 end_time = (temp_sd->time_stamp > t2) ? t2 : temp_sd->time_stamp;
2199 compute_subject_downtime_times(start_time, end_time, subject, NULL);
2200 temp_sd = temp_sd->next;
2201 }
2202
2203 /* process all periods of scheduled downtime */
2204 for(; temp_sd != NULL; temp_sd = temp_sd->next) {
2205
2206 /* we've passed graph bounds... */
2207 if(temp_sd->time_stamp >= t2)
2208 break;
2209
2210 if(temp_sd->entry_type == AS_HOST_DOWNTIME_START)
2211 host_downtime_depth++;
2212 else if(temp_sd->entry_type == AS_HOST_DOWNTIME_END)
2213 host_downtime_depth--;
2214 else if(temp_sd->entry_type == AS_SVC_DOWNTIME_START)
2215 service_downtime_depth++;
2216 else if(temp_sd->entry_type == AS_SVC_DOWNTIME_END)
2217 service_downtime_depth--;
2218 else
2219 continue;
2220
2221 process_chunk = FALSE;
2222 if(temp_sd->entry_type == AS_HOST_DOWNTIME_START || temp_sd->entry_type == AS_SVC_DOWNTIME_START)
2223 process_chunk = TRUE;
2224 else if(subject->type == SERVICE_SUBJECT && (host_downtime_depth > 0 || service_downtime_depth > 0))
2225 process_chunk = TRUE;
2226
2227 /* process this specific "chunk" of scheduled downtime */
2228 if(process_chunk == TRUE) {
2229
2230 start_time = temp_sd->time_stamp;
2231 end_time = (temp_sd->next == NULL) ? current_time : temp_sd->next->time_stamp;
2232
2233 /* check time sanity */
2234 if(end_time <= t1)
2235 continue;
2236 if(start_time >= t2)
2237 continue;
2238 if(start_time >= end_time)
2239 continue;
2240
2241 /* clip time values */
2242 if(start_time < t1)
2243 start_time = t1;
2244 if(end_time > t2)
2245 end_time = t2;
2246
2247 compute_subject_downtime_times(start_time, end_time, subject, temp_sd);
2248 }
2249 }
2250
2251 return;
2252 }
2253
2254
2255
2256 /* computes downtime times */
compute_subject_downtime_times(time_t start_time,time_t end_time,avail_subject * subject,archived_state * sd)2257 void compute_subject_downtime_times(time_t start_time, time_t end_time, avail_subject *subject, archived_state *sd) {
2258 archived_state *temp_as = NULL;
2259 time_t part_start_time = 0L;
2260 time_t part_subject_state = 0L;
2261 int saved_status = 0;
2262 int saved_stamp = 0;
2263 int count = 0;
2264 archived_state *temp_before = NULL;
2265 archived_state *last = NULL;
2266
2267 #ifdef DEBUG2
2268 printf("<P><b>ENTERING COMPUTE_SUBJECT_DOWNTIME_TIMES: start=%lu, end=%lu, t1=%lu, t2=%lu </b></P>", start_time, end_time, t1, t2);
2269 #endif
2270
2271 /* times are weird, so bail out... */
2272 if(start_time > end_time)
2273 return;
2274 if(start_time < t1 || end_time > t2)
2275 return;
2276
2277 /* find starting point in archived state list */
2278 if(sd == NULL) {
2279 #ifdef DEBUG2
2280 printf("<P>TEMP_AS=SUBJECT->AS_LIST </P>");
2281 #endif
2282 temp_as = subject->as_list;
2283 }
2284 else if(sd->misc_ptr == NULL) {
2285 #ifdef DEBUG2
2286 printf("<P>TEMP_AS=SUBJECT->AS_LIST</P>");
2287 #endif
2288 temp_as = subject->as_list;
2289 }
2290 else if(sd->misc_ptr->next == NULL) {
2291 #ifdef DEBUG2
2292 printf("<P>TEMP_AS=SD->MISC_PTR</P>");
2293 #endif
2294 temp_as = sd->misc_ptr;
2295 }
2296 else {
2297 #ifdef DEBUG2
2298 printf("<P>TEMP_AS=SD->MISC_PTR->NEXT</P>");
2299 #endif
2300 temp_as = sd->misc_ptr->next;
2301 }
2302
2303 /* initialize values */
2304 part_start_time = start_time;
2305 if(temp_as == NULL)
2306 part_subject_state = AS_NO_DATA;
2307 else if(temp_as->processed_state == AS_PROGRAM_START || temp_as->processed_state == AS_PROGRAM_END || temp_as->processed_state == AS_NO_DATA) {
2308 #ifdef DEBUG2
2309 printf("<P>ENTRY TYPE #1: %d</P>", temp_as->entry_type);
2310 #endif
2311 part_subject_state = AS_NO_DATA;
2312 }
2313 else {
2314 #ifdef DEBUG2
2315 printf("<P>ENTRY TYPE #2: %d</P>", temp_as->entry_type);
2316 #endif
2317 part_subject_state = temp_as->processed_state;
2318 }
2319
2320 #ifdef DEBUG2
2321 printf("<P>TEMP_AS=%s</P>", (temp_as == NULL) ? "NULL" : "Not NULL");
2322 printf("<P>SD=%s</P>", (sd == NULL) ? "NULL" : "Not NULL");
2323 #endif
2324
2325 /* temp_as now points to first event to possibly "break" this chunk */
2326 for(; temp_as != NULL; temp_as = temp_as->next) {
2327 count++;
2328 last = temp_as;
2329
2330 if(temp_before == NULL) {
2331 if(last->time_stamp > start_time) {
2332 if(last->time_stamp > end_time)
2333 compute_subject_downtime_part_times(start_time, end_time, part_subject_state, subject);
2334 else
2335 compute_subject_downtime_part_times(start_time, last->time_stamp, part_subject_state, subject);
2336 }
2337 temp_before = temp_as;
2338 saved_status = temp_as->entry_type;
2339 saved_stamp = temp_as->time_stamp;
2340
2341 /* check if first time is before schedule downtime */
2342 if(saved_stamp < start_time)
2343 saved_stamp = start_time;
2344
2345 continue;
2346 }
2347
2348 /* if status changed, we have to calculate */
2349 if(saved_status != temp_as->entry_type) {
2350
2351 /* is outside schedule time, use end schdule downtime */
2352 if(temp_as->time_stamp > end_time) {
2353 if(saved_stamp < start_time)
2354 compute_subject_downtime_part_times(start_time, end_time, saved_status, subject);
2355 else
2356 compute_subject_downtime_part_times(saved_stamp, end_time, saved_status, subject);
2357 }
2358 else {
2359 if(saved_stamp < start_time)
2360 compute_subject_downtime_part_times(start_time, temp_as->time_stamp, saved_status, subject);
2361 else
2362 compute_subject_downtime_part_times(saved_stamp, temp_as->time_stamp, saved_status, subject);
2363 }
2364 saved_status = temp_as->entry_type;
2365 saved_stamp = temp_as->time_stamp;
2366 }
2367 }
2368
2369 /* just one entry inside the scheduled downtime */
2370 if(count == 0)
2371 compute_subject_downtime_part_times(start_time, end_time, part_subject_state, subject);
2372 else {
2373 /* is outside scheduled time, use end schdule downtime */
2374 if(last->time_stamp > end_time)
2375 compute_subject_downtime_part_times(saved_stamp, end_time, saved_status, subject);
2376 else
2377 compute_subject_downtime_part_times(saved_stamp, last->time_stamp, saved_status, subject);
2378 }
2379
2380 return;
2381 }
2382
2383
2384
2385 /* computes downtime times */
compute_subject_downtime_part_times(time_t start_time,time_t end_time,int subject_state,avail_subject * subject)2386 void compute_subject_downtime_part_times(time_t start_time, time_t end_time, int subject_state, avail_subject *subject) {
2387 unsigned long state_duration;
2388
2389 #ifdef DEBUG2
2390 printf("ENTERING COMPUTE_SUBJECT_DOWNTIME_PART_TIMES\n");
2391 #endif
2392
2393 /* times are weird */
2394 if(start_time > end_time)
2395 return;
2396
2397 state_duration = (unsigned long)(end_time - start_time);
2398
2399 switch(subject_state) {
2400 case AS_HOST_UP:
2401 subject->scheduled_time_up += state_duration;
2402 break;
2403 case AS_HOST_DOWN:
2404 subject->scheduled_time_down += state_duration;
2405 break;
2406 case AS_HOST_UNREACHABLE:
2407 subject->scheduled_time_unreachable += state_duration;
2408 break;
2409 case AS_SVC_OK:
2410 subject->scheduled_time_ok += state_duration;
2411 break;
2412 case AS_SVC_WARNING:
2413 subject->scheduled_time_warning += state_duration;
2414 break;
2415 case AS_SVC_UNKNOWN:
2416 subject->scheduled_time_unknown += state_duration;
2417 break;
2418 case AS_SVC_CRITICAL:
2419 subject->scheduled_time_critical += state_duration;
2420 break;
2421 default:
2422 subject->scheduled_time_indeterminate += state_duration;
2423 break;
2424 }
2425
2426 #ifdef DEBUG2
2427 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);
2428 #endif
2429
2430 return;
2431 }
2432
2433
2434
2435 /* convert current host state to archived state value */
convert_host_state_to_archived_state(int current_status)2436 int convert_host_state_to_archived_state(int current_status) {
2437
2438 if(current_status == HOST_UP)
2439 return AS_HOST_UP;
2440 if(current_status == HOST_DOWN)
2441 return AS_HOST_DOWN;
2442 if(current_status == HOST_UNREACHABLE)
2443 return AS_HOST_UNREACHABLE;
2444
2445 return AS_NO_DATA;
2446 }
2447
2448
2449 /* convert current service state to archived state value */
convert_service_state_to_archived_state(int current_status)2450 int convert_service_state_to_archived_state(int current_status) {
2451
2452 if(current_status == SERVICE_OK)
2453 return AS_SVC_OK;
2454 if(current_status == SERVICE_UNKNOWN)
2455 return AS_SVC_UNKNOWN;
2456 if(current_status == SERVICE_WARNING)
2457 return AS_SVC_WARNING;
2458 if(current_status == SERVICE_CRITICAL)
2459 return AS_SVC_CRITICAL;
2460
2461 return AS_NO_DATA;
2462 }
2463
2464
2465
2466 /* create list of subjects to collect availability data for */
create_subject_list(void)2467 void create_subject_list(void) {
2468 hostgroup *temp_hostgroup;
2469 hostsmember *temp_hgmember;
2470 servicegroup *temp_servicegroup;
2471 servicesmember *temp_sgmember;
2472 host *temp_host;
2473 service *temp_service;
2474 char *last_host_name = "";
2475
2476 /* we're displaying one or more hosts */
2477 if(display_type == DISPLAY_HOST_AVAIL && host_name && strcmp(host_name, "")) {
2478
2479 /* we're only displaying a specific host (and summaries for all services associated with it) */
2480 if(show_all_hosts == FALSE) {
2481 add_subject(HOST_SUBJECT, host_name, NULL);
2482 for(temp_service = service_list; temp_service != NULL; temp_service = temp_service->next) {
2483 if(!strcmp(temp_service->host_name, host_name))
2484 add_subject(SERVICE_SUBJECT, host_name, temp_service->description);
2485 }
2486 }
2487
2488 /* we're displaying all hosts */
2489 else {
2490 for(temp_host = host_list; temp_host != NULL; temp_host = temp_host->next)
2491 add_subject(HOST_SUBJECT, temp_host->name, NULL);
2492 }
2493 }
2494
2495 /* we're displaying a specific service */
2496 else if(display_type == DISPLAY_SERVICE_AVAIL && svc_description && strcmp(svc_description, "")) {
2497
2498 /* we're only displaying a specific service */
2499 if(show_all_services == FALSE)
2500 add_subject(SERVICE_SUBJECT, host_name, svc_description);
2501
2502 /* we're displaying all services */
2503 else {
2504 for(temp_service = service_list; temp_service != NULL; temp_service = temp_service->next)
2505 add_subject(SERVICE_SUBJECT, temp_service->host_name, temp_service->description);
2506 }
2507 }
2508
2509 /* we're displaying one or more hostgroups (the host members of the groups) */
2510 else if(display_type == DISPLAY_HOSTGROUP_AVAIL && hostgroup_name && strcmp(hostgroup_name, "")) {
2511
2512 /* we're displaying all hostgroups */
2513 if(show_all_hostgroups == TRUE) {
2514 for(temp_hostgroup = hostgroup_list; temp_hostgroup != NULL; temp_hostgroup = temp_hostgroup->next) {
2515 for(temp_hgmember = temp_hostgroup->members; temp_hgmember != NULL; temp_hgmember = temp_hgmember->next)
2516 add_subject(HOST_SUBJECT, temp_hgmember->host_name, NULL);
2517 }
2518 }
2519 /* we're only displaying a specific hostgroup */
2520 else {
2521 temp_hostgroup = find_hostgroup(hostgroup_name);
2522 if(temp_hostgroup != NULL) {
2523 for(temp_hgmember = temp_hostgroup->members; temp_hgmember != NULL; temp_hgmember = temp_hgmember->next)
2524 add_subject(HOST_SUBJECT, temp_hgmember->host_name, NULL);
2525 }
2526 }
2527 }
2528
2529 /* we're displaying one or more servicegroups (the host and service members of the groups) */
2530 else if(display_type == DISPLAY_SERVICEGROUP_AVAIL && servicegroup_name && strcmp(servicegroup_name, "")) {
2531
2532 /* we're displaying all servicegroups */
2533 if(show_all_servicegroups == TRUE) {
2534 for(temp_servicegroup = servicegroup_list; temp_servicegroup != NULL; temp_servicegroup = temp_servicegroup->next) {
2535 for(temp_sgmember = temp_servicegroup->members; temp_sgmember != NULL; temp_sgmember = temp_sgmember->next) {
2536 add_subject(SERVICE_SUBJECT, temp_sgmember->host_name, temp_sgmember->service_description);
2537 if(strcmp(last_host_name, temp_sgmember->host_name))
2538 add_subject(HOST_SUBJECT, temp_sgmember->host_name, NULL);
2539 last_host_name = temp_sgmember->host_name;
2540 }
2541 }
2542 }
2543 /* we're only displaying a specific servicegroup */
2544 else {
2545 temp_servicegroup = find_servicegroup(servicegroup_name);
2546 if(temp_servicegroup != NULL) {
2547 for(temp_sgmember = temp_servicegroup->members; temp_sgmember != NULL; temp_sgmember = temp_sgmember->next) {
2548 add_subject(SERVICE_SUBJECT, temp_sgmember->host_name, temp_sgmember->service_description);
2549 if(strcmp(last_host_name, temp_sgmember->host_name))
2550 add_subject(HOST_SUBJECT, temp_sgmember->host_name, NULL);
2551 last_host_name = temp_sgmember->host_name;
2552 }
2553 }
2554 }
2555 }
2556
2557 return;
2558 }
2559
2560
2561
2562 /* adds a subject */
add_subject(int subject_type,char * hn,char * sd)2563 void add_subject(int subject_type, char *hn, char *sd) {
2564 avail_subject *last_subject = NULL;
2565 avail_subject *temp_subject = NULL;
2566 avail_subject *new_subject = NULL;
2567 int is_authorized = FALSE;
2568
2569 /* bail if we've already added the subject */
2570 if(find_subject(subject_type, hn, sd))
2571 return;
2572
2573 /* see if the user is authorized to see data for this host or service */
2574 if(subject_type == HOST_SUBJECT)
2575 is_authorized = is_authorized_for_host(find_host(hn), ¤t_authdata);
2576 else
2577 is_authorized = is_authorized_for_service(find_service(hn, sd), ¤t_authdata);
2578 if(is_authorized == FALSE)
2579 return;
2580
2581 /* allocate memory for the new entry */
2582 new_subject = (avail_subject *)malloc(sizeof(avail_subject));
2583 if(new_subject == NULL)
2584 return;
2585
2586 /* allocate memory for the host name */
2587 if(hn != NULL) {
2588 new_subject->host_name = (char *)malloc(strlen(hn) + 1);
2589 if(new_subject->host_name != NULL)
2590 strcpy(new_subject->host_name, hn);
2591 }
2592 else
2593 new_subject->host_name = NULL;
2594
2595 /* allocate memory for the service description */
2596 if(sd != NULL) {
2597 new_subject->service_description = (char *)malloc(strlen(sd) + 1);
2598 if(new_subject->service_description != NULL)
2599 strcpy(new_subject->service_description, sd);
2600 }
2601 else
2602 new_subject->service_description = NULL;
2603
2604 new_subject->type = subject_type;
2605 new_subject->earliest_state = AS_NO_DATA;
2606 new_subject->latest_state = AS_NO_DATA;
2607 new_subject->time_up = 0L;
2608 new_subject->time_down = 0L;
2609 new_subject->time_unreachable = 0L;
2610 new_subject->time_ok = 0L;
2611 new_subject->time_warning = 0L;
2612 new_subject->time_unknown = 0L;
2613 new_subject->time_critical = 0L;
2614 new_subject->scheduled_time_up = 0L;
2615 new_subject->scheduled_time_down = 0L;
2616 new_subject->scheduled_time_unreachable = 0L;
2617 new_subject->scheduled_time_ok = 0L;
2618 new_subject->scheduled_time_warning = 0L;
2619 new_subject->scheduled_time_unknown = 0L;
2620 new_subject->scheduled_time_critical = 0L;
2621 new_subject->scheduled_time_indeterminate = 0L;
2622 new_subject->time_indeterminate_nodata = 0L;
2623 new_subject->time_indeterminate_notrunning = 0L;
2624 new_subject->as_list = NULL;
2625 new_subject->as_list_tail = NULL;
2626 new_subject->sd_list = NULL;
2627 new_subject->last_known_state = AS_NO_DATA;
2628
2629 /* add the new entry to the list in memory, sorted by host name */
2630 last_subject = subject_list;
2631 for(temp_subject = subject_list; temp_subject != NULL; temp_subject = temp_subject->next) {
2632 if(strcmp(new_subject->host_name, temp_subject->host_name) < 0) {
2633 new_subject->next = temp_subject;
2634 if(temp_subject == subject_list)
2635 subject_list = new_subject;
2636 else
2637 last_subject->next = new_subject;
2638 break;
2639 }
2640 else
2641 last_subject = temp_subject;
2642 }
2643 if(subject_list == NULL) {
2644 new_subject->next = NULL;
2645 subject_list = new_subject;
2646 }
2647 else if(temp_subject == NULL) {
2648 new_subject->next = NULL;
2649 last_subject->next = new_subject;
2650 }
2651
2652 return;
2653 }
2654
2655
2656
2657 /* finds a specific subject */
find_subject(int type,char * hn,char * sd)2658 avail_subject *find_subject(int type, char *hn, char *sd) {
2659 avail_subject *temp_subject;
2660
2661 if(hn == NULL)
2662 return NULL;
2663
2664 if(type == SERVICE_SUBJECT && sd == NULL)
2665 return NULL;
2666
2667 for(temp_subject = subject_list; temp_subject != NULL; temp_subject = temp_subject->next) {
2668 if(temp_subject->type != type)
2669 continue;
2670 if(strcmp(hn, temp_subject->host_name))
2671 continue;
2672 if(type == SERVICE_SUBJECT && strcmp(sd, temp_subject->service_description))
2673 continue;
2674 return temp_subject;
2675 }
2676
2677 return NULL;
2678 }
2679
2680
2681
2682 /* adds an archived state entry to all subjects */
add_global_archived_state(int entry_type,int state_type,time_t time_stamp,char * state_info)2683 void add_global_archived_state(int entry_type, int state_type, time_t time_stamp, char *state_info) {
2684 avail_subject *temp_subject;
2685
2686 for(temp_subject = subject_list; temp_subject != NULL; temp_subject = temp_subject->next)
2687 add_archived_state(entry_type, state_type, time_stamp, state_info, temp_subject);
2688
2689 return;
2690 }
2691
2692
2693
2694
2695 /* adds an archived state entry to a specific subject */
add_archived_state(int entry_type,int state_type,time_t time_stamp,char * state_info,avail_subject * subject)2696 void add_archived_state(int entry_type, int state_type, time_t time_stamp, char *state_info, avail_subject *subject) {
2697 archived_state *last_as = NULL;
2698 archived_state *temp_as = NULL;
2699 archived_state *new_as = NULL;
2700
2701 /* allocate memory for the new entry */
2702 new_as = (archived_state *)malloc(sizeof(archived_state));
2703 if(new_as == NULL)
2704 return;
2705
2706 /* allocate memory for the state info */
2707 if(state_info != NULL) {
2708 new_as->state_info = (char *)malloc(strlen(state_info) + 1);
2709 if(new_as->state_info != NULL)
2710 strcpy(new_as->state_info, state_info);
2711 }
2712 else new_as->state_info = NULL;
2713
2714 /* initialize the "processed state" value - this gets modified later for most entries */
2715 if(entry_type != AS_PROGRAM_START && entry_type != AS_PROGRAM_END && entry_type != AS_NO_DATA)
2716 new_as->processed_state = entry_type;
2717 else
2718 new_as->processed_state = AS_NO_DATA;
2719
2720 new_as->entry_type = entry_type;
2721 new_as->state_type = state_type;
2722 new_as->time_stamp = time_stamp;
2723 new_as->misc_ptr = NULL;
2724
2725 /* add the new entry to the list in memory, sorted by time (more recent entries should appear towards end of list) */
2726 last_as = subject->as_list;
2727 for(temp_as = subject->as_list; temp_as != NULL; temp_as = temp_as->next) {
2728 if(new_as->time_stamp < temp_as->time_stamp) {
2729 new_as->next = temp_as;
2730 if(temp_as == subject->as_list)
2731 subject->as_list = new_as;
2732 else
2733 last_as->next = new_as;
2734 break;
2735 }
2736 else
2737 last_as = temp_as;
2738 }
2739 if(subject->as_list == NULL) {
2740 new_as->next = NULL;
2741 subject->as_list = new_as;
2742 }
2743 else if(temp_as == NULL) {
2744 new_as->next = NULL;
2745 last_as->next = new_as;
2746 }
2747
2748 /* update "tail" of the list - not really the tail, just last item added */
2749 subject->as_list_tail = new_as;
2750
2751 return;
2752 }
2753
2754
2755 /* adds a scheduled downtime entry to a specific subject */
add_scheduled_downtime(int state_type,time_t time_stamp,avail_subject * subject)2756 void add_scheduled_downtime(int state_type, time_t time_stamp, avail_subject *subject) {
2757 archived_state *last_sd = NULL;
2758 archived_state *temp_sd = NULL;
2759 archived_state *new_sd = NULL;
2760
2761 /* allocate memory for the new entry */
2762 new_sd = (archived_state *)malloc(sizeof(archived_state));
2763 if(new_sd == NULL)
2764 return;
2765
2766 new_sd->state_info = NULL;
2767 new_sd->processed_state = state_type;
2768 new_sd->entry_type = state_type;
2769 new_sd->time_stamp = time_stamp;
2770 new_sd->misc_ptr = subject->as_list_tail;
2771
2772 /* add the new entry to the list in memory, sorted by time (more recent entries should appear towards end of list) */
2773 last_sd = subject->sd_list;
2774 for(temp_sd = subject->sd_list; temp_sd != NULL; temp_sd = temp_sd->next) {
2775 if(new_sd->time_stamp <= temp_sd->time_stamp) {
2776 new_sd->next = temp_sd;
2777 if(temp_sd == subject->sd_list)
2778 subject->sd_list = new_sd;
2779 else
2780 last_sd->next = new_sd;
2781 break;
2782 }
2783 else
2784 last_sd = temp_sd;
2785 }
2786 if(subject->sd_list == NULL) {
2787 new_sd->next = NULL;
2788 subject->sd_list = new_sd;
2789 }
2790 else if(temp_sd == NULL) {
2791 new_sd->next = NULL;
2792 last_sd->next = new_sd;
2793 }
2794
2795 return;
2796 }
2797
2798
2799 /* frees memory allocated to all availability data */
free_availability_data(void)2800 void free_availability_data(void) {
2801 avail_subject *this_subject;
2802 avail_subject *next_subject;
2803
2804 for(this_subject = subject_list; this_subject != NULL;) {
2805 next_subject = this_subject->next;
2806 if(this_subject->host_name != NULL)
2807 free(this_subject->host_name);
2808 if(this_subject->service_description != NULL)
2809 free(this_subject->service_description);
2810 free_archived_state_list(this_subject->as_list);
2811 free_archived_state_list(this_subject->sd_list);
2812 free(this_subject);
2813 this_subject = next_subject;
2814 }
2815
2816 return;
2817 }
2818
2819 /* frees memory allocated to the archived state list */
free_archived_state_list(archived_state * as_list)2820 void free_archived_state_list(archived_state *as_list) {
2821 archived_state *this_as = NULL;
2822 archived_state *next_as = NULL;
2823
2824 for(this_as = as_list; this_as != NULL;) {
2825 next_as = this_as->next;
2826 if(this_as->state_info != NULL)
2827 free(this_as->state_info);
2828 free(this_as);
2829 this_as = next_as;
2830 }
2831
2832 as_list = NULL;
2833
2834 return;
2835 }
2836
2837
2838
2839 /* reads log files for archived state data */
read_archived_state_data(void)2840 void read_archived_state_data(void) {
2841 char filename[MAX_FILENAME_LENGTH];
2842 int oldest_archive = 0;
2843 int newest_archive = 0;
2844 int current_archive = 0;
2845
2846 /* determine oldest archive to use when scanning for data (include backtracked archives as well) */
2847 oldest_archive = determine_archive_to_use_from_time(t1);
2848 if(log_rotation_method != LOG_ROTATION_NONE)
2849 oldest_archive += backtrack_archives;
2850
2851 /* determine most recent archive to use when scanning for data */
2852 newest_archive = determine_archive_to_use_from_time(t2);
2853
2854 if(oldest_archive < newest_archive)
2855 oldest_archive = newest_archive;
2856
2857 /* read in all the necessary archived logs (from most recent to earliest) */
2858 for(current_archive = newest_archive; current_archive <= oldest_archive; current_archive++) {
2859
2860 #ifdef DEBUG
2861 printf("Reading archive #%d\n", current_archive);
2862 #endif
2863
2864 /* get the name of the log file that contains this archive */
2865 get_log_archive_to_use(current_archive, filename, sizeof(filename) - 1);
2866
2867 #ifdef DEBUG
2868 printf("Archive name: '%s'\n", filename);
2869 #endif
2870
2871 /* scan the log file for archived state data */
2872 scan_log_file_for_archived_state_data(filename);
2873 }
2874
2875 return;
2876 }
2877
2878
2879
2880 /* grabs archives state data from a log file */
scan_log_file_for_archived_state_data(char * filename)2881 void scan_log_file_for_archived_state_data(char *filename) {
2882 char *input = NULL;
2883 char *input2 = NULL;
2884 char entry_host_name[MAX_INPUT_BUFFER];
2885 char entry_svc_description[MAX_INPUT_BUFFER];
2886 char *plugin_output = NULL;
2887 char *temp_buffer = NULL;
2888 time_t time_stamp;
2889 mmapfile *thefile = NULL;
2890 avail_subject *temp_subject = NULL;
2891 int state_type = 0;
2892
2893 if((thefile = mmap_fopen(filename)) == NULL)
2894 return;
2895
2896 while(1) {
2897
2898 /* free memory */
2899 free(input);
2900 free(input2);
2901 input = NULL;
2902 input2 = NULL;
2903
2904 /* read the next line */
2905 if((input = mmap_fgets(thefile)) == NULL)
2906 break;
2907
2908 strip(input);
2909
2910 if((input2 = strdup(input)) == NULL)
2911 continue;
2912
2913 temp_buffer = my_strtok(input2, "]");
2914 time_stamp = (temp_buffer == NULL) ? (time_t)0 : (time_t)strtoul(temp_buffer + 1, NULL, 10);
2915
2916 /* program starts/restarts */
2917 if(strstr(input, " starting..."))
2918 add_global_archived_state(AS_PROGRAM_START, AS_NO_DATA, time_stamp, "Program start");
2919 if(strstr(input, " restarting..."))
2920 add_global_archived_state(AS_PROGRAM_START, AS_NO_DATA, time_stamp, "Program restart");
2921
2922 /* program stops */
2923 if(strstr(input, " shutting down..."))
2924 add_global_archived_state(AS_PROGRAM_END, AS_NO_DATA, time_stamp, "Normal program termination");
2925 if(strstr(input, "Bailing out"))
2926 add_global_archived_state(AS_PROGRAM_END, AS_NO_DATA, time_stamp, "Abnormal program termination");
2927
2928 if(display_type == DISPLAY_HOST_AVAIL || display_type == DISPLAY_HOSTGROUP_AVAIL || display_type == DISPLAY_SERVICEGROUP_AVAIL) {
2929
2930 /* normal host alerts and initial/current states */
2931 if(strstr(input, "HOST ALERT:") || strstr(input, "INITIAL HOST STATE:") || strstr(input, "CURRENT HOST STATE:")) {
2932
2933 /* get host name */
2934 temp_buffer = my_strtok(NULL, ":");
2935 temp_buffer = my_strtok(NULL, ";");
2936 strncpy(entry_host_name, (temp_buffer == NULL) ? "" : temp_buffer + 1, sizeof(entry_host_name));
2937 entry_host_name[sizeof(entry_host_name) - 1] = '\x0';
2938
2939 /* see if there is a corresponding subject for this host */
2940 temp_subject = find_subject(HOST_SUBJECT, entry_host_name, NULL);
2941 if(temp_subject == NULL)
2942 continue;
2943
2944 /* state types */
2945 if(strstr(input, ";SOFT;")) {
2946 if(include_soft_states == FALSE)
2947 continue;
2948 state_type = AS_SOFT_STATE;
2949 }
2950 if(strstr(input, ";HARD;"))
2951 state_type = AS_HARD_STATE;
2952
2953 /* get the plugin output */
2954 temp_buffer = my_strtok(NULL, ";");
2955 temp_buffer = my_strtok(NULL, ";");
2956 temp_buffer = my_strtok(NULL, ";");
2957 plugin_output = my_strtok(NULL, "\n");
2958
2959 if(strstr(input, ";DOWN;"))
2960 add_archived_state(AS_HOST_DOWN, state_type, time_stamp, plugin_output, temp_subject);
2961 else if(strstr(input, ";UNREACHABLE;"))
2962 add_archived_state(AS_HOST_UNREACHABLE, state_type, time_stamp, plugin_output, temp_subject);
2963 else if(strstr(input, ";RECOVERY") || strstr(input, ";UP;"))
2964 add_archived_state(AS_HOST_UP, state_type, time_stamp, plugin_output, temp_subject);
2965 else
2966 add_archived_state(AS_NO_DATA, AS_NO_DATA, time_stamp, plugin_output, temp_subject);
2967 }
2968
2969 /* scheduled downtime notices */
2970 else if(strstr(input, "HOST DOWNTIME ALERT:")) {
2971
2972 /* get host name */
2973 temp_buffer = my_strtok(NULL, ":");
2974 temp_buffer = my_strtok(NULL, ";");
2975 strncpy(entry_host_name, (temp_buffer == NULL) ? "" : temp_buffer + 1, sizeof(entry_host_name));
2976 entry_host_name[sizeof(entry_host_name) - 1] = '\x0';
2977
2978 /* see if there is a corresponding subject for this host */
2979 temp_subject = find_subject(HOST_SUBJECT, entry_host_name, NULL);
2980 if(temp_subject == NULL)
2981 continue;
2982
2983 if(show_scheduled_downtime == FALSE)
2984 continue;
2985
2986 if(strstr(input, ";STARTED;"))
2987 add_scheduled_downtime(AS_HOST_DOWNTIME_START, time_stamp, temp_subject);
2988 else
2989 add_scheduled_downtime(AS_HOST_DOWNTIME_END, time_stamp, temp_subject);
2990
2991 }
2992 }
2993
2994 if(display_type == DISPLAY_SERVICE_AVAIL || display_type == DISPLAY_HOST_AVAIL || display_type == DISPLAY_SERVICEGROUP_AVAIL) {
2995
2996 /* normal service alerts and initial/current states */
2997 if(strstr(input, "SERVICE ALERT:") || strstr(input, "INITIAL SERVICE STATE:") || strstr(input, "CURRENT SERVICE STATE:")) {
2998
2999 /* get host name */
3000 temp_buffer = my_strtok(NULL, ":");
3001 temp_buffer = my_strtok(NULL, ";");
3002 strncpy(entry_host_name, (temp_buffer == NULL) ? "" : temp_buffer + 1, sizeof(entry_host_name));
3003 entry_host_name[sizeof(entry_host_name) - 1] = '\x0';
3004
3005 /* get service description */
3006 temp_buffer = my_strtok(NULL, ";");
3007 strncpy(entry_svc_description, (temp_buffer == NULL) ? "" : temp_buffer, sizeof(entry_svc_description));
3008 entry_svc_description[sizeof(entry_svc_description) - 1] = '\x0';
3009
3010 /* see if there is a corresponding subject for this service */
3011 temp_subject = find_subject(SERVICE_SUBJECT, entry_host_name, entry_svc_description);
3012 if(temp_subject == NULL)
3013 continue;
3014
3015 /* state types */
3016 if(strstr(input, ";SOFT;")) {
3017 if(include_soft_states == FALSE)
3018 continue;
3019 state_type = AS_SOFT_STATE;
3020 }
3021 if(strstr(input, ";HARD;"))
3022 state_type = AS_HARD_STATE;
3023
3024 /* get the plugin output */
3025 temp_buffer = my_strtok(NULL, ";");
3026 temp_buffer = my_strtok(NULL, ";");
3027 temp_buffer = my_strtok(NULL, ";");
3028 plugin_output = my_strtok(NULL, "\n");
3029
3030 if(strstr(input, ";CRITICAL;"))
3031 add_archived_state(AS_SVC_CRITICAL, state_type, time_stamp, plugin_output, temp_subject);
3032 else if(strstr(input, ";WARNING;"))
3033 add_archived_state(AS_SVC_WARNING, state_type, time_stamp, plugin_output, temp_subject);
3034 else if(strstr(input, ";UNKNOWN;"))
3035 add_archived_state(AS_SVC_UNKNOWN, state_type, time_stamp, plugin_output, temp_subject);
3036 else if(strstr(input, ";RECOVERY;") || strstr(input, ";OK;"))
3037 add_archived_state(AS_SVC_OK, state_type, time_stamp, plugin_output, temp_subject);
3038 else
3039 add_archived_state(AS_NO_DATA, AS_NO_DATA, time_stamp, plugin_output, temp_subject);
3040
3041 }
3042
3043 /* scheduled service downtime notices */
3044 else if(strstr(input, "SERVICE DOWNTIME ALERT:")) {
3045
3046 /* get host name */
3047 temp_buffer = my_strtok(NULL, ":");
3048 temp_buffer = my_strtok(NULL, ";");
3049 strncpy(entry_host_name, (temp_buffer == NULL) ? "" : temp_buffer + 1, sizeof(entry_host_name));
3050 entry_host_name[sizeof(entry_host_name) - 1] = '\x0';
3051
3052 /* get service description */
3053 temp_buffer = my_strtok(NULL, ";");
3054 strncpy(entry_svc_description, (temp_buffer == NULL) ? "" : temp_buffer, sizeof(entry_svc_description));
3055 entry_svc_description[sizeof(entry_svc_description) - 1] = '\x0';
3056
3057 /* see if there is a corresponding subject for this service */
3058 temp_subject = find_subject(SERVICE_SUBJECT, entry_host_name, entry_svc_description);
3059 if(temp_subject == NULL)
3060 continue;
3061
3062 if(show_scheduled_downtime == FALSE)
3063 continue;
3064
3065 if(strstr(input, ";STARTED;"))
3066 add_scheduled_downtime(AS_SVC_DOWNTIME_START, time_stamp, temp_subject);
3067 else
3068 add_scheduled_downtime(AS_SVC_DOWNTIME_END, time_stamp, temp_subject);
3069 }
3070
3071 /* scheduled host downtime notices */
3072 else if(strstr(input, "HOST DOWNTIME ALERT:")) {
3073
3074 /* get host name */
3075 temp_buffer = my_strtok(NULL, ":");
3076 temp_buffer = my_strtok(NULL, ";");
3077 strncpy(entry_host_name, (temp_buffer == NULL) ? "" : temp_buffer + 1, sizeof(entry_host_name));
3078 entry_host_name[sizeof(entry_host_name) - 1] = '\x0';
3079
3080 /* this host downtime entry must be added to all service subjects associated with the host! */
3081 for(temp_subject = subject_list; temp_subject != NULL; temp_subject = temp_subject->next) {
3082
3083 if(temp_subject->type != SERVICE_SUBJECT)
3084 continue;
3085
3086 if(strcmp(temp_subject->host_name, entry_host_name))
3087 continue;
3088
3089 if(show_scheduled_downtime == FALSE)
3090 continue;
3091
3092 if(strstr(input, ";STARTED;"))
3093 add_scheduled_downtime(AS_HOST_DOWNTIME_START, time_stamp, temp_subject);
3094 else
3095 add_scheduled_downtime(AS_HOST_DOWNTIME_END, time_stamp, temp_subject);
3096 }
3097 }
3098 }
3099
3100 }
3101
3102 /* free memory and close the file */
3103 free(input);
3104 free(input2);
3105 mmap_fclose(thefile);
3106
3107 return;
3108 }
3109
3110
3111
3112
convert_timeperiod_to_times(int type)3113 void convert_timeperiod_to_times(int type) {
3114 time_t current_time;
3115 struct tm *t;
3116
3117 /* get the current time */
3118 time(¤t_time);
3119
3120 t = localtime(¤t_time);
3121
3122 t->tm_sec = 0;
3123 t->tm_min = 0;
3124 t->tm_hour = 0;
3125 t->tm_isdst = -1;
3126
3127 switch(type) {
3128 case TIMEPERIOD_LAST24HOURS:
3129 t1 = current_time - (60 * 60 * 24);
3130 t2 = current_time;
3131 break;
3132 case TIMEPERIOD_TODAY:
3133 t1 = mktime(t);
3134 t2 = current_time;
3135 break;
3136 case TIMEPERIOD_YESTERDAY:
3137 t1 = (time_t)(mktime(t) - (60 * 60 * 24));
3138 t2 = (time_t)mktime(t);
3139 break;
3140 case TIMEPERIOD_THISWEEK:
3141 t1 = (time_t)(mktime(t) - (60 * 60 * 24 * t->tm_wday));
3142 t2 = current_time;
3143 break;
3144 case TIMEPERIOD_LASTWEEK:
3145 t1 = (time_t)(mktime(t) - (60 * 60 * 24 * t->tm_wday) - (60 * 60 * 24 * 7));
3146 t2 = (time_t)(mktime(t) - (60 * 60 * 24 * t->tm_wday));
3147 break;
3148 case TIMEPERIOD_THISMONTH:
3149 t->tm_mday = 1;
3150 t1 = mktime(t);
3151 t2 = current_time;
3152 break;
3153 case TIMEPERIOD_LASTMONTH:
3154 t->tm_mday = 1;
3155 t2 = mktime(t);
3156 if(t->tm_mon == 0) {
3157 t->tm_mon = 11;
3158 t->tm_year--;
3159 }
3160 else
3161 t->tm_mon--;
3162 t1 = mktime(t);
3163 break;
3164 case TIMEPERIOD_THISQUARTER:
3165 /* not implemented */
3166 break;
3167 case TIMEPERIOD_LASTQUARTER:
3168 /* not implemented */
3169 break;
3170 case TIMEPERIOD_THISYEAR:
3171 t->tm_mon = 0;
3172 t->tm_mday = 1;
3173 t1 = mktime(t);
3174 t2 = current_time;
3175 break;
3176 case TIMEPERIOD_LASTYEAR:
3177 t->tm_mon = 0;
3178 t->tm_mday = 1;
3179 t2 = mktime(t);
3180 t->tm_year--;
3181 t1 = mktime(t);
3182 break;
3183 case TIMEPERIOD_LAST7DAYS:
3184 t2 = current_time;
3185 t1 = current_time - (7 * 24 * 60 * 60);
3186 break;
3187 case TIMEPERIOD_LAST31DAYS:
3188 t2 = current_time;
3189 t1 = current_time - (31 * 24 * 60 * 60);
3190 break;
3191 default:
3192 break;
3193 }
3194
3195 return;
3196 }
3197
3198
3199
compute_report_times(void)3200 void compute_report_times(void) {
3201 time_t current_time;
3202 struct tm *st;
3203 struct tm *et;
3204
3205 /* get the current time */
3206 time(¤t_time);
3207
3208 st = localtime(¤t_time);
3209
3210 st->tm_sec = start_second;
3211 st->tm_min = start_minute;
3212 st->tm_hour = start_hour;
3213 st->tm_mday = start_day;
3214 st->tm_mon = start_month - 1;
3215 st->tm_year = start_year - 1900;
3216 st->tm_isdst = -1;
3217
3218 t1 = mktime(st);
3219
3220 et = localtime(¤t_time);
3221
3222 et->tm_sec = end_second;
3223 et->tm_min = end_minute;
3224 et->tm_hour = end_hour;
3225 et->tm_mday = end_day;
3226 et->tm_mon = end_month - 1;
3227 et->tm_year = end_year - 1900;
3228 et->tm_isdst = -1;
3229
3230 t2 = mktime(et);
3231 }
3232
3233
3234 /* writes log entries to screen */
write_log_entries(avail_subject * subject)3235 void write_log_entries(avail_subject *subject) {
3236 archived_state *temp_as;
3237 archived_state *temp_sd;
3238 time_t current_time;
3239 char start_date_time[MAX_DATETIME_LENGTH];
3240 char end_date_time[MAX_DATETIME_LENGTH];
3241 char duration[20];
3242 char *bgclass = "";
3243 char *ebgclass = "";
3244 char *entry_type = "";
3245 char *state_type = "";
3246 int days;
3247 int hours;
3248 int minutes;
3249 int seconds;
3250 int odd = 0;
3251
3252
3253 if(output_format != HTML_OUTPUT)
3254 return;
3255
3256 if(show_log_entries == FALSE)
3257 return;
3258
3259 if(subject == NULL)
3260 return;
3261
3262 time(¤t_time);
3263
3264 /* inject all scheduled downtime entries into the main list for display purposes */
3265 for(temp_sd = subject->sd_list; temp_sd != NULL; temp_sd = temp_sd->next) {
3266 switch(temp_sd->entry_type) {
3267 case AS_SVC_DOWNTIME_START:
3268 case AS_HOST_DOWNTIME_START:
3269 entry_type = "Start of scheduled downtime";
3270 break;
3271 case AS_SVC_DOWNTIME_END:
3272 case AS_HOST_DOWNTIME_END:
3273 entry_type = "End of scheduled downtime";
3274 break;
3275 default:
3276 entry_type = "?";
3277 break;
3278 }
3279 add_archived_state(temp_sd->entry_type, AS_NO_DATA, temp_sd->time_stamp, entry_type, subject);
3280 }
3281
3282
3283 printf("<BR><BR>\n");
3284
3285 printf("<DIV ALIGN=CENTER CLASS='dataTitle'>%s Log Entries:</DIV>\n", (subject->type == HOST_SUBJECT) ? "Host" : "Service");
3286
3287 printf("<DIV ALIGN=CENTER CLASS='infoMessage'>");
3288 if(full_log_entries == TRUE) {
3289 full_log_entries = FALSE;
3290 if(subject->type == HOST_SUBJECT)
3291 host_report_url(subject->host_name, "[ View condensed log entries ]");
3292 else
3293 service_report_url(subject->host_name, subject->service_description, "[ View condensed log entries ]");
3294 full_log_entries = TRUE;
3295 }
3296 else {
3297 full_log_entries = TRUE;
3298 if(subject->type == HOST_SUBJECT)
3299 host_report_url(subject->host_name, "[ View full log entries ]");
3300 else
3301 service_report_url(subject->host_name, subject->service_description, "[ View full log entries ]");
3302 full_log_entries = FALSE;
3303 }
3304 printf("</DIV>\n");
3305
3306 printf("<DIV ALIGN=CENTER>\n");
3307
3308 printf("<table border=1 cellspacing=0 cellpadding=3 class='logEntries'>\n");
3309 printf("<tr><th class='logEntries'>Event Start Time</th><th class='logEntries'>Event End Time</th><th class='logEntries'>Event Duration</th><th class='logEntries'>Event/State Type</th><th class='logEntries'>Event/State Information</th></tr>\n");
3310
3311 /* write all archived state entries */
3312 for(temp_as = subject->as_list; temp_as != NULL; temp_as = temp_as->next) {
3313
3314 if(temp_as->state_type == AS_HARD_STATE)
3315 state_type = " (HARD)";
3316 else if(temp_as->state_type == AS_SOFT_STATE)
3317 state_type = " (SOFT)";
3318 else
3319 state_type = "";
3320
3321 switch(temp_as->entry_type) {
3322 case AS_NO_DATA:
3323 if(full_log_entries == FALSE)
3324 continue;
3325 entry_type = "NO DATA";
3326 ebgclass = "INDETERMINATE";
3327 break;
3328 case AS_PROGRAM_END:
3329 if(full_log_entries == FALSE)
3330 continue;
3331 entry_type = "PROGRAM END";
3332 ebgclass = "INDETERMINATE";
3333 break;
3334 case AS_PROGRAM_START:
3335 if(full_log_entries == FALSE)
3336 continue;
3337 entry_type = "PROGRAM (RE)START";
3338 ebgclass = "INDETERMINATE";
3339 break;
3340 case AS_HOST_UP:
3341 entry_type = "HOST UP";
3342 ebgclass = "UP";
3343 break;
3344 case AS_HOST_DOWN:
3345 entry_type = "HOST DOWN";
3346 ebgclass = "DOWN";
3347 break;
3348 case AS_HOST_UNREACHABLE:
3349 entry_type = "HOST UNREACHABLE";
3350 ebgclass = "UNREACHABLE";
3351 break;
3352 case AS_SVC_OK:
3353 entry_type = "SERVICE OK";
3354 ebgclass = "OK";
3355 break;
3356 case AS_SVC_UNKNOWN:
3357 entry_type = "SERVICE UNKNOWN";
3358 ebgclass = "UNKNOWN";
3359 break;
3360 case AS_SVC_WARNING:
3361 entry_type = "SERVICE WARNING";
3362 ebgclass = "WARNING";
3363 break;
3364 case AS_SVC_CRITICAL:
3365 entry_type = "SERVICE CRITICAL";
3366 ebgclass = "CRITICAL";
3367 break;
3368 case AS_SVC_DOWNTIME_START:
3369 entry_type = "SERVICE DOWNTIME START";
3370 ebgclass = "INDETERMINATE";
3371 break;
3372 case AS_SVC_DOWNTIME_END:
3373 entry_type = "SERVICE DOWNTIME END";
3374 ebgclass = "INDETERMINATE";
3375 break;
3376 case AS_HOST_DOWNTIME_START:
3377 entry_type = "HOST DOWNTIME START";
3378 ebgclass = "INDETERMINATE";
3379 break;
3380 case AS_HOST_DOWNTIME_END:
3381 entry_type = "HOST DOWNTIME END";
3382 ebgclass = "INDETERMINATE";
3383 break;
3384 default:
3385 if(full_log_entries == FALSE)
3386 continue;
3387 entry_type = "?";
3388 ebgclass = "INDETERMINATE";
3389 }
3390
3391 get_time_string(&(temp_as->time_stamp), start_date_time, sizeof(start_date_time) - 1, SHORT_DATE_TIME);
3392 if(temp_as->next == NULL) {
3393 get_time_string(&t2, end_date_time, sizeof(end_date_time) - 1, SHORT_DATE_TIME);
3394 get_time_breakdown((time_t)(t2 - temp_as->time_stamp), &days, &hours, &minutes, &seconds);
3395 snprintf(duration, sizeof(duration) - 1, "%dd %dh %dm %ds+", days, hours, minutes, seconds);
3396 }
3397 else {
3398 get_time_string(&(temp_as->next->time_stamp), end_date_time, sizeof(end_date_time) - 1, SHORT_DATE_TIME);
3399 get_time_breakdown((time_t)(temp_as->next->time_stamp - temp_as->time_stamp), &days, &hours, &minutes, &seconds);
3400 snprintf(duration, sizeof(duration) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds);
3401 }
3402
3403 if(odd) {
3404 bgclass = "Odd";
3405 odd = 0;
3406 }
3407 else {
3408 bgclass = "Even";
3409 odd = 1;
3410 }
3411
3412 printf("<tr class='logEntries%s'>", bgclass);
3413 printf("<td class='logEntries%s'>%s</td>", bgclass, start_date_time);
3414 printf("<td class='logEntries%s'>%s</td>", bgclass, end_date_time);
3415 printf("<td class='logEntries%s'>%s</td>", bgclass, duration);
3416 printf("<td class='logEntries%s'>%s%s</td>", ebgclass, entry_type, state_type);
3417 printf("<td class='logEntries%s'>%s</td>", bgclass, (temp_as->state_info == NULL) ? "" : html_encode(temp_as->state_info, FALSE));
3418 printf("</tr>\n");
3419 }
3420
3421 printf("</table>\n");
3422
3423 printf("</DIV>\n");
3424
3425 return;
3426 }
3427
3428
3429
3430 /* display hostgroup availability */
display_hostgroup_availability(void)3431 void display_hostgroup_availability(void) {
3432 hostgroup *temp_hostgroup;
3433
3434 /* display data for a specific hostgroup */
3435 if(show_all_hostgroups == FALSE) {
3436 temp_hostgroup = find_hostgroup(hostgroup_name);
3437 display_specific_hostgroup_availability(temp_hostgroup);
3438 }
3439
3440 /* display data for all hostgroups */
3441 else {
3442 for(temp_hostgroup = hostgroup_list; temp_hostgroup != NULL; temp_hostgroup = temp_hostgroup->next)
3443 display_specific_hostgroup_availability(temp_hostgroup);
3444 }
3445
3446 return;
3447 }
3448
3449
3450
3451 /* display availability for a specific hostgroup */
display_specific_hostgroup_availability(hostgroup * hg)3452 void display_specific_hostgroup_availability(hostgroup *hg) {
3453 unsigned long total_time;
3454 unsigned long time_determinate;
3455 unsigned long time_indeterminate;
3456 avail_subject *temp_subject;
3457 double percent_time_up = 0.0;
3458 double percent_time_down = 0.0;
3459 double percent_time_unreachable = 0.0;
3460 double percent_time_up_known = 0.0;
3461 double percent_time_down_known = 0.0;
3462 double percent_time_unreachable_known = 0.0;
3463 double percent_time_indeterminate = 0.0;
3464
3465 double average_percent_time_up = 0.0;
3466 double average_percent_time_up_known = 0.0;
3467 double average_percent_time_down = 0.0;
3468 double average_percent_time_down_known = 0.0;
3469 double average_percent_time_unreachable = 0.0;
3470 double average_percent_time_unreachable_known = 0.0;
3471 double average_percent_time_indeterminate = 0.0;
3472
3473 int current_subject = 0;
3474
3475 char *bgclass = "";
3476 int odd = 1;
3477 host *temp_host;
3478
3479 if(hg == NULL)
3480 return;
3481
3482 /* the user isn't authorized to view this hostgroup */
3483 if(is_authorized_for_hostgroup(hg, ¤t_authdata) == FALSE)
3484 return;
3485
3486 /* calculate total time during period based on timeperiod used for reporting */
3487 total_time = calculate_total_time(t1, t2);
3488
3489 printf("<BR><BR>\n");
3490 printf("<DIV ALIGN=CENTER CLASS='dataTitle'>Hostgroup '%s' Host State Breakdowns:</DIV>\n", hg->group_name);
3491
3492 printf("<DIV ALIGN=CENTER>\n");
3493 printf("<TABLE BORDER=0 CLASS='data'>\n");
3494 printf("<TR><TH CLASS='data'>Host</TH><TH CLASS='data'>%% Time Up</TH><TH CLASS='data'>%% Time Down</TH><TH CLASS='data'>%% Time Unreachable</TH><TH CLASS='data'>%% Time Undetermined</TH></TR>\n");
3495
3496 for(temp_subject = subject_list; temp_subject != NULL; temp_subject = temp_subject->next) {
3497
3498 if(temp_subject->type != HOST_SUBJECT)
3499 continue;
3500
3501 temp_host = find_host(temp_subject->host_name);
3502 if(temp_host == NULL)
3503 continue;
3504
3505 if(is_host_member_of_hostgroup(hg, temp_host) == FALSE)
3506 continue;
3507
3508 current_subject++;
3509
3510 /* reset variables */
3511 percent_time_up = 0.0;
3512 percent_time_down = 0.0;
3513 percent_time_unreachable = 0.0;
3514 percent_time_indeterminate = 0.0;
3515 percent_time_up_known = 0.0;
3516 percent_time_down_known = 0.0;
3517 percent_time_unreachable_known = 0.0;
3518
3519 time_determinate = temp_subject->time_up + temp_subject->time_down + temp_subject->time_unreachable;
3520 time_indeterminate = total_time - time_determinate;
3521
3522 if(total_time > 0) {
3523 percent_time_up = (double)(((double)temp_subject->time_up * 100.0) / (double)total_time);
3524 percent_time_down = (double)(((double)temp_subject->time_down * 100.0) / (double)total_time);
3525 percent_time_unreachable = (double)(((double)temp_subject->time_unreachable * 100.0) / (double)total_time);
3526 percent_time_indeterminate = (double)(((double)time_indeterminate * 100.0) / (double)total_time);
3527 if(time_determinate > 0) {
3528 percent_time_up_known = (double)(((double)temp_subject->time_up * 100.0) / (double)time_determinate);
3529 percent_time_down_known = (double)(((double)temp_subject->time_down * 100.0) / (double)time_determinate);
3530 percent_time_unreachable_known = (double)(((double)temp_subject->time_unreachable * 100.0) / (double)time_determinate);
3531 }
3532 }
3533
3534 if(odd) {
3535 odd = 0;
3536 bgclass = "Odd";
3537 }
3538 else {
3539 odd = 1;
3540 bgclass = "Even";
3541 }
3542
3543 printf("<tr CLASS='data%s'><td CLASS='data%s'>", bgclass, bgclass);
3544 host_report_url(temp_subject->host_name, temp_subject->host_name);
3545 printf("</td><td CLASS='hostUP'>%2.3f%% (%2.3f%%)</td><td CLASS='hostDOWN'>%2.3f%% (%2.3f%%)</td><td CLASS='hostUNREACHABLE'>%2.3f%% (%2.3f%%)</td><td class='data%s'>%2.3f%%</td></tr>\n", percent_time_up, percent_time_up_known, percent_time_down, percent_time_down_known, percent_time_unreachable, percent_time_unreachable_known, bgclass, percent_time_indeterminate);
3546
3547 get_running_average(&average_percent_time_up, percent_time_up, current_subject);
3548 get_running_average(&average_percent_time_up_known, percent_time_up_known, current_subject);
3549 get_running_average(&average_percent_time_down, percent_time_down, current_subject);
3550 get_running_average(&average_percent_time_down_known, percent_time_down_known, current_subject);
3551 get_running_average(&average_percent_time_unreachable, percent_time_unreachable, current_subject);
3552 get_running_average(&average_percent_time_unreachable_known, percent_time_unreachable_known, current_subject);
3553 get_running_average(&average_percent_time_indeterminate, percent_time_indeterminate, current_subject);
3554 }
3555
3556 /* average statistics */
3557 if(odd) {
3558 odd = 0;
3559 bgclass = "Odd";
3560 }
3561 else {
3562 odd = 1;
3563 bgclass = "Even";
3564 }
3565 printf("<tr CLASS='data%s'><td CLASS='data%s'>Average</td><td CLASS='hostUP'>%2.3f%% (%2.3f%%)</td><td CLASS='hostDOWN'>%2.3f%% (%2.3f%%)</td><td CLASS='hostUNREACHABLE'>%2.3f%% (%2.3f%%)</td><td class='data%s'>%2.3f%%</td></tr>", bgclass, bgclass, average_percent_time_up, average_percent_time_up_known, average_percent_time_down, average_percent_time_down_known, average_percent_time_unreachable, average_percent_time_unreachable_known, bgclass, average_percent_time_indeterminate);
3566
3567 printf("</table>\n");
3568 printf("</DIV>\n");
3569
3570 return;
3571 }
3572
3573
3574 /* display servicegroup availability */
display_servicegroup_availability(void)3575 void display_servicegroup_availability(void) {
3576 servicegroup *temp_servicegroup;
3577
3578 /* display data for a specific servicegroup */
3579 if(show_all_servicegroups == FALSE) {
3580 temp_servicegroup = find_servicegroup(servicegroup_name);
3581 display_specific_servicegroup_availability(temp_servicegroup);
3582 }
3583
3584 /* display data for all servicegroups */
3585 else {
3586 for(temp_servicegroup = servicegroup_list; temp_servicegroup != NULL; temp_servicegroup = temp_servicegroup->next)
3587 display_specific_servicegroup_availability(temp_servicegroup);
3588 }
3589
3590 return;
3591 }
3592
3593
3594
3595 /* display availability for a specific servicegroup */
display_specific_servicegroup_availability(servicegroup * sg)3596 void display_specific_servicegroup_availability(servicegroup *sg) {
3597 unsigned long total_time;
3598 unsigned long time_determinate;
3599 unsigned long time_indeterminate;
3600 avail_subject *temp_subject;
3601 double percent_time_up = 0.0;
3602 double percent_time_down = 0.0;
3603 double percent_time_unreachable = 0.0;
3604 double percent_time_up_known = 0.0;
3605 double percent_time_down_known = 0.0;
3606 double percent_time_unreachable_known = 0.0;
3607 double percent_time_indeterminate = 0.0;
3608 double percent_time_ok = 0.0;
3609 double percent_time_warning = 0.0;
3610 double percent_time_unknown = 0.0;
3611 double percent_time_critical = 0.0;
3612 double percent_time_ok_known = 0.0;
3613 double percent_time_warning_known = 0.0;
3614 double percent_time_unknown_known = 0.0;
3615 double percent_time_critical_known = 0.0;
3616
3617 double average_percent_time_up = 0.0;
3618 double average_percent_time_up_known = 0.0;
3619 double average_percent_time_down = 0.0;
3620 double average_percent_time_down_known = 0.0;
3621 double average_percent_time_unreachable = 0.0;
3622 double average_percent_time_unreachable_known = 0.0;
3623 double average_percent_time_ok = 0.0;
3624 double average_percent_time_ok_known = 0.0;
3625 double average_percent_time_unknown = 0.0;
3626 double average_percent_time_unknown_known = 0.0;
3627 double average_percent_time_warning = 0.0;
3628 double average_percent_time_warning_known = 0.0;
3629 double average_percent_time_critical = 0.0;
3630 double average_percent_time_critical_known = 0.0;
3631 double average_percent_time_indeterminate = 0.0;
3632
3633 int current_subject = 0;
3634
3635 char *bgclass = "";
3636 int odd = 1;
3637 host *temp_host;
3638 service *temp_service;
3639 char last_host[MAX_INPUT_BUFFER];
3640
3641 if(sg == NULL)
3642 return;
3643
3644 /* the user isn't authorized to view this servicegroup */
3645 if(is_authorized_for_servicegroup(sg, ¤t_authdata) == FALSE)
3646 return;
3647
3648 /* calculate total time during period based on timeperiod used for reporting */
3649 total_time = calculate_total_time(t1, t2);
3650
3651 printf("<BR><BR>\n");
3652 printf("<DIV ALIGN=CENTER CLASS='dataTitle'>Servicegroup '%s' Host State Breakdowns:</DIV>\n", sg->group_name);
3653
3654 printf("<DIV ALIGN=CENTER>\n");
3655 printf("<TABLE BORDER=0 CLASS='data'>\n");
3656 printf("<TR><TH CLASS='data'>Host</TH><TH CLASS='data'>%% Time Up</TH><TH CLASS='data'>%% Time Down</TH><TH CLASS='data'>%% Time Unreachable</TH><TH CLASS='data'>%% Time Undetermined</TH></TR>\n");
3657
3658 for(temp_subject = subject_list; temp_subject != NULL; temp_subject = temp_subject->next) {
3659
3660 if(temp_subject->type != HOST_SUBJECT)
3661 continue;
3662
3663 temp_host = find_host(temp_subject->host_name);
3664 if(temp_host == NULL)
3665 continue;
3666
3667 if(is_host_member_of_servicegroup(sg, temp_host) == FALSE)
3668 continue;
3669
3670 current_subject++;
3671
3672 /* reset variables */
3673 percent_time_up = 0.0;
3674 percent_time_down = 0.0;
3675 percent_time_unreachable = 0.0;
3676 percent_time_indeterminate = 0.0;
3677 percent_time_up_known = 0.0;
3678 percent_time_down_known = 0.0;
3679 percent_time_unreachable_known = 0.0;
3680
3681 time_determinate = temp_subject->time_up + temp_subject->time_down + temp_subject->time_unreachable;
3682 time_indeterminate = total_time - time_determinate;
3683
3684 if(total_time > 0) {
3685 percent_time_up = (double)(((double)temp_subject->time_up * 100.0) / (double)total_time);
3686 percent_time_down = (double)(((double)temp_subject->time_down * 100.0) / (double)total_time);
3687 percent_time_unreachable = (double)(((double)temp_subject->time_unreachable * 100.0) / (double)total_time);
3688 percent_time_indeterminate = (double)(((double)time_indeterminate * 100.0) / (double)total_time);
3689 if(time_determinate > 0) {
3690 percent_time_up_known = (double)(((double)temp_subject->time_up * 100.0) / (double)time_determinate);
3691 percent_time_down_known = (double)(((double)temp_subject->time_down * 100.0) / (double)time_determinate);
3692 percent_time_unreachable_known = (double)(((double)temp_subject->time_unreachable * 100.0) / (double)time_determinate);
3693 }
3694 }
3695
3696 if(odd) {
3697 odd = 0;
3698 bgclass = "Odd";
3699 }
3700 else {
3701 odd = 1;
3702 bgclass = "Even";
3703 }
3704
3705 printf("<tr CLASS='data%s'><td CLASS='data%s'>", bgclass, bgclass);
3706 host_report_url(temp_subject->host_name, temp_subject->host_name);
3707 printf("</td><td CLASS='hostUP'>%2.3f%% (%2.3f%%)</td><td CLASS='hostDOWN'>%2.3f%% (%2.3f%%)</td><td CLASS='hostUNREACHABLE'>%2.3f%% (%2.3f%%)</td><td class='data%s'>%2.3f%%</td></tr>\n", percent_time_up, percent_time_up_known, percent_time_down, percent_time_down_known, percent_time_unreachable, percent_time_unreachable_known, bgclass, percent_time_indeterminate);
3708
3709 get_running_average(&average_percent_time_up, percent_time_up, current_subject);
3710 get_running_average(&average_percent_time_up_known, percent_time_up_known, current_subject);
3711 get_running_average(&average_percent_time_down, percent_time_down, current_subject);
3712 get_running_average(&average_percent_time_down_known, percent_time_down_known, current_subject);
3713 get_running_average(&average_percent_time_unreachable, percent_time_unreachable, current_subject);
3714 get_running_average(&average_percent_time_unreachable_known, percent_time_unreachable_known, current_subject);
3715 get_running_average(&average_percent_time_indeterminate, percent_time_indeterminate, current_subject);
3716 }
3717
3718 /* average statistics */
3719 if(odd) {
3720 odd = 0;
3721 bgclass = "Odd";
3722 }
3723 else {
3724 odd = 1;
3725 bgclass = "Even";
3726 }
3727 printf("<tr CLASS='data%s'><td CLASS='data%s'>Average</td><td CLASS='hostUP'>%2.3f%% (%2.3f%%)</td><td CLASS='hostDOWN'>%2.3f%% (%2.3f%%)</td><td CLASS='hostUNREACHABLE'>%2.3f%% (%2.3f%%)</td><td class='data%s'>%2.3f%%</td></tr>", bgclass, bgclass, average_percent_time_up, average_percent_time_up_known, average_percent_time_down, average_percent_time_down_known, average_percent_time_unreachable, average_percent_time_unreachable_known, bgclass, average_percent_time_indeterminate);
3728
3729 printf("</table>\n");
3730 printf("</DIV>\n");
3731
3732 printf("<BR>\n");
3733 printf("<DIV ALIGN=CENTER CLASS='dataTitle'>Servicegroup '%s' Service State Breakdowns:</DIV>\n", sg->group_name);
3734
3735 printf("<DIV ALIGN=CENTER>\n");
3736 printf("<TABLE BORDER=0 CLASS='data'>\n");
3737 printf("<TR><TH CLASS='data'>Host</TH><TH CLASS='data'>Service</TH><TH CLASS='data'>%% Time OK</TH><TH CLASS='data'>%% Time Warning</TH><TH CLASS='data'>%% Time Unknown</TH><TH CLASS='data'>%% Time Critical</TH><TH CLASS='data'>%% Time Undetermined</TH></TR>\n");
3738
3739 current_subject = 0;
3740 average_percent_time_indeterminate = 0.0;
3741
3742 for(temp_subject = subject_list; temp_subject != NULL; temp_subject = temp_subject->next) {
3743
3744 if(temp_subject->type != SERVICE_SUBJECT)
3745 continue;
3746
3747 temp_service = find_service(temp_subject->host_name, temp_subject->service_description);
3748 if(temp_service == NULL)
3749 continue;
3750
3751 if(is_service_member_of_servicegroup(sg, temp_service) == FALSE)
3752 continue;
3753
3754 current_subject++;
3755
3756 time_determinate = temp_subject->time_ok + temp_subject->time_warning + temp_subject->time_unknown + temp_subject->time_critical;
3757 time_indeterminate = total_time - time_determinate;
3758
3759 /* adjust indeterminate time due to insufficient data (not all was caught) */
3760 temp_subject->time_indeterminate_nodata = time_indeterminate - temp_subject->time_indeterminate_notrunning;
3761
3762 /* initialize values */
3763 percent_time_ok = 0.0;
3764 percent_time_warning = 0.0;
3765 percent_time_unknown = 0.0;
3766 percent_time_critical = 0.0;
3767 percent_time_indeterminate = 0.0;
3768 percent_time_ok_known = 0.0;
3769 percent_time_warning_known = 0.0;
3770 percent_time_unknown_known = 0.0;
3771 percent_time_critical_known = 0.0;
3772
3773 if(total_time > 0) {
3774 percent_time_ok = (double)(((double)temp_subject->time_ok * 100.0) / (double)total_time);
3775 percent_time_warning = (double)(((double)temp_subject->time_warning * 100.0) / (double)total_time);
3776 percent_time_unknown = (double)(((double)temp_subject->time_unknown * 100.0) / (double)total_time);
3777 percent_time_critical = (double)(((double)temp_subject->time_critical * 100.0) / (double)total_time);
3778 percent_time_indeterminate = (double)(((double)time_indeterminate * 100.0) / (double)total_time);
3779 if(time_determinate > 0) {
3780 percent_time_ok_known = (double)(((double)temp_subject->time_ok * 100.0) / (double)time_determinate);
3781 percent_time_warning_known = (double)(((double)temp_subject->time_warning * 100.0) / (double)time_determinate);
3782 percent_time_unknown_known = (double)(((double)temp_subject->time_unknown * 100.0) / (double)time_determinate);
3783 percent_time_critical_known = (double)(((double)temp_subject->time_critical * 100.0) / (double)time_determinate);
3784 }
3785 }
3786
3787 if(odd) {
3788 odd = 0;
3789 bgclass = "Odd";
3790 }
3791 else {
3792 odd = 1;
3793 bgclass = "Even";
3794 }
3795
3796 printf("<tr CLASS='data%s'><td CLASS='data%s'>", bgclass, bgclass);
3797 if(strcmp(temp_subject->host_name, last_host))
3798 host_report_url(temp_subject->host_name, temp_subject->host_name);
3799 printf("</td><td CLASS='data%s'>", bgclass);
3800 service_report_url(temp_subject->host_name, temp_subject->service_description, temp_subject->service_description);
3801 printf("</td><td CLASS='serviceOK'>%2.3f%% (%2.3f%%)</td><td CLASS='serviceWARNING'>%2.3f%% (%2.3f%%)</td><td CLASS='serviceUNKNOWN'>%2.3f%% (%2.3f%%)</td><td class='serviceCRITICAL'>%2.3f%% (%2.3f%%)</td><td class='data%s'>%2.3f%%</td></tr>\n", percent_time_ok, percent_time_ok_known, percent_time_warning, percent_time_warning_known, percent_time_unknown, percent_time_unknown_known, percent_time_critical, percent_time_critical_known, bgclass, percent_time_indeterminate);
3802
3803 strncpy(last_host, temp_subject->host_name, sizeof(last_host) - 1);
3804 last_host[sizeof(last_host) - 1] = '\x0';
3805
3806 get_running_average(&average_percent_time_ok, percent_time_ok, current_subject);
3807 get_running_average(&average_percent_time_ok_known, percent_time_ok_known, current_subject);
3808 get_running_average(&average_percent_time_unknown, percent_time_unknown, current_subject);
3809 get_running_average(&average_percent_time_unknown_known, percent_time_unknown_known, current_subject);
3810 get_running_average(&average_percent_time_warning, percent_time_warning, current_subject);
3811 get_running_average(&average_percent_time_warning_known, percent_time_warning_known, current_subject);
3812 get_running_average(&average_percent_time_critical, percent_time_critical, current_subject);
3813 get_running_average(&average_percent_time_critical_known, percent_time_critical_known, current_subject);
3814 get_running_average(&average_percent_time_indeterminate, percent_time_indeterminate, current_subject);
3815 }
3816
3817 /* display average stats */
3818 if(odd) {
3819 odd = 0;
3820 bgclass = "Odd";
3821 }
3822 else {
3823 odd = 1;
3824 bgclass = "Even";
3825 }
3826
3827 printf("<tr CLASS='data%s'><td CLASS='data%s' colspan='2'>Average</td><td CLASS='serviceOK'>%2.3f%% (%2.3f%%)</td><td CLASS='serviceWARNING'>%2.3f%% (%2.3f%%)</td><td CLASS='serviceUNKNOWN'>%2.3f%% (%2.3f%%)</td><td class='serviceCRITICAL'>%2.3f%% (%2.3f%%)</td><td class='data%s'>%2.3f%%</td></tr>\n", bgclass, bgclass, average_percent_time_ok, average_percent_time_ok_known, average_percent_time_warning, average_percent_time_warning_known, average_percent_time_unknown, average_percent_time_unknown_known, average_percent_time_critical, average_percent_time_critical_known, bgclass, average_percent_time_indeterminate);
3828
3829 printf("</table>\n");
3830 printf("</DIV>\n");
3831
3832 return;
3833 }
3834
3835
3836 /* display host availability */
display_host_availability(void)3837 void display_host_availability(void) {
3838 unsigned long total_time;
3839 unsigned long time_determinate;
3840 unsigned long time_indeterminate;
3841 avail_subject *temp_subject;
3842 host *temp_host;
3843 service *temp_service;
3844 int days, hours, minutes, seconds;
3845 char time_indeterminate_string[48];
3846 char time_determinate_string[48];
3847 char total_time_string[48];
3848 double percent_time_ok = 0.0;
3849 double percent_time_warning = 0.0;
3850 double percent_time_unknown = 0.0;
3851 double percent_time_critical = 0.0;
3852 double percent_time_indeterminate = 0.0;
3853 double percent_time_ok_known = 0.0;
3854 double percent_time_warning_known = 0.0;
3855 double percent_time_unknown_known = 0.0;
3856 double percent_time_critical_known = 0.0;
3857 char time_up_string[48];
3858 char time_down_string[48];
3859 char time_unreachable_string[48];
3860 double percent_time_up = 0.0;
3861 double percent_time_down = 0.0;
3862 double percent_time_unreachable = 0.0;
3863 double percent_time_up_known = 0.0;
3864 double percent_time_down_known = 0.0;
3865 double percent_time_unreachable_known = 0.0;
3866
3867 double percent_time_up_scheduled = 0.0;
3868 double percent_time_up_unscheduled = 0.0;
3869 double percent_time_down_scheduled = 0.0;
3870 double percent_time_down_unscheduled = 0.0;
3871 double percent_time_unreachable_scheduled = 0.0;
3872 double percent_time_unreachable_unscheduled = 0.0;
3873 double percent_time_up_scheduled_known = 0.0;
3874 double percent_time_up_unscheduled_known = 0.0;
3875 double percent_time_down_scheduled_known = 0.0;
3876 double percent_time_down_unscheduled_known = 0.0;
3877 double percent_time_unreachable_scheduled_known = 0.0;
3878 double percent_time_unreachable_unscheduled_known = 0.0;
3879 char time_up_scheduled_string[48];
3880 char time_up_unscheduled_string[48];
3881 char time_down_scheduled_string[48];
3882 char time_down_unscheduled_string[48];
3883 char time_unreachable_scheduled_string[48];
3884 char time_unreachable_unscheduled_string[48];
3885
3886 char time_indeterminate_scheduled_string[48];
3887 char time_indeterminate_unscheduled_string[48];
3888 double percent_time_indeterminate_scheduled = 0.0;
3889 double percent_time_indeterminate_unscheduled = 0.0;
3890 char time_indeterminate_notrunning_string[48];
3891 char time_indeterminate_nodata_string[48];
3892 double percent_time_indeterminate_notrunning = 0.0;
3893 double percent_time_indeterminate_nodata = 0.0;
3894
3895 double average_percent_time_up = 0.0;
3896 double average_percent_time_up_known = 0.0;
3897 double average_percent_time_down = 0.0;
3898 double average_percent_time_down_known = 0.0;
3899 double average_percent_time_unreachable = 0.0;
3900 double average_percent_time_unreachable_known = 0.0;
3901 double average_percent_time_indeterminate = 0.0;
3902
3903 double average_percent_time_ok = 0.0;
3904 double average_percent_time_ok_known = 0.0;
3905 double average_percent_time_unknown = 0.0;
3906 double average_percent_time_unknown_known = 0.0;
3907 double average_percent_time_warning = 0.0;
3908 double average_percent_time_warning_known = 0.0;
3909 double average_percent_time_critical = 0.0;
3910 double average_percent_time_critical_known = 0.0;
3911
3912 int current_subject = 0;
3913
3914 char *bgclass = "";
3915 int odd = 1;
3916
3917 /* calculate total time during period based on timeperiod used for reporting */
3918 total_time = calculate_total_time(t1, t2);
3919
3920 #ifdef DEBUG
3921 printf("Total time: '%ld' seconds<br>\n", total_time);
3922 #endif
3923
3924 /* show data for a specific host */
3925 if(show_all_hosts == FALSE) {
3926
3927 temp_subject = find_subject(HOST_SUBJECT, host_name, NULL);
3928 if(temp_subject == NULL)
3929 return;
3930
3931 temp_host = find_host(temp_subject->host_name);
3932 if(temp_host == NULL)
3933 return;
3934
3935 /* the user isn't authorized to view this host */
3936 if(is_authorized_for_host(temp_host, ¤t_authdata) == FALSE)
3937 return;
3938
3939 time_determinate = temp_subject->time_up + temp_subject->time_down + temp_subject->time_unreachable;
3940 time_indeterminate = total_time - time_determinate;
3941
3942 /* adjust indeterminate time due to insufficient data (not all was caught) */
3943 temp_subject->time_indeterminate_nodata = time_indeterminate - temp_subject->time_indeterminate_notrunning;
3944
3945 /* up times */
3946 get_time_breakdown(temp_subject->time_up, &days, &hours, &minutes, &seconds);
3947 snprintf(time_up_string, sizeof(time_up_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds);
3948 get_time_breakdown(temp_subject->scheduled_time_up, &days, &hours, &minutes, &seconds);
3949 snprintf(time_up_scheduled_string, sizeof(time_up_scheduled_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds);
3950 get_time_breakdown(temp_subject->time_up - temp_subject->scheduled_time_up, &days, &hours, &minutes, &seconds);
3951 snprintf(time_up_unscheduled_string, sizeof(time_up_unscheduled_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds);
3952
3953 /* down times */
3954 get_time_breakdown(temp_subject->time_down, &days, &hours, &minutes, &seconds);
3955 snprintf(time_down_string, sizeof(time_down_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds);
3956 get_time_breakdown(temp_subject->scheduled_time_down, &days, &hours, &minutes, &seconds);
3957 snprintf(time_down_scheduled_string, sizeof(time_down_scheduled_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds);
3958 get_time_breakdown(temp_subject->time_down - temp_subject->scheduled_time_down, &days, &hours, &minutes, &seconds);
3959 snprintf(time_down_unscheduled_string, sizeof(time_down_unscheduled_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds);
3960
3961 /* unreachable times */
3962 get_time_breakdown(temp_subject->time_unreachable, &days, &hours, &minutes, &seconds);
3963 snprintf(time_unreachable_string, sizeof(time_unreachable_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds);
3964 get_time_breakdown(temp_subject->scheduled_time_unreachable, &days, &hours, &minutes, &seconds);
3965 snprintf(time_unreachable_scheduled_string, sizeof(time_unreachable_scheduled_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds);
3966 get_time_breakdown(temp_subject->time_unreachable - temp_subject->scheduled_time_unreachable, &days, &hours, &minutes, &seconds);
3967 snprintf(time_unreachable_unscheduled_string, sizeof(time_unreachable_unscheduled_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds);
3968
3969 /* indeterminate times */
3970 get_time_breakdown(time_indeterminate, &days, &hours, &minutes, &seconds);
3971 snprintf(time_indeterminate_string, sizeof(time_indeterminate_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds);
3972 get_time_breakdown(temp_subject->scheduled_time_indeterminate, &days, &hours, &minutes, &seconds);
3973 snprintf(time_indeterminate_scheduled_string, sizeof(time_indeterminate_scheduled_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds);
3974 get_time_breakdown(time_indeterminate - temp_subject->scheduled_time_indeterminate, &days, &hours, &minutes, &seconds);
3975 snprintf(time_indeterminate_unscheduled_string, sizeof(time_indeterminate_unscheduled_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds);
3976 get_time_breakdown(temp_subject->time_indeterminate_notrunning, &days, &hours, &minutes, &seconds);
3977 snprintf(time_indeterminate_notrunning_string, sizeof(time_indeterminate_notrunning_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds);
3978 get_time_breakdown(temp_subject->time_indeterminate_nodata, &days, &hours, &minutes, &seconds);
3979 snprintf(time_indeterminate_nodata_string, sizeof(time_indeterminate_nodata_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds);
3980
3981 get_time_breakdown(time_determinate, &days, &hours, &minutes, &seconds);
3982 snprintf(time_determinate_string, sizeof(time_determinate_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds);
3983
3984 get_time_breakdown(total_time, &days, &hours, &minutes, &seconds);
3985 snprintf(total_time_string, sizeof(total_time_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds);
3986
3987 if(total_time > 0) {
3988 percent_time_up = (double)(((double)temp_subject->time_up * 100.0) / (double)total_time);
3989 percent_time_up_scheduled = (double)(((double)temp_subject->scheduled_time_up * 100.0) / (double)total_time);
3990 percent_time_up_unscheduled = percent_time_up - percent_time_up_scheduled;
3991 percent_time_down = (double)(((double)temp_subject->time_down * 100.0) / (double)total_time);
3992 percent_time_down_scheduled = (double)(((double)temp_subject->scheduled_time_down * 100.0) / (double)total_time);
3993 percent_time_down_unscheduled = percent_time_down - percent_time_down_scheduled;
3994 percent_time_unreachable = (double)(((double)temp_subject->time_unreachable * 100.0) / (double)total_time);
3995 percent_time_unreachable_scheduled = (double)(((double)temp_subject->scheduled_time_unreachable * 100.0) / (double)total_time);
3996 percent_time_unreachable_unscheduled = percent_time_unreachable - percent_time_unreachable_scheduled;
3997 percent_time_indeterminate = (double)(((double)time_indeterminate * 100.0) / (double)total_time);
3998 percent_time_indeterminate_scheduled = (double)(((double)temp_subject->scheduled_time_indeterminate * 100.0) / (double)total_time);
3999 percent_time_indeterminate_unscheduled = percent_time_indeterminate - percent_time_indeterminate_scheduled;
4000 percent_time_indeterminate_notrunning = (double)(((double)temp_subject->time_indeterminate_notrunning * 100.0) / (double)total_time);
4001 percent_time_indeterminate_nodata = (double)(((double)temp_subject->time_indeterminate_nodata * 100.0) / (double)total_time);
4002 if(time_determinate > 0) {
4003 percent_time_up_known = (double)(((double)temp_subject->time_up * 100.0) / (double)time_determinate);
4004 percent_time_up_scheduled_known = (double)(((double)temp_subject->scheduled_time_up * 100.0) / (double)time_determinate);
4005 percent_time_up_unscheduled_known = percent_time_up_known - percent_time_up_scheduled_known;
4006 percent_time_down_known = (double)(((double)temp_subject->time_down * 100.0) / (double)time_determinate);
4007 percent_time_down_scheduled_known = (double)(((double)temp_subject->scheduled_time_down * 100.0) / (double)time_determinate);
4008 percent_time_down_unscheduled_known = percent_time_down_known - percent_time_down_scheduled_known;
4009 percent_time_unreachable_known = (double)(((double)temp_subject->time_unreachable * 100.0) / (double)time_determinate);
4010 percent_time_unreachable_scheduled_known = (double)(((double)temp_subject->scheduled_time_unreachable * 100.0) / (double)time_determinate);
4011 percent_time_unreachable_unscheduled_known = percent_time_unreachable_known - percent_time_unreachable_scheduled_known;
4012 }
4013 }
4014
4015 printf("<DIV ALIGN=CENTER CLASS='dataTitle'>Host State Breakdowns:</DIV>\n");
4016
4017 #ifdef USE_TRENDS
4018 printf("<p align='center'>\n");
4019 printf("<a href='%s?host=%s", TRENDS_CGI, url_encode(host_name));
4020 printf("&t1=%lu&t2=%lu&includesoftstates=%s&assumestateretention=%s&assumeinitialstates=%s&assumestatesduringnotrunning=%s&initialassumedhoststate=%d&backtrack=%d'>", t1, t2, (include_soft_states == TRUE) ? "yes" : "no", (assume_state_retention == TRUE) ? "yes" : "no", (assume_initial_states == TRUE) ? "yes" : "no", (assume_states_during_notrunning == TRUE) ? "yes" : "no", initial_assumed_host_state, backtrack_archives);
4021 printf("<img src='%s?createimage&smallimage&host=%s", TRENDS_CGI, url_encode(host_name));
4022 printf("&t1=%lu&t2=%lu&includesoftstates=%s&assumestateretention=%s&assumeinitialstates=%s&assumestatesduringnotrunning=%s&initialassumedhoststate=%d&backtrack=%d' border=1 alt='Host State Trends' title='Host State Trends' width='500' height='20'>", t1, t2, (include_soft_states == TRUE) ? "yes" : "no", (assume_state_retention == TRUE) ? "yes" : "no", (assume_initial_states == TRUE) ? "yes" : "no", (assume_states_during_notrunning == TRUE) ? "yes" : "no", initial_assumed_host_state, backtrack_archives);
4023 printf("</a><br>\n");
4024 printf("</p>\n");
4025 #endif
4026 printf("<DIV ALIGN=CENTER>\n");
4027 printf("<TABLE BORDER=0 CLASS='data'>\n");
4028 printf("<TR><TH CLASS='data'>State</TH><TH CLASS='data'>Type / Reason</TH><TH CLASS='data'>Time</TH><TH CLASS='data'>%% Total Time</TH><TH CLASS='data'>%% Known Time</TH></TR>\n");
4029
4030 /* up times */
4031 printf("<tr CLASS='dataEven'><td CLASS='hostUP' rowspan=3>UP</td>");
4032 printf("<td CLASS='dataEven'>Unscheduled</td><td CLASS='dataEven'>%s</td><td CLASS='dataEven'>%2.3f%%</td><td class='dataEven'>%2.3f%%</td></tr>\n", time_up_unscheduled_string, percent_time_up, percent_time_up_known);
4033 printf("<tr CLASS='dataEven'><td CLASS='dataEven'>Scheduled</td><td CLASS='dataEven'>%s</td><td CLASS='dataEven'>%2.3f%%</td><td class='dataEven'>%2.3f%%</td></tr>\n", time_up_scheduled_string, percent_time_up_scheduled, percent_time_up_scheduled_known);
4034 printf("<tr CLASS='hostUP'><td CLASS='hostUP'>Total</td><td CLASS='hostUP'>%s</td><td CLASS='hostUP'>%2.3f%%</td><td class='hostUP'>%2.3f%%</td></tr>\n", time_up_string, percent_time_up, percent_time_up_known);
4035
4036 /* down times */
4037 printf("<tr CLASS='dataOdd'><td CLASS='hostDOWN' rowspan=3>DOWN</td>");
4038 printf("<td CLASS='dataOdd'>Unscheduled</td><td CLASS='dataOdd'>%s</td><td CLASS='dataOdd'>%2.3f%%</td><td class='dataOdd'>%2.3f%%</td></tr>\n", time_down_unscheduled_string, percent_time_down_unscheduled, percent_time_down_unscheduled_known);
4039 printf("<tr CLASS='dataOdd'><td CLASS='dataOdd'>Scheduled</td><td CLASS='dataOdd'>%s</td><td CLASS='dataOdd'>%2.3f%%</td><td class='dataOdd'>%2.3f%%</td></tr>\n", time_down_scheduled_string, percent_time_down_scheduled, percent_time_down_scheduled_known);
4040 printf("<tr CLASS='hostDOWN'><td CLASS='hostDOWN'>Total</td><td CLASS='hostDOWN'>%s</td><td CLASS='hostDOWN'>%2.3f%%</td><td class='hostDOWN'>%2.3f%%</td></tr>\n", time_down_string, percent_time_down, percent_time_down_known);
4041
4042 /* unreachable times */
4043 printf("<tr CLASS='dataEven'><td CLASS='hostUNREACHABLE' rowspan=3>UNREACHABLE</td>");
4044 printf("<td CLASS='dataEven'>Unscheduled</td><td CLASS='dataEven'>%s</td><td CLASS='dataEven'>%2.3f%%</td><td class='dataEven'>%2.3f%%</td></tr>\n", time_unreachable_unscheduled_string, percent_time_unreachable, percent_time_unreachable_known);
4045 printf("<tr CLASS='dataEven'><td CLASS='dataEven'>Scheduled</td><td CLASS='dataEven'>%s</td><td CLASS='dataEven'>%2.3f%%</td><td class='dataEven'>%2.3f%%</td></tr>\n", time_unreachable_scheduled_string, percent_time_unreachable_scheduled, percent_time_unreachable_scheduled_known);
4046 printf("<tr CLASS='hostUNREACHABLE'><td CLASS='hostUNREACHABLE'>Total</td><td CLASS='hostUNREACHABLE'>%s</td><td CLASS='hostUNREACHABLE'>%2.3f%%</td><td class='hostUNREACHABLE'>%2.3f%%</td></tr>\n", time_unreachable_string, percent_time_unreachable, percent_time_unreachable_known);
4047
4048 /* indeterminate times */
4049 printf("<tr CLASS='dataOdd'><td CLASS='dataOdd' rowspan=3>Undetermined</td>");
4050 printf("<td CLASS='dataOdd'>Nagios Not Running</td><td CLASS='dataOdd'>%s</td><td CLASS='dataOdd'>%2.3f%%</td><td CLASS='dataOdd'></td></tr>\n", time_indeterminate_notrunning_string, percent_time_indeterminate_notrunning);
4051 printf("<tr CLASS='dataOdd'><td CLASS='dataOdd'>Insufficient Data</td><td CLASS='dataOdd'>%s</td><td CLASS='dataOdd'>%2.3f%%</td><td CLASS='dataOdd'></td></tr>\n", time_indeterminate_nodata_string, percent_time_indeterminate_nodata);
4052 printf("<tr CLASS='dataOdd'><td CLASS='dataOdd'>Total</td><td CLASS='dataOdd'>%s</td><td CLASS='dataOdd'>%2.3f%%</td><td CLASS='dataOdd'></td></tr>\n", time_indeterminate_string, percent_time_indeterminate);
4053
4054 printf("<tr><td colspan=3></td></tr>\n");
4055
4056 printf("<tr CLASS='dataEven'><td CLASS='dataEven'>All</td><td class='dataEven'>Total</td><td CLASS='dataEven'>%s</td><td CLASS='dataEven'>100.000%%</td><td CLASS='dataEven'>100.000%%</td></tr>\n", total_time_string);
4057 printf("</table>\n");
4058 printf("</DIV>\n");
4059
4060
4061
4062 /* display state breakdowns for all services on this host */
4063
4064 printf("<BR><BR>\n");
4065 printf("<DIV ALIGN=CENTER CLASS='dataTitle'>State Breakdowns For Host Services:</DIV>\n");
4066
4067 printf("<DIV ALIGN=CENTER>\n");
4068 printf("<TABLE BORDER=0 CLASS='data'>\n");
4069 printf("<TR><TH CLASS='data'>Service</TH><TH CLASS='data'>%% Time OK</TH><TH CLASS='data'>%% Time Warning</TH><TH CLASS='data'>%% Time Unknown</TH><TH CLASS='data'>%% Time Critical</TH><TH CLASS='data'>%% Time Undetermined</TH></TR>\n");
4070
4071 for(temp_subject = subject_list; temp_subject != NULL; temp_subject = temp_subject->next) {
4072
4073 if(temp_subject->type != SERVICE_SUBJECT)
4074 continue;
4075
4076 temp_service = find_service(temp_subject->host_name, temp_subject->service_description);
4077 if(temp_service == NULL)
4078 continue;
4079
4080 /* the user isn't authorized to view this service */
4081 if(is_authorized_for_service(temp_service, ¤t_authdata) == FALSE)
4082 continue;
4083
4084 current_subject++;
4085
4086 if(odd) {
4087 odd = 0;
4088 bgclass = "Odd";
4089 }
4090 else {
4091 odd = 1;
4092 bgclass = "Even";
4093 }
4094
4095 /* reset variables */
4096 percent_time_ok = 0.0;
4097 percent_time_warning = 0.0;
4098 percent_time_unknown = 0.0;
4099 percent_time_critical = 0.0;
4100 percent_time_indeterminate = 0.0;
4101 percent_time_ok_known = 0.0;
4102 percent_time_warning_known = 0.0;
4103 percent_time_unknown_known = 0.0;
4104 percent_time_critical_known = 0.0;
4105
4106 time_determinate = temp_subject->time_ok + temp_subject->time_warning + temp_subject->time_unknown + temp_subject->time_critical;
4107 time_indeterminate = total_time - time_determinate;
4108
4109 if(total_time > 0) {
4110 percent_time_ok = (double)(((double)temp_subject->time_ok * 100.0) / (double)total_time);
4111 percent_time_warning = (double)(((double)temp_subject->time_warning * 100.0) / (double)total_time);
4112 percent_time_unknown = (double)(((double)temp_subject->time_unknown * 100.0) / (double)total_time);
4113 percent_time_critical = (double)(((double)temp_subject->time_critical * 100.0) / (double)total_time);
4114 percent_time_indeterminate = (double)(((double)time_indeterminate * 100.0) / (double)total_time);
4115 if(time_determinate > 0) {
4116 percent_time_ok_known = (double)(((double)temp_subject->time_ok * 100.0) / (double)time_determinate);
4117 percent_time_warning_known = (double)(((double)temp_subject->time_warning * 100.0) / (double)time_determinate);
4118 percent_time_unknown_known = (double)(((double)temp_subject->time_unknown * 100.0) / (double)time_determinate);
4119 percent_time_critical_known = (double)(((double)temp_subject->time_critical * 100.0) / (double)time_determinate);
4120 }
4121 }
4122
4123 printf("<tr CLASS='data%s'><td CLASS='data%s'>", bgclass, bgclass);
4124 service_report_url(temp_subject->host_name, temp_subject->service_description, temp_subject->service_description);
4125 printf("</td><td CLASS='serviceOK'>%2.3f%% (%2.3f%%)</td><td CLASS='serviceWARNING'>%2.3f%% (%2.3f%%)</td><td CLASS='serviceUNKNOWN'>%2.3f%% (%2.3f%%)</td><td class='serviceCRITICAL'>%2.3f%% (%2.3f%%)</td><td class='data%s'>%2.3f%%</td></tr>\n", percent_time_ok, percent_time_ok_known, percent_time_warning, percent_time_warning_known, percent_time_unknown, percent_time_unknown_known, percent_time_critical, percent_time_critical_known, bgclass, percent_time_indeterminate);
4126
4127 get_running_average(&average_percent_time_ok, percent_time_ok, current_subject);
4128 get_running_average(&average_percent_time_ok_known, percent_time_ok_known, current_subject);
4129 get_running_average(&average_percent_time_unknown, percent_time_unknown, current_subject);
4130 get_running_average(&average_percent_time_unknown_known, percent_time_unknown_known, current_subject);
4131 get_running_average(&average_percent_time_warning, percent_time_warning, current_subject);
4132 get_running_average(&average_percent_time_warning_known, percent_time_warning_known, current_subject);
4133 get_running_average(&average_percent_time_critical, percent_time_critical, current_subject);
4134 get_running_average(&average_percent_time_critical_known, percent_time_critical_known, current_subject);
4135 get_running_average(&average_percent_time_indeterminate, percent_time_indeterminate, current_subject);
4136 }
4137
4138 /* display average stats */
4139 if(odd) {
4140 odd = 0;
4141 bgclass = "Odd";
4142 }
4143 else {
4144 odd = 1;
4145 bgclass = "Even";
4146 }
4147
4148 printf("<tr CLASS='data%s'><td CLASS='data%s'>Average</td><td CLASS='serviceOK'>%2.3f%% (%2.3f%%)</td><td CLASS='serviceWARNING'>%2.3f%% (%2.3f%%)</td><td CLASS='serviceUNKNOWN'>%2.3f%% (%2.3f%%)</td><td class='serviceCRITICAL'>%2.3f%% (%2.3f%%)</td><td class='data%s'>%2.3f%%</td></tr>\n", bgclass, bgclass, average_percent_time_ok, average_percent_time_ok_known, average_percent_time_warning, average_percent_time_warning_known, average_percent_time_unknown, average_percent_time_unknown_known, average_percent_time_critical, average_percent_time_critical_known, bgclass, average_percent_time_indeterminate);
4149
4150 printf("</table>\n");
4151 printf("</DIV>\n");
4152
4153
4154 /* write log entries for the host */
4155 temp_subject = find_subject(HOST_SUBJECT, host_name, NULL);
4156 write_log_entries(temp_subject);
4157 }
4158
4159
4160 /* display data for all hosts */
4161 else {
4162
4163 if(output_format == HTML_OUTPUT) {
4164
4165 printf("<BR><BR>\n");
4166 printf("<DIV ALIGN=CENTER CLASS='dataTitle'>Host State Breakdowns:</DIV>\n");
4167
4168 printf("<DIV ALIGN=CENTER>\n");
4169 printf("<TABLE BORDER=0 CLASS='data'>\n");
4170 printf("<TR><TH CLASS='data'>Host</TH><TH CLASS='data'>%% Time Up</TH><TH CLASS='data'>%% Time Down</TH><TH CLASS='data'>%% Time Unreachable</TH><TH CLASS='data'>%% Time Undetermined</TH></TR>\n");
4171 }
4172
4173 else if(output_format == CSV_OUTPUT) {
4174 printf("HOST_NAME,");
4175
4176 printf(" TIME_UP_SCHEDULED, PERCENT_TIME_UP_SCHEDULED, PERCENT_KNOWN_TIME_UP_SCHEDULED, TIME_UP_UNSCHEDULED, PERCENT_TIME_UP_UNSCHEDULED, PERCENT_KNOWN_TIME_UP_UNSCHEDULED, TOTAL_TIME_UP, PERCENT_TOTAL_TIME_UP, PERCENT_KNOWN_TIME_UP,");
4177
4178 printf(" TIME_DOWN_SCHEDULED, PERCENT_TIME_DOWN_SCHEDULED, PERCENT_KNOWN_TIME_DOWN_SCHEDULED, TIME_DOWN_UNSCHEDULED, PERCENT_TIME_DOWN_UNSCHEDULED, PERCENT_KNOWN_TIME_DOWN_UNSCHEDULED, TOTAL_TIME_DOWN, PERCENT_TOTAL_TIME_DOWN, PERCENT_KNOWN_TIME_DOWN,");
4179
4180 printf(" TIME_UNREACHABLE_SCHEDULED, PERCENT_TIME_UNREACHABLE_SCHEDULED, PERCENT_KNOWN_TIME_UNREACHABLE_SCHEDULED, TIME_UNREACHABLE_UNSCHEDULED, PERCENT_TIME_UNREACHABLE_UNSCHEDULED, PERCENT_KNOWN_TIME_UNREACHABLE_UNSCHEDULED, TOTAL_TIME_UNREACHABLE, PERCENT_TOTAL_TIME_UNREACHABLE, PERCENT_KNOWN_TIME_UNREACHABLE,");
4181
4182 printf(" TIME_UNDETERMINED_NOT_RUNNING, PERCENT_TIME_UNDETERMINED_NOT_RUNNING, TIME_UNDETERMINED_NO_DATA, PERCENT_TIME_UNDETERMINED_NO_DATA, TOTAL_TIME_UNDETERMINED, PERCENT_TOTAL_TIME_UNDETERMINED\n");
4183 }
4184
4185
4186 for(temp_subject = subject_list; temp_subject != NULL; temp_subject = temp_subject->next) {
4187
4188 if(temp_subject->type != HOST_SUBJECT)
4189 continue;
4190
4191 temp_host = find_host(temp_subject->host_name);
4192 if(temp_host == NULL)
4193 continue;
4194
4195 /* the user isn't authorized to view this host */
4196 if(is_authorized_for_host(temp_host, ¤t_authdata) == FALSE)
4197 continue;
4198
4199 current_subject++;
4200
4201 time_determinate = temp_subject->time_up + temp_subject->time_down + temp_subject->time_unreachable;
4202 time_indeterminate = total_time - time_determinate;
4203
4204 /* adjust indeterminate time due to insufficient data (not all was caught) */
4205 temp_subject->time_indeterminate_nodata = time_indeterminate - temp_subject->time_indeterminate_notrunning;
4206
4207 /* initialize values */
4208 percent_time_up = 0.0;
4209 percent_time_up_scheduled = 0.0;
4210 percent_time_up_unscheduled = 0.0;
4211 percent_time_down = 0.0;
4212 percent_time_down_scheduled = 0.0;
4213 percent_time_down_unscheduled = 0.0;
4214 percent_time_unreachable = 0.0;
4215 percent_time_unreachable_scheduled = 0.0;
4216 percent_time_unreachable_unscheduled = 0.0;
4217 percent_time_indeterminate = 0.0;
4218 percent_time_indeterminate_scheduled = 0.0;
4219 percent_time_indeterminate_unscheduled = 0.0;
4220 percent_time_indeterminate_notrunning = 0.0;
4221 percent_time_indeterminate_nodata = 0.0;
4222 percent_time_up_known = 0.0;
4223 percent_time_up_scheduled_known = 0.0;
4224 percent_time_up_unscheduled_known = 0.0;
4225 percent_time_down_known = 0.0;
4226 percent_time_down_scheduled_known = 0.0;
4227 percent_time_down_unscheduled_known = 0.0;
4228 percent_time_unreachable_known = 0.0;
4229 percent_time_unreachable_scheduled_known = 0.0;
4230 percent_time_unreachable_unscheduled_known = 0.0;
4231
4232 if(total_time > 0) {
4233 percent_time_up = (double)(((double)temp_subject->time_up * 100.0) / (double)total_time);
4234 percent_time_up_scheduled = (double)(((double)temp_subject->scheduled_time_up * 100.0) / (double)total_time);
4235 percent_time_up_unscheduled = percent_time_up - percent_time_up_scheduled;
4236 percent_time_down = (double)(((double)temp_subject->time_down * 100.0) / (double)total_time);
4237 percent_time_down_scheduled = (double)(((double)temp_subject->scheduled_time_down * 100.0) / (double)total_time);
4238 percent_time_down_unscheduled = percent_time_down - percent_time_down_scheduled;
4239 percent_time_unreachable = (double)(((double)temp_subject->time_unreachable * 100.0) / (double)total_time);
4240 percent_time_unreachable_scheduled = (double)(((double)temp_subject->scheduled_time_unreachable * 100.0) / (double)total_time);
4241 percent_time_unreachable_unscheduled = percent_time_unreachable - percent_time_unreachable_scheduled;
4242 percent_time_indeterminate = (double)(((double)time_indeterminate * 100.0) / (double)total_time);
4243 percent_time_indeterminate_scheduled = (double)(((double)temp_subject->scheduled_time_indeterminate * 100.0) / (double)total_time);
4244 percent_time_indeterminate_unscheduled = percent_time_indeterminate - percent_time_indeterminate_scheduled;
4245 percent_time_indeterminate_notrunning = (double)(((double)temp_subject->time_indeterminate_notrunning * 100.0) / (double)total_time);
4246 percent_time_indeterminate_nodata = (double)(((double)temp_subject->time_indeterminate_nodata * 100.0) / (double)total_time);
4247 if(time_determinate > 0) {
4248 percent_time_up_known = (double)(((double)temp_subject->time_up * 100.0) / (double)time_determinate);
4249 percent_time_up_scheduled_known = (double)(((double)temp_subject->scheduled_time_up * 100.0) / (double)time_determinate);
4250 percent_time_up_unscheduled_known = percent_time_up_known - percent_time_up_scheduled_known;
4251 percent_time_down_known = (double)(((double)temp_subject->time_down * 100.0) / (double)time_determinate);
4252 percent_time_down_scheduled_known = (double)(((double)temp_subject->scheduled_time_down * 100.0) / (double)time_determinate);
4253 percent_time_down_unscheduled_known = percent_time_down_known - percent_time_down_scheduled_known;
4254 percent_time_unreachable_known = (double)(((double)temp_subject->time_unreachable * 100.0) / (double)time_determinate);
4255 percent_time_unreachable_scheduled_known = (double)(((double)temp_subject->scheduled_time_unreachable * 100.0) / (double)time_determinate);
4256 percent_time_unreachable_unscheduled_known = percent_time_unreachable_known - percent_time_unreachable_scheduled_known;
4257 }
4258 }
4259
4260 if(output_format == HTML_OUTPUT) {
4261
4262 if(odd) {
4263 odd = 0;
4264 bgclass = "Odd";
4265 }
4266 else {
4267 odd = 1;
4268 bgclass = "Even";
4269 }
4270
4271 printf("<tr CLASS='data%s'><td CLASS='data%s'>", bgclass, bgclass);
4272 host_report_url(temp_subject->host_name, temp_subject->host_name);
4273 printf("</td><td CLASS='hostUP'>%2.3f%% (%2.3f%%)</td><td CLASS='hostDOWN'>%2.3f%% (%2.3f%%)</td><td CLASS='hostUNREACHABLE'>%2.3f%% (%2.3f%%)</td><td class='data%s'>%2.3f%%</td></tr>\n", percent_time_up, percent_time_up_known, percent_time_down, percent_time_down_known, percent_time_unreachable, percent_time_unreachable_known, bgclass, percent_time_indeterminate);
4274 }
4275 else if(output_format == CSV_OUTPUT) {
4276
4277 /* host name */
4278 printf("\"%s\",", temp_subject->host_name);
4279
4280 /* up times */
4281 printf(" %lu, %2.3f%%, %2.3f%%, %lu, %2.3f%%, %2.3f%%, %lu, %2.3f%%, %2.3f%%,", temp_subject->scheduled_time_up, percent_time_up_scheduled, percent_time_up_scheduled_known, temp_subject->time_up - temp_subject->scheduled_time_up, percent_time_up_unscheduled, percent_time_up_unscheduled_known, temp_subject->time_up, percent_time_up, percent_time_up_known);
4282
4283 /* down times */
4284 printf(" %lu, %2.3f%%, %2.3f%%, %lu, %2.3f%%, %2.3f%%, %lu, %2.3f%%, %2.3f%%,", temp_subject->scheduled_time_down, percent_time_down_scheduled, percent_time_down_scheduled_known, temp_subject->time_down - temp_subject->scheduled_time_down, percent_time_down_unscheduled, percent_time_down_unscheduled_known, temp_subject->time_down, percent_time_down, percent_time_down_known);
4285
4286 /* unreachable times */
4287 printf(" %lu, %2.3f%%, %2.3f%%, %lu, %2.3f%%, %2.3f%%, %lu, %2.3f%%, %2.3f%%,", temp_subject->scheduled_time_unreachable, percent_time_unreachable_scheduled, percent_time_unreachable_scheduled_known, temp_subject->time_unreachable - temp_subject->scheduled_time_unreachable, percent_time_unreachable_unscheduled, percent_time_unreachable_unscheduled_known, temp_subject->time_unreachable, percent_time_unreachable, percent_time_unreachable_known);
4288
4289 /* indeterminate times */
4290 printf(" %lu, %2.3f%%, %lu, %2.3f%%, %lu, %2.3f%%\n", temp_subject->time_indeterminate_notrunning, percent_time_indeterminate_notrunning, temp_subject->time_indeterminate_nodata, percent_time_indeterminate_nodata, time_indeterminate, percent_time_indeterminate);
4291 }
4292
4293 get_running_average(&average_percent_time_up, percent_time_up, current_subject);
4294 get_running_average(&average_percent_time_up_known, percent_time_up_known, current_subject);
4295 get_running_average(&average_percent_time_down, percent_time_down, current_subject);
4296 get_running_average(&average_percent_time_down_known, percent_time_down_known, current_subject);
4297 get_running_average(&average_percent_time_unreachable, percent_time_unreachable, current_subject);
4298 get_running_average(&average_percent_time_unreachable_known, percent_time_unreachable_known, current_subject);
4299 get_running_average(&average_percent_time_indeterminate, percent_time_indeterminate, current_subject);
4300 }
4301
4302 if(output_format == HTML_OUTPUT) {
4303
4304 /* average statistics */
4305 if(odd) {
4306 odd = 0;
4307 bgclass = "Odd";
4308 }
4309 else {
4310 odd = 1;
4311 bgclass = "Even";
4312 }
4313 printf("<tr CLASS='data%s'><td CLASS='data%s'>Average</td><td CLASS='hostUP'>%2.3f%% (%2.3f%%)</td><td CLASS='hostDOWN'>%2.3f%% (%2.3f%%)</td><td CLASS='hostUNREACHABLE'>%2.3f%% (%2.3f%%)</td><td class='data%s'>%2.3f%%</td></tr>", bgclass, bgclass, average_percent_time_up, average_percent_time_up_known, average_percent_time_down, average_percent_time_down_known, average_percent_time_unreachable, average_percent_time_unreachable_known, bgclass, average_percent_time_indeterminate);
4314
4315 printf("</table>\n");
4316 printf("</DIV>\n");
4317 }
4318 }
4319
4320 return;
4321 }
4322
4323
4324 /* display service availability */
display_service_availability(void)4325 void display_service_availability(void) {
4326 unsigned long total_time;
4327 unsigned long time_determinate;
4328 unsigned long time_indeterminate;
4329 avail_subject *temp_subject;
4330 service *temp_service;
4331 int days, hours, minutes, seconds;
4332 char time_ok_string[48];
4333 char time_warning_string[48];
4334 char time_unknown_string[48];
4335 char time_critical_string[48];
4336 char time_indeterminate_string[48];
4337 char time_determinate_string[48];
4338 char total_time_string[48];
4339 double percent_time_ok = 0.0;
4340 double percent_time_warning = 0.0;
4341 double percent_time_unknown = 0.0;
4342 double percent_time_critical = 0.0;
4343 double percent_time_indeterminate = 0.0;
4344 double percent_time_ok_known = 0.0;
4345 double percent_time_warning_known = 0.0;
4346 double percent_time_unknown_known = 0.0;
4347 double percent_time_critical_known = 0.0;
4348
4349 char time_critical_scheduled_string[48];
4350 char time_critical_unscheduled_string[48];
4351 double percent_time_critical_scheduled = 0.0;
4352 double percent_time_critical_unscheduled = 0.0;
4353 double percent_time_critical_scheduled_known = 0.0;
4354 double percent_time_critical_unscheduled_known = 0.0;
4355 char time_unknown_scheduled_string[48];
4356 char time_unknown_unscheduled_string[48];
4357 double percent_time_unknown_scheduled = 0.0;
4358 double percent_time_unknown_unscheduled = 0.0;
4359 double percent_time_unknown_scheduled_known = 0.0;
4360 double percent_time_unknown_unscheduled_known = 0.0;
4361 char time_warning_scheduled_string[48];
4362 char time_warning_unscheduled_string[48];
4363 double percent_time_warning_scheduled = 0.0;
4364 double percent_time_warning_unscheduled = 0.0;
4365 double percent_time_warning_scheduled_known = 0.0;
4366 double percent_time_warning_unscheduled_known = 0.0;
4367 char time_ok_scheduled_string[48];
4368 char time_ok_unscheduled_string[48];
4369 double percent_time_ok_scheduled = 0.0;
4370 double percent_time_ok_unscheduled = 0.0;
4371 double percent_time_ok_scheduled_known = 0.0;
4372 double percent_time_ok_unscheduled_known = 0.0;
4373
4374 double average_percent_time_ok = 0.0;
4375 double average_percent_time_ok_known = 0.0;
4376 double average_percent_time_unknown = 0.0;
4377 double average_percent_time_unknown_known = 0.0;
4378 double average_percent_time_warning = 0.0;
4379 double average_percent_time_warning_known = 0.0;
4380 double average_percent_time_critical = 0.0;
4381 double average_percent_time_critical_known = 0.0;
4382 double average_percent_time_indeterminate = 0.0;
4383
4384 int current_subject = 0;
4385
4386 char time_indeterminate_scheduled_string[48];
4387 char time_indeterminate_unscheduled_string[48];
4388 double percent_time_indeterminate_scheduled = 0.0;
4389 double percent_time_indeterminate_unscheduled = 0.0;
4390 char time_indeterminate_notrunning_string[48];
4391 char time_indeterminate_nodata_string[48];
4392 double percent_time_indeterminate_notrunning = 0.0;
4393 double percent_time_indeterminate_nodata = 0.0;
4394
4395 int odd = 1;
4396 char *bgclass = "";
4397 char last_host[128] = "";
4398
4399
4400 /* calculate total time during period based on timeperiod used for reporting */
4401 total_time = calculate_total_time(t1, t2);
4402
4403 /* we're only getting data for one service */
4404 if(show_all_services == FALSE) {
4405
4406 temp_subject = find_subject(SERVICE_SUBJECT, host_name, svc_description);
4407 if(temp_subject == NULL)
4408 return;
4409
4410 temp_service = find_service(temp_subject->host_name, temp_subject->service_description);
4411 if(temp_service == NULL)
4412 return;
4413
4414 /* the user isn't authorized to view this service */
4415 if(is_authorized_for_service(temp_service, ¤t_authdata) == FALSE)
4416 return;
4417
4418 time_determinate = temp_subject->time_ok + temp_subject->time_warning + temp_subject->time_unknown + temp_subject->time_critical;
4419 time_indeterminate = total_time - time_determinate;
4420
4421 /* adjust indeterminate time due to insufficient data (not all was caught) */
4422 temp_subject->time_indeterminate_nodata = time_indeterminate - temp_subject->time_indeterminate_notrunning;
4423
4424 /* ok states */
4425 get_time_breakdown(temp_subject->time_ok, &days, &hours, &minutes, &seconds);
4426 snprintf(time_ok_string, sizeof(time_ok_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds);
4427 get_time_breakdown(temp_subject->scheduled_time_ok, &days, &hours, &minutes, &seconds);
4428 snprintf(time_ok_scheduled_string, sizeof(time_ok_scheduled_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds);
4429 get_time_breakdown(temp_subject->time_ok - temp_subject->scheduled_time_ok, &days, &hours, &minutes, &seconds);
4430 snprintf(time_ok_unscheduled_string, sizeof(time_ok_unscheduled_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds);
4431
4432 /* warning states */
4433 get_time_breakdown(temp_subject->time_warning, &days, &hours, &minutes, &seconds);
4434 snprintf(time_warning_string, sizeof(time_warning_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds);
4435 get_time_breakdown(temp_subject->scheduled_time_warning, &days, &hours, &minutes, &seconds);
4436 snprintf(time_warning_scheduled_string, sizeof(time_warning_scheduled_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds);
4437 get_time_breakdown(temp_subject->time_warning - temp_subject->scheduled_time_warning, &days, &hours, &minutes, &seconds);
4438 snprintf(time_warning_unscheduled_string, sizeof(time_warning_unscheduled_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds);
4439
4440 /* unknown states */
4441 get_time_breakdown(temp_subject->time_unknown, &days, &hours, &minutes, &seconds);
4442 snprintf(time_unknown_string, sizeof(time_unknown_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds);
4443 get_time_breakdown(temp_subject->scheduled_time_unknown, &days, &hours, &minutes, &seconds);
4444 snprintf(time_unknown_scheduled_string, sizeof(time_unknown_scheduled_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds);
4445 get_time_breakdown(temp_subject->time_unknown - temp_subject->scheduled_time_unknown, &days, &hours, &minutes, &seconds);
4446 snprintf(time_unknown_unscheduled_string, sizeof(time_unknown_unscheduled_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds);
4447
4448 /* critical states */
4449 get_time_breakdown(temp_subject->time_critical, &days, &hours, &minutes, &seconds);
4450 snprintf(time_critical_string, sizeof(time_critical_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds);
4451 get_time_breakdown(temp_subject->scheduled_time_critical, &days, &hours, &minutes, &seconds);
4452 snprintf(time_critical_scheduled_string, sizeof(time_critical_scheduled_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds);
4453 get_time_breakdown(temp_subject->time_critical - temp_subject->scheduled_time_critical, &days, &hours, &minutes, &seconds);
4454 snprintf(time_critical_unscheduled_string, sizeof(time_critical_unscheduled_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds);
4455
4456 /* indeterminate time */
4457 get_time_breakdown(time_indeterminate, &days, &hours, &minutes, &seconds);
4458 snprintf(time_indeterminate_string, sizeof(time_indeterminate_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds);
4459 get_time_breakdown(temp_subject->scheduled_time_indeterminate, &days, &hours, &minutes, &seconds);
4460 snprintf(time_indeterminate_scheduled_string, sizeof(time_indeterminate_scheduled_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds);
4461 get_time_breakdown(time_indeterminate - temp_subject->scheduled_time_indeterminate, &days, &hours, &minutes, &seconds);
4462 snprintf(time_indeterminate_unscheduled_string, sizeof(time_indeterminate_unscheduled_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds);
4463 get_time_breakdown(temp_subject->time_indeterminate_notrunning, &days, &hours, &minutes, &seconds);
4464 snprintf(time_indeterminate_notrunning_string, sizeof(time_indeterminate_notrunning_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds);
4465 get_time_breakdown(temp_subject->time_indeterminate_nodata, &days, &hours, &minutes, &seconds);
4466 snprintf(time_indeterminate_nodata_string, sizeof(time_indeterminate_nodata_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds);
4467
4468 get_time_breakdown(time_determinate, &days, &hours, &minutes, &seconds);
4469 snprintf(time_determinate_string, sizeof(time_determinate_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds);
4470
4471 get_time_breakdown(total_time, &days, &hours, &minutes, &seconds);
4472 snprintf(total_time_string, sizeof(total_time_string) - 1, "%dd %dh %dm %ds", days, hours, minutes, seconds);
4473
4474 if(total_time > 0) {
4475 percent_time_ok = (double)(((double)temp_subject->time_ok * 100.0) / (double)total_time);
4476 percent_time_ok_scheduled = (double)(((double)temp_subject->scheduled_time_ok * 100.0) / (double)total_time);
4477 percent_time_ok_unscheduled = percent_time_ok - percent_time_ok_scheduled;
4478 percent_time_warning = (double)(((double)temp_subject->time_warning * 100.0) / (double)total_time);
4479 percent_time_warning_scheduled = (double)(((double)temp_subject->scheduled_time_unknown * 100.0) / (double)total_time);
4480 percent_time_warning_unscheduled = percent_time_warning - percent_time_warning_scheduled;
4481 percent_time_unknown = (double)(((double)temp_subject->time_unknown * 100.0) / (double)total_time);
4482 percent_time_unknown_scheduled = (double)(((double)temp_subject->scheduled_time_unknown * 100.0) / (double)total_time);
4483 percent_time_unknown_unscheduled = percent_time_unknown - percent_time_unknown_scheduled;
4484 percent_time_critical = (double)(((double)temp_subject->time_critical * 100.0) / (double)total_time);
4485 percent_time_critical_scheduled = (double)(((double)temp_subject->scheduled_time_critical * 100.0) / (double)total_time);
4486 percent_time_critical_unscheduled = percent_time_critical - percent_time_critical_scheduled;
4487 percent_time_indeterminate = (double)(((double)time_indeterminate * 100.0) / (double)total_time);
4488 percent_time_indeterminate_scheduled = (double)(((double)temp_subject->scheduled_time_indeterminate * 100.0) / (double)total_time);
4489 percent_time_indeterminate_unscheduled = percent_time_indeterminate - percent_time_indeterminate_scheduled;
4490 percent_time_indeterminate_notrunning = (double)(((double)temp_subject->time_indeterminate_notrunning * 100.0) / (double)total_time);
4491 percent_time_indeterminate_nodata = (double)(((double)temp_subject->time_indeterminate_nodata * 100.0) / (double)total_time);
4492 if(time_determinate > 0) {
4493 percent_time_ok_known = (double)(((double)temp_subject->time_ok * 100.0) / (double)time_determinate);
4494 percent_time_ok_scheduled_known = (double)(((double)temp_subject->scheduled_time_ok * 100.0) / (double)time_determinate);
4495 percent_time_ok_unscheduled_known = percent_time_ok_known - percent_time_ok_scheduled_known;
4496 percent_time_warning_known = (double)(((double)temp_subject->time_warning * 100.0) / (double)time_determinate);
4497 percent_time_warning_scheduled_known = (double)(((double)temp_subject->scheduled_time_warning * 100.0) / (double)time_determinate);
4498 percent_time_warning_unscheduled_known = percent_time_warning_known - percent_time_warning_scheduled_known;
4499 percent_time_unknown_known = (double)(((double)temp_subject->time_unknown * 100.0) / (double)time_determinate);
4500 percent_time_unknown_scheduled_known = (double)(((double)temp_subject->scheduled_time_unknown * 100.0) / (double)time_determinate);
4501 percent_time_unknown_unscheduled_known = percent_time_unknown_known - percent_time_unknown_scheduled_known;
4502 percent_time_critical_known = (double)(((double)temp_subject->time_critical * 100.0) / (double)time_determinate);
4503 percent_time_critical_scheduled_known = (double)(((double)temp_subject->scheduled_time_critical * 100.0) / (double)time_determinate);
4504 percent_time_critical_unscheduled_known = percent_time_critical_known - percent_time_critical_scheduled_known;
4505 }
4506 }
4507
4508 printf("<DIV ALIGN=CENTER CLASS='dataTitle'>Service State Breakdowns:</DIV>\n");
4509 #ifdef USE_TRENDS
4510 printf("<p align='center'>\n");
4511 printf("<a href='%s?host=%s", TRENDS_CGI, url_encode(host_name));
4512 printf("&service=%s&t1=%lu&t2=%lu&includesoftstates=%s&assumestateretention=%s&assumeinitialstates=%s&assumestatesduringnotrunning=%s&initialassumedservicestate=%d&backtrack=%d'>", url_encode(svc_description), t1, t2, (include_soft_states == TRUE) ? "yes" : "no", (assume_state_retention == TRUE) ? "yes" : "no", (assume_initial_states == TRUE) ? "yes" : "no", (assume_states_during_notrunning == TRUE) ? "yes" : "no", initial_assumed_service_state, backtrack_archives);
4513 printf("<img src='%s?createimage&smallimage&host=%s", TRENDS_CGI, url_encode(host_name));
4514 printf("&service=%s&t1=%lu&t2=%lu&includesoftstates=%s&assumestateretention=%s&assumeinitialstates=%s&assumestatesduringnotrunning=%s&initialassumedservicestate=%d&backtrack=%d' border=1 alt='Service State Trends' title='Service State Trends' width='500' height='20'>", url_encode(svc_description), t1, t2, (include_soft_states == TRUE) ? "yes" : "no", (assume_state_retention == TRUE) ? "yes" : "no", (assume_initial_states == TRUE) ? "yes" : "no", (assume_states_during_notrunning == TRUE) ? "yes" : "no", initial_assumed_service_state, backtrack_archives);
4515 printf("</a><br>\n");
4516 printf("</p>\n");
4517 #endif
4518
4519 printf("<DIV ALIGN=CENTER>\n");
4520 printf("<TABLE BORDER=0 CLASS='data'>\n");
4521 printf("<TR><TH CLASS='data'>State</TH><TH CLASS='data'>Type / Reason</TH><TH CLASS='data'>Time</TH><TH CLASS='data'>%% Total Time</TH><TH CLASS='data'>%% Known Time</TH></TR>\n");
4522
4523 /* ok states */
4524 printf("<tr CLASS='dataEven'><td CLASS='serviceOK' rowspan=3>OK</td>");
4525 printf("<td CLASS='dataEven'>Unscheduled</td><td CLASS='dataEven'>%s</td><td CLASS='dataEven'>%2.3f%%</td><td CLASS='dataEven'>%2.3f%%</td></tr>\n", time_ok_unscheduled_string, percent_time_ok_unscheduled, percent_time_ok_unscheduled_known);
4526 printf("<tr CLASS='dataEven'><td CLASS='dataEven'>Scheduled</td><td CLASS='dataEven'>%s</td><td CLASS='dataEven'>%2.3f%%</td><td CLASS='dataEven'>%2.3f%%</td></tr>\n", time_ok_scheduled_string, percent_time_ok_scheduled, percent_time_ok_scheduled_known);
4527 printf("<tr CLASS='serviceOK'><td CLASS='serviceOK'>Total</td><td CLASS='serviceOK'>%s</td><td CLASS='serviceOK'>%2.3f%%</td><td CLASS='serviceOK'>%2.3f%%</td></tr>\n", time_ok_string, percent_time_ok, percent_time_ok_known);
4528
4529 /* warning states */
4530 printf("<tr CLASS='dataOdd'><td CLASS='serviceWARNING' rowspan=3>WARNING</td>");
4531 printf("<td CLASS='dataOdd'>Unscheduled</td><td CLASS='dataOdd'>%s</td><td CLASS='dataOdd'>%2.3f%%</td><td CLASS='dataOdd'>%2.3f%%</td></tr>\n", time_warning_unscheduled_string, percent_time_warning_unscheduled, percent_time_warning_unscheduled_known);
4532 printf("<tr CLASS='dataOdd'><td CLASS='dataOdd'>Scheduled</td><td CLASS='dataOdd'>%s</td><td CLASS='dataOdd'>%2.3f%%</td><td CLASS='dataOdd'>%2.3f%%</td></tr>\n", time_warning_scheduled_string, percent_time_warning_scheduled, percent_time_warning_scheduled_known);
4533 printf("<tr CLASS='serviceWARNING'><td CLASS='serviceWARNING'>Total</td><td CLASS='serviceWARNING'>%s</td><td CLASS='serviceWARNING'>%2.3f%%</td><td CLASS='serviceWARNING'>%2.3f%%</td></tr>\n", time_warning_string, percent_time_warning, percent_time_warning_known);
4534
4535 /* unknown states */
4536 printf("<tr CLASS='dataEven'><td CLASS='serviceUNKNOWN' rowspan=3>UNKNOWN</td>");
4537 printf("<td CLASS='dataEven'>Unscheduled</td><td CLASS='dataEven'>%s</td><td CLASS='dataEven'>%2.3f%%</td><td CLASS='dataEven'>%2.3f%%</td></tr>\n", time_unknown_unscheduled_string, percent_time_unknown_unscheduled, percent_time_unknown_unscheduled_known);
4538 printf("<tr CLASS='dataEven'><td CLASS='dataEven'>Scheduled</td><td CLASS='dataEven'>%s</td><td CLASS='dataEven'>%2.3f%%</td><td CLASS='dataEven'>%2.3f%%</td></tr>\n", time_unknown_scheduled_string, percent_time_unknown_scheduled, percent_time_unknown_scheduled_known);
4539 printf("<tr CLASS='serviceUNKNOWN'><td CLASS='serviceUNKNOWN'>Total</td><td CLASS='serviceUNKNOWN'>%s</td><td CLASS='serviceUNKNOWN'>%2.3f%%</td><td CLASS='serviceUNKNOWN'>%2.3f%%</td></tr>\n", time_unknown_string, percent_time_unknown, percent_time_unknown_known);
4540
4541 /* critical states */
4542 printf("<tr CLASS='dataOdd'><td CLASS='serviceCRITICAL' rowspan=3>CRITICAL</td>");
4543 printf("<td CLASS='dataOdd'>Unscheduled</td><td CLASS='dataOdd'>%s</td><td CLASS='dataOdd'>%2.3f%%</td><td CLASS='dataOdd'>%2.3f%%</td></tr>\n", time_critical_unscheduled_string, percent_time_critical_unscheduled, percent_time_critical_unscheduled_known);
4544 printf("<tr CLASS='dataOdd'><td CLASS='dataOdd'>Scheduled</td><td CLASS='dataOdd'>%s</td><td CLASS='dataOdd'>%2.3f%%</td><td CLASS='dataOdd'>%2.3f%%</td></tr>\n", time_critical_scheduled_string, percent_time_critical_scheduled, percent_time_critical_scheduled_known);
4545 printf("<tr CLASS='serviceCRITICAL'><td CLASS='serviceCRITICAL'>Total</td><td CLASS='serviceCRITICAL'>%s</td><td CLASS='serviceCRITICAL'>%2.3f%%</td><td CLASS='serviceCRITICAL'>%2.3f%%</td></tr>\n", time_critical_string, percent_time_critical, percent_time_critical_known);
4546
4547
4548 printf("<tr CLASS='dataEven'><td CLASS='dataEven' rowspan=3>Undetermined</td>");
4549 /*
4550 printf("<td CLASS='dataEven'>Unscheduled</td><td CLASS='dataEven'>%s</td><td CLASS='dataEven'>%2.3f%%</td><td CLASS='dataEven'></td></tr>\n",time_indeterminate_unscheduled_string,percent_time_indeterminate_unscheduled);
4551 printf("<tr CLASS='dataEven'><td CLASS='dataEven'>Scheduled</td><td CLASS='dataEven'>%s</td><td CLASS='dataEven'>%2.3f%%</td><td CLASS='dataEven'></td></tr>\n",time_indeterminate_scheduled_string,percent_time_indeterminate_scheduled);
4552 */
4553 printf("<td CLASS='dataEven'>Nagios Not Running</td><td CLASS='dataEven'>%s</td><td CLASS='dataEven'>%2.3f%%</td><td CLASS='dataEven'></td></tr>\n", time_indeterminate_notrunning_string, percent_time_indeterminate_notrunning);
4554 printf("<tr CLASS='dataEven'><td CLASS='dataEven'>Insufficient Data</td><td CLASS='dataEven'>%s</td><td CLASS='dataEven'>%2.3f%%</td><td CLASS='dataEven'></td></tr>\n", time_indeterminate_nodata_string, percent_time_indeterminate_nodata);
4555 printf("<tr CLASS='dataEven'><td CLASS='dataEven'>Total</td><td CLASS='dataEven'>%s</td><td CLASS='dataEven'>%2.3f%%</td><td CLASS='dataEven'></td></tr>\n", time_indeterminate_string, percent_time_indeterminate);
4556
4557 printf("<tr><td colspan=3></td></tr>\n");
4558 printf("<tr CLASS='dataOdd'><td CLASS='dataOdd'>All</td><td CLASS='dataOdd'>Total</td><td CLASS='dataOdd'>%s</td><td CLASS='dataOdd'>100.000%%</td><td CLASS='dataOdd'>100.000%%</td></tr>\n", total_time_string);
4559 printf("</table>\n");
4560 printf("</DIV>\n");
4561
4562
4563 write_log_entries(temp_subject);
4564 }
4565
4566
4567 /* display data for all services */
4568 else {
4569
4570 if(output_format == HTML_OUTPUT) {
4571
4572 printf("<DIV ALIGN=CENTER CLASS='dataTitle'>Service State Breakdowns:</DIV>\n");
4573
4574 printf("<DIV ALIGN=CENTER>\n");
4575 printf("<TABLE BORDER=0 CLASS='data'>\n");
4576 printf("<TR><TH CLASS='data'>Host</TH><TH CLASS='data'>Service</TH><TH CLASS='data'>%% Time OK</TH><TH CLASS='data'>%% Time Warning</TH><TH CLASS='data'>%% Time Unknown</TH><TH CLASS='data'>%% Time Critical</TH><TH CLASS='data'>%% Time Undetermined</TH></TR>\n");
4577 }
4578 else if(output_format == CSV_OUTPUT) {
4579 printf("HOST_NAME, SERVICE_DESCRIPTION,");
4580
4581 printf(" TIME_OK_SCHEDULED, PERCENT_TIME_OK_SCHEDULED, PERCENT_KNOWN_TIME_OK_SCHEDULED, TIME_OK_UNSCHEDULED, PERCENT_TIME_OK_UNSCHEDULED, PERCENT_KNOWN_TIME_OK_UNSCHEDULED, TOTAL_TIME_OK, PERCENT_TOTAL_TIME_OK, PERCENT_KNOWN_TIME_OK,");
4582
4583 printf(" TIME_WARNING_SCHEDULED, PERCENT_TIME_WARNING_SCHEDULED, PERCENT_KNOWN_TIME_WARNING_SCHEDULED, TIME_WARNING_UNSCHEDULED, PERCENT_TIME_WARNING_UNSCHEDULED, PERCENT_KNOWN_TIME_WARNING_UNSCHEDULED, TOTAL_TIME_WARNING, PERCENT_TOTAL_TIME_WARNING, PERCENT_KNOWN_TIME_WARNING,");
4584
4585 printf(" TIME_UNKNOWN_SCHEDULED, PERCENT_TIME_UNKNOWN_SCHEDULED, PERCENT_KNOWN_TIME_UNKNOWN_SCHEDULED, TIME_UNKNOWN_UNSCHEDULED, PERCENT_TIME_UNKNOWN_UNSCHEDULED, PERCENT_KNOWN_TIME_UNKNOWN_UNSCHEDULED, TOTAL_TIME_UNKNOWN, PERCENT_TOTAL_TIME_UNKNOWN, PERCENT_KNOWN_TIME_UNKNOWN,");
4586
4587 printf(" TIME_CRITICAL_SCHEDULED, PERCENT_TIME_CRITICAL_SCHEDULED, PERCENT_KNOWN_TIME_CRITICAL_SCHEDULED, TIME_CRITICAL_UNSCHEDULED, PERCENT_TIME_CRITICAL_UNSCHEDULED, PERCENT_KNOWN_TIME_CRITICAL_UNSCHEDULED, TOTAL_TIME_CRITICAL, PERCENT_TOTAL_TIME_CRITICAL, PERCENT_KNOWN_TIME_CRITICAL,");
4588
4589 printf(" TIME_UNDETERMINED_NOT_RUNNING, PERCENT_TIME_UNDETERMINED_NOT_RUNNING, TIME_UNDETERMINED_NO_DATA, PERCENT_TIME_UNDETERMINED_NO_DATA, TOTAL_TIME_UNDETERMINED, PERCENT_TOTAL_TIME_UNDETERMINED\n");
4590 }
4591
4592
4593 for(temp_subject = subject_list; temp_subject != NULL; temp_subject = temp_subject->next) {
4594
4595 if(temp_subject->type != SERVICE_SUBJECT)
4596 continue;
4597
4598 temp_service = find_service(temp_subject->host_name, temp_subject->service_description);
4599 if(temp_service == NULL)
4600 continue;
4601
4602 /* the user isn't authorized to view this service */
4603 if(is_authorized_for_service(temp_service, ¤t_authdata) == FALSE)
4604 continue;
4605
4606 current_subject++;
4607
4608 time_determinate = temp_subject->time_ok + temp_subject->time_warning + temp_subject->time_unknown + temp_subject->time_critical;
4609 time_indeterminate = total_time - time_determinate;
4610
4611 /* adjust indeterminate time due to insufficient data (not all was caught) */
4612 temp_subject->time_indeterminate_nodata = time_indeterminate - temp_subject->time_indeterminate_notrunning;
4613
4614 /* initialize values */
4615 percent_time_ok = 0.0;
4616 percent_time_ok_scheduled = 0.0;
4617 percent_time_ok_unscheduled = 0.0;
4618 percent_time_warning = 0.0;
4619 percent_time_warning_scheduled = 0.0;
4620 percent_time_warning_unscheduled = 0.0;
4621 percent_time_unknown = 0.0;
4622 percent_time_unknown_scheduled = 0.0;
4623 percent_time_unknown_unscheduled = 0.0;
4624 percent_time_critical = 0.0;
4625 percent_time_critical_scheduled = 0.0;
4626 percent_time_critical_unscheduled = 0.0;
4627 percent_time_indeterminate = 0.0;
4628 percent_time_indeterminate_scheduled = 0.0;
4629 percent_time_indeterminate_unscheduled = 0.0;
4630 percent_time_indeterminate_notrunning = 0.0;
4631 percent_time_indeterminate_nodata = 0.0;
4632 percent_time_ok_known = 0.0;
4633 percent_time_ok_scheduled_known = 0.0;
4634 percent_time_ok_unscheduled_known = 0.0;
4635 percent_time_warning_known = 0.0;
4636 percent_time_warning_scheduled_known = 0.0;
4637 percent_time_warning_unscheduled_known = 0.0;
4638 percent_time_unknown_known = 0.0;
4639 percent_time_unknown_scheduled_known = 0.0;
4640 percent_time_unknown_unscheduled_known = 0.0;
4641 percent_time_critical_known = 0.0;
4642 percent_time_critical_scheduled_known = 0.0;
4643 percent_time_critical_unscheduled_known = 0.0;
4644
4645 if(total_time > 0) {
4646 percent_time_ok = (double)(((double)temp_subject->time_ok * 100.0) / (double)total_time);
4647 percent_time_ok_scheduled = (double)(((double)temp_subject->scheduled_time_ok * 100.0) / (double)total_time);
4648 percent_time_ok_unscheduled = percent_time_ok - percent_time_ok_scheduled;
4649 percent_time_warning = (double)(((double)temp_subject->time_warning * 100.0) / (double)total_time);
4650 percent_time_warning_scheduled = (double)(((double)temp_subject->scheduled_time_unknown * 100.0) / (double)total_time);
4651 percent_time_warning_unscheduled = percent_time_warning - percent_time_warning_scheduled;
4652 percent_time_unknown = (double)(((double)temp_subject->time_unknown * 100.0) / (double)total_time);
4653 percent_time_unknown_scheduled = (double)(((double)temp_subject->scheduled_time_unknown * 100.0) / (double)total_time);
4654 percent_time_unknown_unscheduled = percent_time_unknown - percent_time_unknown_scheduled;
4655 percent_time_critical = (double)(((double)temp_subject->time_critical * 100.0) / (double)total_time);
4656 percent_time_critical_scheduled = (double)(((double)temp_subject->scheduled_time_critical * 100.0) / (double)total_time);
4657 percent_time_critical_unscheduled = percent_time_critical - percent_time_critical_scheduled;
4658 percent_time_indeterminate = (double)(((double)time_indeterminate * 100.0) / (double)total_time);
4659 percent_time_indeterminate_scheduled = (double)(((double)temp_subject->scheduled_time_indeterminate * 100.0) / (double)total_time);
4660 percent_time_indeterminate_unscheduled = percent_time_indeterminate - percent_time_indeterminate_scheduled;
4661 percent_time_indeterminate_notrunning = (double)(((double)temp_subject->time_indeterminate_notrunning * 100.0) / (double)total_time);
4662 percent_time_indeterminate_nodata = (double)(((double)temp_subject->time_indeterminate_nodata * 100.0) / (double)total_time);
4663 if(time_determinate > 0) {
4664 percent_time_ok_known = (double)(((double)temp_subject->time_ok * 100.0) / (double)time_determinate);
4665 percent_time_ok_scheduled_known = (double)(((double)temp_subject->scheduled_time_ok * 100.0) / (double)time_determinate);
4666 percent_time_ok_unscheduled_known = percent_time_ok_known - percent_time_ok_scheduled_known;
4667 percent_time_warning_known = (double)(((double)temp_subject->time_warning * 100.0) / (double)time_determinate);
4668 percent_time_warning_scheduled_known = (double)(((double)temp_subject->scheduled_time_warning * 100.0) / (double)time_determinate);
4669 percent_time_warning_unscheduled_known = percent_time_warning_known - percent_time_warning_scheduled_known;
4670 percent_time_unknown_known = (double)(((double)temp_subject->time_unknown * 100.0) / (double)time_determinate);
4671 percent_time_unknown_scheduled_known = (double)(((double)temp_subject->scheduled_time_unknown * 100.0) / (double)time_determinate);
4672 percent_time_unknown_unscheduled_known = percent_time_unknown_known - percent_time_unknown_scheduled_known;
4673 percent_time_critical_known = (double)(((double)temp_subject->time_critical * 100.0) / (double)time_determinate);
4674 percent_time_critical_scheduled_known = (double)(((double)temp_subject->scheduled_time_critical * 100.0) / (double)time_determinate);
4675 percent_time_critical_unscheduled_known = percent_time_critical_known - percent_time_critical_scheduled_known;
4676 }
4677 }
4678
4679 if(output_format == HTML_OUTPUT) {
4680
4681 if(odd) {
4682 odd = 0;
4683 bgclass = "Odd";
4684 }
4685 else {
4686 odd = 1;
4687 bgclass = "Even";
4688 }
4689
4690 printf("<tr CLASS='data%s'><td CLASS='data%s'>", bgclass, bgclass);
4691 if(strcmp(temp_subject->host_name, last_host))
4692 host_report_url(temp_subject->host_name, temp_subject->host_name);
4693 printf("</td><td CLASS='data%s'>", bgclass);
4694 service_report_url(temp_subject->host_name, temp_subject->service_description, temp_subject->service_description);
4695 printf("</td><td CLASS='serviceOK'>%2.3f%% (%2.3f%%)</td><td CLASS='serviceWARNING'>%2.3f%% (%2.3f%%)</td><td CLASS='serviceUNKNOWN'>%2.3f%% (%2.3f%%)</td><td class='serviceCRITICAL'>%2.3f%% (%2.3f%%)</td><td class='data%s'>%2.3f%%</td></tr>\n", percent_time_ok, percent_time_ok_known, percent_time_warning, percent_time_warning_known, percent_time_unknown, percent_time_unknown_known, percent_time_critical, percent_time_critical_known, bgclass, percent_time_indeterminate);
4696 }
4697 else if(output_format == CSV_OUTPUT) {
4698
4699 /* host name and service description */
4700 printf("\"%s\", \"%s\",", temp_subject->host_name, temp_subject->service_description);
4701
4702 /* ok times */
4703 printf(" %lu, %2.3f%%, %2.3f%%, %lu, %2.3f%%, %2.3f%%, %lu, %2.3f%%, %2.3f%%,", temp_subject->scheduled_time_ok, percent_time_ok_scheduled, percent_time_ok_scheduled_known, temp_subject->time_ok - temp_subject->scheduled_time_ok, percent_time_ok_unscheduled, percent_time_ok_unscheduled_known, temp_subject->time_ok, percent_time_ok, percent_time_ok_known);
4704
4705 /* warning times */
4706 printf(" %lu, %2.3f%%, %2.3f%%, %lu, %2.3f%%, %2.3f%%, %lu, %2.3f%%, %2.3f%%,", temp_subject->scheduled_time_warning, percent_time_warning_scheduled, percent_time_warning_scheduled_known, temp_subject->time_warning - temp_subject->scheduled_time_warning, percent_time_warning_unscheduled, percent_time_warning_unscheduled_known, temp_subject->time_warning, percent_time_warning, percent_time_warning_known);
4707
4708 /* unknown times */
4709 printf(" %lu, %2.3f%%, %2.3f%%, %lu, %2.3f%%, %2.3f%%, %lu, %2.3f%%, %2.3f%%,", temp_subject->scheduled_time_unknown, percent_time_unknown_scheduled, percent_time_unknown_scheduled_known, temp_subject->time_unknown - temp_subject->scheduled_time_unknown, percent_time_unknown_unscheduled, percent_time_unknown_unscheduled_known, temp_subject->time_unknown, percent_time_unknown, percent_time_unknown_known);
4710
4711 /* critical times */
4712 printf(" %lu, %2.3f%%, %2.3f%%, %lu, %2.3f%%, %2.3f%%, %lu, %2.3f%%, %2.3f%%,", temp_subject->scheduled_time_critical, percent_time_critical_scheduled, percent_time_critical_scheduled_known, temp_subject->time_critical - temp_subject->scheduled_time_critical, percent_time_critical_unscheduled, percent_time_critical_unscheduled_known, temp_subject->time_critical, percent_time_critical, percent_time_critical_known);
4713
4714 /* indeterminate times */
4715 printf(" %lu, %2.3f%%, %lu, %2.3f%%, %lu, %2.3f%%\n", temp_subject->time_indeterminate_notrunning, percent_time_indeterminate_notrunning, temp_subject->time_indeterminate_nodata, percent_time_indeterminate_nodata, time_indeterminate, percent_time_indeterminate);
4716 }
4717
4718 strncpy(last_host, temp_subject->host_name, sizeof(last_host) - 1);
4719 last_host[sizeof(last_host) - 1] = '\x0';
4720
4721 get_running_average(&average_percent_time_ok, percent_time_ok, current_subject);
4722 get_running_average(&average_percent_time_ok_known, percent_time_ok_known, current_subject);
4723 get_running_average(&average_percent_time_unknown, percent_time_unknown, current_subject);
4724 get_running_average(&average_percent_time_unknown_known, percent_time_unknown_known, current_subject);
4725 get_running_average(&average_percent_time_warning, percent_time_warning, current_subject);
4726 get_running_average(&average_percent_time_warning_known, percent_time_warning_known, current_subject);
4727 get_running_average(&average_percent_time_critical, percent_time_critical, current_subject);
4728 get_running_average(&average_percent_time_critical_known, percent_time_critical_known, current_subject);
4729 get_running_average(&average_percent_time_indeterminate, percent_time_indeterminate, current_subject);
4730 }
4731
4732 if(output_format == HTML_OUTPUT) {
4733
4734 /* average statistics */
4735 if(odd) {
4736 odd = 0;
4737 bgclass = "Odd";
4738 }
4739 else {
4740 odd = 1;
4741 bgclass = "Even";
4742 }
4743 printf("<tr CLASS='data%s'><td CLASS='data%s' colspan='2'>Average</td><td CLASS='serviceOK'>%2.3f%% (%2.3f%%)</td><td CLASS='serviceWARNING'>%2.3f%% (%2.3f%%)</td><td CLASS='serviceUNKNOWN'>%2.3f%% (%2.3f%%)</td><td class='serviceCRITICAL'>%2.3f%% (%2.3f%%)</td><td class='data%s'>%2.3f%%</td></tr>\n", bgclass, bgclass, average_percent_time_ok, average_percent_time_ok_known, average_percent_time_warning, average_percent_time_warning_known, average_percent_time_unknown, average_percent_time_unknown_known, average_percent_time_critical, average_percent_time_critical_known, bgclass, average_percent_time_indeterminate);
4744
4745 printf("</table>\n");
4746 printf("</DIV>\n");
4747 }
4748 }
4749
4750 return;
4751 }
4752
4753
4754
4755
host_report_url(char * hn,char * label)4756 void host_report_url(char *hn, char *label) {
4757
4758 printf("<a href='%s?host=%s", AVAIL_CGI, url_encode(hn));
4759 printf("&show_log_entries");
4760 printf("&t1=%lu&t2=%lu", t1, t2);
4761 printf("&backtrack=%d", backtrack_archives);
4762 printf("&assumestateretention=%s", (assume_state_retention == TRUE) ? "yes" : "no");
4763 printf("&assumeinitialstates=%s", (assume_initial_states == TRUE) ? "yes" : "no");
4764 printf("&assumestatesduringnotrunning=%s", (assume_states_during_notrunning == TRUE) ? "yes" : "no");
4765 printf("&initialassumedhoststate=%d", initial_assumed_host_state);
4766 printf("&initialassumedservicestate=%d", initial_assumed_service_state);
4767 if(show_log_entries == TRUE)
4768 printf("&show_log_entries");
4769 if(full_log_entries == TRUE)
4770 printf("&full_log_entries");
4771 printf("&showscheduleddowntime=%s", (show_scheduled_downtime == TRUE) ? "yes" : "no");
4772 if(current_timeperiod != NULL)
4773 printf("&rpttimeperiod=%s", url_encode(current_timeperiod->name));
4774 printf("'>%s</a>", label);
4775
4776 return;
4777 }
4778
4779
service_report_url(char * hn,char * sd,char * label)4780 void service_report_url(char *hn, char *sd, char *label) {
4781
4782 printf("<a href='%s?host=%s", AVAIL_CGI, url_encode(hn));
4783 printf("&service=%s", url_encode(sd));
4784 printf("&t1=%lu&t2=%lu", t1, t2);
4785 printf("&backtrack=%d", backtrack_archives);
4786 printf("&assumestateretention=%s", (assume_state_retention == TRUE) ? "yes" : "no");
4787 printf("&assumeinitialstates=%s", (assume_initial_states == TRUE) ? "yes" : "no");
4788 printf("&assumestatesduringnotrunning=%s", (assume_states_during_notrunning == TRUE) ? "yes" : "no");
4789 printf("&initialassumedhoststate=%d", initial_assumed_host_state);
4790 printf("&initialassumedservicestate=%d", initial_assumed_service_state);
4791 if(show_log_entries == TRUE)
4792 printf("&show_log_entries");
4793 if(full_log_entries == TRUE)
4794 printf("&full_log_entries");
4795 printf("&showscheduleddowntime=%s", (show_scheduled_downtime == TRUE) ? "yes" : "no");
4796 if(current_timeperiod != NULL)
4797 printf("&rpttimeperiod=%s", url_encode(current_timeperiod->name));
4798 printf("'>%s</a>", label);
4799
4800 return;
4801 }
4802
4803
4804 /* calculates running average */
get_running_average(double * running_average,double new_value,int current_item)4805 void get_running_average(double *running_average, double new_value, int current_item) {
4806
4807 *running_average = (((*running_average * ((double)current_item - 1.0)) + new_value) / (double)current_item);
4808
4809 return;
4810 }
4811
4812
4813 /* used in reports where a timeperiod is selected */
calculate_total_time(time_t start_time,time_t end_time)4814 unsigned long calculate_total_time(time_t start_time, time_t end_time) {
4815 struct tm *t;
4816 unsigned long midnight_today;
4817 int weekday;
4818 unsigned long total_time;
4819 timerange *temp_timerange;
4820 unsigned long temp_duration;
4821 unsigned long temp_end;
4822 unsigned long temp_start;
4823 unsigned long start;
4824 unsigned long end;
4825
4826 /* attempt to handle the current time_period */
4827 if(current_timeperiod != NULL) {
4828
4829 /* "A day" is 86400 seconds */
4830 t = localtime(&start_time);
4831
4832 /* calculate the start of the day (midnight, 00:00 hours) */
4833 t->tm_sec = 0;
4834 t->tm_min = 0;
4835 t->tm_hour = 0;
4836 t->tm_isdst = -1;
4837 midnight_today = (unsigned long)mktime(t);
4838 weekday = t->tm_wday;
4839
4840 total_time = 0;
4841 while(midnight_today < end_time) {
4842 temp_duration = 0;
4843 temp_end = min(86400, t2 - midnight_today);
4844 temp_start = 0;
4845 if(t1 > midnight_today)
4846 temp_start = t1 - midnight_today;
4847
4848 /* check all time ranges for this day of the week */
4849 for(temp_timerange = current_timeperiod->days[weekday]; temp_timerange != NULL; temp_timerange = temp_timerange->next) {
4850 start = max(temp_timerange->range_start, temp_start);
4851 end = min(temp_timerange->range_end, temp_end);
4852 #ifdef DEBUG
4853 printf("<li>Matching in timerange[%d]: %d -> %d (%ld -> %ld) %d -> %d = %ld<br>\n", weekday, temp_timerange->range_start, temp_timerange->range_end, temp_start, temp_end, start, end, end - start);
4854 #endif
4855 if(end > start)
4856 temp_duration += end - start;
4857 }
4858 total_time += temp_duration;
4859 temp_start = 0;
4860 midnight_today += 86400;
4861 if(++weekday > 6)
4862 weekday = 0;
4863 }
4864
4865 return total_time;
4866 }
4867
4868 /* no timeperiod was selected */
4869 return end_time - start_time;
4870 }
4871