/***********************************************************************
*
* HISTORY.C - Nagios History CGI
*
* Copyright (c) 1999-2007 Ethan Galstad (nagios@nagios.org)
* Last Modified: 10-21-2007
*
* This CGI program will display the history for the specified host.
* If no host is specified, the history for all hosts will be displayed.
*
* License:
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
***********************************************************************/
#include "../include/config.h"
#include "../include/common.h"
#include "../include/objects.h"
#include "../include/getcgi.h"
#include "../include/cgiutils.h"
#include "../include/cgiauth.h"
#define DISPLAY_HOSTS 0
#define DISPLAY_SERVICES 1
#define SERVICE_HISTORY 0
#define HOST_HISTORY 1
#define SERVICE_FLAPPING_HISTORY 2
#define HOST_FLAPPING_HISTORY 3
#define SERVICE_DOWNTIME_HISTORY 4
#define HOST_DOWNTIME_HISTORY 5
#define STATE_ALL 0
#define STATE_SOFT 1
#define STATE_HARD 2
void get_history(void);
void document_header(int);
void document_footer(void);
int process_cgivars(void);
extern char main_config_file[MAX_FILENAME_LENGTH];
extern char url_images_path[MAX_FILENAME_LENGTH];
extern char url_stylesheets_path[MAX_FILENAME_LENGTH];
extern int log_rotation_method;
authdata current_authdata;
char log_file_to_use[MAX_FILENAME_LENGTH];
int log_archive=0;
int show_all_hosts=TRUE;
char *host_name="all";
char *svc_description="";
int display_type=DISPLAY_HOSTS;
int use_lifo=TRUE;
int history_options=HISTORY_ALL;
int state_options=STATE_ALL;
int embedded=FALSE;
int display_header=TRUE;
int display_frills=TRUE;
int display_timebreaks=TRUE;
int display_system_messages=TRUE;
int display_flapping_alerts=TRUE;
int display_downtime_alerts=TRUE;
int main(void){
int result=OK;
char temp_buffer[MAX_INPUT_BUFFER];
char temp_buffer2[MAX_INPUT_BUFFER];
/* get the variables passed to us */
process_cgivars();
/* reset internal CGI variables */
reset_cgi_vars();
/* read the CGI configuration file */
result=read_cgi_config_file(get_cgi_config_location());
if(result==ERROR){
document_header(FALSE);
cgi_config_file_error(get_cgi_config_location());
document_footer();
return ERROR;
}
/* read the main configuration file */
result=read_main_config_file(main_config_file);
if(result==ERROR){
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){
document_header(FALSE);
object_data_error();
document_footer();
return ERROR;
}
document_header(TRUE);
/* get authentication information */
get_authentication_information(¤t_authdata);
/* determine what log file we should be using */
get_log_archive_to_use(log_archive,log_file_to_use,(int)sizeof(log_file_to_use));
if(display_header==TRUE){
/* begin top table */
printf("
Not enough memory to reverse log file - displaying history in natural order...
\n");
}
else if(result==LIFO_ERROR_FILE){
printf("\n");
while(1){
free(input);
if(use_lifo==TRUE){
if((input=pop_lifo())==NULL)
break;
}
else{
if((input=mmap_fgets(thefile))==NULL)
break;
}
strip(input);
strcpy(image,"");
strcpy(image_alt,"");
system_message=FALSE;
strcpy(input_buffer2,input);
/* service state alerts */
if(strstr(input,"SERVICE ALERT:")){
history_type=SERVICE_HISTORY;
/* get host and service names */
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';
temp_buffer=my_strtok(NULL,";");
strncpy(entry_service_desc,(temp_buffer==NULL)?"":temp_buffer,sizeof(entry_service_desc));
entry_service_desc[sizeof(entry_service_desc)-1]='\x0';
if(strstr(input,";CRITICAL;")){
strncpy(image,CRITICAL_ICON,sizeof(image));
strncpy(image_alt,CRITICAL_ICON_ALT,sizeof(image_alt));
history_detail_type=HISTORY_SERVICE_CRITICAL;
}
else if(strstr(input,";WARNING;")){
strncpy(image,WARNING_ICON,sizeof(image));
strncpy(image_alt,WARNING_ICON_ALT,sizeof(image_alt));
history_detail_type=HISTORY_SERVICE_WARNING;
}
else if(strstr(input,";UNKNOWN;")){
strncpy(image,UNKNOWN_ICON,sizeof(image));
strncpy(image_alt,UNKNOWN_ICON_ALT,sizeof(image_alt));
history_detail_type=HISTORY_SERVICE_UNKNOWN;
}
else if(strstr(input,";RECOVERY;") || strstr(input,";OK;")){
strncpy(image,OK_ICON,sizeof(image));
strncpy(image_alt,OK_ICON_ALT,sizeof(image_alt));
history_detail_type=HISTORY_SERVICE_RECOVERY;
}
}
/* service flapping alerts */
else if(strstr(input,"SERVICE FLAPPING ALERT:")){
if(display_flapping_alerts==FALSE)
continue;
history_type=SERVICE_FLAPPING_HISTORY;
/* get host and service names */
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';
temp_buffer=my_strtok(NULL,";");
strncpy(entry_service_desc,(temp_buffer==NULL)?"":temp_buffer,sizeof(entry_service_desc));
entry_service_desc[sizeof(entry_service_desc)-1]='\x0';
strncpy(image,FLAPPING_ICON,sizeof(image));
if(strstr(input,";STARTED;"))
strncpy(image_alt,"Service started flapping",sizeof(image_alt));
else if(strstr(input,";STOPPED;"))
strncpy(image_alt,"Service stopped flapping",sizeof(image_alt));
else if(strstr(input,";DISABLED;"))
strncpy(image_alt,"Service flap detection disabled",sizeof(image_alt));
}
/* service downtime alerts */
else if(strstr(input,"SERVICE DOWNTIME ALERT:")){
if(display_downtime_alerts==FALSE)
continue;
history_type=SERVICE_DOWNTIME_HISTORY;
/* get host and service names */
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';
temp_buffer=my_strtok(NULL,";");
strncpy(entry_service_desc,(temp_buffer==NULL)?"":temp_buffer,sizeof(entry_service_desc));
entry_service_desc[sizeof(entry_service_desc)-1]='\x0';
strncpy(image,SCHEDULED_DOWNTIME_ICON,sizeof(image));
if(strstr(input,";STARTED;"))
strncpy(image_alt,"Service entered a period of scheduled downtime",sizeof(image_alt));
else if(strstr(input,";STOPPED;"))
strncpy(image_alt,"Service exited from a period of scheduled downtime",sizeof(image_alt));
else if(strstr(input,";CANCELLED;"))
strncpy(image_alt,"Service scheduled downtime has been cancelled",sizeof(image_alt));
}
/* host state alerts */
else if(strstr(input,"HOST ALERT:")){
history_type=HOST_HISTORY;
/* 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(strstr(input,";DOWN;")){
strncpy(image,HOST_DOWN_ICON,sizeof(image));
strncpy(image_alt,HOST_DOWN_ICON_ALT,sizeof(image_alt));
history_detail_type=HISTORY_HOST_DOWN;
}
else if(strstr(input,";UNREACHABLE;")){
strncpy(image,HOST_UNREACHABLE_ICON,sizeof(image));
strncpy(image_alt,HOST_UNREACHABLE_ICON_ALT,sizeof(image_alt));
history_detail_type=HISTORY_HOST_UNREACHABLE;
}
else if(strstr(input,";RECOVERY") || strstr(input,";UP;")){
strncpy(image,HOST_UP_ICON,sizeof(image));
strncpy(image_alt,HOST_UP_ICON_ALT,sizeof(image_alt));
history_detail_type=HISTORY_HOST_RECOVERY;
}
}
/* host flapping alerts */
else if(strstr(input,"HOST FLAPPING ALERT:")){
if(display_flapping_alerts==FALSE)
continue;
history_type=HOST_FLAPPING_HISTORY;
/* 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';
strncpy(image,FLAPPING_ICON,sizeof(image));
if(strstr(input,";STARTED;"))
strncpy(image_alt,"Host started flapping",sizeof(image_alt));
else if(strstr(input,";STOPPED;"))
strncpy(image_alt,"Host stopped flapping",sizeof(image_alt));
else if(strstr(input,";DISABLED;"))
strncpy(image_alt,"Host flap detection disabled",sizeof(image_alt));
}
/* host downtime alerts */
else if(strstr(input,"HOST DOWNTIME ALERT:")){
if(display_downtime_alerts==FALSE)
continue;
history_type=HOST_DOWNTIME_HISTORY;
/* 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';
strncpy(image,SCHEDULED_DOWNTIME_ICON,sizeof(image));
if(strstr(input,";STARTED;"))
strncpy(image_alt,"Host entered a period of scheduled downtime",sizeof(image_alt));
else if(strstr(input,";STOPPED;"))
strncpy(image_alt,"Host exited from a period of scheduled downtime",sizeof(image_alt));
else if(strstr(input,";CANCELLED;"))
strncpy(image_alt,"Host scheduled downtime has been cancelled",sizeof(image_alt));
}
else if(display_system_messages==FALSE)
continue;
/* program start */
else if(strstr(input," starting...")){
strncpy(image,START_ICON,sizeof(image));
strncpy(image_alt,START_ICON_ALT,sizeof(image_alt));
system_message=TRUE;
}
/* normal program termination */
else if(strstr(input," shutting down...")){
strncpy(image,STOP_ICON,sizeof(image));
strncpy(image_alt,STOP_ICON_ALT,sizeof(image_alt));
system_message=TRUE;
}
/* abnormal program termination */
else if(strstr(input,"Bailing out")){
strncpy(image,STOP_ICON,sizeof(image));
strncpy(image_alt,STOP_ICON_ALT,sizeof(image_alt));
system_message=TRUE;
}
/* program restart */
else if(strstr(input," restarting...")){
strncpy(image,RESTART_ICON,sizeof(image));
strncpy(image_alt,RESTART_ICON_ALT,sizeof(image_alt));
system_message=TRUE;
}
image[sizeof(image)-1]='\x0';
image_alt[sizeof(image_alt)-1]='\x0';
/* get the timestamp */
temp_buffer=strtok(input,"]");
t=(temp_buffer==NULL)?0L:strtoul(temp_buffer+1,NULL,10);
time_ptr=localtime(&t);
strftime(current_message_date,sizeof(current_message_date),"%B %d, %Y %H:00\n",time_ptr);
current_message_date[sizeof(current_message_date)-1]='\x0';
get_time_string(&t,date_time,sizeof(date_time),SHORT_DATE_TIME);
strip(date_time);
temp_buffer=strtok(NULL,"\n");
if(strcmp(image,"")){
display_line=FALSE;
if(system_message==TRUE)
display_line=TRUE;
else if(display_type==DISPLAY_HOSTS){
if(history_type==HOST_HISTORY || history_type==SERVICE_HISTORY){
sprintf(match1," HOST ALERT: %s;",host_name);
sprintf(match2," SERVICE ALERT: %s;",host_name);
}
else if(history_type==HOST_FLAPPING_HISTORY || history_type==SERVICE_FLAPPING_HISTORY){
sprintf(match1," HOST FLAPPING ALERT: %s;",host_name);
sprintf(match2," SERVICE FLAPPING ALERT: %s;",host_name);
}
else if(history_type==HOST_DOWNTIME_HISTORY || history_type==SERVICE_DOWNTIME_HISTORY){
sprintf(match1," HOST DOWNTIME ALERT: %s;",host_name);
sprintf(match2," SERVICE DOWNTIME ALERT: %s;",host_name);
}
if(show_all_hosts==TRUE)
display_line=TRUE;
else if(strstr(temp_buffer,match1))
display_line=TRUE;
else if(strstr(temp_buffer,match2))
display_line=TRUE;
if(display_line==TRUE){
if(history_options==HISTORY_ALL)
display_line=TRUE;
else if(history_options==HISTORY_HOST_ALL && (history_type==HOST_HISTORY || history_type==HOST_FLAPPING_HISTORY || history_type==HOST_DOWNTIME_HISTORY))
display_line=TRUE;
else if(history_options==HISTORY_SERVICE_ALL && (history_type==SERVICE_HISTORY || history_type==SERVICE_FLAPPING_HISTORY || history_type==SERVICE_DOWNTIME_HISTORY))
display_line=TRUE;
else if((history_type==HOST_HISTORY || history_type==SERVICE_HISTORY) && (history_detail_type & history_options))
display_line=TRUE;
else
display_line=FALSE;
}
/* check alert state types */
if(display_line==TRUE && (history_type==HOST_HISTORY || history_type==SERVICE_HISTORY)){
if(state_options==STATE_ALL)
display_line=TRUE;
else if((state_options & STATE_SOFT) && strstr(temp_buffer,";SOFT;"))
display_line=TRUE;
else if((state_options & STATE_HARD) && strstr(temp_buffer,";HARD;"))
display_line=TRUE;
else
display_line=FALSE;
}
}
else if(display_type==DISPLAY_SERVICES){
if(history_type==SERVICE_HISTORY)
sprintf(match1," SERVICE ALERT: %s;%s;",host_name,svc_description);
else if(history_type==SERVICE_FLAPPING_HISTORY)
sprintf(match1," SERVICE FLAPPING ALERT: %s;%s;",host_name,svc_description);
else if(history_type==SERVICE_DOWNTIME_HISTORY)
sprintf(match1," SERVICE DOWNTIME ALERT: %s;%s;",host_name,svc_description);
if(strstr(temp_buffer,match1) && (history_type==SERVICE_HISTORY || history_type==SERVICE_FLAPPING_HISTORY || history_type==SERVICE_DOWNTIME_HISTORY))
display_line=TRUE;
if(display_line==TRUE){
if(history_options==HISTORY_ALL || history_options==HISTORY_SERVICE_ALL)
display_line=TRUE;
else if(history_options & history_detail_type)
display_line=TRUE;
else
display_line=FALSE;
}
/* check alert state type */
if(display_line==TRUE && history_type==SERVICE_HISTORY){
if(state_options==STATE_ALL)
display_line=TRUE;
else if((state_options & STATE_SOFT) && strstr(temp_buffer,";SOFT;"))
display_line=TRUE;
else if((state_options & STATE_HARD) && strstr(temp_buffer,";HARD;"))
display_line=TRUE;
else
display_line=FALSE;
}
}
/* make sure user is authorized to view this host or service information */
if(system_message==FALSE){
if(history_type==HOST_HISTORY || history_type==HOST_FLAPPING_HISTORY || history_type==HOST_DOWNTIME_HISTORY){
temp_host=find_host(entry_host_name);
if(is_authorized_for_host(temp_host,¤t_authdata)==FALSE)
display_line=FALSE;
}
else{
temp_service=find_service(entry_host_name,entry_service_desc);
if(is_authorized_for_service(temp_service,¤t_authdata)==FALSE)
display_line=FALSE;
}
}
/* display the entry if we should... */
if(display_line==TRUE){
if(strcmp(last_message_date,current_message_date)!=0 && display_timebreaks==TRUE){
printf("
\n");
printf("
\n");
printf("
");
printf("
| ");
printf("%s | ",current_message_date);
printf("
| ");
printf("
\n");
printf("
\n");
printf("
\n");
strncpy(last_message_date,current_message_date,sizeof(last_message_date));
last_message_date[sizeof(last_message_date)-1]='\x0';
}
if(display_frills==TRUE)
printf("

",url_images_path,image,image_alt,image_alt);
printf("[%s] %s
\n",date_time,strip_plugin_html(temp_buffer));
found_line=TRUE;
}
}
}
printf("\n");
if(found_line==FALSE){
printf("
\n");
printf("
No history information was found ");
if(display_type==DISPLAY_HOSTS)
printf("%s",(show_all_hosts==TRUE)?"":"for this host ");
else
printf("for this this service ");
printf("in %s log file
",(log_archive==0)?"the current":"this archived");
}
printf("
\n");
free(input);
if(use_lifo==TRUE)
free_lifo_memory();
else
mmap_fclose(thefile);
return;
}