/************************************************************************
 *
 * NOTIFICATIONS.C - Nagios Notifications CGI
 *
 * Copyright (c) 1999-2006 Ethan Galstad (nagios@nagios.org)
 * Last Modified: 10-09-2006
 *
 * This CGI program will display the notification events for 
 * a given host or contact or for all contacts/hosts.
 *
 * 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/getcgi.h"
#include "../include/cgiutils.h"
#include "../include/cgiauth.h"

extern char main_config_file[MAX_FILENAME_LENGTH];
extern char url_html_path[MAX_FILENAME_LENGTH];
extern char url_images_path[MAX_FILENAME_LENGTH];
extern char url_docs_path[MAX_FILENAME_LENGTH];
extern char url_stylesheets_path[MAX_FILENAME_LENGTH];

extern int    log_rotation_method;


#define FIND_HOST		1
#define FIND_CONTACT		2
#define FIND_SERVICE		3

#define MAX_QUERYNAME_LENGTH	256

#define SERVICE_NOTIFICATION	0
#define HOST_NOTIFICATION	1

#define SERVICE_NOTIFICATION_STRING 	"] SERVICE NOTIFICATION:"
#define HOST_NOTIFICATION_STRING	"] HOST NOTIFICATION:"

void display_notifications(void);

void document_header(int);
void document_footer(void);
int process_cgivars(void);

authdata current_authdata;

char log_file_to_use[MAX_FILENAME_LENGTH];
int log_archive=0;

int query_type=FIND_HOST;
int find_all=TRUE;
char *query_contact_name="";
char *query_host_name="";
char *query_svc_description="";

int notification_options=NOTIFICATION_ALL;
int use_lifo=TRUE;

int embedded=FALSE;
int display_header=TRUE;


int main(void){
	int result=OK;
	char temp_buffer[MAX_INPUT_BUFFER];
	char temp_buffer2[MAX_INPUT_BUFFER];

	
	/* get the arguments passed in the URL */
	process_cgivars();

	/* reset internal 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(&current_authdata);

	/* determine what log file we should use */
	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("<table border=0 width=100%%>\n");
		printf("<tr>\n");

		/* left column of top row */
		printf("<td align=left valign=top width=33%%>\n");
	
		if(query_type==FIND_SERVICE)
			snprintf(temp_buffer,sizeof(temp_buffer)-1,"Service Notifications");
		else if(query_type==FIND_HOST){
			if(find_all==TRUE)
				snprintf(temp_buffer,sizeof(temp_buffer)-1,"Notifications");
			else
				snprintf(temp_buffer,sizeof(temp_buffer)-1,"Host Notifications");
		        }
		else
			snprintf(temp_buffer,sizeof(temp_buffer)-1,"Contact Notifications");
		display_info_table(temp_buffer,FALSE,&current_authdata);

		if(query_type==FIND_HOST || query_type==FIND_SERVICE){
			printf("<TABLE BORDER=1 CELLPADDING=0 CELLSPACING=0 CLASS='linkBox'>\n");
			printf("<TR><TD CLASS='linkBox'>\n");
			if(query_type==FIND_HOST){
				printf("<A HREF='%s?host=%s'>View Status Detail For %s</A><BR>\n",STATUS_CGI,(find_all==TRUE)?"all":url_encode(query_host_name),(find_all==TRUE)?"All Hosts":"This Host");
				printf("<A HREF='%s?host=%s'>View History For %s</A><BR>\n",HISTORY_CGI,(find_all==TRUE)?"all":url_encode(query_host_name),(find_all==TRUE)?"All Hosts":"This Host");
#ifdef USE_TRENDS
				if(find_all==FALSE)
					printf("<A HREF='%s?host=%s'>View Trends For This Host</A><BR>\n",TRENDS_CGI,url_encode(query_host_name));
#endif
	                        }
			else if(query_type==FIND_SERVICE){
				printf("<A HREF='%s?host=%s&",HISTORY_CGI,(find_all==TRUE)?"all":url_encode(query_host_name));
				printf("service=%s'>View History For This Service</A><BR>\n",url_encode(query_svc_description));
#ifdef USE_TRENDS
				printf("<A HREF='%s?host=%s&",TRENDS_CGI,(find_all==TRUE)?"all":url_encode(query_host_name));
				printf("service=%s'>View Trends For This Service</A><BR>\n",url_encode(query_svc_description));
#endif
	                        }
			printf("</TD></TR>\n");
			printf("</TABLE>\n");
	                }

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


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

		printf("<DIV ALIGN=CENTER CLASS='dataTitle'>\n");
		if(query_type==FIND_SERVICE)
			printf("Service '%s' On Host '%s'",query_svc_description,query_host_name);
		else if(query_type==FIND_HOST){
			if(find_all==TRUE)
				printf("All Hosts and Services");
			else
				printf("Host '%s'",query_host_name);
		        }
		else{
			if(find_all==TRUE)
				printf("All Contacts");
			else
				printf("Contact '%s'",query_contact_name);
		        }
		printf("</DIV>\n");
		printf("<BR>\n");

		if(query_type==FIND_SERVICE){
			snprintf(temp_buffer,sizeof(temp_buffer)-1,"%s?%shost=%s&",NOTIFICATIONS_CGI,(use_lifo==FALSE)?"oldestfirst&":"",url_encode(query_host_name));
			snprintf(temp_buffer2,sizeof(temp_buffer2)-1,"service=%s&type=%d&",url_encode(query_svc_description),notification_options);
			strncat(temp_buffer,temp_buffer2,sizeof(temp_buffer)-strlen(temp_buffer)-1);
	                }
		else
			snprintf(temp_buffer,sizeof(temp_buffer)-1,"%s?%s%s=%s&type=%d&",NOTIFICATIONS_CGI,(use_lifo==FALSE)?"oldestfirst&":"",(query_type==FIND_HOST)?"host":"contact",(query_type==FIND_HOST)?url_encode(query_host_name):url_encode(query_contact_name),notification_options);
		temp_buffer[sizeof(temp_buffer)-1]='\x0';
		display_nav_table(temp_buffer,log_archive);

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


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

		printf("<table border=0 CLASS='optBox'>\n");
		printf("<form method='GET' action='%s'>\n",NOTIFICATIONS_CGI);
		if(query_type==FIND_SERVICE){
			printf("<input type='hidden' name='host' value='%s'>\n",query_host_name);
			printf("<input type='hidden' name='service' value='%s'>\n",query_svc_description);
	                }
		else
			printf("<input type='hidden' name='%s' value='%s'>\n",(query_type==FIND_HOST)?"host":"contact",(query_type==FIND_HOST)?query_host_name:query_contact_name);
		printf("<input type='hidden' name='archive' value='%d'>\n",log_archive);
		printf("<tr>\n");
		if(query_type==FIND_SERVICE)
			printf("<td align=left colspan=2 CLASS='optBoxItem'>Notification detail level for this service:</td>");
		else
			printf("<td align=left colspan=2 CLASS='optBoxItem'>Notification detail level for %s %s%s:</td>",(find_all==TRUE)?"all":"this",(query_type==FIND_HOST)?"host":"contact",(find_all==TRUE)?"s":"");
		printf("</tr>\n");
		printf("<tr>\n");
		printf("<td align=left colspan=2 CLASS='optBoxItem'><select name='type'>\n");
		printf("<option value=%d %s>All notifications\n",NOTIFICATION_ALL,(notification_options==NOTIFICATION_ALL)?"selected":"");
		if(query_type!=FIND_SERVICE){
			printf("<option value=%d %s>All service notifications\n",NOTIFICATION_SERVICE_ALL,(notification_options==NOTIFICATION_SERVICE_ALL)?"selected":"");
			printf("<option value=%d %s>All host notifications\n",NOTIFICATION_HOST_ALL,(notification_options==NOTIFICATION_HOST_ALL)?"selected":"");
	                }
		printf("<option value=%d %s>Service acknowledgements\n",NOTIFICATION_SERVICE_ACK,(notification_options==NOTIFICATION_SERVICE_ACK)?"selected":"");
		printf("<option value=%d %s>Service warning\n",NOTIFICATION_SERVICE_WARNING,(notification_options==NOTIFICATION_SERVICE_WARNING)?"selected":"");
		printf("<option value=%d %s>Service unknown\n",NOTIFICATION_SERVICE_UNKNOWN,(notification_options==NOTIFICATION_SERVICE_UNKNOWN)?"selected":"");
		printf("<option value=%d %s>Service critical\n",NOTIFICATION_SERVICE_CRITICAL,(notification_options==NOTIFICATION_SERVICE_CRITICAL)?"selected":"");
		printf("<option value=%d %s>Service recovery\n",NOTIFICATION_SERVICE_RECOVERY,(notification_options==NOTIFICATION_SERVICE_RECOVERY)?"selected":"");
		printf("<option value=%d %s>Service flapping\n",NOTIFICATION_SERVICE_FLAP,(notification_options==NOTIFICATION_SERVICE_FLAP)?"selected":"");
		if(query_type!=FIND_SERVICE){
			printf("<option value=%d %s>Host acknowledgements\n",NOTIFICATION_HOST_ACK,(notification_options==NOTIFICATION_HOST_ACK)?"selected":"");
			printf("<option value=%d %s>Host down\n",NOTIFICATION_HOST_DOWN,(notification_options==NOTIFICATION_HOST_DOWN)?"selected":"");
			printf("<option value=%d %s>Host unreachable\n",NOTIFICATION_HOST_UNREACHABLE,(notification_options==NOTIFICATION_HOST_UNREACHABLE)?"selected":"");
			printf("<option value=%d %s>Host recovery\n",NOTIFICATION_HOST_RECOVERY,(notification_options==NOTIFICATION_HOST_RECOVERY)?"selected":"");
			printf("<option value=%d %s>Host flapping\n",NOTIFICATION_HOST_FLAP,(notification_options==NOTIFICATION_HOST_FLAP)?"selected":"");
	                }
		printf("</select></td>\n");
		printf("</tr>\n");
		printf("<tr>\n");
		printf("<td align=left CLASS='optBoxItem'>Older Entries First:</td>\n");
		printf("<td></td>\n");
		printf("</tr>\n");
		printf("<tr>\n");
		printf("<td align=left valign=bottom CLASS='optBoxItem'><input type='checkbox' name='oldestfirst' %s></td>",(use_lifo==FALSE)?"checked":"");
		printf("<td align=right CLASS='optBoxItem'><input type='submit' value='Update'></td>\n");
		printf("</tr>\n");

		/* display context-sensitive help */
		printf("<tr><td></td><td align=right valign=bottom>\n");
		display_context_help(CONTEXTHELP_NOTIFICATIONS);
		printf("</td></tr>\n");

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

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

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

	        }


	/* display notifications */
	display_notifications();

	document_footer();

	/* free allocated memory */
	free_memory();
	
	return OK;
        }



void document_header(int use_stylesheet){
	char date_time[MAX_DATETIME_LENGTH];
	time_t current_time;
	time_t expire_time;

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

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

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

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

	if(embedded==TRUE)
		return;

	printf("<html>\n");
	printf("<head>\n");
	printf("<title>\n");
	printf("Alert Notifications\n");
	printf("</title>\n");

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

	printf("<body CLASS='notifications'>\n");

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

	return;
        }



void document_footer(void){

	if(embedded==TRUE)
		return;

	/* include user SSI footer */
	include_ssi_files(NOTIFICATIONS_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")){
			query_type=FIND_HOST;
			x++;
			if(variables[x]==NULL){
				error=TRUE;
				break;
			        }

			query_host_name=strdup(variables[x]);
			if(query_host_name==NULL)
				query_host_name="";
			if(!strcmp(query_host_name,"all"))
				find_all=TRUE;
			else
				find_all=FALSE;
		        }
	
		/* we found the contact argument */
		else if(!strcmp(variables[x],"contact")){
			query_type=FIND_CONTACT;
			x++;
			if(variables[x]==NULL){
				error=TRUE;
				break;
			        }

			query_contact_name=strdup(variables[x]);

			if(query_contact_name==NULL)
				query_contact_name="";
			if(!strcmp(query_contact_name,"all"))
				find_all=TRUE;
			else
				find_all=FALSE;
		        }
	
		/* we found the service argument */
		else if(!strcmp(variables[x],"service")){
			query_type=FIND_SERVICE;
			x++;
			if(variables[x]==NULL){
				error=TRUE;
				break;
			        }

			query_svc_description=strdup(variables[x]);
			if(query_svc_description==NULL)
				query_svc_description="";
		        }
	
		/* we found the notification type argument */
		else if(!strcmp(variables[x],"type")){
			x++;
			if(variables[x]==NULL){
				error=TRUE;
				break;
			        }

			notification_options=atoi(variables[x]);
		        }
	
		/* we found the log archive argument */
		else if(!strcmp(variables[x],"archive")){
			x++;
			if(variables[x]==NULL){
				error=TRUE;
				break;
			        }

			log_archive=atoi(variables[x]);
			if(log_archive<0)
				log_archive=0;
		        }
	
		/* we found the order argument */
		else if(!strcmp(variables[x],"oldestfirst")){
			use_lifo=FALSE;
		        }

		/* we found the embed option */
		else if(!strcmp(variables[x],"embedded"))
			embedded=TRUE;
	
		/* we found the noheader option */
		else if(!strcmp(variables[x],"noheader"))
			display_header=FALSE;
                }

	/* free memory allocated to the CGI variables */
	free_cgivars(variables);

	return error;
        }



void display_notifications(void){
	mmapfile *thefile;
	char *input=NULL;
	char *temp_buffer;
	char date_time[MAX_DATETIME_LENGTH];
	char alert_level[MAX_INPUT_BUFFER];
	char alert_level_class[MAX_INPUT_BUFFER];
	char contact_name[MAX_INPUT_BUFFER];
	char service_name[MAX_INPUT_BUFFER];
	char host_name[MAX_INPUT_BUFFER];
	char method_name[MAX_INPUT_BUFFER];
	int show_entry;
	int total_notifications;
	int notification_type=SERVICE_NOTIFICATION;
	int notification_detail_type=NOTIFICATION_SERVICE_CRITICAL;
	int odd=0;
	time_t t;
	host *temp_host;
	service *temp_service;
	int result;

	if(use_lifo==TRUE){
		result=read_file_into_lifo(log_file_to_use);
		if(result!=LIFO_OK){
			if(result==LIFO_ERROR_MEMORY){
				printf("<P><DIV CLASS='warningMessage'>Not enough memory to reverse log file - displaying notifications in natural order...</DIV></P>");
			        }
			else if(result==LIFO_ERROR_FILE){
				printf("<P><DIV CLASS='errorMessage'>Error: Cannot open log file '%s' for reading!</DIV></P>",log_file_to_use);
				return;
			        }
			use_lifo=FALSE;
		        }
	        }

	if(use_lifo==FALSE){

		if((thefile=mmap_fopen(log_file_to_use))==NULL){
			printf("<P><DIV CLASS='errorMessage'>Error: Cannot open log file '%s' for reading!</DIV></P>",log_file_to_use);
			return;
		        }
	        }

	printf("<p>\n");
	printf("<div align='center'>\n");

	printf("<table border=0 CLASS='notifications'>\n");
	printf("<tr>\n");
	printf("<th CLASS='notifications'>Host</th>\n");
	printf("<th CLASS='notifications'>Service</th>\n");
	printf("<th CLASS='notifications'>Type</th>\n");
	printf("<th CLASS='notifications'>Time</th>\n");
	printf("<th CLASS='notifications'>Contact</th>\n");
	printf("<th CLASS='notifications'>Notification Command</th>\n");
	printf("<th CLASS='notifications'>Information</th>\n");
	printf("</tr>\n");

	total_notifications=0;
  
	while(1){

		free(input);
    
		if(use_lifo==TRUE){
			if((input=pop_lifo())==NULL)
				break;
		        }
		else{
			if((input=mmap_fgets(thefile))==NULL)
				break;
		        }

		strip(input);

		/* see if this line contains the notification event string */
		if(strstr(input,HOST_NOTIFICATION_STRING)||strstr(input,SERVICE_NOTIFICATION_STRING)){

			if(strstr(input,HOST_NOTIFICATION_STRING))
				notification_type=HOST_NOTIFICATION;
			else
				notification_type=SERVICE_NOTIFICATION;
      
			/* get the date/time */
			temp_buffer=(char *)strtok(input,"]");
			t=(time_t)(temp_buffer==NULL)?0L:strtoul(temp_buffer+1,NULL,10);
			get_time_string(&t,date_time,(int)sizeof(date_time),SHORT_DATE_TIME);
			strip(date_time);

			/* get the contact name */
			temp_buffer=(char *)strtok(NULL,":");
			temp_buffer=(char *)strtok(NULL,";");
			snprintf(contact_name,sizeof(contact_name),"%s",(temp_buffer==NULL)?"":temp_buffer+1);
			contact_name[sizeof(contact_name)-1]='\x0';

			/* get the host name */
			temp_buffer=(char *)strtok(NULL,";");
			snprintf(host_name,sizeof(host_name),"%s",(temp_buffer==NULL)?"":temp_buffer);
			host_name[sizeof(host_name)-1]='\x0';

			/* get the service name */
			if(notification_type==SERVICE_NOTIFICATION){
				temp_buffer=(char *)strtok(NULL,";");
				snprintf(service_name,sizeof(service_name),"%s",(temp_buffer==NULL)?"":temp_buffer);
				service_name[sizeof(service_name)-1]='\x0';
			        }

			/* get the alert level */
			temp_buffer=(char *)strtok(NULL,";");
			snprintf(alert_level,sizeof(alert_level),"%s",(temp_buffer==NULL)?"":temp_buffer);
			alert_level[sizeof(alert_level)-1]='\x0';

			if(notification_type==SERVICE_NOTIFICATION){

				if(!strcmp(alert_level,"CRITICAL")){
					notification_detail_type=NOTIFICATION_SERVICE_CRITICAL;
					strcpy(alert_level_class,"CRITICAL");
				        }
				else if(!strcmp(alert_level,"WARNING")){
					notification_detail_type=NOTIFICATION_SERVICE_WARNING;
					strcpy(alert_level_class,"WARNING");
				        }
				else if(!strcmp(alert_level,"RECOVERY") || !strcmp(alert_level,"OK")){
					strcpy(alert_level,"OK");
					notification_detail_type=NOTIFICATION_SERVICE_RECOVERY;
					strcpy(alert_level_class,"OK");
				        }
				else if(strstr(alert_level,"ACKNOWLEDGEMENT (")){
					notification_detail_type=NOTIFICATION_SERVICE_ACK;
					strcpy(alert_level_class,"ACKNOWLEDGEMENT");
				        }
				else if(strstr(alert_level,"FLAPPINGSTART (")){
					strcpy(alert_level,"FLAPPING START");
					notification_detail_type=NOTIFICATION_SERVICE_FLAP;
					strcpy(alert_level_class,"UNKNOWN");
				        }
				else if(strstr(alert_level,"FLAPPINGSTOP (")){
					strcpy(alert_level,"FLAPPING STOP");
					notification_detail_type=NOTIFICATION_SERVICE_FLAP;
					strcpy(alert_level_class,"UNKNOWN");
				        }
				else{
					strcpy(alert_level,"UNKNOWN");
					notification_detail_type=NOTIFICATION_SERVICE_UNKNOWN;
					strcpy(alert_level_class,"UNKNOWN");
				        }
			        }

			else{

				if(!strcmp(alert_level,"DOWN")){
					strncpy(alert_level,"HOST DOWN",sizeof(alert_level));
					strcpy(alert_level_class,"HOSTDOWN");
					notification_detail_type=NOTIFICATION_HOST_DOWN;
				        }
				else if(!strcmp(alert_level,"UNREACHABLE")){
					strncpy(alert_level,"HOST UNREACHABLE",sizeof(alert_level));
					strcpy(alert_level_class,"HOSTUNREACHABLE");
					notification_detail_type=NOTIFICATION_HOST_UNREACHABLE;
				        }
				else if(!strcmp(alert_level,"RECOVERY") || !strcmp(alert_level,"UP")){
					strncpy(alert_level,"HOST UP",sizeof(alert_level));
					strcpy(alert_level_class,"HOSTUP");
					notification_detail_type=NOTIFICATION_HOST_RECOVERY;
				        }
				else if(strstr(alert_level,"ACKNOWLEDGEMENT (")){
					strcpy(alert_level_class,"HOSTACKNOWLEDGEMENT");
					notification_detail_type=NOTIFICATION_HOST_ACK;
				        }
				else if(strstr(alert_level,"FLAPPINGSTART (")){
					strcpy(alert_level,"FLAPPING START");
					strcpy(alert_level_class,"UNKNOWN");
					notification_detail_type=NOTIFICATION_HOST_FLAP;
				        }
				else if(strstr(alert_level,"FLAPPINGSTOP (")){
					strcpy(alert_level,"FLAPPING STOP");
					strcpy(alert_level_class,"UNKNOWN");
					notification_detail_type=NOTIFICATION_HOST_FLAP;
				        }
			        }

			/* get the method name */
			temp_buffer=(char *)strtok(NULL,";");
			snprintf(method_name,sizeof(method_name),"%s",(temp_buffer==NULL)?"":temp_buffer);
			method_name[sizeof(method_name)-1]='\x0';

			/* move to the informational message */
			temp_buffer=strtok(NULL,";");

			show_entry=FALSE;
      
			/* if we're searching by contact, filter out unwanted contact */
			if(query_type==FIND_CONTACT){
				if(find_all==TRUE)
					show_entry=TRUE;
				else if(!strcmp(query_contact_name,contact_name))
					show_entry=TRUE;
			        }

			else if(query_type==FIND_HOST){
				if(find_all==TRUE)
					show_entry=TRUE;
				else if(!strcmp(query_host_name,host_name))
					show_entry=TRUE;
			        }

			else if(query_type==FIND_SERVICE){
				if(!strcmp(query_host_name,host_name) && !strcmp(query_svc_description,service_name))
					show_entry=TRUE;
			        }

			if(show_entry==TRUE){
				if(notification_options==NOTIFICATION_ALL)
					show_entry=TRUE;
				else if(notification_options==NOTIFICATION_HOST_ALL && notification_type==HOST_NOTIFICATION)
					show_entry=TRUE;
				else if(notification_options==NOTIFICATION_SERVICE_ALL && notification_type==SERVICE_NOTIFICATION)
					show_entry=TRUE;
				else if(notification_detail_type & notification_options)
					show_entry=TRUE;
				else 
					show_entry=FALSE;
			        }

			/* make sure user has authorization to view this notification */
			if(notification_type==HOST_NOTIFICATION){
				temp_host=find_host(host_name);
				if(is_authorized_for_host(temp_host,&current_authdata)==FALSE)
					show_entry=FALSE;
			        }
			else{
				temp_service=find_service(host_name,service_name);
				if(is_authorized_for_service(temp_service,&current_authdata)==FALSE)
					show_entry=FALSE;
			        }

			if(show_entry==TRUE){

				total_notifications++;

				if(odd){
					odd=0;
					printf("<tr CLASS='notificationsOdd'>\n");
				        }
				else{
					odd=1;
					printf("<tr CLASS='notificationsEven'>\n");
				        }
				printf("<td CLASS='notifications%s'><a href='%s?type=%d&host=%s'>%s</a></td>\n",(odd)?"Even":"Odd",EXTINFO_CGI,DISPLAY_HOST_INFO,url_encode(host_name),host_name);
				if(notification_type==SERVICE_NOTIFICATION){
					printf("<td CLASS='notifications%s'><a href='%s?type=%d&host=%s",(odd)?"Even":"Odd",EXTINFO_CGI,DISPLAY_SERVICE_INFO,url_encode(host_name));
					printf("&service=%s'>%s</a></td>\n",url_encode(service_name),service_name);
				        }
				else
					printf("<td CLASS='notifications%s'>N/A</td>\n",(odd)?"Even":"Odd");
				printf("<td CLASS='notifications%s'>%s</td>\n",alert_level_class,alert_level);
				printf("<td CLASS='notifications%s'>%s</td>\n",(odd)?"Even":"Odd",date_time);
				printf("<td CLASS='notifications%s'><a href='%s?type=contacts#%s'>%s</a></td>\n",(odd)?"Even":"Odd",CONFIG_CGI,url_encode(contact_name),contact_name);
				printf("<td CLASS='notifications%s'><a href='%s?type=commands#%s'>%s</a></td>\n",(odd)?"Even":"Odd",CONFIG_CGI,url_encode(method_name),method_name);
				printf("<td CLASS='notifications%s'>%s</td>\n",(odd)?"Even":"Odd",temp_buffer);
				printf("</tr>\n");
			        }
		        }
	        }


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

	printf("</div>\n");
	printf("</p>\n");

	if(total_notifications==0){
		printf("<P><DIV CLASS='errorMessage'>No notifications have been recorded");
		if(find_all==FALSE){
			if(query_type==FIND_SERVICE)
				printf(" for this service");
			else if(query_type==FIND_CONTACT)
				printf(" for this contact");
			else
				printf(" for this host");
		        }
		printf(" in %s log file</DIV></P>",(log_archive==0)?"the current":"this archived");
	        }

	free(input);

	if(use_lifo==TRUE)
		free_lifo_memory();
	else
		mmap_fclose(thefile);

	return;
        }
