Logo Search packages:      
Sourcecode: nagios version File versions  Download package

histogram.c

/**************************************************************************
 *
 * HISTOGRAM.C -  Nagios Alert Histogram CGI
 *
 * Copyright (c) 2001-2002 Ethan Galstad (nagios@nagios.org)
 * Last Modified: 11-22-2002
 *
 * 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/statusdata.h"

#include "cgiutils.h"
#include "getcgi.h"
#include "auth.h"

#include <gd.h>               /* Boutell's GD library function */
#include <gdfonts.h>          /* 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 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 host *host_list;
extern service *service_list;

extern int     log_rotation_method;



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_DAY_OF_MONTH;
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(DEFAULT_CGI_CONFIG_FILE);
      if(result==ERROR){
            if(mode==CREATE_HTML){
                  document_header(FALSE);
                  cgi_config_file_error(DEFAULT_CGI_CONFIG_FILE);
                  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(DEFAULT_CGI_CONFIG_FILE,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(&current_authdata);

      if(compute_time_from_parts==TRUE)
            compute_report_times();

      /* make sure times are sane, otherwise swap them */
      if(t2<t1){
            t3=t2;
            t2=t1;
            t1=t3;
              }
                  

      if(mode==CREATE_HTML && display_header==TRUE){

            /* begin top table */
            printf("<table border=0 width=100%% cellspacing=0 cellpadding=0>\n");
            printf("<tr>\n");

            /* left column of the first row */
            printf("<td align=left valign=top width=33%%>\n");

            if(display_type==DISPLAY_HOST_HISTOGRAM)
                  snprintf(temp_buffer,sizeof(temp_buffer)-1,"Host Alert Histogram");
            else if(display_type==DISPLAY_SERVICE_HISTOGRAM)
                  snprintf(temp_buffer,sizeof(temp_buffer)-1,"Service Alert Histogram");
            else
                  snprintf(temp_buffer,sizeof(temp_buffer)-1,"Host and Service Alert Histogram");
            temp_buffer[sizeof(temp_buffer)-1]='\x0';
            display_info_table(temp_buffer,FALSE,&current_authdata);

            if(display_type!=DISPLAY_NO_HISTOGRAM && input_type==GET_INPUT_NONE){

                  printf("<TABLE BORDER=1 CELLPADDING=0 CELLSPACING=0 CLASS='linkBox'>\n");
                  printf("<TR><TD CLASS='linkBox'>\n");

                  if(display_type==DISPLAY_HOST_HISTOGRAM){
                        printf("<a href='%s?host=%s&t1=%lu&t2=%lu&assumestateretention=%s'>View Trends For This Host</a><BR>\n",TRENDS_CGI,url_encode(host_name),t1,t2,(assume_state_retention==TRUE)?"yes":"no");
                        printf("<a href='%s?host=%s&t1=%lu&t2=%lu&assumestateretention=%s&show_log_entries'>View Availability Report For This Host</a><BR>\n",AVAIL_CGI,url_encode(host_name),t1,t2,(assume_state_retention==TRUE)?"yes":"no");
                        printf("<a href='%s?host=%s'>View Status Detail For This Host</a><BR>\n",STATUS_CGI,url_encode(host_name));
                        printf("<a href='%s?host=%s'>View History For This Host</a><BR>\n",HISTORY_CGI,url_encode(host_name));
                        printf("<a href='%s?host=%s'>View Notifications For This Host</a><BR>\n",NOTIFICATIONS_CGI,url_encode(host_name));
                            }
                  else{
                        printf("<a href='%s?host=%s",TRENDS_CGI,url_encode(host_name));
                        printf("&service=%s&t1=%lu&t2=%lu&assumestateretention=%s'>View Trends For This Service</a><BR>\n",url_encode(svc_description),t1,t2,(assume_state_retention==TRUE)?"yes":"no");
                        printf("<a href='%s?host=%s",AVAIL_CGI,url_encode(host_name));
                        printf("&service=%s&t1=%lu&t2=%lu&assumestateretention=%s&show_log_entries'>View Availability Report For This Service</a><BR>\n",url_encode(svc_description),t1,t2,(assume_state_retention==TRUE)?"yes":"no");
                        printf("<A HREF='%s?host=%s&",HISTORY_CGI,url_encode(host_name));
                        printf("service=%s'>View History This Service</A><BR>\n",url_encode(svc_description));
                        printf("<A HREF='%s?host=%s&",NOTIFICATIONS_CGI,url_encode(host_name));
                        printf("service=%s'>View Notifications This Service</A><BR>\n",url_encode(svc_description));
                            }

                  printf("</TD></TR>\n");
                  printf("</TABLE>\n");
                    }

            printf("</td>\n");

            /* center column of top row */
            printf("<td align=center valign=top width=33%%>\n");

            if(display_type!=DISPLAY_NO_HISTOGRAM && input_type==GET_INPUT_NONE){

                  printf("<DIV ALIGN=CENTER CLASS='dataTitle'>\n");
                  if(display_type==DISPLAY_HOST_HISTOGRAM)
                        printf("Host '%s'",host_name);
                  else if(display_type==DISPLAY_SERVICE_HISTOGRAM)
                        printf("Service '%s' On Host '%s'",svc_description,host_name);
                  printf("</DIV>\n");

                  printf("<BR>\n");

                  printf("<IMG SRC='%s%s' BORDER=0 ALT='%s Event Histogram'>\n",url_images_path,TRENDS_ICON,(display_type==DISPLAY_HOST_HISTOGRAM)?"Host":"Service");

                  printf("<BR CLEAR=ALL>\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("<div align=center class='reportRange'>%s to %s</div>\n",start_timestring,end_timestring);

                  get_time_breakdown((time_t)(t2-t1),&days,&hours,&minutes,&seconds);
                  printf("<div align=center class='reportDuration'>Duration: %dd %dh %dm %ds</div>\n",days,hours,minutes,seconds);
                    }

            printf("</td>\n");

            /* right hand column of top row */
            printf("<td align=right valign=bottom width=33%%>\n");

            printf("<table border=0 CLASS='optBox'>\n");

            if(display_type!=DISPLAY_NO_HISTOGRAM && input_type==GET_INPUT_NONE){

                  printf("<form method=\"GET\" action=\"%s\">\n",HISTOGRAM_CGI);
                  printf("<input type='hidden' name='t1' value='%lu'>\n",(unsigned long)t1);
                  printf("<input type='hidden' name='t2' value='%lu'>\n",(unsigned long)t2);
                  printf("<input type='hidden' name='host' value='%s'>\n",host_name);
                  if(display_type==DISPLAY_SERVICE_HISTOGRAM)
                        printf("<input type='hidden' name='service' value='%s'>\n",svc_description);


                  printf("<tr><td CLASS='optBoxItem' valign=top align=left>Report period:</td><td CLASS='optBoxItem' valign=top align=left>Assume state retention:</td></tr>\n");
                  printf("<tr><td CLASS='optBoxItem' valign=top align=left>\n");
                  printf("<select name='timeperiod'>\n");
                  printf("<option value=custom SELECTED>[ Current time range ]\n");
                  printf("<option value=last24hours>Last 24 Hours\n");
                  printf("<option value=today>Today\n");
                  printf("<option value=yesterday>Yesterday\n");
                  printf("<option value=thisweek>This Week\n");
                  printf("<option value=last7days>Last 7 Days\n");
                  printf("<option value=lastweek>Last Week\n");
                  printf("<option value=thismonth>This Month\n");
                  printf("<option value=lastmonth>Last Month\n");
                  printf("<option value=thisyear>This Year\n");
                  printf("<option value=lastyear>Last Year\n");
                  printf("</select>\n");
                  printf("</td><td CLASS='optBoxItem' valign=top align=left>\n");
                  printf("<select name='assumestateretention'>\n");
                  printf("<option value=yes %s>yes\n",(assume_state_retention==TRUE)?"SELECTED":"");
                  printf("<option value=no %s>no\n",(assume_state_retention==TRUE)?"":"SELECTED");
                  printf("</select>\n");
                  printf("</td></tr>\n");

                  printf("<tr><td CLASS='optBoxItem' valign=top align=left>Breakdown type:</td><td CLASS='optBoxItem' valign=top align=left>Initial states logged:</td></tr>\n");
                  printf("<tr><td CLASS='optBoxItem' valign=top align=left>\n");
                  printf("<select name='breakdown'>\n");
                  printf("<option value=monthly %s>Month\n",(breakdown_type==BREAKDOWN_MONTHLY)?"SELECTED":"");
                  printf("<option value=dayofmonth %s>Day of the Month\n",(breakdown_type==BREAKDOWN_DAY_OF_MONTH)?"SELECTED":"");
                  printf("<option value=dayofweek %s>Day of the Week\n",(breakdown_type==BREAKDOWN_DAY_OF_WEEK)?"SELECTED":"");
                  printf("<option value=hourly %s>Hour of the Day\n",(breakdown_type==BREAKDOWN_HOURLY)?"SELECTED":"");
                  printf("</select>\n");
                  printf("</td><td CLASS='optBoxItem' valign=top align=left>\n");
                  printf("<select name='initialstateslogged'>\n");
                  printf("<option value=yes %s>yes\n",(initial_states_logged==TRUE)?"SELECTED":"");
                  printf("<option value=no %s>no\n",(initial_states_logged==TRUE)?"":"SELECTED");
                  printf("</select>\n");
                  printf("</td></tr>\n");

                  printf("<tr><td CLASS='optBoxItem' valign=top align=left>Events to graph:</td><td CLASS='optBoxItem' valign=top align=left>Ignore repeated states:</td></tr>\n");
                  printf("<tr><td CLASS='optBoxItem' valign=top align=left>\n");
                  printf("<select name='graphevents'>\n");
                  if(display_type==DISPLAY_HOST_HISTOGRAM){
                        printf("<option value=%d %s>All host events\n",GRAPH_HOST_ALL,(graph_events==GRAPH_HOST_ALL)?"SELECTED":"");
                        printf("<option value=%d %s>Host problem events\n",GRAPH_HOST_PROBLEMS,(graph_events==GRAPH_HOST_PROBLEMS)?"SELECTED":"");
                        printf("<option value=%d %s>Host up events\n",GRAPH_HOST_UP,(graph_events==GRAPH_HOST_UP)?"SELECTED":"");
                        printf("<option value=%d %s>Host down events\n",GRAPH_HOST_DOWN,(graph_events==GRAPH_HOST_DOWN)?"SELECTED":"");
                        printf("<option value=%d %s>Host unreachable events\n",GRAPH_HOST_UNREACHABLE,(graph_events==GRAPH_HOST_UNREACHABLE)?"SELECTED":"");
                          }
                  else{
                        printf("<option value=%d %s>All service events\n",GRAPH_SERVICE_ALL,(graph_events==GRAPH_SERVICE_ALL)?"SELECTED":"");
                        printf("<option value=%d %s>Service problem events\n",GRAPH_SERVICE_PROBLEMS,(graph_events==GRAPH_SERVICE_PROBLEMS)?"SELECTED":"");
                        printf("<option value=%d %s>Service ok events\n",GRAPH_SERVICE_OK,(graph_events==GRAPH_SERVICE_OK)?"SELECTED":"");
                        printf("<option value=%d %s>Service warning events\n",GRAPH_SERVICE_WARNING,(graph_events==GRAPH_SERVICE_WARNING)?"SELECTED":"");
                        printf("<option value=%d %s>Service unknown events\n",GRAPH_SERVICE_UNKNOWN,(graph_events==GRAPH_SERVICE_UNKNOWN)?"SELECTED":"");
                        printf("<option value=%d %s>Service critical events\n",GRAPH_SERVICE_CRITICAL,(graph_events==GRAPH_SERVICE_CRITICAL)?"SELECTED":"");
                          }
                  printf("</select>\n");
                  printf("</td><td CLASS='optBoxItem' valign=top align=left>\n");
                  printf("<select name='newstatesonly'>\n");
                  printf("<option value=yes %s>yes\n",(new_states_only==TRUE)?"SELECTED":"");
                  printf("<option value=no %s>no\n",(new_states_only==TRUE)?"":"SELECTED");
                  printf("</select>\n");
                  printf("</td></tr>\n");

                  printf("<tr><td CLASS='optBoxItem' valign=top align=left>State types to graph:</td><td CLASS='optBoxItem' valign=top align=left></td></tr>\n");
                  printf("<tr><td CLASS='optBoxItem' valign=top align=left>\n");
                  printf("<select name='graphstatetypes'>\n");
                  printf("<option value=%d %s>Hard states\n",GRAPH_HARD_STATETYPES,(graph_statetypes==GRAPH_HARD_STATETYPES)?"SELECTED":"");
                  printf("<option value=%d %s>Soft states\n",GRAPH_SOFT_STATETYPES,(graph_statetypes==GRAPH_SOFT_STATETYPES)?"SELECTED":"");
                  printf("<option value=%d %s>Hard and soft states\n",GRAPH_ALL_STATETYPES,(graph_statetypes==GRAPH_ALL_STATETYPES)?"SELECTED":"");
                  printf("</select>\n");
                  printf("</td><td CLASS='optBoxItem' valign=top align=left>\n");
                  printf("<input type='submit' value='Update'>\n");
                  printf("</td></tr>\n");

                  printf("</form>\n");
                    }

            /* display context-sensitive help */
            printf("<tr><td></td><td align=right valign=bottom>\n");
            if(display_type!=DISPLAY_NO_HISTOGRAM && input_type==GET_INPUT_NONE){
                  if(display_type==DISPLAY_HOST_HISTOGRAM)
                        display_context_help(CONTEXTHELP_HISTOGRAM_HOST);
                  else
                        display_context_help(CONTEXTHELP_HISTOGRAM_SERVICE);
                    }
            else if(display_type==DISPLAY_NO_HISTOGRAM || input_type!=GET_INPUT_NONE){
                  if(input_type==GET_INPUT_NONE)
                        display_context_help(CONTEXTHELP_HISTOGRAM_MENU1);
                  else if(input_type==GET_INPUT_TARGET_TYPE)
                        display_context_help(CONTEXTHELP_HISTOGRAM_MENU1);
                  else if(input_type==GET_INPUT_HOST_TARGET)
                        display_context_help(CONTEXTHELP_HISTOGRAM_MENU2);
                  else if(input_type==GET_INPUT_SERVICE_TARGET)
                        display_context_help(CONTEXTHELP_HISTOGRAM_MENU3);
                  else if(input_type==GET_INPUT_OPTIONS)
                        display_context_help(CONTEXTHELP_HISTOGRAM_MENU4);
                    }
            printf("</td></tr>\n");

            printf("</table>\n");

            printf("</td>\n");

            /* end of top table */
            printf("</tr>\n");
            printf("</table>\n");
              }

      /* check authorization... */
      if(display_type==DISPLAY_HOST_HISTOGRAM){
            temp_host=find_host(host_name,NULL);
            if(temp_host==NULL || is_authorized_for_host(temp_host,&current_authdata)==FALSE)
                  is_authorized=FALSE;
              }
      else if(display_type==DISPLAY_SERVICE_HISTOGRAM){
            temp_service=find_service(host_name,svc_description,NULL);
            if(temp_service==NULL || is_authorized_for_service(temp_service,&current_authdata)==FALSE)
                  is_authorized=FALSE;
              }
      if(is_authorized==FALSE){

            if(mode==CREATE_HTML)
                  printf("<P><DIV ALIGN=CENTER CLASS='errorMessage'>It appears as though you are not authorized to view information for the specified %s...</DIV></P>\n",(display_type==DISPLAY_HOST_HISTOGRAM)?"host":"service");

            document_footer();
            free_memory();
            return ERROR;
              }

      if(display_type!=DISPLAY_NO_HISTOGRAM && input_type==GET_INPUT_NONE){

            /* print URL to image */
            if(mode==CREATE_HTML){

                  printf("<BR><BR>\n");
                  printf("<DIV ALIGN=CENTER>\n");
                  printf("<IMG SRC='%s?createimage&t1=%lu&t2=%lu",HISTOGRAM_CGI,(unsigned long)t1,(unsigned long)t2);
                  printf("&host=%s",url_encode(host_name));
                  if(display_type==DISPLAY_SERVICE_HISTOGRAM)
                        printf("&service=%s",url_encode(svc_description));
                  printf("&breakdown=");
                  if(breakdown_type==BREAKDOWN_MONTHLY)
                        printf("monthly");
                  else if(breakdown_type==BREAKDOWN_DAY_OF_MONTH)
                        printf("dayofmonth");
                  else if(breakdown_type==BREAKDOWN_DAY_OF_WEEK)
                        printf("dayofweek");
                  else
                        printf("hourly");
                  printf("&assumestateretention=%s",(assume_state_retention==TRUE)?"yes":"no");
                  printf("&initialstateslogged=%s",(initial_states_logged==TRUE)?"yes":"no");
                  printf("&newstatesonly=%s",(new_states_only==TRUE)?"yes":"no");
                  printf("&graphevents=%d",graph_events);
                  printf("&graphstatetypes=%d",graph_statetypes);
                  printf("' BORDER=0 name='histogramimage'>\n");
                  printf("</DIV>\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<total_buckets;x++){
                        tsdata[x].service_ok=0L;
                        tsdata[x].service_unknown=0L;
                        tsdata[x].service_warning=0L;
                        tsdata[x].service_critical=0L;
                        tsdata[x].host_up=0L;
                        tsdata[x].host_down=0L;
                        tsdata[x].host_unreachable=0L;
                          }

                  /* read in all necessary archived state data */
                  read_archived_state_data();

#ifdef DEBUG
                  printf("Done reading archived state data.\n");
#endif

                  /* location of image template */
                  snprintf(image_template,sizeof(image_template)-1,"%s/%s",physical_images_path,HISTOGRAM_IMAGE);
                  image_template[sizeof(image_template)-1]='\x0';

                  /* allocate buffer for storing image */
                  image_file=fopen(image_template,"r");
                  if(image_file!=NULL){
                        histogram_image=gdImageCreateFromPng(image_file);
                        fclose(image_file);
                          }
                  if(histogram_image==NULL)
                        histogram_image=gdImageCreate(image_width,image_height);
                  if(histogram_image==NULL){
#ifdef DEBUG
                        printf("Error: Could not allocate memory for image\n");
#endif
                        return ERROR;
                              }

                  /* allocate colors used for drawing */
                  color_white=gdImageColorAllocate(histogram_image,255,255,255);
                  color_black=gdImageColorAllocate(histogram_image,0,0,0);
                  color_red=gdImageColorAllocate(histogram_image,255,0,0);
                  color_darkred=gdImageColorAllocate(histogram_image,128,0,0);
                  color_green=gdImageColorAllocate(histogram_image,0,128,0);
                  color_yellow=gdImageColorAllocate(histogram_image,176,178,20);
                  color_orange=gdImageColorAllocate(histogram_image,255,100,25);
                  color_lightgray=gdImageColorAllocate(histogram_image,192,192,192);

                  /* set transparency index */
                  gdImageColorTransparent(histogram_image,color_white);

                  /* make sure the graphic is interlaced */
                  gdImageInterlace(histogram_image,1);

#ifdef DEBUG
                  printf("Starting to graph data...\n");
#endif

                  /* graph archived state histogram data */
                  graph_all_histogram_data();

#ifdef DEBUG
                  printf("Done graphing data.\n");
#endif

                  /* use STDOUT for writing the image data... */
                  image_file=stdout;

#ifdef DEBUG
                  image_file=fopen("/tmp/histogram.png","w");
#endif

                  /* write the image to to STDOUT */
                  gdImagePng(histogram_image,image_file);
      
#ifdef DEBUG            
                  fclose(image_file);
#endif

                  /* free memory allocated to image */
                  gdImageDestroy(histogram_image);

                  /* free memory allocated for data */
                  free(tsdata);
                      }
              }


      /* show user a selection of hosts and services to choose from... */
      if(display_type==DISPLAY_NO_HISTOGRAM || input_type!=GET_INPUT_NONE){

            /* ask the user for what host they want a report for */
            if(input_type==GET_INPUT_HOST_TARGET){

                  printf("<P><DIV ALIGN=CENTER>\n");
                  printf("<DIV CLASS='reportSelectTitle'>Step 2: Select Host</DIV>\n");
                  printf("</DIV></P>\n");

                  printf("<P><DIV ALIGN=CENTER>\n");

                  printf("<TABLE BORDER=0 cellspacing=0 cellpadding=10>\n");
                  printf("<form method=\"GET\" action=\"%s\">\n",HISTOGRAM_CGI);
                  printf("<input type='hidden' name='input' value='getoptions'>\n");

                  printf("<tr><td class='reportSelectSubTitle' valign=center>Host</td>\n");
                  printf("<td class='reportSelectItem' valign=center>\n");
                  printf("<select name='host'>\n");

                  for(temp_host=host_list;temp_host!=NULL;temp_host=temp_host->next){
                        if(is_authorized_for_host(temp_host,&current_authdata)==TRUE)
                              printf("<option value='%s'>%s\n",temp_host->name,temp_host->name);
                          }

                  printf("</select>\n");
                  printf("</td></tr>\n");

                  printf("<tr><td></td><td class='reportSelectItem'>\n");
                  printf("<input type='submit' value='Continue to Step 3'>\n");
                  printf("</td></tr>\n");

                  printf("</form>\n");
                  printf("</TABLE>\n");

                  printf("</DIV></P>\n");
                    }

            /* ask the user for what service they want a report for */
            else if(input_type==GET_INPUT_SERVICE_TARGET){

                  printf("<SCRIPT LANGUAGE='JavaScript'>\n");
                  printf("function gethostname(hostindex){\n");
                  printf("hostnames=[");

                  for(temp_service=service_list;temp_service!=NULL;temp_service=temp_service->next){
                        if(is_authorized_for_service(temp_service,&current_authdata)==TRUE){
                              if(found==TRUE)
                                    printf(",");
                              else
                                    first_service=temp_service->host_name;
                              printf(" \"%s\"",temp_service->host_name);
                              found=TRUE;
                                  }
                            }
            
                  printf(" ]\n");
                  printf("return hostnames[hostindex];\n");
                  printf("}\n");
                  printf("</SCRIPT>\n");


                  printf("<P><DIV ALIGN=CENTER>\n");
                  printf("<DIV CLASS='reportSelectTitle'>Step 2: Select Service</DIV>\n");
                  printf("</DIV></P>\n");

                  printf("<P><DIV ALIGN=CENTER>\n");
                  
                  printf("<TABLE BORDER=0 cellpadding=5>\n");
                  printf("<form method=\"GET\" action=\"%s\" name=\"serviceform\">\n",HISTOGRAM_CGI);
                  printf("<input type='hidden' name='input' value='getoptions'>\n");
                  printf("<input type='hidden' name='host' value='%s'>\n",(first_service==NULL)?"unknown":first_service);

                  printf("<tr><td class='reportSelectSubTitle'>Service:</td>\n");
                  printf("<td class='reportSelectItem'>\n");
                  printf("<select name='service' onFocus='document.serviceform.host.value=gethostname(this.selectedIndex);' onChange='document.serviceform.host.value=gethostname(this.selectedIndex);'>\n");

                  for(temp_service=service_list;temp_service!=NULL;temp_service=temp_service->next){
                        if(is_authorized_for_service(temp_service,&current_authdata)==TRUE)
                              printf("<option value='%s'>%s;%s\n",temp_service->description,temp_service->host_name,temp_service->description);
                            }

                  printf("</select>\n");
                  printf("</td></tr>\n");

                  printf("<tr><td></td><td class='reportSelectItem'>\n");
                  printf("<input type='submit' value='Continue to Step 3'>\n");
                  printf("</td></tr>\n");

                  printf("</form>\n");
                  printf("</TABLE>\n");

                  printf("</DIV></P>\n");
                    }

            /* ask the user for report range and options */
            else if(input_type==GET_INPUT_OPTIONS){

                  time(&current_time);
                  t=localtime(&current_time);

                  start_day=1;
                  start_year=t->tm_year+1900;
                  end_day=t->tm_mday;
                  end_year=t->tm_year+1900;

                  printf("<P><DIV ALIGN=CENTER>\n");
                  printf("<DIV CLASS='reportSelectTitle'>Step 3: Select Report Options</DIV>\n");
                  printf("</DIV></P>\n");

                  printf("<P><DIV ALIGN=CENTER>\n");

                  printf("<TABLE BORDER=0 cellpadding=5>\n");
                  printf("<form method=\"GET\" action=\"%s\">\n",HISTOGRAM_CGI);
                  printf("<input type='hidden' name='host' value='%s'>\n",host_name);
                  if(display_type==DISPLAY_SERVICE_HISTOGRAM)
                        printf("<input type='hidden' name='service' value='%s'>\n",svc_description);

                  printf("<tr><td class='reportSelectSubTitle' align=right>Report Period:</td>\n");
                  printf("<td class='reportSelectItem'>\n");
                  printf("<select name='timeperiod'>\n");
                  printf("<option value=last24hours>Last 24 Hours\n");
                  printf("<option value=today>Today\n");
                  printf("<option value=yesterday>Yesterday\n");
                  printf("<option value=thisweek>This Week\n");
                  printf("<option value=last7days SELECTED>Last 7 Days\n");
                  printf("<option value=lastweek>Last Week\n");
                  printf("<option value=thismonth>This Month\n");
                  printf("<option value=lastmonth>Last Month\n");
                  printf("<option value=thisyear>This Year\n");
                  printf("<option value=lastyear>Last Year\n");
                  printf("<option value=custom>* CUSTOM REPORT PERIOD *\n");
                  printf("</select>\n");
                  printf("</td></tr>\n");

                  printf("<tr><td colspan=2 valign=top calss='reportSelectSubTitle'><i>If Custom Report Period...</i></td></tr>\n");

                  printf("<tr>");
                  printf("<td valign=top class='reportSelectSubTitle'>Start Date (Inclusive):</td>\n");
                  printf("<td align=left valign=top class='reportSelectItem'>");
                  printf("<select name='smon'>\n");
                  printf("<option value='1' %s>January\n",(t->tm_mon==0)?"SELECTED":"");
                  printf("<option value='2' %s>February\n",(t->tm_mon==1)?"SELECTED":"");
                  printf("<option value='3' %s>March\n",(t->tm_mon==2)?"SELECTED":"");
                  printf("<option value='4' %s>April\n",(t->tm_mon==3)?"SELECTED":"");
                  printf("<option value='5' %s>May\n",(t->tm_mon==4)?"SELECTED":"");
                  printf("<option value='6' %s>June\n",(t->tm_mon==5)?"SELECTED":"");
                  printf("<option value='7' %s>July\n",(t->tm_mon==6)?"SELECTED":"");
                  printf("<option value='8' %s>August\n",(t->tm_mon==7)?"SELECTED":"");
                  printf("<option value='9' %s>September\n",(t->tm_mon==8)?"SELECTED":"");
                  printf("<option value='10' %s>October\n",(t->tm_mon==9)?"SELECTED":"");
                  printf("<option value='11' %s>November\n",(t->tm_mon==10)?"SELECTED":"");
                  printf("<option value='12' %s>December\n",(t->tm_mon==11)?"SELECTED":"");
                  printf("</select>\n ");
                  printf("<input type='text' size='2' maxlength='2' name='sday' value='%d'> ",start_day);
                  printf("<input type='text' size='4' maxlength='4' name='syear' value='%d'>",start_year);
                  printf("<input type='hidden' name='shour' value='0'>\n");
                  printf("<input type='hidden' name='smin' value='0'>\n");
                  printf("<input type='hidden' name='ssec' value='0'>\n");
                  printf("</td>\n");
                  printf("</tr>\n");

                  printf("<tr>");
                  printf("<td valign=top class='reportSelectSubTitle'>End Date (Inclusive):</td>\n");
                  printf("<td align=left valign=top class='reportSelectItem'>");
                  printf("<select name='emon'>\n");
                  printf("<option value='1' %s>January\n",(t->tm_mon==0)?"SELECTED":"");
                  printf("<option value='2' %s>February\n",(t->tm_mon==1)?"SELECTED":"");
                  printf("<option value='3' %s>March\n",(t->tm_mon==2)?"SELECTED":"");
                  printf("<option value='4' %s>April\n",(t->tm_mon==3)?"SELECTED":"");
                  printf("<option value='5' %s>May\n",(t->tm_mon==4)?"SELECTED":"");
                  printf("<option value='6' %s>June\n",(t->tm_mon==5)?"SELECTED":"");
                  printf("<option value='7' %s>July\n",(t->tm_mon==6)?"SELECTED":"");
                  printf("<option value='8' %s>August\n",(t->tm_mon==7)?"SELECTED":"");
                  printf("<option value='9' %s>September\n",(t->tm_mon==8)?"SELECTED":"");
                  printf("<option value='10' %s>October\n",(t->tm_mon==9)?"SELECTED":"");
                  printf("<option value='11' %s>November\n",(t->tm_mon==10)?"SELECTED":"");
                  printf("<option value='12' %s>December\n",(t->tm_mon==11)?"SELECTED":"");
                  printf("</select>\n ");
                  printf("<input type='text' size='2' maxlength='2' name='eday' value='%d'> ",end_day);
                  printf("<input type='text' size='4' maxlength='4' name='eyear' value='%d'>",end_year);
                  printf("<input type='hidden' name='ehour' value='24'>\n");
                  printf("<input type='hidden' name='emin' value='0'>\n");
                  printf("<input type='hidden' name='esec' value='0'>\n");
                  printf("</td>\n");
                  printf("</tr>\n");

                  printf("<tr><td colspan=2><br></td></tr>\n");

                  printf("<tr><td class='reportSelectSubTitle' align=right>Statistics Breakdown:</td>\n");
                  printf("<td class='reportSelectItem'>\n");
                  printf("<select name='breakdown'>\n");
                  printf("<option value=monthly>Month\n");
                  printf("<option value=dayofmonth SELECTED>Day of the Month\n");
                  printf("<option value=dayofweek>Day of the Week\n");
                  printf("<option value=hourly>Hour of the Day\n");
                  printf("</select>\n");
                  printf("</td></tr>\n");

                  printf("<tr><td class='reportSelectSubTitle' align=right>Events To Graph:</td>\n");
                  printf("<td class='reportSelectItem'>\n");
                  printf("<select name='graphevents'>\n");
                  if(display_type==DISPLAY_HOST_HISTOGRAM){
                        printf("<option value=%d %s>All host events\n",GRAPH_HOST_ALL,(graph_events==GRAPH_HOST_ALL)?"SELECTED":"");
                        printf("<option value=%d %s>Host problem events\n",GRAPH_HOST_PROBLEMS,(graph_events==GRAPH_HOST_PROBLEMS)?"SELECTED":"");
                        printf("<option value=%d %s>Host up events\n",GRAPH_HOST_UP,(graph_events==GRAPH_HOST_UP)?"SELECTED":"");
                        printf("<option value=%d %s>Host down events\n",GRAPH_HOST_DOWN,(graph_events==GRAPH_HOST_DOWN)?"SELECTED":"");
                        printf("<option value=%d %s>Host unreachable events\n",GRAPH_HOST_UNREACHABLE,(graph_events==GRAPH_HOST_UNREACHABLE)?"SELECTED":"");
                          }
                  else{
                        printf("<option value=%d %s>All service events\n",GRAPH_SERVICE_ALL,(graph_events==GRAPH_SERVICE_ALL)?"SELECTED":"");
                        printf("<option value=%d %s>Service problem events\n",GRAPH_SERVICE_PROBLEMS,(graph_events==GRAPH_SERVICE_PROBLEMS)?"SELECTED":"");
                        printf("<option value=%d %s>Service ok events\n",GRAPH_SERVICE_OK,(graph_events==GRAPH_SERVICE_OK)?"SELECTED":"");
                        printf("<option value=%d %s>Service warning events\n",GRAPH_SERVICE_WARNING,(graph_events==GRAPH_SERVICE_WARNING)?"SELECTED":"");
                        printf("<option value=%d %s>Service unknown events\n",GRAPH_SERVICE_UNKNOWN,(graph_events==GRAPH_SERVICE_UNKNOWN)?"SELECTED":"");
                        printf("<option value=%d %s>Service critical events\n",GRAPH_SERVICE_CRITICAL,(graph_events==GRAPH_SERVICE_CRITICAL)?"SELECTED":"");
                          }
                  printf("</select>\n");
                  printf("</td></tr>\n");

                  printf("<tr><td class='reportSelectSubTitle' align=right>State Types To Graph:</td>\n");
                  printf("<td class='reportSelectItem'>\n");
                  printf("<select name='graphstatetypes'>\n");
                  printf("<option value=%d>Hard states\n",GRAPH_HARD_STATETYPES);
                  printf("<option value=%d>Soft states\n",GRAPH_SOFT_STATETYPES);
                  printf("<option value=%d SELECTED>Hard and soft states\n",GRAPH_ALL_STATETYPES);
                  printf("</select>\n");
                  printf("</td></tr>\n");

                  printf("<tr><td class='reportSelectSubTitle' align=right>Assume State Retention:</td>\n");
                  printf("<td class='reportSelectItem'>\n");
                  printf("<select name='assumestateretention'>\n");
                  printf("<option value='yes'>Yes\n");
                  printf("<option value='no'>No\n");
                  printf("</select>\n");
                  printf("</td></tr>\n");

                  printf("<tr><td class='reportSelectSubTitle' align=right>Initial States Logged:</td>\n");
                  printf("<td class='reportSelectItem'>\n");
                  printf("<select name='initialstateslogged'>\n");
                  printf("<option value='yes'>Yes\n");
                  printf("<option value='no' SELECTED>No\n");
                  printf("</select>\n");
                  printf("</td></tr>\n");

                  printf("<tr><td class='reportSelectSubTitle' align=right>Ignore Repeated States:</td>\n");
                  printf("<td class='reportSelectItem'>\n");
                  printf("<select name='newstatesonly'>\n");
                  printf("<option value='yes'>Yes\n");
                  printf("<option value='no' SELECTED>No\n");
                  printf("</select>\n");
                  printf("</td></tr>\n");

                  printf("<tr><td></td><td class='reportSelectItem'><input type='submit' value='Create Report'></td></tr>\n");

                  printf("</form>\n");
                  printf("</TABLE>\n");

                  printf("</DIV></P>\n");
                    }

            /* as the user whether they want a graph for a host or service */
            else{
                  printf("<P><DIV ALIGN=CENTER>\n");
                  printf("<DIV CLASS='reportSelectTitle'>Step 1: Select Report Type</DIV>\n");
                  printf("</DIV></P>\n");

                  printf("<P><DIV ALIGN=CENTER>\n");

                  printf("<TABLE BORDER=0 cellpadding=5>\n");
                  printf("<form method=\"GET\" action=\"%s\">\n",HISTOGRAM_CGI);

                  printf("<tr><td class='reportSelectSubTitle'><input type='radio' name='input' value='gethost'></td><td class='reportSelectItem'>Host</td></tr>\n");
                  printf("<tr><td class='reportSelectSubTitle'><input type='radio' name='input' value='getservice'></td><td class='reportSelectItem'>Service</td></tr>\n");

                  printf("<tr><td></td><td class='reportSelectItem'>\n");
                  printf("<input type='submit' value='Continue to Step 2'>\n");
                  printf("</td></tr>\n");

                  printf("</form>\n");
                  printf("</TABLE>\n");

                  printf("</DIV></P>\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\n");
            printf("Pragma: no-cache\n");

            time(&current_time);
            get_time_string(&current_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);

            printf("Content-type: text/html\n\n");

            if(embedded==TRUE)
                  return;

            printf("<html>\n");
            printf("<head>\n");
            printf("<title>\n");
            printf("Nagios Histogram\n");
            printf("</title>\n");

            if(use_stylesheet==TRUE)
                  printf("<LINK REL='stylesheet' TYPE='text/css' HREF='%s%s'>\n",url_stylesheets_path,HISTOGRAM_CSS);
      
            printf("</head>\n");

            printf("<BODY CLASS='histogram'>\n");

            /* include user SSI header */
            include_ssi_files(HISTOGRAM_CGI,SSI_HEADER);

            printf("<div id=\"popup\" style=\"position:absolute; z-index:1; visibility: hidden\"></div>\n");
              }

      else{
            printf("Cache-Control: no-store\n");
            printf("Pragma: no-cache\n");

            time(&current_time);
            get_time_string(&current_time,date_time,sizeof(date_time),HTTP_DATE_TIME);
            printf("Last-Modified: %s\n",date_time);

            expire_time=(time_t)0L;
            get_time_string(&expire_time,date_time,sizeof(date_time),HTTP_DATE_TIME);
            printf("Expires: %s\n",date_time);

            printf("Content-Type: image/png\n\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("</body>\n");
            printf("</html>\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]);

                  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]);

                  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],"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 logges 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_bucket<total_buckets;current_bucket++){
            if(tsdata[current_bucket].service_ok>max_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),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,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),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,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_bucket<total_buckets){
                              if(have_state1_min==FALSE || tsdata[actual_bucket].host_up<state1_min){
                                    state1_min=tsdata[actual_bucket].host_up;
                                    have_state1_min=TRUE;
                                        }
                              if(state1_max==0 || tsdata[actual_bucket].host_up>state1_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_bucket<total_buckets){
                              if(have_state2_min==FALSE || tsdata[actual_bucket].host_down<state2_min){
                                    state2_min=tsdata[actual_bucket].host_down;
                                    have_state2_min=TRUE;
                                        }
                              if(state2_max==0 || tsdata[actual_bucket].host_down>state2_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_bucket<total_buckets){
                              if(have_state3_min==FALSE || tsdata[actual_bucket].host_unreachable<state3_min){
                                    state3_min=tsdata[actual_bucket].host_unreachable;
                                    have_state3_min=TRUE;
                                        }
                              if(state3_max==0 || tsdata[actual_bucket].host_unreachable>state3_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_bucket<total_buckets){
                              if(have_state1_min==FALSE || tsdata[actual_bucket].service_ok<state1_min){
                                    state1_min=tsdata[actual_bucket].service_ok;
                                    have_state1_min=TRUE;
                                        }
                              if(state1_max==0 || tsdata[actual_bucket].service_ok>state1_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_bucket<total_buckets){
                              if(have_state2_min==FALSE || tsdata[actual_bucket].service_warning<state2_min){
                                    state2_min=tsdata[actual_bucket].service_warning;
                                    have_state2_min=TRUE;
                                        }
                              if(state2_max==0 || tsdata[actual_bucket].service_warning>state2_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_bucket<total_buckets){
                              if(have_state3_min==FALSE || tsdata[actual_bucket].service_unknown<state3_min){
                                    state3_min=tsdata[actual_bucket].service_unknown;
                                    have_state3_min=TRUE;
                                        }
                              if(state3_max==0 || tsdata[actual_bucket].service_unknown>state3_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_bucket<total_buckets){
                              if(have_state4_min==FALSE || tsdata[actual_bucket].service_critical<state4_min){
                                    state4_min=tsdata[actual_bucket].service_critical;
                                    have_state4_min=TRUE;
                                        }
                              if(state4_max==0 || tsdata[actual_bucket].service_critical>state4_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,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,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),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),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),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),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),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),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),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),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_archive<newest_archive)
            oldest_archive=newest_archive;

#ifdef DEBUG2
      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 DEBUG2
            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_buffer[MAX_INPUT_BUFFER];
      char input_buffer2[MAX_INPUT_BUFFER];
      char entry_host_name[MAX_INPUT_BUFFER];
      char entry_svc_description[MAX_INPUT_BUFFER];
      char *temp_buffer;
      time_t time_stamp;
      FILE *fp;

      /* print something so browser doesn't time out */
      if(mode==CREATE_HTML){
            printf(" ");
            fflush(NULL);
              }

      fp=fopen(filename,"r");
      if(fp==NULL){
#ifdef DEBUG2
            printf("Could not open file '%s' for reading.\n",filename);
#endif
            return;
              }

#ifdef DEBUG2
      printf("Scanning log file '%s' for archived state data...\n",filename);
#endif

      while(read_line(input_buffer,MAX_INPUT_BUFFER,fp)){

              if(feof(fp))
                    break;

            if(input_buffer==NULL)
                    continue;

            strcpy(input_buffer2,input_buffer);
            temp_buffer=strtok(input_buffer2,"]");
            time_stamp=(temp_buffer==NULL)?(time_t)0:(time_t)strtoul(temp_buffer+1,NULL,10);

            /* program starts/restarts */
            if(strstr(input_buffer," starting..."))
                  add_archived_state(AS_PROGRAM_START,time_stamp);
            if(strstr(input_buffer," restarting..."))
                  add_archived_state(AS_PROGRAM_START,time_stamp);

            /* program stops */
            if(strstr(input_buffer," shutting down..."))
                  add_archived_state(AS_PROGRAM_END,time_stamp);
            if(strstr(input_buffer,"Bailing out"))
                  add_archived_state(AS_PROGRAM_END,time_stamp);

            if(display_type==DISPLAY_HOST_HISTOGRAM){
                  if(strstr(input_buffer,"HOST ALERT:")){

                        strcpy(input_buffer2,input_buffer);

                        /* get host name */
                        temp_buffer=my_strtok(input_buffer2,"]");
                        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;

                        /* skip soft states if necessary */
                        if(!(graph_statetypes & GRAPH_SOFT_STATETYPES) && strstr(input_buffer,";SOFT;"))
                              continue;

                        /* skip hard states if necessary */
                        if(!(graph_statetypes & GRAPH_HARD_STATETYPES) && strstr(input_buffer,";HARD;"))
                              continue;

                        if(strstr(input_buffer,";DOWN;"))
                              add_archived_state(AS_HOST_DOWN,time_stamp);
                        else if(strstr(input_buffer,";UNREACHABLE;"))
                              add_archived_state(AS_HOST_UNREACHABLE,time_stamp);
                        else if(strstr(input_buffer,";RECOVERY") || strstr(input_buffer,";UP;"))
                              add_archived_state(AS_HOST_UP,time_stamp);
                          }
                    }
            if(display_type==DISPLAY_SERVICE_HISTOGRAM){
                  if(strstr(input_buffer,"SERVICE ALERT:")){

                        strcpy(input_buffer2,input_buffer);

                        /* get host name */
                        temp_buffer=my_strtok(input_buffer2,"]");
                        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;

                        /* skip soft states if necessary */
                        if(!(graph_statetypes & GRAPH_SOFT_STATETYPES) && strstr(input_buffer,";SOFT;"))
                              continue;

                        /* skip hard states if necessary */
                        if(!(graph_statetypes & GRAPH_HARD_STATETYPES) && strstr(input_buffer,";HARD;"))
                              continue;

                        if(strstr(input_buffer,";CRITICAL;"))
                              add_archived_state(AS_SVC_CRITICAL,time_stamp);
                        else if(strstr(input_buffer,";WARNING;"))
                              add_archived_state(AS_SVC_WARNING,time_stamp);
                        else if(strstr(input_buffer,";UNKNOWN;"))
                              add_archived_state(AS_SVC_UNKNOWN,time_stamp);
                        else if(strstr(input_buffer,";RECOVERY;") || strstr(input_buffer,";OK;"))
                              add_archived_state(AS_SVC_OK,time_stamp);
                          }
                    }
            
              }

      fclose(fp);
      
      return;
        }
      



void convert_timeperiod_to_times(int type){
      time_t current_time;
      struct tm *t;

      /* get the current time */
      time(&current_time);

      t=localtime(&current_time);

      t->tm_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;
      default:
            break;
              }

      return;
        }



void compute_report_times(void){
      time_t current_time;
      struct tm *st;
      struct tm *et;

      /* get the current time */
      time(&current_time);

      st=localtime(&current_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(&current_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;
      }


Generated by  Doxygen 1.6.0   Back to index