/************************************************************************** * * AVAIL.C - NetSaint Availability CGI * * Copyright (c) 2000-2001 Ethan Galstad (netsaint@netsaint.org) * Last Modified: 12-21-2001 * * License: * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *************************************************************************/ #include "../common/config.h" #include "../common/locations.h" #include "../common/common.h" #include "../common/objects.h" #include "../common/comments.h" #include "../common/statusdata.h" #include "cgiutils.h" #include "getcgi.h" #include "auth.h" #include "edata.h" /*#define DEBUG*/ /* output types */ #define HTML_OUTPUT 0 #define CSV_OUTPUT 1 /* archived state types */ #define AS_NO_DATA 0 #define AS_PROGRAM_END 1 #define AS_PROGRAM_START 2 #define AS_HOST_UP 3 #define AS_HOST_DOWN 4 #define AS_HOST_UNREACHABLE 5 #define AS_SVC_OK 6 #define AS_SVC_UNKNOWN 7 #define AS_SVC_WARNING 8 #define AS_SVC_CRITICAL 9 /* display types */ #define DISPLAY_NO_AVAIL 0 #define DISPLAY_HOSTGROUP_AVAIL 1 #define DISPLAY_HOST_AVAIL 2 #define DISPLAY_SERVICE_AVAIL 3 /* subject types */ #define HOST_SUBJECT 0 #define SERVICE_SUBJECT 1 /* standard report times */ #define TIMEPERIOD_CUSTOM 0 #define TIMEPERIOD_TODAY 1 #define TIMEPERIOD_YESTERDAY 2 #define TIMEPERIOD_THISWEEK 3 #define TIMEPERIOD_LASTWEEK 4 #define TIMEPERIOD_THISMONTH 5 #define TIMEPERIOD_LASTMONTH 6 #define TIMEPERIOD_THISQUARTER 7 #define TIMEPERIOD_LASTQUARTER 8 #define TIMEPERIOD_THISYEAR 9 #define TIMEPERIOD_LASTYEAR 10 #define TIMEPERIOD_LAST24HOURS 11 #define TIMEPERIOD_LAST7DAYS 12 #define MIN_TIMESTAMP_SPACING 10 #define MAX_ARCHIVE_SPREAD 65 #define MAX_ARCHIVE 65 #define MAX_ARCHIVE_BACKTRACKS 60 authdata current_authdata; typedef struct archived_state_struct{ time_t time_stamp; int entry_type; char *state_info; struct archived_state_struct *next; }archived_state; typedef struct avail_subject_struct{ int type; char *host_name; char *service_description; archived_state *as_list; int last_known_state; time_t earliest_time; time_t latest_time; int earliest_state; int latest_state; unsigned long time_up; unsigned long time_down; unsigned long time_unreachable; unsigned long time_ok; unsigned long time_warning; unsigned long time_unknown; unsigned long time_critical; struct avail_subject_struct *next; }avail_subject; avail_subject *subject_list=NULL; time_t t1; time_t t2; int display_type=DISPLAY_NO_AVAIL; int timeperiod_type=TIMEPERIOD_LAST24HOURS; int show_log_entries=FALSE; int full_log_entries=FALSE; int start_second=0; int start_minute=0; int start_hour=0; int start_day=1; int start_month=1; int start_year=2000; int end_second=0; int end_minute=0; int end_hour=24; int end_day=1; int end_month=1; int end_year=2000; int get_date_parts=FALSE; int select_hostgroups=FALSE; int select_hosts=FALSE; int select_services=FALSE; int select_output_format=FALSE; int compute_time_from_parts=FALSE; int show_all_hostgroups=FALSE; int show_all_hosts=FALSE; int show_all_services=FALSE; int assume_initial_states=TRUE; int assume_state_retention=TRUE; int assume_initial_state_ok=TRUE; char *hostgroup_name=""; char *host_name=""; char *svc_description=""; void create_subject_list(void); void add_subject(int,char *,char *); avail_subject *find_subject(int,char *,char *); void compute_availability(void); void compute_subject_availability(avail_subject *,time_t); void compute_subject_availability_times(int,int,time_t,time_t,time_t,avail_subject *); void display_hostgroup_availability(void); void display_specific_hostgroup_availability(hostgroup *); void display_host_availability(void); void display_service_availability(void); void write_log_entries(avail_subject *); void host_report_url(char *,char *); void service_report_url(char *,char *,char *); void compute_report_times(void); int convert_host_state_to_archived_state(int); int convert_service_state_to_archived_state(int); void add_global_archived_state(int,time_t,char *); void add_archived_state(int,time_t,char *,avail_subject *); void free_availability_data(void); void free_archived_state_list(archived_state *); void read_archived_state_data(void); void scan_log_file_for_archived_state_data(char *); void convert_timeperiod_to_times(int); void document_header(int); void document_footer(void); int process_cgivars(void); extern char main_config_file[MAX_FILENAME_LENGTH]; extern char url_images_path[MAX_FILENAME_LENGTH]; extern char url_stylesheets_path[MAX_FILENAME_LENGTH]; extern hostgroup *hostgroup_list; extern host *host_list; extern service *service_list; extern int log_rotation_method; extern time_t last_scheduled_log_rotation; int backtrack_archives=2; int earliest_archive=0; int embedded=FALSE; int display_header=TRUE; int output_format=HTML_OUTPUT; int main(int argc, char **argv){ int result=OK; char temp_buffer[MAX_INPUT_BUFFER]; char start_timestring[MAX_DATETIME_LENGTH]; char end_timestring[MAX_DATETIME_LENGTH]; host *temp_host; service *temp_service; int is_authorized=TRUE; time_t report_start_time; time_t report_end_time; int days, hours, minutes, seconds; hostgroup *temp_hostgroup; time_t t3; time_t current_time; struct tm *t; /* initialize time period to last 24 hours */ time(&t2); t1=(time_t)(t2-(60*60*24)); /* get the arguments passed in the URL */ process_cgivars(); /* reset internal CGI variables */ reset_cgi_vars(); /* read the CGI configuration file */ result=read_cgi_config_file(DEFAULT_CGI_CONFIG_FILE); if(result==ERROR){ document_header(FALSE); printf("

Error: Could not open CGI configuration file '%s' for reading!

\n",DEFAULT_CGI_CONFIG_FILE); document_footer(); return ERROR; } document_header(TRUE); /* read the main configuration file */ result=read_main_config_file(main_config_file); if(result==ERROR){ printf("

Error: Could not open main configuration file '%s' for reading!

\n",main_config_file); document_footer(); return ERROR; } /* read all object configuration data */ result=read_all_object_configuration_data(main_config_file,READ_HOSTGROUPS|READ_CONTACTGROUPS|READ_CONTACTS|READ_HOSTS|READ_SERVICES); if(result==ERROR){ printf("

Error: Could not read some or all object configuration data!

\n"); document_footer(); return ERROR; } /* read all status data */ result=read_all_status_data(DEFAULT_CGI_CONFIG_FILE,READ_PROGRAM_STATUS|READ_HOST_STATUS|READ_SERVICE_STATUS); if(result==ERROR){ printf("

Error: Could not read host and service status information!

\n"); document_footer(); return ERROR; } /* get authentication information */ get_authentication_information(¤t_authdata); if(compute_time_from_parts==TRUE) compute_report_times(); /* make sure times are sane, otherwise swap them */ if(t2\n"); printf("\n"); /* left column of the first row */ printf("\n"); if(display_type==DISPLAY_HOST_AVAIL) snprintf(temp_buffer,sizeof(temp_buffer)-1,"Host Availability Report"); else if(display_type==DISPLAY_SERVICE_AVAIL) snprintf(temp_buffer,sizeof(temp_buffer)-1,"Service Availability Report"); else snprintf(temp_buffer,sizeof(temp_buffer)-1,"Hostgroup Availability Report"); temp_buffer[sizeof(temp_buffer)-1]='\x0'; display_info_table(temp_buffer,FALSE,¤t_authdata); if(((display_type==DISPLAY_HOST_AVAIL && show_all_hosts==FALSE) || (display_type==DISPLAY_SERVICE_AVAIL && show_all_services==FALSE)) && get_date_parts==FALSE){ printf("\n"); printf("\n"); printf("\n"); } printf("\n"); /* center column of top row */ printf("\n"); if(display_type!=DISPLAY_NO_AVAIL && get_date_parts==FALSE){ printf("
\n"); if(display_type==DISPLAY_HOST_AVAIL){ if(show_all_hosts==TRUE) printf("All Hosts"); else printf("Host '%s'",host_name); } else if(display_type==DISPLAY_SERVICE_AVAIL){ if(show_all_services==TRUE) printf("All Services"); else printf("Service '%s' On Host '%s'",svc_description,host_name); } else if(display_type==DISPLAY_HOSTGROUP_AVAIL){ if(show_all_hostgroups==TRUE) printf("All Hostgroups"); else printf("Hostgroup '%s'",hostgroup_name); } printf("
\n"); printf("
\n"); printf("Availability Report\n",url_images_path,TRENDS_ICON); printf("
\n"); get_time_string(&t1,start_timestring,sizeof(start_timestring)-1,SHORT_DATE_TIME); get_time_string(&t2,end_timestring,sizeof(end_timestring)-1,SHORT_DATE_TIME); printf("
%s to %s
\n",start_timestring,end_timestring); get_time_breakdown((time_t)(t2-t1),&days,&hours,&minutes,&seconds); printf("
Duration: %dd %dh %dm %ds
\n",days,hours,minutes,seconds); } printf("\n"); /* right hand column of top row */ printf("\n"); if(display_type!=DISPLAY_NO_AVAIL && get_date_parts==FALSE){ printf("\n"); printf("\n",AVAIL_CGI); printf("\n",(unsigned long)t1); printf("\n",(unsigned long)t2); if(show_log_entries==TRUE) printf("\n"); if(full_log_entries==TRUE) printf("\n"); if(display_type==DISPLAY_HOSTGROUP_AVAIL) printf("\n",hostgroup_name); if(display_type==DISPLAY_HOST_AVAIL || display_type==DISPLAY_SERVICE_AVAIL) printf("\n",host_name); if(display_type==DISPLAY_SERVICE_AVAIL) printf("\n",svc_description); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("
Assume initial states:Assume state retention:
\n"); printf("\n"); printf("\n"); printf("\n"); printf("
Assume initial state ok:Backtracked archives:
\n"); printf("\n"); printf("\n"); printf("\n",backtrack_archives); printf("
Report period:
\n"); printf("\n"); printf("\n"); printf("\n"); printf("
\n"); } printf("\n"); /* end of top table */ printf("\n"); printf("\n"); } /* step 3 - ask user for report date range */ if(get_date_parts==TRUE){ time(¤t_time); t=localtime(¤t_time); start_day=1; start_year=t->tm_year+1900; end_day=t->tm_mday; end_year=t->tm_year+1900; printf("
Step 3: Report Range%s
\n",((display_type==DISPLAY_HOST_AVAIL && show_all_hosts==TRUE) || (display_type==DISPLAY_SERVICE_AVAIL && show_all_services==TRUE))?" and Output Format":""); printf("
\n"); printf("
\n",AVAIL_CGI); printf("\n"); if(display_type==DISPLAY_HOSTGROUP_AVAIL) printf("\n",hostgroup_name); if(display_type==DISPLAY_HOST_AVAIL || display_type==DISPLAY_SERVICE_AVAIL) printf("\n",host_name); if(display_type==DISPLAY_SERVICE_AVAIL) printf("\n",svc_description); printf("\n"); printf(""); printf("\n"); printf("\n"); printf("\n"); if((display_type==DISPLAY_HOST_AVAIL && show_all_hosts==TRUE) || (display_type==DISPLAY_SERVICE_AVAIL && show_all_services==TRUE)){ printf(""); printf("\n"); printf("\n"); } printf("\n"); printf("
"); printf("
Start Date:

\n"); printf("\n "); printf(" ",start_day); printf("",start_year); printf("\n"); printf("\n"); printf("\n"); printf("
"); printf("
End Date (Inclusive):

\n"); printf("\n "); printf(" ",end_day); printf("",end_year); printf("\n"); printf("\n"); printf("\n"); printf("
"); printf("
Output in CSV Format:
\n"); printf("\n"); printf("
\n"); printf("
\n"); printf("
\n"); } /* step 2 - the user wants to select a hostgroup */ else if(select_hostgroups==TRUE){ printf("
Step 2: Select Hostgroup
\n"); printf("
\n"); printf("
\n",AVAIL_CGI); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("
Hostgroup(s):\n"); printf("\n"); printf("
\n"); printf("
\n"); printf("
\n"); } /* step 2 - the user wants to select a host */ else if(select_hosts==TRUE){ printf("
Step 2: Select Host
\n"); printf("
\n"); printf("
\n",AVAIL_CGI); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("
Host(s):\n"); printf("\n"); printf("
\n"); printf("
\n"); printf("
\n"); printf("
Tip: If you want to have the option of getting the availability data in CSV format, select '** ALL HOSTS **' from the pull-down menu.\n"); } /* step 2 - the user wants to select a service */ else if(select_services==TRUE){ printf("\n"); printf("
Step 2: Select Service
\n"); printf("
\n"); printf("
\n",AVAIL_CGI); printf("\n"); printf("\n",(service_list==NULL)?"unknown":service_list->host_name); printf("\n"); printf("\n"); printf("\n"); printf("
Service(s):\n"); printf("\n"); printf("\n"); printf("
\n"); printf("
\n"); printf("
\n"); printf("
Tip: If you want to have the option of getting the availability data in CSV format, select '** ALL SERVICES **' from the pull-down menu.\n"); } /* generate availability report */ else if(display_type!=DISPLAY_NO_AVAIL){ /* check authorization */ is_authorized=TRUE; if((display_type==DISPLAY_HOST_AVAIL && show_all_hosts==FALSE) || (display_type==DISPLAY_SERVICE_AVAIL && show_all_services==FALSE)){ if(display_type==DISPLAY_HOST_AVAIL && show_all_hosts==FALSE) is_authorized=is_authorized_for_host(find_host(host_name,NULL),¤t_authdata); else is_authorized=is_authorized_for_service(find_service(host_name,svc_description,NULL),¤t_authdata); } if(is_authorized==FALSE) printf("

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

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

\n"); } /* display availability data */ if(display_type==DISPLAY_HOST_AVAIL) display_host_availability(); else if(display_type==DISPLAY_SERVICE_AVAIL) display_service_availability(); else display_hostgroup_availability(); /* free memory allocated to availability data */ free_availability_data(); } } /* step 1 - ask the user what kind of report they want */ else{ printf("
Step 1: Select Type Of Availability Report
\n"); printf("
\n"); printf("
\n",AVAIL_CGI); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("\n"); printf("
Hostgroup(s)
Host(s)
Service(s)
\n"); printf("
\n"); printf("
\n"); } document_footer(); /* free all other allocated memory */ free_memory(); return OK; } void document_header(int use_stylesheet){ char date_time[MAX_DATETIME_LENGTH]; time_t current_time; time_t expire_time; printf("Cache-Control: no-store\n"); printf("Pragma: no-cache\n"); time(¤t_time); get_time_string(¤t_time,date_time,sizeof(date_time),HTTP_DATE_TIME); printf("Last-Modified: %s\n",date_time); expire_time=(time_t)0; get_time_string(&expire_time,date_time,sizeof(date_time),HTTP_DATE_TIME); printf("Expires: %s\n",date_time); if(output_format==HTML_OUTPUT) printf("Content-type: text/html\n\n"); else{ printf("Content-type: text/plain\n\n"); return; } if(embedded==TRUE) return; printf("\n"); printf("\n"); printf("\n"); printf("NetSaint Availability\n"); printf("\n"); if(use_stylesheet==TRUE) printf("\n",url_stylesheets_path,AVAIL_CSS); printf("\n"); printf("\n"); return; } void document_footer(void){ if(output_format!=HTML_OUTPUT) return; if(embedded==TRUE) return; printf("\n"); printf("\n"); return; } int process_cgivars(void){ char **variables; int error=FALSE; int x; variables=getcgivars(); for(x=0;variables[x]!=NULL;x++){ /* do some basic length checking on the variable identifier to prevent buffer overflows */ if(strlen(variables[x])>=MAX_INPUT_BUFFER-1){ x++; continue; } /* we found the hostgroup argument */ else if(!strcmp(variables[x],"hostgroup")){ x++; if(variables[x]==NULL){ error=TRUE; break; } hostgroup_name=(char *)malloc(strlen(variables[x])+1); if(hostgroup_name==NULL) hostgroup_name=""; else strcpy(hostgroup_name,variables[x]); display_type=DISPLAY_HOSTGROUP_AVAIL; show_all_hostgroups=(strcmp(hostgroup_name,"all"))?FALSE:TRUE; } /* we found the host argument */ else if(!strcmp(variables[x],"host")){ x++; if(variables[x]==NULL){ error=TRUE; break; } host_name=(char *)malloc(strlen(variables[x])+1); if(host_name==NULL) host_name=""; else strcpy(host_name,variables[x]); display_type=DISPLAY_HOST_AVAIL; show_all_hosts=(strcmp(host_name,"all"))?FALSE:TRUE; } /* we found the service description argument */ else if(!strcmp(variables[x],"service")){ x++; if(variables[x]==NULL){ error=TRUE; break; } svc_description=(char *)malloc(strlen(variables[x])+1); if(svc_description==NULL) svc_description=""; else strcpy(svc_description,variables[x]); display_type=DISPLAY_SERVICE_AVAIL; show_all_services=(strcmp(svc_description,"all"))?FALSE:TRUE; } /* we found first time argument */ else if(!strcmp(variables[x],"t1")){ x++; if(variables[x]==NULL){ error=TRUE; break; } t1=(time_t)strtoul(variables[x],NULL,10); timeperiod_type=TIMEPERIOD_CUSTOM; compute_time_from_parts=FALSE; } /* we found first time argument */ else if(!strcmp(variables[x],"t2")){ x++; if(variables[x]==NULL){ error=TRUE; break; } t2=(time_t)strtoul(variables[x],NULL,10); timeperiod_type=TIMEPERIOD_CUSTOM; compute_time_from_parts=FALSE; } /* we found the assume initial states option */ else if(!strcmp(variables[x],"assumeinitialstates")){ x++; if(variables[x]==NULL){ error=TRUE; break; } if(!strcmp(variables[x],"on")) assume_initial_states=TRUE; else assume_initial_states=FALSE; } /* we found the assume initial state ok option */ else if(!strcmp(variables[x],"assumeinitialstateok")){ x++; if(variables[x]==NULL){ error=TRUE; break; } if(!strcmp(variables[x],"on")) assume_initial_state_ok=TRUE; else assume_initial_state_ok=FALSE; } /* we found the assume state retention option */ else if(!strcmp(variables[x],"assumestateretention")){ x++; if(variables[x]==NULL){ error=TRUE; break; } if(!strcmp(variables[x],"on")) assume_state_retention=TRUE; else assume_state_retention=FALSE; } /* we found the backtrack archives argument */ else if(!strcmp(variables[x],"backtrack")){ x++; if(variables[x]==NULL){ error=TRUE; break; } backtrack_archives=atoi(variables[x]); if(backtrack_archives<0) backtrack_archives=0; if(backtrack_archives>MAX_ARCHIVE_BACKTRACKS) backtrack_archives=MAX_ARCHIVE_BACKTRACKS; #ifdef DEBUG printf("BACKTRACK ARCHIVES: %d\n",backtrack_archives); #endif } /* we found the standard timeperiod argument */ else if(!strcmp(variables[x],"timeperiod")){ x++; if(variables[x]==NULL){ error=TRUE; break; } if(!strcmp(variables[x],"today")) timeperiod_type=TIMEPERIOD_TODAY; else if(!strcmp(variables[x],"yesterday")) timeperiod_type=TIMEPERIOD_YESTERDAY; else if(!strcmp(variables[x],"thisweek")) timeperiod_type=TIMEPERIOD_THISWEEK; else if(!strcmp(variables[x],"lastweek")) timeperiod_type=TIMEPERIOD_LASTWEEK; else if(!strcmp(variables[x],"thismonth")) timeperiod_type=TIMEPERIOD_THISMONTH; else if(!strcmp(variables[x],"lastmonth")) timeperiod_type=TIMEPERIOD_LASTMONTH; else if(!strcmp(variables[x],"thisquarter")) timeperiod_type=TIMEPERIOD_THISQUARTER; else if(!strcmp(variables[x],"lastquarter")) timeperiod_type=TIMEPERIOD_LASTQUARTER; else if(!strcmp(variables[x],"thisyear")) timeperiod_type=TIMEPERIOD_THISYEAR; else if(!strcmp(variables[x],"lastyear")) timeperiod_type=TIMEPERIOD_LASTYEAR; else if(!strcmp(variables[x],"last24hours")) timeperiod_type=TIMEPERIOD_LAST24HOURS; else if(!strcmp(variables[x],"last7days")) timeperiod_type=TIMEPERIOD_LAST7DAYS; else if(!strcmp(variables[x],"custom")) timeperiod_type=TIMEPERIOD_CUSTOM; else return error; convert_timeperiod_to_times(timeperiod_type); compute_time_from_parts=FALSE; } /* we found the embed option */ else if(!strcmp(variables[x],"embedded")) embedded=TRUE; /* we found the noheader option */ else if(!strcmp(variables[x],"noheader")) display_header=FALSE; /* we found the CSV output option */ else if(!strcmp(variables[x],"csvoutput")){ display_header=FALSE; output_format=CSV_OUTPUT; } /* we found the log entries option */ else if(!strcmp(variables[x],"show_log_entries")) show_log_entries=TRUE; /* we found the full log entries option */ else if(!strcmp(variables[x],"full_log_entries")) full_log_entries=TRUE; /* we found the get date parts option */ else if(!strcmp(variables[x],"get_date_parts")) get_date_parts=TRUE; /* we found the report type selection option */ else if(!strcmp(variables[x],"report_type")){ x++; if(variables[x]==NULL){ error=TRUE; break; } if(!strcmp(variables[x],"hostgroups")) select_hostgroups=TRUE; else if(!strcmp(variables[x],"hosts")) select_hosts=TRUE; else select_services=TRUE; } /* we found time argument */ else if(!strcmp(variables[x],"smon")){ x++; if(variables[x]==NULL){ error=TRUE; break; } start_month=atoi(variables[x]); timeperiod_type=TIMEPERIOD_CUSTOM; compute_time_from_parts=TRUE; } /* we found time argument */ else if(!strcmp(variables[x],"sday")){ x++; if(variables[x]==NULL){ error=TRUE; break; } start_day=atoi(variables[x]); timeperiod_type=TIMEPERIOD_CUSTOM; compute_time_from_parts=TRUE; } /* we found time argument */ else if(!strcmp(variables[x],"syear")){ x++; if(variables[x]==NULL){ error=TRUE; break; } start_year=atoi(variables[x]); timeperiod_type=TIMEPERIOD_CUSTOM; compute_time_from_parts=TRUE; } /* we found time argument */ else if(!strcmp(variables[x],"smin")){ x++; if(variables[x]==NULL){ error=TRUE; break; } start_minute=atoi(variables[x]); timeperiod_type=TIMEPERIOD_CUSTOM; compute_time_from_parts=TRUE; } /* we found time argument */ else if(!strcmp(variables[x],"ssec")){ x++; if(variables[x]==NULL){ error=TRUE; break; } start_second=atoi(variables[x]); timeperiod_type=TIMEPERIOD_CUSTOM; compute_time_from_parts=TRUE; } /* we found time argument */ else if(!strcmp(variables[x],"shour")){ x++; if(variables[x]==NULL){ error=TRUE; break; } start_hour=atoi(variables[x]); timeperiod_type=TIMEPERIOD_CUSTOM; compute_time_from_parts=TRUE; } /* we found time argument */ else if(!strcmp(variables[x],"emon")){ x++; if(variables[x]==NULL){ error=TRUE; break; } end_month=atoi(variables[x]); timeperiod_type=TIMEPERIOD_CUSTOM; compute_time_from_parts=TRUE; } /* we found time argument */ else if(!strcmp(variables[x],"eday")){ x++; if(variables[x]==NULL){ error=TRUE; break; } end_day=atoi(variables[x]); timeperiod_type=TIMEPERIOD_CUSTOM; compute_time_from_parts=TRUE; } /* we found time argument */ else if(!strcmp(variables[x],"eyear")){ x++; if(variables[x]==NULL){ error=TRUE; break; } end_year=atoi(variables[x]); timeperiod_type=TIMEPERIOD_CUSTOM; compute_time_from_parts=TRUE; } /* we found time argument */ else if(!strcmp(variables[x],"emin")){ x++; if(variables[x]==NULL){ error=TRUE; break; } end_minute=atoi(variables[x]); timeperiod_type=TIMEPERIOD_CUSTOM; compute_time_from_parts=TRUE; } /* we found time argument */ else if(!strcmp(variables[x],"esec")){ x++; if(variables[x]==NULL){ error=TRUE; break; } end_second=atoi(variables[x]); timeperiod_type=TIMEPERIOD_CUSTOM; compute_time_from_parts=TRUE; } /* we found time argument */ else if(!strcmp(variables[x],"ehour")){ x++; if(variables[x]==NULL){ error=TRUE; break; } end_hour=atoi(variables[x]); timeperiod_type=TIMEPERIOD_CUSTOM; compute_time_from_parts=TRUE; } } return error; } /* computes availability data for all subjects */ void compute_availability(void){ avail_subject *temp_subject; time_t current_time; time(¤t_time); for(temp_subject=subject_list;temp_subject!=NULL;temp_subject=temp_subject->next) compute_subject_availability(temp_subject,current_time); return; } /* computes availability data for a given subject */ void compute_subject_availability(avail_subject *subject,time_t current_time){ archived_state *temp_as; archived_state *last_as; time_t a; time_t b; int current_state=AS_NO_DATA; int graph_end_data=TRUE; int have_some_real_data=FALSE; hoststatus *hststatus=NULL; servicestatus *svcstatus=NULL; int first_real_state=AS_NO_DATA; int initial_assumed_state=AS_NO_DATA; time_t initial_assumed_time; int wobble=300; /* if left hand of graph is after current time, we can't do anything at all.... */ if(t1>current_time) return; /* check to see if we have any real data whatsoever... */ for(temp_as=subject->as_list;temp_as!=NULL;temp_as=temp_as->next){ if(temp_as->entry_type!=AS_NO_DATA && temp_as->entry_type!=AS_PROGRAM_START && temp_as->entry_type!=AS_PROGRAM_END){ have_some_real_data=TRUE; first_real_state=temp_as->entry_type; break; } } /* if we don't have any data, assume current state (if possible) */ if(have_some_real_data==FALSE){ /* current time DOES NOT fall within graph bounds, so we can't do anything */ /* the "wobble" value is necessary because when the CGI is called to do the PNG generation, t2 will actually be less that current_time by a bit */ if(current_time(t2+wobble)) return; if(subject->type==HOST_SUBJECT) subject->last_known_state=AS_HOST_UP; else subject->last_known_state=AS_SVC_OK; /* we don't have any historical information, but the current time falls within the reporting period, so use */ /* the current status of the host/service as the starting data */ if(subject->type==HOST_SUBJECT){ hststatus=find_hoststatus(host_name); if(hststatus!=NULL){ if(hststatus->status==HOST_DOWN) subject->last_known_state=AS_HOST_DOWN; else if(hststatus->status==HOST_UNREACHABLE) subject->last_known_state=AS_HOST_UNREACHABLE; else subject->last_known_state=AS_HOST_UP; } /* add a dummy archived state item, so something can get graphed */ add_archived_state(subject->last_known_state,t1,"Current Host State (Assumed)",subject); } else{ svcstatus=find_servicestatus(host_name,svc_description); if(svcstatus!=NULL){ if(svcstatus->status==SERVICE_OK || svcstatus->status==SERVICE_RECOVERY) subject->last_known_state=AS_SVC_OK; else if(svcstatus->status==SERVICE_WARNING) subject->last_known_state=AS_SVC_WARNING; else if(svcstatus->status==SERVICE_CRITICAL || svcstatus->status==SERVICE_HOST_DOWN || svcstatus->status==SERVICE_UNREACHABLE) subject->last_known_state=AS_SVC_CRITICAL; else if(svcstatus->status==SERVICE_UNKNOWN) subject->last_known_state=AS_SVC_UNKNOWN; } /* add a dummy archived state item, so something can get graphed */ add_archived_state(subject->last_known_state,t1,"Current Service State (Assumed)",subject); } } /* we do have some real data, so insert initial (assumed) state if we can */ else if(assume_initial_states==TRUE){ /* we're assuming initial states of either OK or UP (for service or host) */ if(assume_initial_state_ok==TRUE){ if(subject->type==HOST_SUBJECT) initial_assumed_state=AS_HOST_UP; else initial_assumed_state=AS_SVC_OK; } /* else assume initial state is the same as the first 'real' state we encountered */ else initial_assumed_state=first_real_state; /* add this assumed state entry before any entries in the list and <= t1 */ if(subject->as_list->time_stamp>t1) initial_assumed_time=t1; else initial_assumed_time=subject->as_list->time_stamp-1; /* add initial state as first entry */ if(subject->type==HOST_SUBJECT) add_archived_state(initial_assumed_state,initial_assumed_time,"Assumed Initial Host State (Faked Log Entry)",subject); else add_archived_state(initial_assumed_state,initial_assumed_time,"Assumed Initial Service State (Faked Log Entry)",subject); } last_as=NULL; subject->earliest_time=t2; subject->latest_time=t1; /**********************************/ /* BEGINNING/MIDDLE SECTION */ /**********************************/ for(temp_as=subject->as_list;temp_as!=NULL;temp_as=temp_as->next){ if(last_as!=NULL){ a=last_as->time_stamp; b=temp_as->time_stamp; /* we've already passed the last time displayed in the graph */ if(a>t2) break; /* only graph this data if its on the graph */ else if(b>t1){ /* clip last time if it exceeds graph limits */ if(b>t2) b=t2; /* clip first time if it preceeds graph limits */ if(aearliest_time){ subject->earliest_time=a; subject->earliest_state=last_as->entry_type; } /* save this time if its the latest we've graphed */ if(b>subject->latest_time){ subject->latest_time=b; subject->latest_state=last_as->entry_type; } /* compute availability times for this chunk */ compute_subject_availability_times(last_as->entry_type,temp_as->entry_type,last_as->time_stamp,a,b,subject); /* return if we've reached the end of the graph limits */ if(b>=t2) break; } /* else we're still before the first time on the graph, but keep this as the last know state (if possible) */ else if(b<=t1){ if(temp_as->entry_type!=AS_NO_DATA && temp_as->entry_type!=AS_PROGRAM_END && temp_as->entry_type!=AS_PROGRAM_START) subject->last_known_state=temp_as->entry_type; } } last_as=temp_as; /* special case for first entry in list */ if(temp_as==subject->as_list){ if(temp_as->entry_type!=AS_NO_DATA && temp_as->entry_type!=AS_PROGRAM_END && temp_as->entry_type!=AS_PROGRAM_START) subject->last_known_state=temp_as->entry_type; } } /**********************************/ /* END SECTION */ /**********************************/ if(subject->as_list!=NULL){ time(¤t_time); b=current_time; if(b>t2) b=t2; /* fake the current state (it doesn't really matter for graphing) */ if(subject->type==HOST_SUBJECT) current_state=AS_HOST_UP; else current_state=AS_SVC_OK; /***** SPECIAL CASE - THERE WAS ONLY ONE ENTRY IN THE LIST *****/ if(subject->latest_time<=t1){ compute_subject_availability_times(subject->as_list->entry_type,current_state,subject->as_list->time_stamp,subject->as_list->time_stamp,b,subject); } /***** NORMAL CASE - THERE WERE TWO OR MORE ENTRIES IN THE LIST *****/ else{ /* the timestamp on the last data point has to be within the graph bounds */ if(subject->latest_time < b){ compute_subject_availability_times(last_as->entry_type,current_state,subject->latest_time,subject->latest_time,b,subject); } } } return; } /* computes availability times */ void compute_subject_availability_times(int first_state,int last_state,time_t real_start_time,time_t start_time,time_t end_time,avail_subject *subject){ int start_state; int end_state; /* can't graph if we don't have data... */ if(first_state==AS_NO_DATA || last_state==AS_NO_DATA) return; if(first_state==AS_PROGRAM_START && (last_state==AS_PROGRAM_END || last_state==AS_PROGRAM_START)){ if(assume_initial_states==FALSE) return; } if(first_state==AS_PROGRAM_END) return; /* special case if first entry was program start */ if(first_state==AS_PROGRAM_START){ if(assume_initial_states==TRUE){ if(assume_state_retention==TRUE) start_state=subject->last_known_state; else{ if(subject->type==HOST_SUBJECT) start_state=AS_HOST_UP; else start_state=AS_SVC_OK; } } else return; } else{ start_state=first_state; subject->last_known_state=first_state; } /* special case if last entry was program stop */ if(last_state==AS_PROGRAM_END) end_state=first_state; else end_state=last_state; /* clip times if necessary */ if(start_timet2) end_time=t2; /* make sure this is a valid time */ if(start_time>t2) return; if(end_timetime_up+=(unsigned long)(end_time-start_time); break; case AS_HOST_DOWN: subject->time_down+=(unsigned long)(end_time-start_time); break; case AS_HOST_UNREACHABLE: subject->time_unreachable+=(unsigned long)(end_time-start_time); break; case AS_SVC_OK: subject->time_ok+=(unsigned long)(end_time-start_time); break; case AS_SVC_WARNING: subject->time_warning+=(unsigned long)(end_time-start_time); break; case AS_SVC_UNKNOWN: subject->time_unknown+=(unsigned long)(end_time-start_time); break; case AS_SVC_CRITICAL: subject->time_critical+=(unsigned long)(end_time-start_time); break; default: break; } return; } /* convert current host state to archived state value */ int convert_host_state_to_archived_state(int current_status){ if(current_status==HOST_UP) return AS_HOST_UP; if(current_status==HOST_DOWN) return AS_HOST_DOWN; if(current_status==HOST_UNREACHABLE) return AS_HOST_UNREACHABLE; return AS_NO_DATA; } /* convert current service state to archived state value */ int convert_service_state_to_archived_state(int current_status){ if(current_status==SERVICE_OK) return AS_SVC_OK; if(current_status==SERVICE_UNKNOWN) return AS_SVC_UNKNOWN; if(current_status==SERVICE_WARNING) return AS_SVC_WARNING; if(current_status==SERVICE_CRITICAL) return AS_SVC_CRITICAL; return AS_NO_DATA; } /* create list of subjects to collect availability data for */ void create_subject_list(void){ hostgroup *temp_hostgroup; host *temp_host; service *temp_service; /* we're displaying one or more hosts */ if(display_type==DISPLAY_HOST_AVAIL && host_name!=""){ /* we're only displaying a specific host (and summaries for all services associated with it) */ if(show_all_hosts==FALSE){ add_subject(HOST_SUBJECT,host_name,NULL); for(temp_service=service_list;temp_service!=NULL;temp_service=temp_service->next){ if(!strcmp(temp_service->host_name,host_name)) add_subject(SERVICE_SUBJECT,host_name,temp_service->description); } } /* we're displaying all hosts */ else{ for(temp_host=host_list;temp_host!=NULL;temp_host=temp_host->next) add_subject(HOST_SUBJECT,temp_host->name,NULL); } } /* we're displaying a specific service */ else if(display_type==DISPLAY_SERVICE_AVAIL && svc_description!=""){ /* we're only displaying a specific service */ if(show_all_services==FALSE) add_subject(SERVICE_SUBJECT,host_name,svc_description); /* we're displaying all services */ else{ for(temp_service=service_list;temp_service!=NULL;temp_service=temp_service->next) add_subject(SERVICE_SUBJECT,temp_service->host_name,temp_service->description); } } /* we're displaying one or more hostgroups (the host members of the groups) */ else if(display_type==DISPLAY_HOSTGROUP_AVAIL && hostgroup_name!=""){ /* we're displaying all hostgroups, so use all hosts */ if(show_all_hostgroups==TRUE){ for(temp_host=host_list;temp_host!=NULL;temp_host=temp_host->next) add_subject(HOST_SUBJECT,temp_host->name,NULL); } /* we're only displaying a specific hostgroup */ else{ temp_hostgroup=find_hostgroup(hostgroup_name,NULL); if(temp_hostgroup!=NULL){ for(temp_host=host_list;temp_host!=NULL;temp_host=temp_host->next){ if(is_host_member_of_hostgroup(temp_hostgroup,temp_host)==TRUE) add_subject(HOST_SUBJECT,temp_host->name,NULL); } } } } return; } /* adds a subject */ void add_subject(int subject_type, char *hn, char *sd){ avail_subject *last_subject=NULL; avail_subject *temp_subject=NULL; avail_subject *new_subject=NULL; int is_authorized=FALSE; /* see if the user is authorized to see data for this host or service */ if(subject_type==HOST_SUBJECT) is_authorized=is_authorized_for_host(find_host(hn,NULL),¤t_authdata); else is_authorized=is_authorized_for_service(find_service(hn,sd,NULL),¤t_authdata); if(is_authorized==FALSE) return; /* allocate memory for the new entry */ new_subject=(avail_subject *)malloc(sizeof(avail_subject)); if(new_subject==NULL) return; /* allocate memory fo the host name */ if(hn!=NULL){ new_subject->host_name=(char *)malloc(strlen(hn)+1); if(new_subject->host_name!=NULL) strcpy(new_subject->host_name,hn); } else new_subject->host_name=NULL; /* allocate memory fo the service description */ if(sd!=NULL){ new_subject->service_description=(char *)malloc(strlen(sd)+1); if(new_subject->service_description!=NULL) strcpy(new_subject->service_description,sd); } else new_subject->service_description=NULL; new_subject->type=subject_type; new_subject->earliest_state=AS_NO_DATA; new_subject->latest_state=AS_NO_DATA; new_subject->time_up=0L; new_subject->time_down=0L; new_subject->time_unreachable=0L; new_subject->time_ok=0L; new_subject->time_warning=0L; new_subject->time_unknown=0L; new_subject->time_critical=0L; new_subject->as_list=NULL; new_subject->last_known_state=AS_NO_DATA; /* add the new entry to the list in memory, sorted by host name */ last_subject=subject_list; for(temp_subject=subject_list;temp_subject!=NULL;temp_subject=temp_subject->next){ if(strcmp(new_subject->host_name,temp_subject->host_name)<0){ new_subject->next=temp_subject; if(temp_subject==subject_list) subject_list=new_subject; else last_subject->next=new_subject; break; } else last_subject=temp_subject; } if(subject_list==NULL){ new_subject->next=NULL; subject_list=new_subject; } else if(temp_subject==NULL){ new_subject->next=NULL; last_subject->next=new_subject; } return; } /* finds a specific subject */ avail_subject *find_subject(int type, char *hn, char *sd){ avail_subject *temp_subject; if(hn==NULL) return NULL; if(type==SERVICE_SUBJECT && sd==NULL) return NULL; for(temp_subject=subject_list;temp_subject!=NULL;temp_subject=temp_subject->next){ if(temp_subject->type!=type) continue; if(strcmp(hn,temp_subject->host_name)) continue; if(type==SERVICE_SUBJECT && strcmp(sd,temp_subject->service_description)) continue; return temp_subject; } return NULL; } /* adds an archived state entry to all subjects */ void add_global_archived_state(int state_type, time_t time_stamp, char *state_info){ avail_subject *temp_subject; for(temp_subject=subject_list;temp_subject!=NULL;temp_subject=temp_subject->next) add_archived_state(state_type,time_stamp,state_info,temp_subject); return; } /* adds an archived state entry to a specific subject */ void add_archived_state(int state_type, time_t time_stamp, char *state_info, avail_subject *subject){ archived_state *last_as=NULL; archived_state *temp_as=NULL; archived_state *new_as=NULL; /* allocate memory for the new entry */ new_as=(archived_state *)malloc(sizeof(archived_state)); if(new_as==NULL) return; /* allocate memory fo the state info */ if(state_info!=NULL){ new_as->state_info=(char *)malloc(strlen(state_info)+1); if(new_as->state_info!=NULL) strcpy(new_as->state_info,state_info); } else new_as->state_info=NULL; new_as->entry_type=state_type; new_as->time_stamp=time_stamp; /* add the new entry to the list in memory, sorted by time */ last_as=subject->as_list; for(temp_as=subject->as_list;temp_as!=NULL;temp_as=temp_as->next){ if(new_as->time_stamptime_stamp){ new_as->next=temp_as; if(temp_as==subject->as_list) subject->as_list=new_as; else last_as->next=new_as; break; } else last_as=temp_as; } if(subject->as_list==NULL){ new_as->next=NULL; subject->as_list=new_as; } else if(temp_as==NULL){ new_as->next=NULL; last_as->next=new_as; } return; } /* frees memory allocated to all availability data */ void free_availability_data(void){ avail_subject *this_subject; avail_subject *next_subject; for(this_subject=subject_list;this_subject!=NULL;){ next_subject=this_subject->next; if(this_subject->host_name!=NULL) free(this_subject->host_name); if(this_subject->service_description!=NULL) free(this_subject->service_description); free_archived_state_list(this_subject->as_list); free(this_subject); this_subject=next_subject; } return; } /* frees memory allocated to the archived state list */ void free_archived_state_list(archived_state *as_list){ archived_state *this_as=NULL; archived_state *next_as=NULL; for(this_as=as_list;this_as!=NULL;){ next_as=this_as->next; if(this_as->state_info!=NULL) free(this_as->state_info); free(this_as); this_as=next_as; } as_list=NULL; return; } /* reads log files for archived state data */ void read_archived_state_data(void){ char filename[MAX_FILENAME_LENGTH]; int oldest_archive=0; int newest_archive=0; int current_archive=0; /* determine oldest archive to use when scanning for data (include backtracked archives as well) */ oldest_archive=determine_archive_to_use_from_time(t1); if(log_rotation_method!=LOG_ROTATION_NONE) oldest_archive+=backtrack_archives; /* determine most recent archive to use when scanning for data */ newest_archive=determine_archive_to_use_from_time(t2); if(oldest_archivetm_sec=0; t->tm_min=0; t->tm_hour=0; switch(type){ case TIMEPERIOD_LAST24HOURS: t1=current_time-(60*60*24); t2=current_time; break; case TIMEPERIOD_TODAY: t1=mktime(t); t2=current_time; break; case TIMEPERIOD_YESTERDAY: t1=(time_t)(mktime(t)-(60*60*24)); t2=(time_t)mktime(t); break; case TIMEPERIOD_THISWEEK: t1=(time_t)(mktime(t)-(60*60*24*t->tm_wday)); t2=current_time; break; case TIMEPERIOD_LASTWEEK: t1=(time_t)(mktime(t)-(60*60*24*t->tm_wday)-(60*60*24*7)); t2=(time_t)(mktime(t)-(60*60*24*t->tm_wday)); break; case TIMEPERIOD_THISMONTH: t->tm_mday=1; t1=mktime(t); t2=current_time; break; case TIMEPERIOD_LASTMONTH: t->tm_mday=1; t2=mktime(t); if(t->tm_mon==0){ t->tm_mon=11; t->tm_year--; } else t->tm_mon--; t1=mktime(t); break; case TIMEPERIOD_THISQUARTER: /* not implemented */ break; case TIMEPERIOD_LASTQUARTER: /* not implemented */ break; case TIMEPERIOD_THISYEAR: t->tm_mon=0; t->tm_mday=1; t1=mktime(t); t2=current_time; break; case TIMEPERIOD_LASTYEAR: t->tm_mon=0; t->tm_mday=1; t2=mktime(t); t->tm_year--; t1=mktime(t); break; case TIMEPERIOD_LAST7DAYS: t2=current_time; t1=current_time-(7*24*60*60); break; default: break; } return; } void compute_report_times(void){ time_t current_time; struct tm *st; struct tm *et; /* get the current time */ time(¤t_time); st=localtime(¤t_time); st->tm_sec=start_second; st->tm_min=start_minute; st->tm_hour=start_hour; st->tm_mday=start_day; st->tm_mon=start_month-1; st->tm_year=start_year-1900; t1=mktime(st); et=localtime(¤t_time); et->tm_sec=end_second; et->tm_min=end_minute; et->tm_hour=end_hour; et->tm_mday=end_day; et->tm_mon=end_month-1; et->tm_year=end_year-1900; t2=mktime(et); } /* writes log entries to screen */ void write_log_entries(avail_subject *subject){ archived_state *temp_as; char start_date_time[MAX_DATETIME_LENGTH]; char end_date_time[MAX_DATETIME_LENGTH]; char duration[17]; char *bgclass=""; char *ebgclass=""; char *entry_type=""; int days; int hours; int minutes; int seconds; int odd=0; if(output_format!=HTML_OUTPUT) return; if(show_log_entries==FALSE) return; if(subject==NULL) return; printf("

\n"); printf("
%s Log Entries:
\n",(subject->type==HOST_SUBJECT)?"Host":"Service"); printf("
"); if(full_log_entries==TRUE){ full_log_entries=FALSE; if(subject->type==HOST_SUBJECT) host_report_url(subject->host_name,"[ View condensed log entries ]"); else service_report_url(subject->host_name,subject->service_description,"[ View condensed log entries ]"); full_log_entries=TRUE; } else{ full_log_entries=TRUE; if(subject->type==HOST_SUBJECT) host_report_url(subject->host_name,"[ View full log entries ]"); else service_report_url(subject->host_name,subject->service_description,"[ View full log entries ]"); full_log_entries=FALSE; } printf("
\n"); printf("
\n"); printf("\n"); printf("\n"); /* write all archived state entries */ for(temp_as=subject->as_list;temp_as!=NULL;temp_as=temp_as->next){ switch(temp_as->entry_type){ case AS_NO_DATA: if(full_log_entries==FALSE) continue; entry_type="NO DATA"; ebgclass="INDETERMINATE"; break; case AS_PROGRAM_END: if(full_log_entries==FALSE) continue; entry_type="PROGRAM END"; ebgclass="INDETERMINATE"; break; case AS_PROGRAM_START: if(full_log_entries==FALSE) continue; entry_type="PROGRAM (RE)START"; ebgclass="INDETERMINATE"; break; case AS_HOST_UP: entry_type="HOST UP"; ebgclass="UP"; break; case AS_HOST_DOWN: entry_type="HOST DOWN"; ebgclass="DOWN"; break; case AS_HOST_UNREACHABLE: entry_type="HOST UNREACHABLE"; ebgclass="UNREACHABLE"; break; case AS_SVC_OK: entry_type="SERVICE OK"; ebgclass="OK"; break; case AS_SVC_UNKNOWN: entry_type="SERVICE UNKNOWN"; ebgclass="UNKNOWN"; break; case AS_SVC_WARNING: entry_type="SERVICE WARNING"; ebgclass="WARNING"; break; case AS_SVC_CRITICAL: entry_type="SERVICE CRITICAL"; ebgclass="CRITICAL"; break; default: if(full_log_entries==FALSE) continue; entry_type="?"; ebgclass="INDETERMINATE"; } get_time_string(&(temp_as->time_stamp),start_date_time,sizeof(start_date_time)-1,SHORT_DATE_TIME); if(temp_as->next==NULL){ strcpy(end_date_time,"-"); strcpy(duration,"-"); } else{ get_time_string(&(temp_as->next->time_stamp),end_date_time,sizeof(end_date_time)-1,SHORT_DATE_TIME); get_time_breakdown((time_t)(temp_as->next->time_stamp-temp_as->time_stamp),&days,&hours,&minutes,&seconds); snprintf(duration,sizeof(duration)-1,"%dd %dh %dm %ds",days,hours,minutes,seconds); } if(odd){ bgclass="Odd"; odd=0; } else{ bgclass="Even"; odd=1; } printf("",bgclass); printf("",bgclass,start_date_time); printf("",bgclass,end_date_time); printf("",bgclass,duration); printf("",ebgclass,entry_type); printf("",bgclass,(temp_as->state_info==NULL)?"":temp_as->state_info); printf("\n"); } printf("
Event Start TimeEvent End TimeEvent DurationEvent/State TypeEvent/State Information
%s%s%s%s%s
\n"); printf("
\n"); return; } /* display hostgroup availability */ void display_hostgroup_availability(void){ hostgroup *temp_hostgroup; /* display data for a specific hostgroup */ if(show_all_hostgroups==FALSE){ temp_hostgroup=find_hostgroup(hostgroup_name,NULL); display_specific_hostgroup_availability(temp_hostgroup); } /* display data for all hostgroups */ else{ for(temp_hostgroup=hostgroup_list;temp_hostgroup!=NULL;temp_hostgroup=temp_hostgroup->next) display_specific_hostgroup_availability(temp_hostgroup); } return; } /* display availability for a specific hostgroup */ void display_specific_hostgroup_availability(hostgroup *hg){ unsigned long total_time; unsigned long time_determinate; unsigned long time_indeterminate; avail_subject *temp_subject; double percent_time_up=0.0; double percent_time_down=0.0; double percent_time_unreachable=0.0; double percent_time_up_known=0.0; double percent_time_down_known=0.0; double percent_time_unreachable_known=0.0; double percent_time_indeterminate=0.0; char *bgclass=""; int odd=1; host *temp_host; if(hg==NULL) return; /* the user isn't authorized to view this hostgroup */ if(is_authorized_for_hostgroup(hg,¤t_authdata)==FALSE) return; total_time=t2-t1; printf("

\n"); printf("
Hostgroup '%s' Host State Breakdowns:
\n",hg->group_name); printf("
\n"); printf("\n"); printf("\n"); for(temp_subject=subject_list;temp_subject!=NULL;temp_subject=temp_subject->next){ if(temp_subject->type!=HOST_SUBJECT) continue; temp_host=find_host(temp_subject->host_name,NULL); if(temp_host==NULL) continue; if(is_host_member_of_hostgroup(hg,temp_host)==FALSE) continue; /* reset variables */ percent_time_up=0.0; percent_time_down=0.0; percent_time_unreachable=0.0; percent_time_indeterminate=0.0; percent_time_up_known=0.0; percent_time_down_known=0.0; percent_time_unreachable_known=0.0; time_determinate=temp_subject->time_up+temp_subject->time_down+temp_subject->time_unreachable; time_indeterminate=total_time-time_determinate; if(total_time>0){ percent_time_up=(double)(((double)temp_subject->time_up*100.0)/(double)total_time); percent_time_down=(double)(((double)temp_subject->time_down*100.0)/(double)total_time); percent_time_unreachable=(double)(((double)temp_subject->time_unreachable*100.0)/(double)total_time); percent_time_indeterminate=(double)(((double)time_indeterminate*100.0)/(double)total_time); if(time_determinate>0){ percent_time_up_known=(double)(((double)temp_subject->time_up*100.0)/(double)time_determinate); percent_time_down_known=(double)(((double)temp_subject->time_down*100.0)/(double)time_determinate); percent_time_unreachable_known=(double)(((double)temp_subject->time_unreachable*100.0)/(double)time_determinate); } } if(odd){ odd=0; bgclass="Odd"; } else{ odd=1; bgclass="Even"; } printf("\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); } printf("
Host%% Time Up%% Time Down%% Time Unreachable%% Time Undetermined
",bgclass,bgclass); host_report_url(temp_subject->host_name,temp_subject->host_name); printf("%2.2f%% (%2.2f%%)%2.2f%% (%2.2f%%)%2.2f%% (%2.2f%%)%2.2f%%
\n"); printf("
\n"); return; } /* display host availability */ void display_host_availability(void){ unsigned long total_time; unsigned long time_determinate; unsigned long time_indeterminate; avail_subject *temp_subject; host *temp_host; service *temp_service; int days, hours, minutes, seconds; char time_indeterminate_string[48]; char time_determinate_string[48]; char total_time_string[48]; double percent_time_ok=0.0; double percent_time_warning=0.0; double percent_time_unknown=0.0; double percent_time_critical=0.0; double percent_time_indeterminate=0.0; double percent_time_ok_known=0.0; double percent_time_warning_known=0.0; double percent_time_unknown_known=0.0; double percent_time_critical_known=0.0; char time_up_string[48]; char time_down_string[48]; char time_unreachable_string[48]; double percent_time_up=0.0; double percent_time_down=0.0; double percent_time_unreachable=0.0; double percent_time_up_known=0.0; double percent_time_down_known=0.0; double percent_time_unreachable_known=0.0; char *bgclass=""; int odd=1; total_time=t2-t1; /* show data for a specific host */ if(show_all_hosts==FALSE){ temp_subject=find_subject(HOST_SUBJECT,host_name,NULL); if(temp_subject==NULL) return; temp_host=find_host(temp_subject->host_name,NULL); if(temp_host==NULL) return; /* the user isn't authorized to view this host */ if(is_authorized_for_host(temp_host,¤t_authdata)==FALSE) return; time_determinate=temp_subject->time_up+temp_subject->time_down+temp_subject->time_unreachable; time_indeterminate=total_time-time_determinate; get_time_breakdown(temp_subject->time_up,&days,&hours,&minutes,&seconds); snprintf(time_up_string,sizeof(time_up_string)-1,"%dd %dh %dm %ds",days,hours,minutes,seconds); get_time_breakdown(temp_subject->time_down,&days,&hours,&minutes,&seconds); snprintf(time_down_string,sizeof(time_down_string)-1,"%dd %dh %dm %ds",days,hours,minutes,seconds); get_time_breakdown(temp_subject->time_unreachable,&days,&hours,&minutes,&seconds); snprintf(time_unreachable_string,sizeof(time_unreachable_string)-1,"%dd %dh %dm %ds",days,hours,minutes,seconds); get_time_breakdown(time_indeterminate,&days,&hours,&minutes,&seconds); snprintf(time_indeterminate_string,sizeof(time_indeterminate_string)-1,"%dd %dh %dm %ds",days,hours,minutes,seconds); get_time_breakdown(time_determinate,&days,&hours,&minutes,&seconds); snprintf(time_determinate_string,sizeof(time_determinate_string)-1,"%dd %dh %dm %ds",days,hours,minutes,seconds); get_time_breakdown(total_time,&days,&hours,&minutes,&seconds); snprintf(total_time_string,sizeof(total_time_string)-1,"%dd %dh %dm %ds",days,hours,minutes,seconds); if(total_time>0){ percent_time_up=(double)(((double)temp_subject->time_up*100.0)/(double)total_time); percent_time_down=(double)(((double)temp_subject->time_down*100.0)/(double)total_time); percent_time_unreachable=(double)(((double)temp_subject->time_unreachable*100.0)/(double)total_time); percent_time_indeterminate=(double)(((double)time_indeterminate*100.0)/(double)total_time); if(time_determinate>0){ percent_time_up_known=(double)(((double)temp_subject->time_up*100.0)/(double)time_determinate); percent_time_down_known=(double)(((double)temp_subject->time_down*100.0)/(double)time_determinate); percent_time_unreachable_known=(double)(((double)temp_subject->time_unreachable*100.0)/(double)time_determinate); } } printf("
Host State Breakdowns:
\n"); printf("
\n"); printf("\n"); printf("\n"); printf("\n",time_up_string,percent_time_up,percent_time_up_known); printf("\n",time_down_string,percent_time_down,percent_time_down_known); printf("\n",time_unreachable_string,percent_time_unreachable,percent_time_unreachable_known); printf("\n",time_indeterminate_string,percent_time_indeterminate); printf("\n"); printf("\n",total_time_string); printf("
StateTime%% Total Time%% Known Time
UP%s%2.2f%%%2.2f%%
DOWN%s%2.2f%%%2.2f%%
UNREACHABLE%s%2.2f%%%2.2f%%
Undetermined%s%2.2f%%
All%s100.0%%100.0%%
\n"); printf("
\n"); /* display state breakdowns for all services on this host */ printf("

\n"); printf("
State Breakdowns For Host Services:
\n"); printf("
\n"); printf("\n"); printf("\n"); for(temp_subject=subject_list;temp_subject!=NULL;temp_subject=temp_subject->next){ if(temp_subject->type!=SERVICE_SUBJECT) continue; temp_service=find_service(temp_subject->host_name,temp_subject->service_description,NULL); if(temp_service==NULL) continue; /* the user isn't authorized to view this service */ if(is_authorized_for_service(temp_service,¤t_authdata)==FALSE) continue; if(odd){ odd=0; bgclass="Odd"; } else{ odd=1; bgclass="Even"; } /* reset variables */ percent_time_ok=0.0; percent_time_warning=0.0; percent_time_unknown=0.0; percent_time_critical=0.0; percent_time_indeterminate=0.0; percent_time_ok_known=0.0; percent_time_warning_known=0.0; percent_time_unknown_known=0.0; percent_time_critical_known=0.0; time_determinate=temp_subject->time_ok+temp_subject->time_warning+temp_subject->time_unknown+temp_subject->time_critical; time_indeterminate=total_time-time_determinate; if(total_time>0){ percent_time_ok=(double)(((double)temp_subject->time_ok*100.0)/(double)total_time); percent_time_warning=(double)(((double)temp_subject->time_warning*100.0)/(double)total_time); percent_time_unknown=(double)(((double)temp_subject->time_unknown*100.0)/(double)total_time); percent_time_critical=(double)(((double)temp_subject->time_critical*100.0)/(double)total_time); percent_time_indeterminate=(double)(((double)time_indeterminate*100.0)/(double)total_time); if(time_determinate>0){ percent_time_ok_known=(double)(((double)temp_subject->time_ok*100.0)/(double)time_determinate); percent_time_warning_known=(double)(((double)temp_subject->time_warning*100.0)/(double)time_determinate); percent_time_unknown_known=(double)(((double)temp_subject->time_unknown*100.0)/(double)time_determinate); percent_time_critical_known=(double)(((double)temp_subject->time_critical*100.0)/(double)time_determinate); } } printf("\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); } printf("
Service%% Time OK%% Time Warning%% Time Unknown%% Time Critical%% Time Undetermined
",bgclass,bgclass); service_report_url(temp_subject->host_name,temp_subject->service_description,temp_subject->service_description); printf("%2.2f%% (%2.2f%%)%2.2f%% (%2.2f%%)%2.2f%% (%2.2f%%)%2.2f%% (%2.2f%%)%2.2f%%
\n"); printf("
\n"); /* write log entries for the host */ temp_subject=find_subject(HOST_SUBJECT,host_name,NULL); write_log_entries(temp_subject); } /* display data for all hosts */ else{ if(output_format==HTML_OUTPUT){ printf("

\n"); printf("
Host State Breakdowns:
\n"); printf("
\n"); printf("\n"); printf("\n"); } else if(output_format==CSV_OUTPUT) printf("HOST_NAME, TIME_UP, PERCENT_TOTAL_TIME_UP, PERCENT_KNOWN_TIME_UP, TIME_DOWN, PERCENT_TOTAL_TIME_DOWN, PERCENT_KNOWN_TIME_DOWN, TIME_UNREACHABLE, PERCENT_TOTAL_TIME_UNREACHABLE, PERCENT_KNOWN_TIME_UNREACHABLE, TIME_UNDETERMINED, PERCENT_TOTAL_TIME_UNDETERMINED\n"); for(temp_subject=subject_list;temp_subject!=NULL;temp_subject=temp_subject->next){ if(temp_subject->type!=HOST_SUBJECT) continue; temp_host=find_host(temp_subject->host_name,NULL); if(temp_host==NULL) continue; /* the user isn't authorized to view this host */ if(is_authorized_for_host(temp_host,¤t_authdata)==FALSE) continue; /* reset variables */ percent_time_up=0.0; percent_time_down=0.0; percent_time_unreachable=0.0; percent_time_indeterminate=0.0; percent_time_up_known=0.0; percent_time_down_known=0.0; percent_time_unreachable_known=0.0; time_determinate=temp_subject->time_up+temp_subject->time_down+temp_subject->time_unreachable; time_indeterminate=total_time-time_determinate; if(total_time>0){ percent_time_up=(double)(((double)temp_subject->time_up*100.0)/(double)total_time); percent_time_down=(double)(((double)temp_subject->time_down*100.0)/(double)total_time); percent_time_unreachable=(double)(((double)temp_subject->time_unreachable*100.0)/(double)total_time); percent_time_indeterminate=(double)(((double)time_indeterminate*100.0)/(double)total_time); if(time_determinate>0){ percent_time_up_known=(double)(((double)temp_subject->time_up*100.0)/(double)time_determinate); percent_time_down_known=(double)(((double)temp_subject->time_down*100.0)/(double)time_determinate); percent_time_unreachable_known=(double)(((double)temp_subject->time_unreachable*100.0)/(double)time_determinate); } } if(odd){ odd=0; bgclass="Odd"; } else{ odd=1; bgclass="Even"; } if(output_format==HTML_OUTPUT){ printf("\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); } else if(output_format==CSV_OUTPUT){ printf("\"%s\", %lu, %2.2f%%, %2.2f%%, %lu, %2.2f%%, %2.2f%%, %lu, %2.2f%%, %2.2f%%, %lu, %2.2f%%\n",temp_subject->host_name,temp_subject->time_up,percent_time_up,percent_time_up_known,temp_subject->time_down,percent_time_down,percent_time_down_known,temp_subject->time_unreachable,percent_time_unreachable,percent_time_unreachable_known,time_indeterminate,percent_time_indeterminate); } } if(output_format==HTML_OUTPUT){ printf("
Host%% Time Up%% Time Down%% Time Unreachable%% Time Undetermined
",bgclass,bgclass); host_report_url(temp_subject->host_name,temp_subject->host_name); printf("%2.2f%% (%2.2f%%)%2.2f%% (%2.2f%%)%2.2f%% (%2.2f%%)%2.2f%%
\n"); printf("
\n"); } } return; } /* display service availability */ void display_service_availability(void){ unsigned long total_time; unsigned long time_determinate; unsigned long time_indeterminate; avail_subject *temp_subject; service *temp_service; int days, hours, minutes, seconds; char time_ok_string[48]; char time_warning_string[48]; char time_unknown_string[48]; char time_critical_string[48]; char time_indeterminate_string[48]; char time_determinate_string[48]; char total_time_string[48]; double percent_time_ok=0.0; double percent_time_warning=0.0; double percent_time_unknown=0.0; double percent_time_critical=0.0; double percent_time_indeterminate=0.0; double percent_time_ok_known=0.0; double percent_time_warning_known=0.0; double percent_time_unknown_known=0.0; double percent_time_critical_known=0.0; int odd=1; char *bgclass=""; char last_host[128]=""; total_time=t2-t1; /* we're only getting data for one service */ if(show_all_services==FALSE){ temp_subject=find_subject(SERVICE_SUBJECT,host_name,svc_description); if(temp_subject==NULL) return; temp_service=find_service(temp_subject->host_name,temp_subject->service_description,NULL); if(temp_service==NULL) return; /* the user isn't authorized to view this service */ if(is_authorized_for_service(temp_service,¤t_authdata)==FALSE) return; time_determinate=temp_subject->time_ok+temp_subject->time_warning+temp_subject->time_unknown+temp_subject->time_critical; time_indeterminate=total_time-time_determinate; get_time_breakdown(temp_subject->time_ok,&days,&hours,&minutes,&seconds); snprintf(time_ok_string,sizeof(time_ok_string)-1,"%dd %dh %dm %ds",days,hours,minutes,seconds); get_time_breakdown(temp_subject->time_warning,&days,&hours,&minutes,&seconds); snprintf(time_warning_string,sizeof(time_warning_string)-1,"%dd %dh %dm %ds",days,hours,minutes,seconds); get_time_breakdown(temp_subject->time_unknown,&days,&hours,&minutes,&seconds); snprintf(time_unknown_string,sizeof(time_unknown_string)-1,"%dd %dh %dm %ds",days,hours,minutes,seconds); get_time_breakdown(temp_subject->time_critical,&days,&hours,&minutes,&seconds); snprintf(time_critical_string,sizeof(time_critical_string)-1,"%dd %dh %dm %ds",days,hours,minutes,seconds); get_time_breakdown(time_indeterminate,&days,&hours,&minutes,&seconds); snprintf(time_indeterminate_string,sizeof(time_indeterminate_string)-1,"%dd %dh %dm %ds",days,hours,minutes,seconds); get_time_breakdown(time_determinate,&days,&hours,&minutes,&seconds); snprintf(time_determinate_string,sizeof(time_determinate_string)-1,"%dd %dh %dm %ds",days,hours,minutes,seconds); get_time_breakdown(total_time,&days,&hours,&minutes,&seconds); snprintf(total_time_string,sizeof(total_time_string)-1,"%dd %dh %dm %ds",days,hours,minutes,seconds); if(total_time>0){ percent_time_ok=(double)(((double)temp_subject->time_ok*100.0)/(double)total_time); percent_time_warning=(double)(((double)temp_subject->time_warning*100.0)/(double)total_time); percent_time_unknown=(double)(((double)temp_subject->time_unknown*100.0)/(double)total_time); percent_time_critical=(double)(((double)temp_subject->time_critical*100.0)/(double)total_time); percent_time_indeterminate=(double)(((double)time_indeterminate*100.0)/(double)total_time); if(time_determinate>0){ percent_time_ok_known=(double)(((double)temp_subject->time_ok*100.0)/(double)time_determinate); percent_time_warning_known=(double)(((double)temp_subject->time_warning*100.0)/(double)time_determinate); percent_time_unknown_known=(double)(((double)temp_subject->time_unknown*100.0)/(double)time_determinate); percent_time_critical_known=(double)(((double)temp_subject->time_critical*100.0)/(double)time_determinate); } } printf("
Service State Breakdowns:
\n"); printf("
\n"); printf("\n"); printf("\n"); printf("\n",time_ok_string,percent_time_ok,percent_time_ok_known); printf("\n",time_warning_string,percent_time_warning,percent_time_warning_known); printf("\n",time_unknown_string,percent_time_unknown,percent_time_unknown_known); printf("\n",time_critical_string,percent_time_critical,percent_time_critical_known); printf("\n",time_indeterminate_string,percent_time_indeterminate); printf("\n"); printf("\n",total_time_string); printf("
StateTime%% Total Time%% Known Time
OK%s%2.2f%%%2.2f%%
WARNING%s%2.2f%%%2.2f%%
UNKNOWN%s%2.2f%%%2.2f%%
CRITICAL%s%2.2f%%%2.2f%%
Undetermined%s%2.2f%%
All%s100.0%%100.0%%
\n"); printf("
\n"); write_log_entries(temp_subject); } /* display data for all services */ else{ if(output_format==HTML_OUTPUT){ printf("
Service State Breakdowns:
\n"); printf("
\n"); printf("\n"); printf("\n"); } else if(output_format==CSV_OUTPUT) printf("HOST_NAME, SERVICE_DESCRIPTION, TIME_OK, PERCENT_TOTAL_TIME_OK, PERCENT_KNOWN_TIME_OK, TIME_WARNING, PERCENT_TOTAL_TIME_WARNING, PERCENT_KNOWN_TIME_WARNING, TIME_UNKNOWN, PERCENT_TOTAL_TIME_UNKNOWN, PERCENT_KNOWN_TIME_UNKNOWN, TIME_CRITICAL, PERCENT_TOTAL_TIME_CRITICAL, PERCENT_KNOWN_TIME_CRITICAL, TIME_UNDETERMINED, PERCENT_TOTAL_TIME_UNDETERMINED\n"); for(temp_subject=subject_list;temp_subject!=NULL;temp_subject=temp_subject->next){ if(temp_subject->type!=SERVICE_SUBJECT) continue; temp_service=find_service(temp_subject->host_name,temp_subject->service_description,NULL); if(temp_service==NULL) continue; /* the user isn't authorized to view this service */ if(is_authorized_for_service(temp_service,¤t_authdata)==FALSE) continue; time_determinate=temp_subject->time_ok+temp_subject->time_warning+temp_subject->time_unknown+temp_subject->time_critical; time_indeterminate=total_time-time_determinate; if(total_time>0){ percent_time_ok=(double)(((double)temp_subject->time_ok*100.0)/(double)total_time); percent_time_warning=(double)(((double)temp_subject->time_warning*100.0)/(double)total_time); percent_time_unknown=(double)(((double)temp_subject->time_unknown*100.0)/(double)total_time); percent_time_critical=(double)(((double)temp_subject->time_critical*100.0)/(double)total_time); percent_time_indeterminate=(double)(((double)time_indeterminate*100.0)/(double)total_time); if(time_determinate>0){ percent_time_ok_known=(double)(((double)temp_subject->time_ok*100.0)/(double)time_determinate); percent_time_warning_known=(double)(((double)temp_subject->time_warning*100.0)/(double)time_determinate); percent_time_unknown_known=(double)(((double)temp_subject->time_unknown*100.0)/(double)time_determinate); percent_time_critical_known=(double)(((double)temp_subject->time_critical*100.0)/(double)time_determinate); } } if(odd){ odd=0; bgclass="Odd"; } else{ odd=1; bgclass="Even"; } if(output_format==HTML_OUTPUT){ printf("\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); } else if(output_format==CSV_OUTPUT){ printf("\"%s\", \"%s\", %lu, %2.2f%%, %2.2f%%, %lu, %2.2f%%, %2.2f%%, %lu, %2.2f%%, %2.2f%%, %lu, %2.2f%%, %2.2f%%, %lu, %2.2f%%\n",temp_subject->host_name,temp_subject->service_description,temp_subject->time_ok,percent_time_ok,percent_time_ok_known,temp_subject->time_warning,percent_time_warning,percent_time_warning_known,temp_subject->time_unknown,percent_time_unknown,percent_time_unknown_known,temp_subject->time_critical,percent_time_critical,percent_time_critical_known,time_indeterminate,percent_time_indeterminate); } strncpy(last_host,temp_subject->host_name,sizeof(last_host)-1); last_host[sizeof(last_host)-1]='\x0'; } if(output_format==HTML_OUTPUT){ printf("
HostService%% Time OK%% Time Warning%% Time Unknown%% Time Critical%% Time Undetermined
",bgclass,bgclass); if(strcmp(temp_subject->host_name,last_host)) host_report_url(temp_subject->host_name,temp_subject->host_name); printf("",bgclass); service_report_url(temp_subject->host_name,temp_subject->service_description,temp_subject->service_description); printf("%2.2f%% (%2.2f%%)%2.2f%% (%2.2f%%)%2.2f%% (%2.2f%%)%2.2f%% (%2.2f%%)%2.2f%%
\n"); printf("
\n"); } } return; } void host_report_url(char *hn, char *label){ printf("%s",label); return; } void service_report_url(char *hn, char *sd, char *label){ printf("%s",label); return; }