/**************************************************************************
*
* HISTOGRAM.C - Nagios Alert Histogram CGI
*
* Copyright (c) 2001-2007 Ethan Galstad (nagios@nagios.org)
* Last Modified: 10-21-2007
*
* License:
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*************************************************************************/
#include "../include/config.h"
#include "../include/common.h"
#include "../include/objects.h"
#include "../include/statusdata.h"
#include "../include/cgiutils.h"
#include "../include/getcgi.h"
#include "../include/cgiauth.h"
#include /* Boutell's GD library function */
#include /* GD library small font definition */
/*#define DEBUG 1*/
#define HISTOGRAM_IMAGE "histogram.png"
/* archived state types */
#define AS_NO_DATA 0
#define AS_PROGRAM_START 1
#define AS_PROGRAM_END 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_HOST_HISTOGRAM 0
#define DISPLAY_SERVICE_HISTOGRAM 1
#define DISPLAY_NO_HISTOGRAM 2
/* input types */
#define GET_INPUT_NONE 0
#define GET_INPUT_TARGET_TYPE 1
#define GET_INPUT_HOST_TARGET 2
#define GET_INPUT_SERVICE_TARGET 3
#define GET_INPUT_OPTIONS 4
/* breakdown types */
#define BREAKDOWN_MONTHLY 0
#define BREAKDOWN_DAY_OF_MONTH 1
#define BREAKDOWN_DAY_OF_WEEK 2
#define BREAKDOWN_HOURLY 3
/* modes */
#define CREATE_HTML 0
#define CREATE_IMAGE 1
/* standard report times */
#define TIMEPERIOD_CUSTOM 0
#define TIMEPERIOD_TODAY 1
#define TIMEPERIOD_YESTERDAY 2
#define TIMEPERIOD_THISWEEK 3
#define TIMEPERIOD_LASTWEEK 4
#define TIMEPERIOD_THISMONTH 5
#define TIMEPERIOD_LASTMONTH 6
#define TIMEPERIOD_THISQUARTER 7
#define TIMEPERIOD_LASTQUARTER 8
#define TIMEPERIOD_THISYEAR 9
#define TIMEPERIOD_LASTYEAR 10
#define TIMEPERIOD_LAST24HOURS 11
#define TIMEPERIOD_LAST7DAYS 12
#define TIMEPERIOD_LAST31DAYS 13
#define MAX_ARCHIVE_SPREAD 65
#define MAX_ARCHIVE 65
#define MAX_ARCHIVE_BACKTRACKS 60
#define DRAWING_WIDTH 550
#define DRAWING_HEIGHT 195
#define DRAWING_X_OFFSET 60
#define DRAWING_Y_OFFSET 235
#define GRAPH_HOST_UP 1
#define GRAPH_HOST_DOWN 2
#define GRAPH_HOST_UNREACHABLE 4
#define GRAPH_SERVICE_OK 8
#define GRAPH_SERVICE_WARNING 16
#define GRAPH_SERVICE_UNKNOWN 32
#define GRAPH_SERVICE_CRITICAL 64
#define GRAPH_HOST_PROBLEMS 6
#define GRAPH_HOST_ALL 7
#define GRAPH_SERVICE_PROBLEMS 112
#define GRAPH_SERVICE_ALL 120
#define GRAPH_EVERYTHING 255
#define GRAPH_SOFT_STATETYPES 1
#define GRAPH_HARD_STATETYPES 2
#define GRAPH_ALL_STATETYPES 3
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 char physical_images_path[MAX_FILENAME_LENGTH];
extern int log_rotation_method;
extern host *host_list;
extern service *service_list;
authdata current_authdata;
typedef struct timeslice_data_struct{
unsigned long service_ok;
unsigned long host_up;
unsigned long service_critical;
unsigned long host_down;
unsigned long service_unknown;
unsigned long host_unreachable;
unsigned long service_warning;
}timeslice_data;
timeslice_data *tsdata;
void convert_timeperiod_to_times(int);
void compute_report_times(void);
void graph_all_histogram_data(void);
void add_archived_state(int,time_t);
void read_archived_state_data(void);
void scan_log_file_for_archived_state_data(char *);
void draw_line(int,int,int,int,int);
void draw_dashed_line(int,int,int,int,int);
void document_header(int);
void document_footer(void);
int process_cgivars(void);
time_t t1;
time_t t2;
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 display_type=DISPLAY_NO_HISTOGRAM;
int mode=CREATE_HTML;
int input_type=GET_INPUT_NONE;
int timeperiod_type=TIMEPERIOD_LAST24HOURS;
int breakdown_type=BREAKDOWN_HOURLY;
int compute_time_from_parts=FALSE;
int initial_states_logged=FALSE;
int assume_state_retention=TRUE;
int new_states_only=FALSE;
int last_state=AS_NO_DATA;
int program_restart_has_occurred=FALSE;
int graph_events=GRAPH_EVERYTHING;
int graph_statetypes=GRAPH_HARD_STATETYPES;
int embedded=FALSE;
int display_header=TRUE;
char *host_name="";
char *svc_description="";
gdImagePtr histogram_image=0;
int color_white=0;
int color_black=0;
int color_red=0;
int color_darkred=0;
int color_green=0;
int color_yellow=0;
int color_orange=0;
int color_lightgray=0;
FILE *image_file=NULL;
int backtrack_archives=0;
int earliest_archive=0;
time_t earliest_time;
time_t latest_time;
int image_width=900;
int image_height=320;
int total_buckets=96;
int main(int argc, char **argv){
int result=OK;
char temp_buffer[MAX_INPUT_BUFFER];
char image_template[MAX_INPUT_BUFFER];
char start_timestring[MAX_INPUT_BUFFER];
char end_timestring[MAX_INPUT_BUFFER];
host *temp_host;
service *temp_service;
int is_authorized=TRUE;
int found=FALSE;
int days,hours,minutes,seconds;
char *first_service=NULL;
int x;
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(get_cgi_config_location());
if(result==ERROR){
if(mode==CREATE_HTML){
document_header(FALSE);
cgi_config_file_error(get_cgi_config_location());
document_footer();
}
return ERROR;
}
/* read the main configuration file */
result=read_main_config_file(main_config_file);
if(result==ERROR){
if(mode==CREATE_HTML){
document_header(FALSE);
main_config_file_error(main_config_file);
document_footer();
}
return ERROR;
}
/* read all object configuration data */
result=read_all_object_configuration_data(main_config_file,READ_ALL_OBJECT_DATA);
if(result==ERROR){
if(mode==CREATE_HTML){
document_header(FALSE);
object_data_error();
document_footer();
}
return ERROR;
}
/* read all status data */
result=read_all_status_data(get_cgi_config_location(),READ_ALL_STATUS_DATA);
if(result==ERROR){
if(mode==CREATE_HTML){
document_header(FALSE);
status_data_error();
document_footer();
}
free_memory();
return ERROR;
}
document_header(TRUE);
/* get authentication information */
get_authentication_information(¤t_authdata);
if(compute_time_from_parts==TRUE)
compute_report_times();
/* make sure times are sane, otherwise swap them */
if(t2\n");
printf("
\n");
}
/* read and process state data */
else{
/* allocate memory */
tsdata=NULL;
if(breakdown_type==BREAKDOWN_MONTHLY)
total_buckets=12;
else if(breakdown_type==BREAKDOWN_DAY_OF_MONTH)
total_buckets=31;
else if(breakdown_type==BREAKDOWN_DAY_OF_WEEK)
total_buckets=7;
else
total_buckets=96;
tsdata=(timeslice_data *)malloc(sizeof(timeslice_data)*total_buckets);
if(tsdata==NULL)
return ERROR;
for(x=0;x
\n");
printf("
Step 2: Select Host
\n");
printf("
\n");
printf("
\n");
printf("
\n");
printf("\n");
printf("
\n");
printf("
\n");
}
/* ask the user for what service they want a report for */
else if(input_type==GET_INPUT_SERVICE_TARGET){
printf("\n");
printf("
\n");
printf("
Step 2: Select Service
\n");
printf("
\n");
printf("
\n");
printf("
\n");
printf("\n");
printf("
\n");
printf("
\n");
}
/* ask the user for report range and options */
else if(input_type==GET_INPUT_OPTIONS){
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("
\n");
printf("
Step 3: Select Report Options
\n");
printf("
\n");
printf("
\n");
printf("
\n");
printf("\n");
printf("
\n");
printf("
\n");
}
/* as the user whether they want a graph for a host or service */
else{
printf("
\n");
printf("
Step 1: Select Report Type
\n");
printf("
\n");
printf("
\n");
printf("
\n");
printf("\n");
printf("
\n");
printf("
\n");
}
}
document_footer();
/* free all other allocated memory */
free_memory();
return OK;
}
void document_header(int use_stylesheet){
char date_time[MAX_DATETIME_LENGTH];
time_t current_time;
time_t expire_time;
if(mode==CREATE_HTML){
printf("Cache-Control: no-store\r\n");
printf("Pragma: no-cache\r\n");
time(¤t_time);
get_time_string(¤t_time,date_time,sizeof(date_time),HTTP_DATE_TIME);
printf("Last-Modified: %s\r\n",date_time);
expire_time=(time_t)0;
get_time_string(&expire_time,date_time,sizeof(date_time),HTTP_DATE_TIME);
printf("Expires: %s\r\n",date_time);
printf("Content-type: text/html\r\n\r\n");
if(embedded==TRUE)
return;
printf("\n");
printf("\n");
printf("\n");
printf("Nagios Histogram\n");
printf("\n");
if(use_stylesheet==TRUE){
printf("\n",url_stylesheets_path,COMMON_CSS);
printf("\n",url_stylesheets_path,HISTOGRAM_CSS);
}
printf("\n");
printf("\n");
/* include user SSI header */
include_ssi_files(HISTOGRAM_CGI,SSI_HEADER);
printf("\n");
}
else{
printf("Cache-Control: no-store\r\n");
printf("Pragma: no-cache\r\n");
time(¤t_time);
get_time_string(¤t_time,date_time,sizeof(date_time),HTTP_DATE_TIME);
printf("Last-Modified: %s\r\n",date_time);
expire_time=(time_t)0L;
get_time_string(&expire_time,date_time,sizeof(date_time),HTTP_DATE_TIME);
printf("Expires: %s\r\n",date_time);
printf("Content-Type: image/png\r\n\r\n");
}
return;
}
void document_footer(void){
if(embedded==TRUE)
return;
if(mode==CREATE_HTML){
/* include user SSI footer */
include_ssi_files(HISTOGRAM_CGI,SSI_FOOTER);
printf("\n");
printf("\n");
}
return;
}
int process_cgivars(void){
char **variables;
int error=FALSE;
int x;
variables=getcgivars();
for(x=0;variables[x]!=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 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]);
strip_html_brackets(host_name);
display_type=DISPLAY_HOST_HISTOGRAM;
}
/* we found the node width 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]);
strip_html_brackets(svc_description);
display_type=DISPLAY_SERVICE_HISTOGRAM;
}
/* 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;
}
/* 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;
}
/* we found the image creation option */
else if(!strcmp(variables[x],"createimage")){
mode=CREATE_IMAGE;
}
/* 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;
}
/* we found the standard timeperiod argument */
else if(!strcmp(variables[x],"timeperiod")){
x++;
if(variables[x]==NULL){
error=TRUE;
break;
}
if(!strcmp(variables[x],"today"))
timeperiod_type=TIMEPERIOD_TODAY;
else if(!strcmp(variables[x],"yesterday"))
timeperiod_type=TIMEPERIOD_YESTERDAY;
else if(!strcmp(variables[x],"thisweek"))
timeperiod_type=TIMEPERIOD_THISWEEK;
else if(!strcmp(variables[x],"lastweek"))
timeperiod_type=TIMEPERIOD_LASTWEEK;
else if(!strcmp(variables[x],"thismonth"))
timeperiod_type=TIMEPERIOD_THISMONTH;
else if(!strcmp(variables[x],"lastmonth"))
timeperiod_type=TIMEPERIOD_LASTMONTH;
else if(!strcmp(variables[x],"thisquarter"))
timeperiod_type=TIMEPERIOD_THISQUARTER;
else if(!strcmp(variables[x],"lastquarter"))
timeperiod_type=TIMEPERIOD_LASTQUARTER;
else if(!strcmp(variables[x],"thisyear"))
timeperiod_type=TIMEPERIOD_THISYEAR;
else if(!strcmp(variables[x],"lastyear"))
timeperiod_type=TIMEPERIOD_LASTYEAR;
else if(!strcmp(variables[x],"last24hours"))
timeperiod_type=TIMEPERIOD_LAST24HOURS;
else if(!strcmp(variables[x],"last7days"))
timeperiod_type=TIMEPERIOD_LAST7DAYS;
else if(!strcmp(variables[x],"last31days"))
timeperiod_type=TIMEPERIOD_LAST31DAYS;
else if(!strcmp(variables[x],"custom"))
timeperiod_type=TIMEPERIOD_CUSTOM;
else
timeperiod_type=TIMEPERIOD_TODAY;
if(timeperiod_type!=TIMEPERIOD_CUSTOM)
convert_timeperiod_to_times(timeperiod_type);
}
/* we found time argument */
else if(!strcmp(variables[x],"smon")){
x++;
if(variables[x]==NULL){
error=TRUE;
break;
}
if(timeperiod_type!=TIMEPERIOD_CUSTOM)
continue;
start_month=atoi(variables[x]);
timeperiod_type=TIMEPERIOD_CUSTOM;
compute_time_from_parts=TRUE;
}
/* we found time argument */
else if(!strcmp(variables[x],"sday")){
x++;
if(variables[x]==NULL){
error=TRUE;
break;
}
if(timeperiod_type!=TIMEPERIOD_CUSTOM)
continue;
start_day=atoi(variables[x]);
timeperiod_type=TIMEPERIOD_CUSTOM;
compute_time_from_parts=TRUE;
}
/* we found time argument */
else if(!strcmp(variables[x],"syear")){
x++;
if(variables[x]==NULL){
error=TRUE;
break;
}
if(timeperiod_type!=TIMEPERIOD_CUSTOM)
continue;
start_year=atoi(variables[x]);
timeperiod_type=TIMEPERIOD_CUSTOM;
compute_time_from_parts=TRUE;
}
/* we found time argument */
else if(!strcmp(variables[x],"smin")){
x++;
if(variables[x]==NULL){
error=TRUE;
break;
}
if(timeperiod_type!=TIMEPERIOD_CUSTOM)
continue;
start_minute=atoi(variables[x]);
timeperiod_type=TIMEPERIOD_CUSTOM;
compute_time_from_parts=TRUE;
}
/* we found time argument */
else if(!strcmp(variables[x],"ssec")){
x++;
if(variables[x]==NULL){
error=TRUE;
break;
}
if(timeperiod_type!=TIMEPERIOD_CUSTOM)
continue;
start_second=atoi(variables[x]);
timeperiod_type=TIMEPERIOD_CUSTOM;
compute_time_from_parts=TRUE;
}
/* we found time argument */
else if(!strcmp(variables[x],"shour")){
x++;
if(variables[x]==NULL){
error=TRUE;
break;
}
if(timeperiod_type!=TIMEPERIOD_CUSTOM)
continue;
start_hour=atoi(variables[x]);
timeperiod_type=TIMEPERIOD_CUSTOM;
compute_time_from_parts=TRUE;
}
/* we found time argument */
else if(!strcmp(variables[x],"emon")){
x++;
if(variables[x]==NULL){
error=TRUE;
break;
}
if(timeperiod_type!=TIMEPERIOD_CUSTOM)
continue;
end_month=atoi(variables[x]);
timeperiod_type=TIMEPERIOD_CUSTOM;
compute_time_from_parts=TRUE;
}
/* we found time argument */
else if(!strcmp(variables[x],"eday")){
x++;
if(variables[x]==NULL){
error=TRUE;
break;
}
if(timeperiod_type!=TIMEPERIOD_CUSTOM)
continue;
end_day=atoi(variables[x]);
timeperiod_type=TIMEPERIOD_CUSTOM;
compute_time_from_parts=TRUE;
}
/* we found time argument */
else if(!strcmp(variables[x],"eyear")){
x++;
if(variables[x]==NULL){
error=TRUE;
break;
}
if(timeperiod_type!=TIMEPERIOD_CUSTOM)
continue;
end_year=atoi(variables[x]);
timeperiod_type=TIMEPERIOD_CUSTOM;
compute_time_from_parts=TRUE;
}
/* we found time argument */
else if(!strcmp(variables[x],"emin")){
x++;
if(variables[x]==NULL){
error=TRUE;
break;
}
if(timeperiod_type!=TIMEPERIOD_CUSTOM)
continue;
end_minute=atoi(variables[x]);
timeperiod_type=TIMEPERIOD_CUSTOM;
compute_time_from_parts=TRUE;
}
/* we found time argument */
else if(!strcmp(variables[x],"esec")){
x++;
if(variables[x]==NULL){
error=TRUE;
break;
}
if(timeperiod_type!=TIMEPERIOD_CUSTOM)
continue;
end_second=atoi(variables[x]);
timeperiod_type=TIMEPERIOD_CUSTOM;
compute_time_from_parts=TRUE;
}
/* we found time argument */
else if(!strcmp(variables[x],"ehour")){
x++;
if(variables[x]==NULL){
error=TRUE;
break;
}
if(timeperiod_type!=TIMEPERIOD_CUSTOM)
continue;
end_hour=atoi(variables[x]);
timeperiod_type=TIMEPERIOD_CUSTOM;
compute_time_from_parts=TRUE;
}
/* we found the 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 input option */
else if(!strcmp(variables[x],"input")){
x++;
if(variables[x]==NULL){
error=TRUE;
break;
}
if(!strcmp(variables[x],"gethost"))
input_type=GET_INPUT_HOST_TARGET;
else if(!strcmp(variables[x],"getservice"))
input_type=GET_INPUT_SERVICE_TARGET;
else if(!strcmp(variables[x],"getoptions"))
input_type=GET_INPUT_OPTIONS;
else
input_type=GET_INPUT_TARGET_TYPE;
}
/* we found the graph states option */
else if(!strcmp(variables[x],"graphevents")){
x++;
if(variables[x]==NULL){
error=TRUE;
break;
}
graph_events=atoi(variables[x]);
}
/* we found the graph state types option */
else if(!strcmp(variables[x],"graphstatetypes")){
x++;
if(variables[x]==NULL){
error=TRUE;
break;
}
graph_statetypes=atoi(variables[x]);
}
/* we found the breakdown option */
else if(!strcmp(variables[x],"breakdown")){
x++;
if(variables[x]==NULL){
error=TRUE;
break;
}
if(!strcmp(variables[x],"monthly"))
breakdown_type=BREAKDOWN_MONTHLY;
else if(!strcmp(variables[x],"dayofmonth"))
breakdown_type=BREAKDOWN_DAY_OF_MONTH;
else if(!strcmp(variables[x],"dayofweek"))
breakdown_type=BREAKDOWN_DAY_OF_WEEK;
else
breakdown_type=BREAKDOWN_HOURLY;
}
/* we found the assume state retention option */
else if(!strcmp(variables[x],"assumestateretention")){
x++;
if(variables[x]==NULL){
error=TRUE;
break;
}
if(!strcmp(variables[x],"yes"))
assume_state_retention=TRUE;
else
assume_state_retention=FALSE;
}
/* we found the initial states logged option */
else if(!strcmp(variables[x],"initialstateslogged")){
x++;
if(variables[x]==NULL){
error=TRUE;
break;
}
if(!strcmp(variables[x],"yes"))
initial_states_logged=TRUE;
else
initial_states_logged=FALSE;
}
/* we found the new states only option */
else if(!strcmp(variables[x],"newstatesonly")){
x++;
if(variables[x]==NULL){
error=TRUE;
break;
}
if(!strcmp(variables[x],"yes"))
new_states_only=TRUE;
else
new_states_only=FALSE;
}
}
/* free memory allocated to the CGI variables */
free_cgivars(variables);
return error;
}
/* graphs histogram data */
void graph_all_histogram_data(void){
int pixel_x;
int pixel_y;
int last_pixel_y;
int current_bucket;
int actual_bucket;
unsigned long max_value;
double x_scaling_factor;
double y_scaling_factor;
double x_units;
double y_units;
int current_unit;
int actual_unit;
char temp_buffer[MAX_INPUT_BUFFER];
int string_width;
int string_height;
char *days[7]={"Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"};
char *months[12]={"January","February","March","April","May","June","July","August","September","October","November","December"};
char start_time[MAX_INPUT_BUFFER];
char end_time[MAX_INPUT_BUFFER];
unsigned long state1_max=0L;
unsigned long state1_min=0L;
int have_state1_min=FALSE;
unsigned long state1_sum=0L;
double state1_avg=0.0;
unsigned long state2_max=0L;
unsigned long state2_min=0L;
int have_state2_min=FALSE;
unsigned long state2_sum=0L;
double state2_avg=0.0;
unsigned long state3_max=0L;
unsigned long state3_min=0L;
int have_state3_min=FALSE;
unsigned long state3_sum=0L;
double state3_avg=0.0;
unsigned long state4_max=0L;
unsigned long state4_min=0L;
int have_state4_min=FALSE;
unsigned long state4_sum=0L;
double state4_avg=0.0;
#ifdef DEBUG
printf("Total Buckets: %d\n",total_buckets);
#endif
/* determine max value in the buckets (for scaling) */
max_value=0L;
for(current_bucket=0;current_bucketmax_value)
max_value=tsdata[current_bucket].service_ok;
if(tsdata[current_bucket].service_warning>max_value)
max_value=tsdata[current_bucket].service_warning;
if(tsdata[current_bucket].service_unknown>max_value)
max_value=tsdata[current_bucket].service_unknown;
if(tsdata[current_bucket].service_critical>max_value)
max_value=tsdata[current_bucket].service_critical;
if(tsdata[current_bucket].host_up>max_value)
max_value=tsdata[current_bucket].host_up;
if(tsdata[current_bucket].host_down>max_value)
max_value=tsdata[current_bucket].host_down;
if(tsdata[current_bucket].host_unreachable>max_value)
max_value=tsdata[current_bucket].host_unreachable;
}
#ifdef DEBUG
printf("Done determining max bucket values\n");
printf("MAX_VALUE=%lu\n",max_value);
printf("DRAWING_HEIGHT=%lu\n",DRAWING_HEIGHT);
#endif
/* min number of values to graph */
if(max_value<10)
max_value=10;
#ifdef DEBUG
printf("ADJUSTED MAX_VALUE=%lu\n",max_value);
#endif
/* determine y scaling factor */
/*y_scaling_factor=floor((double)DRAWING_HEIGHT/(double)max_value);*/
y_scaling_factor=(double)((double)DRAWING_HEIGHT/(double)max_value);
/* determine x scaling factor */
x_scaling_factor=(double)((double)DRAWING_WIDTH/(double)total_buckets);
/* determine y units resolution - we want a max of about 10 y grid lines */
/*
y_units=(double)((double)DRAWING_HEIGHT/19.0);
y_units=ceil(y_units/y_scaling_factor)*y_scaling_factor;
*/
y_units=ceil(19.0/y_scaling_factor);
/* determine x units resolution */
if(breakdown_type==BREAKDOWN_HOURLY)
x_units=(double)((double)DRAWING_WIDTH/(double)(total_buckets/4.0));
else
x_units=x_scaling_factor;
#ifdef DEBUG
printf("DRAWING_WIDTH: %d\n",DRAWING_WIDTH);
printf("DRAWING_HEIGHT: %d\n",DRAWING_HEIGHT);
printf("max_value: %lu\n",max_value);
printf("x_scaling_factor: %.3f\n",x_scaling_factor);
printf("y_scaling_factor: %.3f\n",y_scaling_factor);
printf("x_units: %.3f\n",x_units);
printf("y_units: %.3f\n",y_units);
printf("y units to draw: %.3f\n",((double)max_value/y_units));
#endif
string_height=gdFontSmall->h;
#ifdef DEBUG
printf("Starting to draw Y grid lines...\n");
#endif
/* draw y grid lines */
if(max_value>0){
for(current_unit=1;(current_unit*y_units*y_scaling_factor)<=DRAWING_HEIGHT;current_unit++){
draw_dashed_line(DRAWING_X_OFFSET,DRAWING_Y_OFFSET-(current_unit*y_units*y_scaling_factor),DRAWING_X_OFFSET+DRAWING_WIDTH,DRAWING_Y_OFFSET-(current_unit*y_units*y_scaling_factor),color_lightgray);
#ifdef DEBUG
printf(" Drawing Y unit #%d @ %d\n",current_unit,(int)(current_unit*y_units*y_scaling_factor));
#endif
}
}
#ifdef DEBUG
printf("Starting to draw X grid lines...\n");
#endif
/* draw x grid lines */
for(current_unit=1;(int)(current_unit*x_units)<=DRAWING_WIDTH;current_unit++)
draw_dashed_line(DRAWING_X_OFFSET+(int)(current_unit*x_units),DRAWING_Y_OFFSET,DRAWING_X_OFFSET+(int)(current_unit*x_units),DRAWING_Y_OFFSET-DRAWING_HEIGHT,color_lightgray);
#ifdef DEBUG
printf("Starting to draw grid units...\n");
#endif
/* draw y units */
if(max_value>0){
for(current_unit=0;(current_unit*y_units*y_scaling_factor)<=DRAWING_HEIGHT;current_unit++){
snprintf(temp_buffer,sizeof(temp_buffer)-1,"%d",(int)(current_unit*y_units));
temp_buffer[sizeof(temp_buffer)-1]='\x0';
string_width=gdFontSmall->w*strlen(temp_buffer);
gdImageString(histogram_image,gdFontSmall,DRAWING_X_OFFSET-string_width-5,DRAWING_Y_OFFSET-(current_unit*y_units*y_scaling_factor)-(string_height/2),(unsigned char *)temp_buffer,color_black);
}
}
/* draw x units */
for(current_unit=0,actual_unit=0;(int)(current_unit*x_units)<=DRAWING_WIDTH;current_unit++,actual_unit++){
if(actual_unit>=total_buckets)
actual_unit=0;
if(breakdown_type==BREAKDOWN_MONTHLY)
snprintf(temp_buffer,sizeof(temp_buffer)-1,"%s",months[actual_unit]);
else if(breakdown_type==BREAKDOWN_DAY_OF_MONTH)
snprintf(temp_buffer,sizeof(temp_buffer)-1,"%d",actual_unit+1);
else if(breakdown_type==BREAKDOWN_DAY_OF_WEEK)
snprintf(temp_buffer,sizeof(temp_buffer)-1,"%s",days[actual_unit]);
else
snprintf(temp_buffer,sizeof(temp_buffer)-1,"%02d:00",(actual_unit==24)?0:actual_unit);
temp_buffer[sizeof(temp_buffer)-1]='\x0';
string_width=gdFontSmall->w*strlen(temp_buffer);
gdImageStringUp(histogram_image,gdFontSmall,DRAWING_X_OFFSET+(current_unit*x_units)-(string_height/2),DRAWING_Y_OFFSET+5+string_width,(unsigned char *)temp_buffer,color_black);
}
/* draw y unit measure */
snprintf(temp_buffer,sizeof(temp_buffer)-1,"Number of Events");
temp_buffer[sizeof(temp_buffer)-1]='\x0';
string_width=gdFontSmall->w*strlen(temp_buffer);
gdImageStringUp(histogram_image,gdFontSmall,0,DRAWING_Y_OFFSET-(DRAWING_HEIGHT/2)+(string_width/2),(unsigned char *)temp_buffer,color_black);
/* draw x unit measure */
if(breakdown_type==BREAKDOWN_MONTHLY)
snprintf(temp_buffer,sizeof(temp_buffer)-1,"Month");
else if(breakdown_type==BREAKDOWN_DAY_OF_MONTH)
snprintf(temp_buffer,sizeof(temp_buffer)-1,"Day of the Month");
else if(breakdown_type==BREAKDOWN_DAY_OF_WEEK)
snprintf(temp_buffer,sizeof(temp_buffer)-1,"Day of the Week");
else
snprintf(temp_buffer,sizeof(temp_buffer)-1,"Hour of the Day (15 minute increments)");
temp_buffer[sizeof(temp_buffer)-1]='\x0';
string_width=gdFontSmall->w*strlen(temp_buffer);
gdImageString(histogram_image,gdFontSmall,DRAWING_X_OFFSET+(DRAWING_WIDTH/2)-(string_width/2),DRAWING_Y_OFFSET+70,(unsigned char *)temp_buffer,color_black);
/* draw title */
snprintf(start_time,sizeof(start_time)-1,"%s",ctime(&t1));
start_time[sizeof(start_time)-1]='\x0';
start_time[strlen(start_time)-1]='\x0';
snprintf(end_time,sizeof(end_time)-1,"%s",ctime(&t2));
end_time[sizeof(end_time)-1]='\x0';
end_time[strlen(end_time)-1]='\x0';
if(display_type==DISPLAY_HOST_HISTOGRAM)
snprintf(temp_buffer,sizeof(temp_buffer)-1,"Event History For Host '%s'",host_name);
else
snprintf(temp_buffer,sizeof(temp_buffer)-1,"Event History For Service '%s' On Host '%s'",svc_description,host_name);
temp_buffer[sizeof(temp_buffer)-1]='\x0';
string_width=gdFontSmall->w*strlen(temp_buffer);
gdImageString(histogram_image,gdFontSmall,DRAWING_X_OFFSET+(DRAWING_WIDTH/2)-(string_width/2),0,(unsigned char *)temp_buffer,color_black);
snprintf(temp_buffer,sizeof(temp_buffer)-1,"%s to %s",start_time,end_time);
temp_buffer[sizeof(temp_buffer)-1]='\x0';
string_width=gdFontSmall->w*strlen(temp_buffer);
gdImageString(histogram_image,gdFontSmall,DRAWING_X_OFFSET+(DRAWING_WIDTH/2)-(string_width/2),string_height+5,(unsigned char *)temp_buffer,color_black);
#ifdef DEBUG
printf("About to starting graphing (total_buckets=%d)...\n",total_buckets);
#endif
/* graph service states */
if(display_type==DISPLAY_HOST_HISTOGRAM){
/* graph host recoveries */
if(graph_events & GRAPH_HOST_UP){
last_pixel_y=0;
for(current_bucket=0,actual_bucket=0;current_bucket<=total_buckets;current_bucket++,actual_bucket++){
if(actual_bucket>=total_buckets)
actual_bucket=0;
pixel_x=(int)(current_bucket*x_scaling_factor);
pixel_y=(int)(tsdata[actual_bucket].host_up*y_scaling_factor);
if(current_bucket>0 && !(last_pixel_y==0 && pixel_y==0))
draw_line(DRAWING_X_OFFSET+pixel_x-(int)x_scaling_factor,DRAWING_Y_OFFSET-last_pixel_y,DRAWING_X_OFFSET+pixel_x,DRAWING_Y_OFFSET-pixel_y,color_green);
last_pixel_y=pixel_y;
if(current_bucketstate1_max)
state1_max=tsdata[actual_bucket].host_up;
state1_sum+=tsdata[actual_bucket].host_up;
}
}
}
#ifdef DEBUG
printf("Done graphing HOST UP states...\n");
#endif
/* graph host down states */
if(graph_events & GRAPH_HOST_DOWN){
last_pixel_y=0;
for(current_bucket=0,actual_bucket=0;current_bucket<=total_buckets;current_bucket++,actual_bucket++){
if(actual_bucket>=total_buckets)
actual_bucket=0;
pixel_x=(int)(current_bucket*x_scaling_factor);
pixel_y=(int)(tsdata[actual_bucket].host_down*y_scaling_factor);
if(current_bucket>0 && !(last_pixel_y==0 && pixel_y==0))
draw_line(DRAWING_X_OFFSET+pixel_x-(int)x_scaling_factor,DRAWING_Y_OFFSET-last_pixel_y,DRAWING_X_OFFSET+pixel_x,DRAWING_Y_OFFSET-pixel_y,color_red);
last_pixel_y=pixel_y;
if(current_bucketstate2_max)
state2_max=tsdata[actual_bucket].host_down;
state2_sum+=tsdata[actual_bucket].host_down;
}
}
}
#ifdef DEBUG
printf("Done graphing HOST DOWN states...\n");
#endif
/* graph host unreachable states */
if(graph_events & GRAPH_HOST_UNREACHABLE){
last_pixel_y=0;
for(current_bucket=0,actual_bucket=0;current_bucket<=total_buckets;current_bucket++,actual_bucket++){
if(actual_bucket>=total_buckets)
actual_bucket=0;
pixel_x=(int)(current_bucket*x_scaling_factor);
pixel_y=(int)(tsdata[actual_bucket].host_unreachable*y_scaling_factor);
if(current_bucket>0 && !(last_pixel_y==0 && pixel_y==0))
draw_line(DRAWING_X_OFFSET+pixel_x-(int)x_scaling_factor,DRAWING_Y_OFFSET-last_pixel_y,DRAWING_X_OFFSET+pixel_x,DRAWING_Y_OFFSET-pixel_y,color_darkred);
last_pixel_y=pixel_y;
if(current_bucketstate3_max)
state3_max=tsdata[actual_bucket].host_unreachable;
state3_sum+=tsdata[actual_bucket].host_unreachable;
}
}
}
#ifdef DEBUG
printf("Done graphing HOST UNREACHABLE states...\n");
#endif
}
/* graph service states */
else{
/* graph service recoveries */
if(graph_events & GRAPH_SERVICE_OK){
last_pixel_y=0;
for(current_bucket=0,actual_bucket=0;current_bucket<=total_buckets;current_bucket++,actual_bucket++){
if(actual_bucket>=total_buckets)
actual_bucket=0;
pixel_x=(int)(current_bucket*x_scaling_factor);
pixel_y=(int)(tsdata[actual_bucket].service_ok*y_scaling_factor);
if(current_bucket>0 && !(last_pixel_y==0 && pixel_y==0))
draw_line(DRAWING_X_OFFSET+pixel_x-(int)x_scaling_factor,DRAWING_Y_OFFSET-last_pixel_y,DRAWING_X_OFFSET+pixel_x,DRAWING_Y_OFFSET-pixel_y,color_green);
last_pixel_y=pixel_y;
if(current_bucketstate1_max)
state1_max=tsdata[actual_bucket].service_ok;
state1_sum+=tsdata[actual_bucket].service_ok;
}
}
}
/* graph service warning states */
if(graph_events & GRAPH_SERVICE_WARNING){
last_pixel_y=0;
for(current_bucket=0,actual_bucket=0;current_bucket<=total_buckets;current_bucket++,actual_bucket++){
if(actual_bucket>=total_buckets)
actual_bucket=0;
pixel_x=(int)(current_bucket*x_scaling_factor);
pixel_y=(int)(tsdata[actual_bucket].service_warning*y_scaling_factor);
if(current_bucket>0 && !(last_pixel_y==0 && pixel_y==0))
draw_line(DRAWING_X_OFFSET+pixel_x-(int)x_scaling_factor,DRAWING_Y_OFFSET-last_pixel_y,DRAWING_X_OFFSET+pixel_x,DRAWING_Y_OFFSET-pixel_y,color_yellow);
last_pixel_y=pixel_y;
if(current_bucketstate2_max)
state2_max=tsdata[actual_bucket].service_warning;
state2_sum+=tsdata[actual_bucket].service_warning;
}
}
}
/* graph service unknown states */
if(graph_events & GRAPH_SERVICE_UNKNOWN){
last_pixel_y=0;
for(current_bucket=0,actual_bucket=0;current_bucket<=total_buckets;current_bucket++,actual_bucket++){
if(actual_bucket>=total_buckets)
actual_bucket=0;
pixel_x=(int)(current_bucket*x_scaling_factor);
pixel_y=(int)(tsdata[actual_bucket].service_unknown*y_scaling_factor);
if(current_bucket>0 && !(last_pixel_y==0 && pixel_y==0))
draw_line(DRAWING_X_OFFSET+pixel_x-(int)x_scaling_factor,DRAWING_Y_OFFSET-last_pixel_y,DRAWING_X_OFFSET+pixel_x,DRAWING_Y_OFFSET-pixel_y,color_orange);
last_pixel_y=pixel_y;
if(current_bucketstate3_max)
state3_max=tsdata[actual_bucket].service_unknown;
state3_sum+=tsdata[actual_bucket].service_unknown;
}
}
}
/* graph service critical states */
if(graph_events & GRAPH_SERVICE_CRITICAL){
last_pixel_y=0;
for(current_bucket=0,actual_bucket=0;current_bucket<=total_buckets;current_bucket++,actual_bucket++){
if(actual_bucket>=total_buckets)
actual_bucket=0;
pixel_x=(int)(current_bucket*x_scaling_factor);
pixel_y=(int)(tsdata[actual_bucket].service_critical*y_scaling_factor);
if(current_bucket>0 && !(last_pixel_y==0 && pixel_y==0))
draw_line(DRAWING_X_OFFSET+pixel_x-(int)x_scaling_factor,DRAWING_Y_OFFSET-last_pixel_y,DRAWING_X_OFFSET+pixel_x,DRAWING_Y_OFFSET-pixel_y,color_red);
last_pixel_y=pixel_y;
if(current_bucketstate4_max)
state4_max=tsdata[actual_bucket].service_critical;
state4_sum+=tsdata[actual_bucket].service_critical;
}
}
}
}
#ifdef DEBUG
printf("Done graphing states...\n");
#endif
/* draw graph boundaries */
draw_line(DRAWING_X_OFFSET,DRAWING_Y_OFFSET,DRAWING_X_OFFSET,DRAWING_Y_OFFSET-DRAWING_HEIGHT,color_black);
draw_line(DRAWING_X_OFFSET+DRAWING_WIDTH,DRAWING_Y_OFFSET,DRAWING_X_OFFSET+DRAWING_WIDTH,DRAWING_Y_OFFSET-DRAWING_HEIGHT,color_black);
draw_line(DRAWING_X_OFFSET,DRAWING_Y_OFFSET,DRAWING_X_OFFSET+DRAWING_WIDTH,DRAWING_Y_OFFSET,color_black);
/* graph stats */
snprintf(temp_buffer,sizeof(temp_buffer)-1,"EVENT TYPE");
temp_buffer[sizeof(temp_buffer)-1]='\x0';
string_width=gdFontSmall->w*strlen(temp_buffer);
gdImageString(histogram_image,gdFontSmall,DRAWING_X_OFFSET+DRAWING_WIDTH+15,DRAWING_Y_OFFSET-DRAWING_HEIGHT,(unsigned char *)temp_buffer,color_black);
snprintf(temp_buffer,sizeof(temp_buffer)-1," MIN MAX SUM AVG");
temp_buffer[sizeof(temp_buffer)-1]='\x0';
string_width=gdFontSmall->w*strlen(temp_buffer);
gdImageString(histogram_image,gdFontSmall,DRAWING_X_OFFSET+DRAWING_WIDTH+115,DRAWING_Y_OFFSET-DRAWING_HEIGHT,(unsigned char *)temp_buffer,color_black);
draw_line(DRAWING_X_OFFSET+DRAWING_WIDTH+15,DRAWING_Y_OFFSET-DRAWING_HEIGHT+string_height+2,DRAWING_X_OFFSET+DRAWING_WIDTH+275,DRAWING_Y_OFFSET-DRAWING_HEIGHT+string_height+2,color_black);
snprintf(temp_buffer,sizeof(temp_buffer)-1,"Recovery (%s):",(display_type==DISPLAY_SERVICE_HISTOGRAM)?"Ok":"Up");
temp_buffer[sizeof(temp_buffer)-1]='\x0';
string_width=gdFontSmall->w*strlen(temp_buffer);
gdImageString(histogram_image,gdFontSmall,DRAWING_X_OFFSET+DRAWING_WIDTH+15,DRAWING_Y_OFFSET-DRAWING_HEIGHT+((string_height+5)*1),(unsigned char *)temp_buffer,color_green);
state1_avg=(double)((double)state1_sum/(double)total_buckets);
snprintf(temp_buffer,sizeof(temp_buffer)-1,"%5lu %5lu %5lu %.2f",state1_min,state1_max,state1_sum,state1_avg);
temp_buffer[sizeof(temp_buffer)-1]='\x0';
string_width=gdFontSmall->w*strlen(temp_buffer);
gdImageString(histogram_image,gdFontSmall,DRAWING_X_OFFSET+DRAWING_WIDTH+115,DRAWING_Y_OFFSET-DRAWING_HEIGHT+((string_height+5)*1),(unsigned char *)temp_buffer,color_black);
snprintf(temp_buffer,sizeof(temp_buffer)-1,"%s:",(display_type==DISPLAY_SERVICE_HISTOGRAM)?"Warning":"Down");
temp_buffer[sizeof(temp_buffer)-1]='\x0';
string_width=gdFontSmall->w*strlen(temp_buffer);
gdImageString(histogram_image,gdFontSmall,DRAWING_X_OFFSET+DRAWING_WIDTH+15,DRAWING_Y_OFFSET-DRAWING_HEIGHT+((string_height+5)*2),(unsigned char *)temp_buffer,(display_type==DISPLAY_SERVICE_HISTOGRAM)?color_yellow:color_red);
state2_avg=(double)((double)state2_sum/(double)total_buckets);
snprintf(temp_buffer,sizeof(temp_buffer)-1,"%5lu %5lu %5lu %.2f",state2_min,state2_max,state2_sum,state2_avg);
temp_buffer[sizeof(temp_buffer)-1]='\x0';
string_width=gdFontSmall->w*strlen(temp_buffer);
gdImageString(histogram_image,gdFontSmall,DRAWING_X_OFFSET+DRAWING_WIDTH+115,DRAWING_Y_OFFSET-DRAWING_HEIGHT+((string_height+5)*2),(unsigned char *)temp_buffer,color_black);
snprintf(temp_buffer,sizeof(temp_buffer)-1,"%s:",(display_type==DISPLAY_SERVICE_HISTOGRAM)?"Unknown":"Unreachable");
temp_buffer[sizeof(temp_buffer)-1]='\x0';
string_width=gdFontSmall->w*strlen(temp_buffer);
gdImageString(histogram_image,gdFontSmall,DRAWING_X_OFFSET+DRAWING_WIDTH+15,DRAWING_Y_OFFSET-DRAWING_HEIGHT+((string_height+5)*3),(unsigned char *)temp_buffer,(display_type==DISPLAY_SERVICE_HISTOGRAM)?color_orange:color_darkred);
state3_avg=(double)((double)state3_sum/(double)total_buckets);
snprintf(temp_buffer,sizeof(temp_buffer)-1,"%5lu %5lu %5lu %.2f",state3_min,state3_max,state3_sum,state3_avg);
temp_buffer[sizeof(temp_buffer)-1]='\x0';
string_width=gdFontSmall->w*strlen(temp_buffer);
gdImageString(histogram_image,gdFontSmall,DRAWING_X_OFFSET+DRAWING_WIDTH+115,DRAWING_Y_OFFSET-DRAWING_HEIGHT+((string_height+5)*3),(unsigned char *)temp_buffer,color_black);
if(display_type==DISPLAY_SERVICE_HISTOGRAM){
snprintf(temp_buffer,sizeof(temp_buffer)-1,"Critical:");
temp_buffer[sizeof(temp_buffer)-1]='\x0';
string_width=gdFontSmall->w*strlen(temp_buffer);
gdImageString(histogram_image,gdFontSmall,DRAWING_X_OFFSET+DRAWING_WIDTH+15,DRAWING_Y_OFFSET-DRAWING_HEIGHT+((string_height+5)*4),(unsigned char *)temp_buffer,color_red);
state4_avg=(double)((double)state4_sum/(double)total_buckets);
snprintf(temp_buffer,sizeof(temp_buffer)-1,"%5lu %5lu %5lu %.2f",state4_min,state4_max,state4_sum,state4_avg);
temp_buffer[sizeof(temp_buffer)-1]='\x0';
string_width=gdFontSmall->w*strlen(temp_buffer);
gdImageString(histogram_image,gdFontSmall,DRAWING_X_OFFSET+DRAWING_WIDTH+115,DRAWING_Y_OFFSET-DRAWING_HEIGHT+((string_height+5)*4),(unsigned char *)temp_buffer,color_black);
}
return;
}
/* adds an archived state entry */
void add_archived_state(int state_type, time_t time_stamp){
struct tm *our_time;
int bucket;
int skip_state=FALSE;
#ifdef DEBUG2
printf("NEW ENTRY: last=%d this=%d\n",last_state,state_type);
#endif
/* don't record program starts/stops, just make a note that one occurred */
if(state_type==AS_PROGRAM_START || state_type==AS_PROGRAM_END){
#ifdef DEBUG2
printf("Recording a program start: %d\n",state_type);
#endif
program_restart_has_occurred=TRUE;
return;
}
/* see if we should even take into account this event */
if(program_restart_has_occurred==TRUE){
#ifdef DEBUG2
printf("program_restart_has_occurred: last=%d this=%d\n",last_state,state_type);
#endif
if(initial_states_logged==TRUE){
if(state_type==AS_SVC_OK && last_state==AS_SVC_OK)
skip_state=TRUE;
if(state_type==AS_HOST_UP && last_state==AS_HOST_UP)
skip_state=TRUE;
}
if(assume_state_retention==TRUE && initial_states_logged==TRUE){
if(state_type==AS_SVC_WARNING && last_state==AS_SVC_WARNING)
skip_state=TRUE;
if(state_type==AS_SVC_UNKNOWN && last_state==AS_SVC_UNKNOWN)
skip_state=TRUE;
if(state_type==AS_SVC_CRITICAL && last_state==AS_SVC_CRITICAL)
skip_state=TRUE;
if(state_type==AS_HOST_DOWN && last_state==AS_HOST_DOWN)
skip_state=TRUE;
if(state_type==AS_HOST_UNREACHABLE && last_state==AS_HOST_UNREACHABLE)
skip_state=TRUE;
}
if(skip_state==TRUE){
program_restart_has_occurred=FALSE;
#ifdef DEBUG2
printf("Skipping state...\n");
#endif
return;
}
}
/* reset program restart variable */
program_restart_has_occurred=FALSE;
/* are we only processing new states */
if(new_states_only==TRUE && state_type==last_state){
#ifdef DEBUG2
printf("Skipping state (not a new state)...\n");
#endif
return;
}
#ifdef DEBUG2
printf("GOODSTATE: %d @ %lu\n",state_type,(unsigned long)time_stamp);
#endif
our_time=localtime(&time_stamp);
/* calculate the correct bucket to dump the data into */
if(breakdown_type==BREAKDOWN_MONTHLY)
bucket=our_time->tm_mon;
else if(breakdown_type==BREAKDOWN_DAY_OF_MONTH)
bucket=our_time->tm_mday-1;
else if(breakdown_type==BREAKDOWN_DAY_OF_WEEK)
bucket=our_time->tm_wday;
else
bucket=(our_time->tm_hour*4)+(our_time->tm_min/15);
#ifdef DEBUG2
printf("\tBucket=%d\n",bucket);
#endif
/* save the data in the correct bucket */
if(state_type==AS_SVC_OK)
tsdata[bucket].service_ok++;
else if(state_type==AS_SVC_UNKNOWN)
tsdata[bucket].service_unknown++;
else if(state_type==AS_SVC_WARNING)
tsdata[bucket].service_warning++;
else if(state_type==AS_SVC_CRITICAL)
tsdata[bucket].service_critical++;
else if(state_type==AS_HOST_UP)
tsdata[bucket].host_up++;
else if(state_type==AS_HOST_DOWN)
tsdata[bucket].host_down++;
else if(state_type==AS_HOST_UNREACHABLE)
tsdata[bucket].host_unreachable++;
/* record last state type */
last_state=state_type;
return;
}
/* reads log files for archived state data */
void read_archived_state_data(void){
char filename[MAX_FILENAME_LENGTH];
int newest_archive=0;
int oldest_archive=0;
int current_archive;
#ifdef DEBUG2
printf("Determining archives to use...\n");
#endif
/* determine earliest archive to use */
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 */
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:
break;
case TIMEPERIOD_LASTQUARTER:
break;
case TIMEPERIOD_THISYEAR:
t->tm_mon=0;
t->tm_mday=1;
t1=mktime(t);
t2=current_time;
break;
case TIMEPERIOD_LASTYEAR:
t->tm_mon=0;
t->tm_mday=1;
t2=mktime(t);
t->tm_year--;
t1=mktime(t);
break;
case TIMEPERIOD_LAST7DAYS:
t2=current_time;
t1=current_time-(7*24*60*60);
break;
case TIMEPERIOD_LAST31DAYS:
t2=current_time;
t1=current_time-(31*24*60*60);
break;
default:
break;
}
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);
}
/* draws a solid line */
void draw_line(int x1,int y1,int x2,int y2,int color){
int styleSolid[1];
styleSolid[0]=color;
/* sets current style to a solid line */
gdImageSetStyle(histogram_image,styleSolid,1);
/* draws a line (dashed) */
gdImageLine(histogram_image,x1,y1,x2,y2,gdStyled);
return;
}
/* draws a dashed line */
void draw_dashed_line(int x1,int y1,int x2,int y2,int color){
int styleDashed[6];
styleDashed[0]=color;
styleDashed[1]=color;
styleDashed[2]=gdTransparent;
styleDashed[3]=gdTransparent;
styleDashed[4]=gdTransparent;
styleDashed[5]=gdTransparent;
/* sets current style to a solid line */
gdImageSetStyle(histogram_image,styleDashed,6);
/* draws a line (dashed) */
gdImageLine(histogram_image,x1,y1,x2,y2,gdStyled);
return;
}