\n");
}
if(mode == CREATE_IMAGE || (mode == CREATE_HTML && use_map == TRUE)) {
/* draw timestamps */
draw_timestamps();
/* draw horizontal lines */
draw_horizontal_grid_lines();
/* draw state time breakdowns */
draw_time_breakdowns();
}
if(mode == CREATE_IMAGE) {
/* use STDOUT for writing the image data... */
image_file = stdout;
#ifndef DEBUG
/* write the image to file */
gdImagePng(trends_image, image_file);
#endif
#ifdef DEBUG
image_file = fopen("trends.png", "w");
if(image_file == NULL)
printf("Could not open trends.png for writing!\n");
else {
gdImagePng(trends_image, image_file);
fclose(image_file);
}
#endif
/* free memory allocated to image */
gdImageDestroy(trends_image);
}
}
/* show user a selection of hosts and services to choose from... */
if(display_type == DISPLAY_NO_TRENDS || input_type != GET_INPUT_NONE) {
/* ask the user for what host they want a report for */
if(input_type == GET_INPUT_HOST_TARGET) {
printf("
\n");
printf("
Step 2: Select Host
\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");
}
/* 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("Note: Choosing the 'suppress image map' option will make the report run approximately twice as fast as it would otherwise, but it will prevent you from being able to zoom in on specific time periods.\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");
}
}
document_footer();
/* free memory allocated to the archived state data list */
free_archived_state_list();
/* 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", url_images_path);
printf("\n");
printf("Nagios Trends\n");
printf("\n");
if(use_stylesheet == TRUE) {
printf("\n", url_stylesheets_path, COMMON_CSS);
printf("\n", url_stylesheets_path, TRENDS_CSS);
}
/* write JavaScript code for popup window */
if(display_type != DISPLAY_NO_TRENDS)
write_popup_code();
printf("\n");
printf("\n");
/* include user SSI header */
include_ssi_files(TRENDS_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(TRENDS_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;
}
if((host_name = (char *)strdup(variables[x])) == NULL)
host_name = "";
strip_html_brackets(host_name);
display_type = DISPLAY_HOST_TRENDS;
}
/* we found the node width argument */
else if(!strcmp(variables[x], "service")) {
x++;
if(variables[x] == NULL) {
error = TRUE;
break;
}
if((svc_description = (char *)strdup(variables[x])) == NULL)
svc_description = "";
strip_html_brackets(svc_description);
display_type = DISPLAY_SERVICE_TRENDS;
}
/* 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 assume initial states option */
else if(!strcmp(variables[x], "assumeinitialstates")) {
x++;
if(variables[x] == NULL) {
error = TRUE;
break;
}
if(!strcmp(variables[x], "yes"))
assume_initial_states = TRUE;
else
assume_initial_states = FALSE;
}
/* we found the initial assumed host state option */
else if(!strcmp(variables[x], "initialassumedhoststate")) {
x++;
if(variables[x] == NULL) {
error = TRUE;
break;
}
initial_assumed_host_state = atoi(variables[x]);
}
/* we found the initial assumed service state option */
else if(!strcmp(variables[x], "initialassumedservicestate")) {
x++;
if(variables[x] == NULL) {
error = TRUE;
break;
}
initial_assumed_service_state = atoi(variables[x]);
}
/* we found the assume state during program not running option */
else if(!strcmp(variables[x], "assumestatesduringnotrunning")) {
x++;
if(variables[x] == NULL) {
error = TRUE;
break;
}
if(!strcmp(variables[x], "yes"))
assume_states_during_notrunning = TRUE;
else
assume_states_during_notrunning = FALSE;
}
/* we found the assume state retention option */
else if(!strcmp(variables[x], "assumestateretention")) {
x++;
if(variables[x] == NULL) {
error = TRUE;
break;
}
if(!strcmp(variables[x], "yes"))
assume_state_retention = TRUE;
else
assume_state_retention = FALSE;
}
/* we found the include soft states option */
else if(!strcmp(variables[x], "includesoftstates")) {
x++;
if(variables[x] == NULL) {
error = TRUE;
break;
}
if(!strcmp(variables[x], "yes"))
include_soft_states = TRUE;
else
include_soft_states = FALSE;
}
/* we found the zoom factor argument */
else if(!strcmp(variables[x], "zoom")) {
x++;
if(variables[x] == NULL) {
error = TRUE;
break;
}
zoom_factor = atoi(variables[x]);
if(zoom_factor == 0)
zoom_factor = 1;
}
/* 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], "nextproblem"))
timeperiod_type = TIMEPERIOD_NEXTPROBLEM;
else if(!strcmp(variables[x], "last24hours"))
timeperiod_type = TIMEPERIOD_LAST24HOURS;
else if(!strcmp(variables[x], "last7days"))
timeperiod_type = TIMEPERIOD_LAST7DAYS;
else if(!strcmp(variables[x], "last31days"))
timeperiod_type = TIMEPERIOD_LAST31DAYS;
else if(!strcmp(variables[x], "custom"))
timeperiod_type = TIMEPERIOD_CUSTOM;
else
continue;
convert_timeperiod_to_times(timeperiod_type);
}
/* 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 nopopups option */
else if(!strcmp(variables[x], "nopopups"))
display_popups = FALSE;
/* we found the nomap option */
else if(!strcmp(variables[x], "nomap")) {
display_popups = FALSE;
use_map = 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 small image option */
else if(!strcmp(variables[x], "smallimage"))
small_image = TRUE;
}
/* free memory allocated to the CGI variables */
free_cgivars(variables);
return error;
}
/* top level routine for graphic all trend data */
void graph_all_trend_data(void) {
archived_state *temp_as;
archived_state *last_as;
time_t a;
time_t b;
time_t current_time;
int current_state = AS_NO_DATA;
int have_some_real_data = FALSE;
hoststatus *hststatus = NULL;
servicestatus *svcstatus = NULL;
unsigned long wobble = 300;
int first_real_state = AS_NO_DATA;
time_t initial_assumed_time;
int initial_assumed_state = AS_SVC_OK;
int error = FALSE;
time(¤t_time);
/* if left hand of graph is after current time, we can't do anything at all.... */
if(t1 > current_time)
return;
/* find current state for host or service */
if(display_type == DISPLAY_HOST_TRENDS)
hststatus = find_hoststatus(host_name);
else
svcstatus = find_servicestatus(host_name, svc_description);
/************************************/
/* INSERT CURRENT STATE (IF WE CAN) */
/************************************/
/* if current time DOES NOT fall within graph bounds, so we can't do anything as far as assuming current state */
/* 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 we don't have any data, assume current state (if possible) */
if(as_list == NULL && current_time > t1 && current_time < (t2 + wobble)) {
/* 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(display_type == DISPLAY_HOST_TRENDS) {
if(hststatus != NULL) {
if(hststatus->status == HOST_DOWN)
last_known_state = AS_HOST_DOWN;
else if(hststatus->status == HOST_UNREACHABLE)
last_known_state = AS_HOST_UNREACHABLE;
else
last_known_state = AS_HOST_UP;
/* add a dummy archived state item, so something can get graphed */
add_archived_state(last_known_state, AS_HARD_STATE, t1, "Current Host State Assumed (Faked Log Entry)");
/* use the current state as the last known real state */
first_real_state = last_known_state;
}
}
else {
if(svcstatus != NULL) {
if(svcstatus->status == SERVICE_OK)
last_known_state = AS_SVC_OK;
else if(svcstatus->status == SERVICE_WARNING)
last_known_state = AS_SVC_WARNING;
else if(svcstatus->status == SERVICE_CRITICAL)
last_known_state = AS_SVC_CRITICAL;
else if(svcstatus->status == SERVICE_UNKNOWN)
last_known_state = AS_SVC_UNKNOWN;
/* add a dummy archived state item, so something can get graphed */
add_archived_state(last_known_state, AS_HARD_STATE, t1, "Current Service State Assumed (Faked Log Entry)");
/* use the current state as the last known real state */
first_real_state = last_known_state;
}
}
}
/******************************************/
/* INSERT FIRST ASSUMED STATE (IF WE CAN) */
/******************************************/
if((display_type == DISPLAY_HOST_TRENDS && initial_assumed_host_state != AS_NO_DATA) || (display_type == DISPLAY_SERVICE_TRENDS && initial_assumed_service_state != AS_NO_DATA)) {
/* see if its okay to assume initial state for this subject */
error = FALSE;
if(display_type == DISPLAY_SERVICE_TRENDS) {
if(initial_assumed_service_state != AS_SVC_OK && initial_assumed_service_state != AS_SVC_WARNING && initial_assumed_service_state != AS_SVC_UNKNOWN && initial_assumed_service_state != AS_SVC_CRITICAL && initial_assumed_service_state != AS_CURRENT_STATE)
error = TRUE;
else
initial_assumed_state = initial_assumed_service_state;
if(initial_assumed_service_state == AS_CURRENT_STATE && svcstatus == NULL)
error = TRUE;
}
else {
if(initial_assumed_host_state != AS_HOST_UP && initial_assumed_host_state != AS_HOST_DOWN && initial_assumed_host_state != AS_HOST_UNREACHABLE && initial_assumed_host_state != AS_CURRENT_STATE)
error = TRUE;
else
initial_assumed_state = initial_assumed_host_state;
if(initial_assumed_host_state == AS_CURRENT_STATE && hststatus == NULL)
error = TRUE;
}
/* get the current state if applicable */
if(((display_type == DISPLAY_HOST_TRENDS && initial_assumed_host_state == AS_CURRENT_STATE) || (display_type == DISPLAY_SERVICE_TRENDS && initial_assumed_service_state == AS_CURRENT_STATE)) && error == FALSE) {
if(display_type == DISPLAY_HOST_TRENDS) {
switch(hststatus->status) {
case HOST_DOWN:
initial_assumed_state = AS_HOST_DOWN;
break;
case HOST_UNREACHABLE:
initial_assumed_state = AS_HOST_UNREACHABLE;
break;
case HOST_UP:
initial_assumed_state = AS_HOST_UP;
break;
default:
error = TRUE;
break;
}
}
else {
switch(svcstatus->status) {
case SERVICE_OK:
initial_assumed_state = AS_SVC_OK;
break;
case SERVICE_WARNING:
initial_assumed_state = AS_SVC_WARNING;
break;
case SERVICE_UNKNOWN:
initial_assumed_state = AS_SVC_UNKNOWN;
break;
case SERVICE_CRITICAL:
initial_assumed_state = AS_SVC_CRITICAL;
break;
default:
error = TRUE;
break;
}
}
}
if(error == FALSE) {
/* add this assumed state entry before any entries in the list and <= t1 */
if(as_list == NULL)
initial_assumed_time = t1;
else if(as_list->time_stamp > t1)
initial_assumed_time = t1;
else
initial_assumed_time = as_list->time_stamp - 1;
if(display_type == DISPLAY_HOST_TRENDS)
add_archived_state(initial_assumed_state, AS_HARD_STATE, initial_assumed_time, "First Host State Assumed (Faked Log Entry)");
else
add_archived_state(initial_assumed_state, AS_HARD_STATE, initial_assumed_time, "First Service State Assumed (Faked Log Entry)");
}
}
/**************************************/
/* BAIL OUT IF WE DON'T HAVE ANYTHING */
/**************************************/
have_some_real_data = FALSE;
for(temp_as = as_list; temp_as != NULL; temp_as = temp_as->next) {
if(temp_as->entry_type != AS_NO_DATA && temp_as->entry_type != AS_PROGRAM_START && temp_as->entry_type != AS_PROGRAM_END) {
have_some_real_data = TRUE;
break;
}
}
if(have_some_real_data == FALSE)
return;
/* if we're creating the HTML, start map code... */
if(mode == CREATE_HTML)
printf("\n");
return;
}
/* graphs trend data */
void graph_trend_data(int first_state, int last_state, time_t real_start_time, time_t start_time, time_t end_time, char *state_info) {
int start_state;
int end_state;
int start_pixel = 0;
int end_pixel = 0;
int color_to_use = 0;
int height = 0;
double start_pixel_ratio;
double end_pixel_ratio;
char temp_buffer[MAX_INPUT_BUFFER];
char state_string[MAX_INPUT_BUFFER];
char end_timestring[MAX_INPUT_BUFFER];
char start_timestring[MAX_INPUT_BUFFER];
time_t center_time;
time_t next_start_time;
time_t next_end_time;
int days = 0;
int hours = 0;
int minutes = 0;
int seconds = 0;
/* 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) {
if(assume_states_during_notrunning == TRUE)
first_state = last_known_state;
else
return;
}
/* special case if first entry was program start */
if(first_state == AS_PROGRAM_START) {
#ifdef DEBUG
printf("First state=program start!\n");
#endif
if(assume_initial_states == TRUE) {
#ifdef DEBUG
printf("\tWe are assuming initial states...\n");
#endif
if(assume_state_retention == TRUE) {
start_state = last_known_state;
#ifdef DEBUG
printf("\tWe are assuming state retention (%d)...\n", start_state);
#endif
}
else {
#ifdef DEBUG
printf("\tWe are NOT assuming state retention...\n");
#endif
if(display_type == DISPLAY_HOST_TRENDS)
start_state = AS_HOST_UP;
else
start_state = AS_SVC_OK;
}
}
else {
#ifdef DEBUG
printf("We ARE NOT assuming initial states!\n");
#endif
return;
}
}
else {
start_state = first_state;
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;
#ifdef DEBUG
printf("Graphing state %d\n", start_state);
printf("\tfrom %s", ctime(&start_time));
printf("\tto %s", ctime(&end_time));
#endif
if(start_time < t1)
start_time = t1;
if(end_time > t2)
end_time = t2;
if(end_time < t1 || start_time > t2)
return;
/* calculate the first and last pixels to use */
if(start_time == t1)
start_pixel = 0;
else {
start_pixel_ratio = ((double)(start_time - t1)) / ((double)(t2 - t1));
start_pixel = (int)(start_pixel_ratio * (drawing_width - 1));
}
if(end_time == t1)
end_pixel = 0;
else {
end_pixel_ratio = ((double)(end_time - t1)) / ((double)(t2 - t1));
end_pixel = (int)(end_pixel_ratio * (drawing_width - 1));
}
#ifdef DEBUG
printf("\tPixel %d to %d\n\n", start_pixel, end_pixel);
#endif
/* we're creating the image, so draw... */
if(mode == CREATE_IMAGE) {
/* figure out the color to use for drawing */
switch(start_state) {
case AS_HOST_UP:
color_to_use = color_green;
height = 60;
break;
case AS_HOST_DOWN:
color_to_use = color_red;
height = 40;
break;
case AS_HOST_UNREACHABLE:
color_to_use = color_darkred;
height = 20;
break;
case AS_SVC_OK:
color_to_use = color_green;
height = 80;
break;
case AS_SVC_WARNING:
color_to_use = color_yellow;
height = 60;
break;
case AS_SVC_UNKNOWN:
color_to_use = color_orange;
height = 40;
break;
case AS_SVC_CRITICAL:
color_to_use = color_red;
height = 20;
break;
default:
color_to_use = color_black;
height = 0;
break;
}
/* draw a rectangle */
if(start_state != AS_NO_DATA)
gdImageFilledRectangle(trends_image, start_pixel + drawing_x_offset, drawing_height - height + drawing_y_offset, end_pixel + drawing_x_offset, drawing_height + drawing_y_offset, color_to_use);
}
/* else we're creating the HTML, so write map area code... */
else {
/* figure out the the state string to use */
switch(start_state) {
case AS_HOST_UP:
strcpy(state_string, "UP");
height = 60;
break;
case AS_HOST_DOWN:
strcpy(state_string, "DOWN");
height = 40;
break;
case AS_HOST_UNREACHABLE:
strcpy(state_string, "UNREACHABLE");
height = 20;
break;
case AS_SVC_OK:
strcpy(state_string, "OK");
height = 80;
break;
case AS_SVC_WARNING:
strcpy(state_string, "WARNING");
height = 60;
break;
case AS_SVC_UNKNOWN:
strcpy(state_string, "UNKNOWN");
height = 40;
break;
case AS_SVC_CRITICAL:
strcpy(state_string, "CRITICAL");
height = 20;
break;
default:
strcpy(state_string, "?");
height = 5;
break;
}
/* get the center of this time range */
center_time = start_time + ((end_time - start_time) / 2);
/* determine next start and end time range with zoom factor */
if(zoom_factor > 0) {
next_start_time = center_time - (((t2 - t1) / 2) / zoom_factor);
next_end_time = center_time + (((t2 - t1) / 2) / zoom_factor);
}
else {
next_start_time = center_time + (((t2 - t1) / 2) * zoom_factor);
next_end_time = center_time - (((t2 - t1) / 2) * zoom_factor);
}
printf(" 0)
printf("&backtrack=%d", backtrack_archives);
printf("&zoom=%d", zoom_factor);
printf("' ");
/* display popup text */
if(display_popups == TRUE) {
snprintf(start_timestring, sizeof(start_timestring) - 1, "%s", ctime(&real_start_time));
start_timestring[sizeof(start_timestring) - 1] = '\x0';
start_timestring[strlen(start_timestring) - 1] = '\x0';
snprintf(end_timestring, sizeof(end_timestring) - 1, "%s", ctime(&end_time));
end_timestring[sizeof(end_timestring) - 1] = '\x0';
end_timestring[strlen(end_timestring) - 1] = '\x0';
/* calculate total time in this state */
get_time_breakdown((time_t)(end_time - start_time), &days, &hours, &minutes, &seconds);
/* sanitize plugin output */
sanitize_plugin_output(state_info);
printf("onMouseOver='showPopup(\"");
snprintf(temp_buffer, sizeof(temp_buffer) - 1, "%s Time Range: %s to %s Duration: %dd %dh %dm %ds State Info: %s", state_string, start_timestring, end_timestring, days, hours, minutes, seconds, (state_info == NULL) ? "N/A" : state_info);
temp_buffer[sizeof(temp_buffer) - 1] = '\x0';
printf("%s", temp_buffer);
printf("\",event)' onMouseOut='hidePopup()'");
}
printf(">\n");
}
/* calculate time in this state */
switch(start_state) {
case AS_HOST_UP:
time_up += (unsigned long)(end_time - start_time);
break;
case AS_HOST_DOWN:
time_down += (unsigned long)(end_time - start_time);
break;
case AS_HOST_UNREACHABLE:
time_unreachable += (unsigned long)(end_time - start_time);
break;
case AS_SVC_OK:
time_ok += (unsigned long)(end_time - start_time);
break;
case AS_SVC_WARNING:
time_warning += (unsigned long)(end_time - start_time);
break;
case AS_SVC_UNKNOWN:
time_unknown += (unsigned long)(end_time - start_time);
break;
case AS_SVC_CRITICAL:
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;
}
/* adds an archived state entry */
void add_archived_state(int entry_type, int state_type, time_t time_stamp, char *state_info) {
archived_state *last_as = NULL;
archived_state *temp_as = NULL;
archived_state *new_as = NULL;
#ifdef DEBUG
printf("Added state %d @ %s", state_type, ctime(&time_stamp));
#endif
/* 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 = entry_type;
new_as->processed_state = entry_type;
new_as->state_type = state_type;
new_as->time_stamp = time_stamp;
/* add the new entry to the list in memory, sorted by time */
last_as = as_list;
for(temp_as = as_list; temp_as != NULL; temp_as = temp_as->next) {
if(new_as->time_stamp < temp_as->time_stamp) {
new_as->next = temp_as;
if(temp_as == as_list)
as_list = new_as;
else
last_as->next = new_as;
break;
}
else
last_as = temp_as;
}
if(as_list == NULL) {
new_as->next = NULL;
as_list = new_as;
}
else if(temp_as == NULL) {
new_as->next = NULL;
last_as->next = new_as;
}
return;
}
/* frees memory allocated to the archived state list */
void free_archived_state_list(void) {
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 newest_archive = 0;
int oldest_archive = 0;
int current_archive;
#ifdef DEBUG
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_archive < newest_archive)
oldest_archive = newest_archive;
#ifdef DEBUG
printf("Oldest archive: %d\n", oldest_archive);
printf("Newest archive: %d\n", newest_archive);
#endif
/* read in all the necessary archived logs */
for(current_archive = newest_archive; current_archive <= oldest_archive; current_archive++) {
/* get the name of the log file that contains this archive */
get_log_archive_to_use(current_archive, filename, sizeof(filename) - 1);
#ifdef DEBUG
printf("\tCurrent archive: %d (%s)\n", current_archive, filename);
#endif
/* scan the log file for archived state data */
scan_log_file_for_archived_state_data(filename);
}
return;
}
/* grabs archives state data from a log file */
void scan_log_file_for_archived_state_data(char *filename) {
char *input = NULL;
char *input2 = NULL;
char entry_host_name[MAX_INPUT_BUFFER];
char entry_svc_description[MAX_INPUT_BUFFER];
char *plugin_output = NULL;
char *temp_buffer = NULL;
time_t time_stamp;
mmapfile *thefile = NULL;
int state_type = 0;
/* print something so browser doesn't time out */
if(mode == CREATE_HTML) {
printf(" ");
fflush(NULL);
}
if((thefile = mmap_fopen(filename)) == NULL) {
#ifdef DEBUG
printf("Could not open file '%s' for reading.\n", filename);
#endif
return;
}
#ifdef DEBUG
printf("Scanning log file '%s' for archived state data...\n", filename);
#endif
while(1) {
/* free memory */
free(input);
free(input2);
input = NULL;
input2 = NULL;
/* read the next line */
if((input = mmap_fgets(thefile)) == NULL)
break;
strip(input);
if((input2 = strdup(input)) == NULL)
continue;
temp_buffer = my_strtok(input2, "]");
time_stamp = (temp_buffer == NULL) ? (time_t)0 : (time_t)strtoul(temp_buffer + 1, NULL, 10);
/* program starts/restarts */
if(strstr(input, " starting..."))
add_archived_state(AS_PROGRAM_START, AS_NO_DATA, time_stamp, "Program start");
if(strstr(input, " restarting..."))
add_archived_state(AS_PROGRAM_START, AS_NO_DATA, time_stamp, "Program restart");
/* program stops */
if(strstr(input, " shutting down..."))
add_archived_state(AS_PROGRAM_END, AS_NO_DATA, time_stamp, "Normal program termination");
if(strstr(input, "Bailing out"))
add_archived_state(AS_PROGRAM_END, AS_NO_DATA, time_stamp, "Abnormal program termination");
if(display_type == DISPLAY_HOST_TRENDS) {
if(strstr(input, "HOST ALERT:") || strstr(input, "INITIAL HOST STATE:") || strstr(input, "CURRENT HOST STATE:")) {
free(input2);
if((input2 = strdup(input)) == NULL)
continue;
/* get host name */
temp_buffer = my_strtok(input2, "]");
temp_buffer = my_strtok(NULL, ":");
temp_buffer = my_strtok(NULL, ";");
strncpy(entry_host_name, (temp_buffer == NULL) ? "" : temp_buffer + 1, sizeof(entry_host_name));
entry_host_name[sizeof(entry_host_name) - 1] = '\x0';
if(strcmp(host_name, entry_host_name))
continue;
/* state types */
if(strstr(input, ";SOFT;")) {
if(include_soft_states == FALSE)
continue;
state_type = AS_SOFT_STATE;
}
if(strstr(input, ";HARD;"))
state_type = AS_HARD_STATE;
/* get the plugin output */
temp_buffer = my_strtok(NULL, ";");
temp_buffer = my_strtok(NULL, ";");
temp_buffer = my_strtok(NULL, ";");
plugin_output = my_strtok(NULL, "\n");
if(strstr(input, ";DOWN;"))
add_archived_state(AS_HOST_DOWN, state_type, time_stamp, plugin_output);
else if(strstr(input, ";UNREACHABLE;"))
add_archived_state(AS_HOST_UNREACHABLE, state_type, time_stamp, plugin_output);
else if(strstr(input, ";RECOVERY") || strstr(input, ";UP;"))
add_archived_state(AS_HOST_UP, state_type, time_stamp, plugin_output);
else
add_archived_state(AS_NO_DATA, AS_NO_DATA, time_stamp, plugin_output);
}
}
if(display_type == DISPLAY_SERVICE_TRENDS) {
if(strstr(input, "SERVICE ALERT:") || strstr(input, "INITIAL SERVICE STATE:") || strstr(input, "CURRENT SERVICE STATE:")) {
free(input2);
if((input2 = strdup(input)) == NULL)
continue;
/* get host name */
temp_buffer = my_strtok(input2, "]");
temp_buffer = my_strtok(NULL, ":");
temp_buffer = my_strtok(NULL, ";");
strncpy(entry_host_name, (temp_buffer == NULL) ? "" : temp_buffer + 1, sizeof(entry_host_name));
entry_host_name[sizeof(entry_host_name) - 1] = '\x0';
if(strcmp(host_name, entry_host_name))
continue;
/* get service description */
temp_buffer = my_strtok(NULL, ";");
strncpy(entry_svc_description, (temp_buffer == NULL) ? "" : temp_buffer, sizeof(entry_svc_description));
entry_svc_description[sizeof(entry_svc_description) - 1] = '\x0';
if(strcmp(svc_description, entry_svc_description))
continue;
/* state types */
if(strstr(input, ";SOFT;")) {
if(include_soft_states == FALSE)
continue;
state_type = AS_SOFT_STATE;
}
if(strstr(input, ";HARD;"))
state_type = AS_HARD_STATE;
/* get the plugin output */
temp_buffer = my_strtok(NULL, ";");
temp_buffer = my_strtok(NULL, ";");
temp_buffer = my_strtok(NULL, ";");
plugin_output = my_strtok(NULL, "\n");
if(strstr(input, ";CRITICAL;"))
add_archived_state(AS_SVC_CRITICAL, state_type, time_stamp, plugin_output);
else if(strstr(input, ";WARNING;"))
add_archived_state(AS_SVC_WARNING, state_type, time_stamp, plugin_output);
else if(strstr(input, ";UNKNOWN;"))
add_archived_state(AS_SVC_UNKNOWN, state_type, time_stamp, plugin_output);
else if(strstr(input, ";RECOVERY;") || strstr(input, ";OK;"))
add_archived_state(AS_SVC_OK, state_type, time_stamp, plugin_output);
else
add_archived_state(AS_NO_DATA, AS_NO_DATA, time_stamp, plugin_output);
}
}
}
/* free memory and close the file */
free(input);
free(input2);
mmap_fclose(thefile);
return;
}
/* write JavaScript code and layer for popup window */
void write_popup_code(void) {
char *border_color = "#000000";
char *background_color = "#ffffcc";
int border = 1;
int padding = 3;
int x_offset = 3;
int y_offset = 3;
printf("\n");
return;
}
/* write timestamps */
void draw_timestamps(void) {
int last_timestamp = 0;
archived_state *temp_as;
double start_pixel_ratio;
int start_pixel;
if(mode != CREATE_IMAGE)
return;
/* draw first timestamp */
draw_timestamp(0, t1);
last_timestamp = 0;
for(temp_as = as_list; temp_as != NULL; temp_as = temp_as->next) {
if(temp_as->time_stamp < t1 || temp_as->time_stamp > t2)
continue;
start_pixel_ratio = ((double)(temp_as->time_stamp - t1)) / ((double)(t2 - t1));
start_pixel = (int)(start_pixel_ratio * (drawing_width - 1));
/* draw start timestamp if possible */
if((start_pixel > last_timestamp + MIN_TIMESTAMP_SPACING) && (start_pixel < drawing_width - 1 - MIN_TIMESTAMP_SPACING)) {
draw_timestamp(start_pixel, temp_as->time_stamp);
last_timestamp = start_pixel;
}
}
/* draw last timestamp */
draw_timestamp(drawing_width - 1, t2);
return;
}
/* write timestamp below graph */
void draw_timestamp(int ts_pixel, time_t ts_time) {
char temp_buffer[MAX_INPUT_BUFFER];
int string_height;
int string_width;
snprintf(temp_buffer, sizeof(temp_buffer) - 1, "%s", ctime(&ts_time));
temp_buffer[sizeof(temp_buffer) - 1] = '\x0';
temp_buffer[strlen(temp_buffer) - 1] = '\x0';
string_height = gdFontSmall->h;
string_width = gdFontSmall->w * strlen(temp_buffer);
if(small_image == FALSE)
gdImageStringUp(trends_image, gdFontSmall, ts_pixel + drawing_x_offset - (string_height / 2), drawing_y_offset + drawing_height + string_width + 5, (unsigned char *)temp_buffer, color_black);
/* draw a dashed vertical line at this point */
if(ts_pixel > 0 && ts_pixel < (drawing_width - 1))
draw_dashed_line(ts_pixel + drawing_x_offset, drawing_y_offset, ts_pixel + drawing_x_offset, drawing_y_offset + drawing_height, color_black);
return;
}
/* draw total state times */
void draw_time_breakdowns(void) {
char temp_buffer[MAX_INPUT_BUFFER];
unsigned long total_time = 0L;
unsigned long total_state_time;
unsigned long time_indeterminate = 0L;
int string_height;
if(mode == CREATE_HTML)
return;
if(small_image == TRUE)
return;
total_time = (unsigned long)(t2 - t1);
if(display_type == DISPLAY_HOST_TRENDS)
total_state_time = time_up + time_down + time_unreachable;
else
total_state_time = time_ok + time_warning + time_unknown + time_critical;
if(total_state_time >= total_time)
time_indeterminate = 0L;
else
time_indeterminate = total_time - total_state_time;
string_height = gdFontSmall->h;
if(display_type == DISPLAY_HOST_TRENDS) {
get_time_breakdown_string(total_time, time_up, "Up", &temp_buffer[0], sizeof(temp_buffer));
gdImageString(trends_image, gdFontSmall, drawing_x_offset + drawing_width + 20, drawing_y_offset + 5, (unsigned char *)temp_buffer, color_darkgreen);
gdImageString(trends_image, gdFontSmall, drawing_x_offset - 10 - (gdFontSmall->w * 2), drawing_y_offset + 5, (unsigned char *)"Up", color_darkgreen);
get_time_breakdown_string(total_time, time_down, "Down", &temp_buffer[0], sizeof(temp_buffer));
gdImageString(trends_image, gdFontSmall, drawing_x_offset + drawing_width + 20, drawing_y_offset + 25, (unsigned char *)temp_buffer, color_red);
gdImageString(trends_image, gdFontSmall, drawing_x_offset - 10 - (gdFontSmall->w * 4), drawing_y_offset + 25, (unsigned char *)"Down", color_red);
get_time_breakdown_string(total_time, time_unreachable, "Unreachable", &temp_buffer[0], sizeof(temp_buffer));
gdImageString(trends_image, gdFontSmall, drawing_x_offset + drawing_width + 20, drawing_y_offset + 45, (unsigned char *)temp_buffer, color_darkred);
gdImageString(trends_image, gdFontSmall, drawing_x_offset - 10 - (gdFontSmall->w * 11), drawing_y_offset + 45, (unsigned char *)"Unreachable", color_darkred);
get_time_breakdown_string(total_time, time_indeterminate, "Indeterminate", &temp_buffer[0], sizeof(temp_buffer));
gdImageString(trends_image, gdFontSmall, drawing_x_offset + drawing_width + 20, drawing_y_offset + 65, (unsigned char *)temp_buffer, color_black);
gdImageString(trends_image, gdFontSmall, drawing_x_offset - 10 - (gdFontSmall->w * 13), drawing_y_offset + 65, (unsigned char *)"Indeterminate", color_black);
}
else {
get_time_breakdown_string(total_time, time_ok, "Ok", &temp_buffer[0], sizeof(temp_buffer));
gdImageString(trends_image, gdFontSmall, drawing_x_offset + drawing_width + 20, drawing_y_offset + 5, (unsigned char *)temp_buffer, color_darkgreen);
gdImageString(trends_image, gdFontSmall, drawing_x_offset - 10 - (gdFontSmall->w * 2), drawing_y_offset + 5, (unsigned char *)"Ok", color_darkgreen);
get_time_breakdown_string(total_time, time_warning, "Warning", &temp_buffer[0], sizeof(temp_buffer));
gdImageString(trends_image, gdFontSmall, drawing_x_offset + drawing_width + 20, drawing_y_offset + 25, (unsigned char *)temp_buffer, color_yellow);
gdImageString(trends_image, gdFontSmall, drawing_x_offset - 10 - (gdFontSmall->w * 7), drawing_y_offset + 25, (unsigned char *)"Warning", color_yellow);
get_time_breakdown_string(total_time, time_unknown, "Unknown", &temp_buffer[0], sizeof(temp_buffer));
gdImageString(trends_image, gdFontSmall, drawing_x_offset + drawing_width + 20, drawing_y_offset + 45, (unsigned char *)temp_buffer, color_orange);
gdImageString(trends_image, gdFontSmall, drawing_x_offset - 10 - (gdFontSmall->w * 7), drawing_y_offset + 45, (unsigned char *)"Unknown", color_orange);
get_time_breakdown_string(total_time, time_critical, "Critical", &temp_buffer[0], sizeof(temp_buffer));
gdImageString(trends_image, gdFontSmall, drawing_x_offset + drawing_width + 20, drawing_y_offset + 65, (unsigned char *)temp_buffer, color_red);
gdImageString(trends_image, gdFontSmall, drawing_x_offset - 10 - (gdFontSmall->w * 8), drawing_y_offset + 65, (unsigned char *)"Critical", color_red);
get_time_breakdown_string(total_time, time_indeterminate, "Indeterminate", &temp_buffer[0], sizeof(temp_buffer));
gdImageString(trends_image, gdFontSmall, drawing_x_offset + drawing_width + 20, drawing_y_offset + 85, (unsigned char *)temp_buffer, color_black);
gdImageString(trends_image, gdFontSmall, drawing_x_offset - 10 - (gdFontSmall->w * 13), drawing_y_offset + 85, (unsigned char *)"Indeterminate", color_black);
}
return;
}
void get_time_breakdown_string(unsigned long total_time, unsigned long state_time, char *state_string, char *buffer, int buffer_length) {
int days;
int hours;
int minutes;
int seconds;
double percent_time;
get_time_breakdown(state_time, &days, &hours, &minutes, &seconds);
if(total_time == 0L)
percent_time = 0.0;
else
percent_time = ((double)state_time / total_time) * 100.0;
snprintf(buffer, buffer_length - 1, "%-13s: (%.3f%%) %dd %dh %dm %ds", state_string, percent_time, days, hours, minutes, seconds);
buffer[buffer_length - 1] = '\x0';
return;
}
void convert_timeperiod_to_times(int type) {
time_t current_time;
struct tm *t;
/* get the current time */
time(¤t_time);
t = localtime(¤t_time);
t->tm_sec = 0;
t->tm_min = 0;
t->tm_hour = 0;
t->tm_isdst = -1;
switch(type) {
case TIMEPERIOD_LAST24HOURS:
t1 = current_time - (60 * 60 * 24);
t2 = current_time;
break;
case TIMEPERIOD_TODAY:
t1 = mktime(t);
t2 = current_time;
break;
case TIMEPERIOD_YESTERDAY:
t1 = (time_t)(mktime(t) - (60 * 60 * 24));
t2 = (time_t)mktime(t);
break;
case TIMEPERIOD_THISWEEK:
t1 = (time_t)(mktime(t) - (60 * 60 * 24 * t->tm_wday));
t2 = current_time;
break;
case TIMEPERIOD_LASTWEEK:
t1 = (time_t)(mktime(t) - (60 * 60 * 24 * t->tm_wday) - (60 * 60 * 24 * 7));
t2 = (time_t)(mktime(t) - (60 * 60 * 24 * t->tm_wday));
break;
case TIMEPERIOD_THISMONTH:
t->tm_mday = 1;
t1 = mktime(t);
t2 = current_time;
break;
case TIMEPERIOD_LASTMONTH:
t->tm_mday = 1;
t2 = mktime(t);
if(t->tm_mon == 0) {
t->tm_mon = 11;
t->tm_year--;
}
else
t->tm_mon--;
t1 = mktime(t);
break;
case TIMEPERIOD_THISQUARTER:
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_NEXTPROBLEM:
/* Time period will be defined later */
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;
st->tm_isdst = -1;
t1 = mktime(st);
et = localtime(¤t_time);
et->tm_sec = end_second;
et->tm_min = end_minute;
et->tm_hour = end_hour;
et->tm_mday = end_day;
et->tm_mon = end_month - 1;
et->tm_year = end_year - 1900;
et->tm_isdst = -1;
t2 = mktime(et);
}
/* draws a dashed line */
void draw_dashed_line(int x1, int y1, int x2, int y2, int color) {
int styleDashed[12];
styleDashed[0] = color;
styleDashed[1] = color;
styleDashed[2] = gdTransparent;
styleDashed[3] = gdTransparent;
styleDashed[4] = color;
styleDashed[5] = color;
styleDashed[6] = gdTransparent;
styleDashed[7] = gdTransparent;
styleDashed[8] = color;
styleDashed[9] = color;
styleDashed[10] = gdTransparent;
styleDashed[11] = gdTransparent;
/* sets current style to a dashed line */
gdImageSetStyle(trends_image, styleDashed, 12);
/* draws a line (dashed) */
gdImageLine(trends_image, x1, y1, x2, y2, gdStyled);
return;
}
/* draws horizontal grid lines */
void draw_horizontal_grid_lines(void) {
if(mode == CREATE_HTML)
return;
if(small_image == TRUE)
return;
draw_dashed_line(drawing_x_offset, drawing_y_offset + 10, drawing_x_offset + drawing_width, drawing_y_offset + 10, color_black);
draw_dashed_line(drawing_x_offset, drawing_y_offset + 30, drawing_x_offset + drawing_width, drawing_y_offset + 30, color_black);
draw_dashed_line(drawing_x_offset, drawing_y_offset + 50, drawing_x_offset + drawing_width, drawing_y_offset + 50, color_black);
if(display_type == DISPLAY_SERVICE_TRENDS)
draw_dashed_line(drawing_x_offset, drawing_y_offset + 70, drawing_x_offset + drawing_width, drawing_y_offset + 70, color_black);
return;
}