[Pkg-nagios-devel] Bug#482445: Bug#482445: nagios2: CVE-2007-5803 cross-site scripting vulnerabilities

Marc Haber mh+debian-packages at zugschlus.de
Mon May 26 16:14:20 UTC 2008


On Thu, May 22, 2008 at 10:05:27PM +0200, Nico Golde wrote:
> Package: nagios2
> Severity: important
> Tags: security patch
> 
> Hi,
> the following CVE (Common Vulnerabilities & Exposures) id was
> published for nagios2.

Nagios2 is about to be removed from unstable and testing, so I do not
plan on providing a fix for testing and unstable.

The patch applies to Nagios 2.6 from stable with one failing hunk, and
the reject file can be manually applied. Do you plan/want to issue a
stable security release?

The attached dpatch applies fine to nagios2 in stable, and the package
builds. I have not done any functionality tests though.

Greetings
Marc

-- 
-----------------------------------------------------------------------------
Marc Haber         | "I don't trust Computers. They | Mailadresse im Header
Mannheim, Germany  |  lose things."    Winona Ryder | Fon: *49 621 72739834
Nordisch by Nature |  How to make an American Quilt | Fax: *49 3221 2323190
-------------- next part --------------
#! /bin/sh /usr/share/dpatch/dpatch-run
## 30_urlencode_CVE-2007-5803_482445.dpatch by Marc Haber <mh+debian-packages at zugschlus.de>
##
## All lines beginning with `## DP:' are a description of the patch.
## DP: No description.

@DPATCH@
diff -urNad nagios2-2.6~/cgi/avail.c nagios2-2.6/cgi/avail.c
--- nagios2-2.6~/cgi/avail.c	2006-04-05 22:33:32.000000000 +0000
+++ nagios2-2.6/cgi/avail.c	2008-05-26 16:01:40.000000000 +0000
@@ -511,11 +511,11 @@
 			if(display_type==DISPLAY_HOSTGROUP_AVAIL)
 				printf("<input type='hidden' name='hostgroup' value='%s'>\n",hostgroup_name);
 			if(display_type==DISPLAY_HOST_AVAIL || display_type==DISPLAY_SERVICE_AVAIL)
-				printf("<input type='hidden' name='host' value='%s'>\n",host_name);
+				printf("<input type='hidden' name='host' value='%s'>\n",url_encode(host_name));
 			if(display_type==DISPLAY_SERVICE_AVAIL)
 				printf("<input type='hidden' name='service' value='%s'>\n",svc_description);
 			if(display_type==DISPLAY_SERVICEGROUP_AVAIL)
-				printf("<input type='hidden' name='servicegroup' value='%s'>\n",servicegroup_name);
+				printf("<input type='hidden' name='servicegroup' value='%s'>\n",url_encode(servicegroup_name));
 
 			printf("<input type='hidden' name='assumeinitialstates' value='%s'>\n",(assume_initial_states==TRUE)?"yes":"no");
 			printf("<input type='hidden' name='assumestateretention' value='%s'>\n",(assume_state_retention==TRUE)?"yes":"no");
@@ -646,11 +646,11 @@
 		if(display_type==DISPLAY_HOSTGROUP_AVAIL)
 			printf("<input type='hidden' name='hostgroup' value='%s'>\n",hostgroup_name);
 		if(display_type==DISPLAY_HOST_AVAIL || display_type==DISPLAY_SERVICE_AVAIL)
-			printf("<input type='hidden' name='host' value='%s'>\n",host_name);
+			printf("<input type='hidden' name='host' value='%s'>\n",url_encode(host_name));
 		if(display_type==DISPLAY_SERVICE_AVAIL)
 			printf("<input type='hidden' name='service' value='%s'>\n",svc_description);
 		if(display_type==DISPLAY_SERVICEGROUP_AVAIL)
-			printf("<input type='hidden' name='servicegroup' value='%s'>\n",servicegroup_name);
+			printf("<input type='hidden' name='servicegroup' value='%s'>\n",url_encode(servicegroup_name));
 
 		printf("<table border=0 cellpadding=5>\n");
 
diff -urNad nagios2-2.6~/cgi/cgiutils.c nagios2-2.6/cgi/cgiutils.c
--- nagios2-2.6~/cgi/cgiutils.c	2006-11-13 18:40:34.000000000 +0000
+++ nagios2-2.6/cgi/cgiutils.c	2008-05-26 16:01:40.000000000 +0000
@@ -128,7 +128,7 @@
 char            *my_strtok_buffer=NULL;
 char            *original_my_strtok_buffer=NULL;
 
-char encoded_url_string[MAX_INPUT_BUFFER];
+char encoded_url_string[2][MAX_INPUT_BUFFER]; // 2 to be able use url_encode twice
 char encoded_html_string[MAX_INPUT_BUFFER];
 
 #ifdef HAVE_TZNAME
@@ -1297,46 +1297,48 @@
 	int len,output_len;
 	int x,y;
 	char temp_expansion[4];
+	static int i = 0;
+	char* str = encoded_url_string[i];
 
 	len=(int)strlen(input);
-	output_len=(int)sizeof(encoded_url_string);
+	output_len=(int)sizeof(encoded_url_string[0]);
 
-	encoded_url_string[0]='\x0';
+	str[0]='\x0';
 
 	for(x=0,y=0;x<=len && y<output_len-1;x++){
 
 		/* end of string */
 		if((char)input[x]==(char)'\x0'){
-			encoded_url_string[y]='\x0';
+			str[y]='\x0';
 			break;
 		        }
 
 		/* alpha-numeric characters and a few other characters don't get encoded */
 		else if(((char)input[x]>='0' && (char)input[x]<='9') || ((char)input[x]>='A' && (char)input[x]<='Z') || ((char)input[x]>=(char)'a' && (char)input[x]<=(char)'z') || (char)input[x]==(char)'.' || (char)input[x]==(char)'-' || (char)input[x]==(char)'_'){
-			encoded_url_string[y]=input[x];
+			str[y]=input[x];
 			y++;
 		        }
 
 		/* spaces are pluses */
 		else if((char)input[x]<=(char)' '){
-			encoded_url_string[y]='+';
+			str[y]='+';
 			y++;
 		        }
 
 		/* anything else gets represented by its hex value */
 		else{
-			encoded_url_string[y]='\x0';
-			if((int)strlen(encoded_url_string)<(output_len-3)){
+			str[y]='\x0';
+			if((int)strlen(str)<(output_len-3)){
 				sprintf(temp_expansion,"%%%02X",(unsigned int)input[x]);
-				strcat(encoded_url_string,temp_expansion);
+				strcat(str,temp_expansion);
 				y+=3;
 			        }
 		        }
 	        }
 
-	encoded_url_string[sizeof(encoded_url_string)-1]='\x0';
+	str[sizeof(encoded_url_string[0])-1]='\x0';
 
-	return &encoded_url_string[0];
+	return str;
         }
 
 
diff -urNad nagios2-2.6~/cgi/cmd.c nagios2-2.6/cgi/cmd.c
--- nagios2-2.6~/cgi/cmd.c	2006-05-19 14:25:03.000000000 +0000
+++ nagios2-2.6/cgi/cmd.c	2008-05-26 16:01:40.000000000 +0000
@@ -943,10 +943,10 @@
 		printf("<INPUT TYPE='checkbox' NAME='persistent' CHECKED>");
 		printf("</b></td></tr>\n");
 		printf("<tr><td CLASS='optBoxRequiredItem'>Author (Your Name):</td><td><b>");
-		printf("<INPUT TYPE'TEXT' NAME='com_author' VALUE='%s'>",comment_author);
+		printf("<INPUT TYPE='TEXT' NAME='com_author' VALUE='%s'>",url_encode(comment_author));
 		printf("</b></td></tr>\n");
 		printf("<tr><td CLASS='optBoxRequiredItem'>Comment:</td><td><b>");
-		printf("<INPUT TYPE='TEXT' NAME='com_data' VALUE='%s' SIZE=40>",comment_data);
+		printf("<INPUT TYPE='TEXT' NAME='com_data' VALUE='%s' SIZE=40>",url_encode(comment_data));
 		printf("</b></td></tr>\n");
 		break;
 		
@@ -969,10 +969,10 @@
 		printf("<INPUT TYPE='checkbox' NAME='persistent' CHECKED>");
 		printf("</b></td></tr>\n");
 		printf("<tr><td CLASS='optBoxRequiredItem'>Author (Your Name):</td><td><b>");
-		printf("<INPUT TYPE='TEXT' NAME='com_author' VALUE='%s'>",comment_author);
+		printf("<INPUT TYPE='TEXT' NAME='com_author' VALUE='%s'>",url_encode(comment_author));
 		printf("</b></td></tr>\n");
 		printf("<tr><td CLASS='optBoxRequiredItem'>Comment:</td><td><b>");
-		printf("<INPUT TYPE='TEXT' NAME='com_data' VALUE='%s' SIZE=40>",comment_data);
+		printf("<INPUT TYPE='TEXT' NAME='com_data' VALUE='%s' SIZE=40>",url_encode(comment_data));
 		printf("</b></td></tr>\n");
 		break;
 
@@ -1152,10 +1152,10 @@
 			printf("<INPUT TYPE='TEXT' NAME='service' VALUE='%s'>",service_desc);
 		        }
 		printf("<tr><td CLASS='optBoxRequiredItem'>Author (Your Name):</td><td><b>");
-		printf("<INPUT TYPE='TEXT' NAME='com_author' VALUE='%s'>",comment_author);
+		printf("<INPUT TYPE='TEXT' NAME='com_author' VALUE='%s'>",url_encode(comment_author));
 		printf("</b></td></tr>\n");
 		printf("<tr><td CLASS='optBoxRequiredItem'>Comment:</td><td><b>");
-		printf("<INPUT TYPE='TEXT' NAME='com_data' VALUE='%s' SIZE=40>",comment_data);
+		printf("<INPUT TYPE='TEXT' NAME='com_data' VALUE='%s' SIZE=40>",url_encode(comment_data));
 		printf("</b></td></tr>\n");
 
 		printf("<tr><td CLASS='optBoxItem'><br></td></tr>\n");
@@ -1284,10 +1284,10 @@
 			printf("</b></td></tr>\n");
 		        }
 		printf("<tr><td CLASS='optBoxRequiredItem'>Author (Your Name):</td><td><b>");
-		printf("<INPUT TYPE='TEXT' NAME='com_author' VALUE='%s'>",comment_author);
+		printf("<INPUT TYPE='TEXT' NAME='com_author' VALUE='%s'>",url_encode(comment_author));
 		printf("</b></td></tr>\n");
 		printf("<tr><td CLASS='optBoxRequiredItem'>Comment:</td><td><b>");
-		printf("<INPUT TYPE='TEXT' NAME='com_data' VALUE='%s' SIZE=40>",comment_data);
+		printf("<INPUT TYPE='TEXT' NAME='com_data' VALUE='%s' SIZE=40>",url_encode(comment_data));
 		printf("</b></td></tr>\n");
 		time(&t);
 		get_time_string(&t,buffer,sizeof(buffer)-1,SHORT_DATE_TIME);
diff -urNad nagios2-2.6~/cgi/cmd.c.orig nagios2-2.6/cgi/cmd.c.orig
--- nagios2-2.6~/cgi/cmd.c.orig	1970-01-01 00:00:00.000000000 +0000
+++ nagios2-2.6/cgi/cmd.c.orig	2006-05-19 14:25:03.000000000 +0000
@@ -0,0 +1,2719 @@
+/**************************************************************************
+ *
+ * CMD.C -  Nagios Command CGI
+ *
+ * Copyright (c) 1999-2006 Ethan Galstad (nagios at nagios.org)
+ * Last Modified: 05-18-2006
+ *
+ * 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/comments.h"
+#include "../include/downtime.h"
+
+#include "../include/cgiutils.h"
+#include "../include/cgiauth.h"
+#include "../include/getcgi.h"
+
+extern char main_config_file[MAX_FILENAME_LENGTH];
+extern char command_file[MAX_FILENAME_LENGTH];
+extern char comment_file[MAX_FILENAME_LENGTH];
+
+extern char url_stylesheets_path[MAX_FILENAME_LENGTH];
+
+extern int  nagios_process_state;
+
+extern int  check_external_commands;
+
+extern int  use_authentication;
+
+extern scheduled_downtime *scheduled_downtime_list;
+extern comment *comment_list;
+
+extern int date_format;
+
+
+#define MAX_AUTHOR_LENGTH	64
+#define MAX_COMMENT_LENGTH	1024
+
+#define HTML_CONTENT   0
+#define WML_CONTENT    1
+
+
+char *host_name="";
+char *hostgroup_name="";
+char *servicegroup_name="";
+char *service_desc="";
+char *comment_author="";
+char *comment_data="";
+char *start_time_string="";
+char *end_time_string="";
+
+unsigned long comment_id=0;
+unsigned long downtime_id=0;
+int notification_delay=0;
+int schedule_delay=0;
+int persistent_comment=FALSE;
+int sticky_ack=FALSE;
+int send_notification=FALSE;
+int force_check=FALSE;
+int plugin_state=STATE_OK;
+char plugin_output[MAX_INPUT_BUFFER]="";
+char performance_data[MAX_INPUT_BUFFER]="";
+time_t start_time=0L;
+time_t end_time=0L;
+int affect_host_and_services=FALSE;
+int propagate_to_children=FALSE;
+int fixed=FALSE;
+unsigned long duration=0L;
+unsigned long triggered_by=0L;
+int child_options=0;
+
+int command_type=CMD_NONE;
+int command_mode=CMDMODE_REQUEST;
+
+int content_type=HTML_CONTENT;
+
+int display_header=TRUE;
+
+authdata current_authdata;
+
+void show_command_help(int);
+void request_command_data(int);
+void commit_command_data(int);
+int commit_command(int);
+int write_command_to_file(char *);
+void clean_comment_data(char *);
+
+void document_header(int);
+void document_footer(void);
+int process_cgivars(void);
+
+int string_to_time(char *,time_t *);
+
+
+
+int main(void){
+	int result=OK;
+	
+	/* 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);
+		if(content_type==WML_CONTENT)
+			printf("<p>Error: Could not open CGI config file!</p>\n");
+		else
+			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);
+		if(content_type==WML_CONTENT)
+			printf("<p>Error: Could not open main config file!</p>\n");
+		else
+			main_config_file_error(main_config_file);
+		document_footer();
+		return ERROR;
+	        }
+
+	/* This requires the date_format parameter in the main config file */
+	if (strcmp(start_time_string,""))
+		string_to_time(start_time_string,&start_time);
+
+	if (strcmp(end_time_string,""))
+		string_to_time(end_time_string,&end_time);
+
+
+	/* read all object configuration data */
+	result=read_all_object_configuration_data(main_config_file,READ_ALL_OBJECT_DATA);
+	if(result==ERROR){
+		document_header(FALSE);
+		if(content_type==WML_CONTENT)
+			printf("<p>Error: Could not read object config data!</p>\n");
+		else
+			object_data_error();
+		document_footer();
+		return ERROR;
+                }
+
+	document_header(TRUE);
+
+	/* get authentication information */
+	get_authentication_information(&current_authdata);
+
+	if(display_header==TRUE){
+
+		/* begin top table */
+		printf("<table border=0 width=100%%>\n");
+		printf("<tr>\n");
+
+		/* left column of the first row */
+		printf("<td align=left valign=top width=33%%>\n");
+		display_info_table("External Command Interface",FALSE,&current_authdata);
+		printf("</td>\n");
+
+		/* center column of the first row */
+		printf("<td align=center valign=top width=33%%>\n");
+		printf("</td>\n");
+
+		/* right column of the first row */
+		printf("<td align=right valign=bottom width=33%%>\n");
+
+		/* display context-sensitive help */
+		if(command_mode==CMDMODE_COMMIT)
+			display_context_help(CONTEXTHELP_CMD_COMMIT);
+		else
+			display_context_help(CONTEXTHELP_CMD_INPUT);
+
+		printf("</td>\n");
+
+		/* end of top table */
+		printf("</tr>\n");
+		printf("</table>\n");
+	        }
+
+	/* if no command was specified... */
+	if(command_type==CMD_NONE){
+		if(content_type==WML_CONTENT)
+			printf("<p>Error: No command specified!</p>\n");
+		else
+			printf("<P><DIV CLASS='errorMessage'>Error: No command was specified</DIV></P>\n");
+                }
+
+	/* if this is the first request for a command, present option */
+	else if(command_mode==CMDMODE_REQUEST)
+		request_command_data(command_type);
+
+	/* the user wants to commit the command */
+	else if(command_mode==CMDMODE_COMMIT)
+		commit_command_data(command_type);
+
+	document_footer();
+
+	/* free allocated memory */
+	free_memory();
+	free_object_data();
+
+	return OK;
+        }
+
+
+
+void document_header(int use_stylesheet){
+
+	if(content_type==WML_CONTENT){
+
+		printf("Content-type: text/vnd.wap.wml\r\n\r\n");
+
+		printf("<?xml version=\"1.0\"?>\n");
+		printf("<!DOCTYPE wml PUBLIC \"-//WAPFORUM//DTD WML 1.1//EN\" \"http://www.wapforum.org/DTD/wml_1.1.xml\">\n");
+
+		printf("<wml>\n");
+
+		printf("<card id='card1' title='Command Results'>\n");
+	        }
+
+	else{
+
+		printf("Content-type: text/html\r\n\r\n");
+
+		printf("<html>\n");
+		printf("<head>\n");
+		printf("<title>\n");
+		printf("External Command Interface\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,COMMAND_CSS);
+		        }
+
+		printf("</head>\n");
+
+		printf("<body CLASS='cmd'>\n");
+
+		/* include user SSI header */
+		include_ssi_files(COMMAND_CGI,SSI_HEADER);
+	        }
+
+	return;
+        }
+
+
+void document_footer(void){
+
+	if(content_type==WML_CONTENT){
+		printf("</card>\n");
+		printf("</wml>\n");
+	        }
+
+	else{
+
+		/* include user SSI footer */
+		include_ssi_files(COMMAND_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 command type */
+		else if(!strcmp(variables[x],"cmd_typ")){
+			x++;
+			if(variables[x]==NULL){
+				error=TRUE;
+				break;
+			        }
+
+			command_type=atoi(variables[x]);
+		        }
+
+		/* we found the command mode */
+		else if(!strcmp(variables[x],"cmd_mod")){
+			x++;
+			if(variables[x]==NULL){
+				error=TRUE;
+				break;
+			        }
+
+			command_mode=atoi(variables[x]);
+		        }
+
+		/* we found the comment id */
+		else if(!strcmp(variables[x],"com_id")){
+			x++;
+			if(variables[x]==NULL){
+				error=TRUE;
+				break;
+			        }
+
+			comment_id=strtoul(variables[x],NULL,10);
+		        }
+
+		/* we found the downtime id */
+		else if(!strcmp(variables[x],"down_id")){
+			x++;
+			if(variables[x]==NULL){
+				error=TRUE;
+				break;
+			        }
+
+			downtime_id=strtoul(variables[x],NULL,10);
+		        }
+
+		/* we found the notification delay */
+		else if(!strcmp(variables[x],"not_dly")){
+			x++;
+			if(variables[x]==NULL){
+				error=TRUE;
+				break;
+			        }
+
+			notification_delay=atoi(variables[x]);
+		        }
+
+		/* we found the schedule delay */
+		else if(!strcmp(variables[x],"sched_dly")){
+			x++;
+			if(variables[x]==NULL){
+				error=TRUE;
+				break;
+			        }
+
+			schedule_delay=atoi(variables[x]);
+		        }
+
+		/* we found the comment author */
+		else if(!strcmp(variables[x],"com_author")){
+			x++;
+			if(variables[x]==NULL){
+				error=TRUE;
+				break;
+			        }
+
+			comment_author=(char *)malloc(strlen(variables[x])+1);
+			if(comment_author==NULL)
+				comment_author="";
+			else
+				strcpy(comment_author,variables[x]);
+			}
+
+		/* we found the comment data */
+		else if(!strcmp(variables[x],"com_data")){
+			x++;
+			if(variables[x]==NULL){
+				error=TRUE;
+				break;
+			        }
+
+			comment_data=(char *)malloc(strlen(variables[x])+1);
+			if(comment_data==NULL)
+				comment_data="";
+			else
+				strcpy(comment_data,variables[x]);
+			}
+
+		/* we found the host name */
+		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]);
+			}
+
+		/* we found the hostgroup name */
+		else if(!strcmp(variables[x],"hostgroup")){
+			x++;
+			if(variables[x]==NULL){
+				error=TRUE;
+				break;
+			        }
+
+			hostgroup_name=(char *)malloc(strlen(variables[x])+1);
+			if(hostgroup_name==NULL)
+				hostgroup_name="";
+			else
+				strcpy(hostgroup_name,variables[x]);
+			}
+
+		/* we found the service name */
+		else if(!strcmp(variables[x],"service")){
+			x++;
+			if(variables[x]==NULL){
+				error=TRUE;
+				break;
+			        }
+
+			service_desc=(char *)malloc(strlen(variables[x])+1);
+			if(service_desc==NULL)
+				service_desc="";
+			else
+				strcpy(service_desc,variables[x]);
+			}
+
+		/* we found the servicegroup name */
+		else if(!strcmp(variables[x],"servicegroup")){
+			x++;
+			if(variables[x]==NULL){
+				error=TRUE;
+				break;
+			        }
+
+			servicegroup_name=(char *)malloc(strlen(variables[x])+1);
+			if(servicegroup_name==NULL)
+				servicegroup_name="";
+			else
+				strcpy(servicegroup_name,variables[x]);
+			}
+
+		/* we got the persistence option for a comment */
+		else if(!strcmp(variables[x],"persistent"))
+			persistent_comment=TRUE;
+
+		/* we got the notification option for an acknowledgement */
+		else if(!strcmp(variables[x],"send_notification"))
+			send_notification=TRUE;
+
+		/* we got the acknowledgement type */
+		else if(!strcmp(variables[x],"sticky_ack"))
+			sticky_ack=TRUE;
+
+		/* we got the service check force option */
+		else if(!strcmp(variables[x],"force_check"))
+			force_check=TRUE;
+
+		/* we got the option to affect host and all its services */
+		else if(!strcmp(variables[x],"ahas"))
+			affect_host_and_services=TRUE;
+
+		/* we got the option to propagate to child hosts */
+		else if(!strcmp(variables[x],"ptc"))
+			propagate_to_children=TRUE;
+
+		/* we got the option for fixed downtime */
+		else if(!strcmp(variables[x],"fixed")){
+			x++;
+			if(variables[x]==NULL){
+				error=TRUE;
+				break;
+			        }
+
+			fixed=(atoi(variables[x])>0)?TRUE:FALSE;
+		        }
+
+		/* we got the triggered by downtime option */
+		else if(!strcmp(variables[x],"trigger")){
+			x++;
+			if(variables[x]==NULL){
+				error=TRUE;
+				break;
+			        }
+
+			triggered_by=strtoul(variables[x],NULL,10);
+		        }
+
+		/* we got the child options */
+		else if(!strcmp(variables[x],"childoptions")){
+			x++;
+			if(variables[x]==NULL){
+				error=TRUE;
+				break;
+			        }
+
+			child_options=atoi(variables[x]);
+		        }
+
+		/* we found the plugin output */
+		else if(!strcmp(variables[x],"plugin_output")){
+			x++;
+			if(variables[x]==NULL){
+				error=TRUE;
+				break;
+			        }
+
+			/* protect against buffer overflows */
+			if(strlen(variables[x])>=MAX_INPUT_BUFFER-1){
+				error=TRUE;
+				break;
+			        }
+			else
+				strcpy(plugin_output,variables[x]);
+			}
+
+		/* we found the performance data */
+		else if(!strcmp(variables[x],"performance_data")){
+			x++;
+			if(variables[x]==NULL){
+				error=TRUE;
+				break;
+			        }
+
+			/* protect against buffer overflows */
+			if(strlen(variables[x])>=MAX_INPUT_BUFFER-1){
+				error=TRUE;
+				break;
+			        }
+			else
+				strcpy(performance_data,variables[x]);
+			}
+
+		/* we found the plugin state */
+		else if(!strcmp(variables[x],"plugin_state")){
+			x++;
+			if(variables[x]==NULL){
+				error=TRUE;
+				break;
+			        }
+
+			plugin_state=atoi(variables[x]);
+		        }
+
+		/* we found the hour duration */
+		else if(!strcmp(variables[x],"hours")){
+			x++;
+			if(variables[x]==NULL){
+				error=TRUE;
+				break;
+			        }
+
+			if(atoi(variables[x])<0){
+				error=TRUE;
+				break;
+			        }
+			duration+=(unsigned long)(atoi(variables[x])*3600);
+		        }
+
+		/* we found the minute duration */
+		else if(!strcmp(variables[x],"minutes")){
+			x++;
+			if(variables[x]==NULL){
+				error=TRUE;
+				break;
+			        }
+
+			if(atoi(variables[x])<0){
+				error=TRUE;
+				break;
+			        }
+			duration+=(unsigned long)(atoi(variables[x])*60);
+		        }
+
+		/* we found the start time */
+		else if(!strcmp(variables[x],"start_time")){
+			x++;
+			if(variables[x]==NULL){
+				error=TRUE;
+				break;
+			        }
+
+			start_time_string=(char *)malloc(strlen(variables[x])+1);
+			if(start_time_string==NULL)
+				start_time_string="";
+			else
+				strcpy(start_time_string,variables[x]);
+		        }
+
+		/* we found the end time */
+		else if(!strcmp(variables[x],"end_time")){
+			x++;
+			if(variables[x]==NULL){
+				error=TRUE;
+				break;
+			        }
+
+			end_time_string=(char *)malloc(strlen(variables[x])+1);
+			if(end_time_string==NULL)
+				end_time_string="";
+			else
+				strcpy(end_time_string,variables[x]);
+		        }
+
+		/* we found the content type argument */
+		else if(!strcmp(variables[x],"content")){
+			x++;
+			if(variables[x]==NULL){
+				error=TRUE;
+				break;
+			        }
+			if(!strcmp(variables[x],"wml")){
+				content_type=WML_CONTENT;
+				display_header=FALSE;
+			        }
+			else
+				content_type=HTML_CONTENT;
+		        }
+                }
+
+	/* free memory allocated to the CGI variables */
+	free_cgivars(variables);
+
+	return error;
+        }
+
+
+
+void request_command_data(int cmd){
+	time_t t;
+	char start_time[MAX_DATETIME_LENGTH];
+	char buffer[MAX_INPUT_BUFFER];
+	contact *temp_contact;
+	scheduled_downtime *temp_downtime;
+
+
+	/* get default name to use for comment author */
+	temp_contact=find_contact(current_authdata.username);
+	if(temp_contact!=NULL && temp_contact->alias!=NULL)
+		comment_author=temp_contact->alias;
+	else
+		comment_author=current_authdata.username;
+
+
+	printf("<P><DIV ALIGN=CENTER CLASS='cmdType'>You are requesting to ");
+
+	switch(cmd){
+
+	case CMD_ADD_HOST_COMMENT:
+	case CMD_ADD_SVC_COMMENT:
+		printf("add a %s comment",(cmd==CMD_ADD_HOST_COMMENT)?"host":"service");
+		break;
+
+	case CMD_DEL_HOST_COMMENT:
+	case CMD_DEL_SVC_COMMENT:
+		printf("delete a %s comment",(cmd==CMD_DEL_HOST_COMMENT)?"host":"service");
+		break;
+		
+	case CMD_DELAY_HOST_NOTIFICATION:
+	case CMD_DELAY_SVC_NOTIFICATION:
+		printf("delay a %s notification",(cmd==CMD_DELAY_HOST_NOTIFICATION)?"host":"service");
+		break;
+
+	case CMD_SCHEDULE_SVC_CHECK:
+		printf("schedule a service check");
+		break;
+
+	case CMD_ENABLE_SVC_CHECK:
+	case CMD_DISABLE_SVC_CHECK:
+		printf("%s actice checks of a particular service",(cmd==CMD_ENABLE_SVC_CHECK)?"enable":"disable");
+		break;
+		
+	case CMD_ENABLE_NOTIFICATIONS:
+	case CMD_DISABLE_NOTIFICATIONS:
+		printf("%s notifications",(cmd==CMD_ENABLE_NOTIFICATIONS)?"enable":"disable");
+		break;
+		
+	case CMD_SHUTDOWN_PROCESS:
+	case CMD_RESTART_PROCESS:
+		printf("%s the Nagios process",(cmd==CMD_SHUTDOWN_PROCESS)?"shutdown":"restart");
+		break;
+
+	case CMD_ENABLE_HOST_SVC_CHECKS:
+	case CMD_DISABLE_HOST_SVC_CHECKS:
+		printf("%s active checks of all services on a host",(cmd==CMD_ENABLE_HOST_SVC_CHECKS)?"enable":"disable");
+		break;
+
+	case CMD_SCHEDULE_HOST_SVC_CHECKS:
+		printf("schedule a check of all services for a host");
+		break;
+
+	case CMD_DEL_ALL_HOST_COMMENTS:
+	case CMD_DEL_ALL_SVC_COMMENTS:
+		printf("delete all comments for a %s",(cmd==CMD_DEL_ALL_HOST_COMMENTS)?"host":"service");
+		break;
+
+	case CMD_ENABLE_SVC_NOTIFICATIONS:
+	case CMD_DISABLE_SVC_NOTIFICATIONS:
+		printf("%s notifications for a service",(cmd==CMD_ENABLE_SVC_NOTIFICATIONS)?"enable":"disable");
+		break;
+
+	case CMD_ENABLE_HOST_NOTIFICATIONS:
+	case CMD_DISABLE_HOST_NOTIFICATIONS:
+		printf("%s notifications for a host",(cmd==CMD_ENABLE_HOST_NOTIFICATIONS)?"enable":"disable");
+		break;
+
+	case CMD_ENABLE_ALL_NOTIFICATIONS_BEYOND_HOST:
+	case CMD_DISABLE_ALL_NOTIFICATIONS_BEYOND_HOST:
+		printf("%s notifications for all hosts and services beyond a host",(cmd==CMD_ENABLE_ALL_NOTIFICATIONS_BEYOND_HOST)?"enable":"disable");
+		break;
+
+	case CMD_ENABLE_HOST_SVC_NOTIFICATIONS:
+	case CMD_DISABLE_HOST_SVC_NOTIFICATIONS:
+		printf("%s notifications for all services on a host",(cmd==CMD_ENABLE_HOST_SVC_NOTIFICATIONS)?"enable":"disable");
+		break;
+
+	case CMD_ACKNOWLEDGE_HOST_PROBLEM:
+	case CMD_ACKNOWLEDGE_SVC_PROBLEM:
+		printf("acknowledge a %s problem",(cmd==CMD_ACKNOWLEDGE_HOST_PROBLEM)?"host":"service");
+		break;
+
+	case CMD_START_EXECUTING_SVC_CHECKS:
+	case CMD_STOP_EXECUTING_SVC_CHECKS:
+		printf("%s executing active service checks",(cmd==CMD_START_EXECUTING_SVC_CHECKS)?"start":"stop");
+		break;
+
+	case CMD_START_ACCEPTING_PASSIVE_SVC_CHECKS:
+	case CMD_STOP_ACCEPTING_PASSIVE_SVC_CHECKS:
+		printf("%s accepting passive service checks",(cmd==CMD_START_ACCEPTING_PASSIVE_SVC_CHECKS)?"start":"stop");
+		break;
+
+	case CMD_ENABLE_PASSIVE_SVC_CHECKS:
+	case CMD_DISABLE_PASSIVE_SVC_CHECKS:
+		printf("%s accepting passive service checks for a particular service",(cmd==CMD_ENABLE_PASSIVE_SVC_CHECKS)?"start":"stop");
+		break;
+
+	case CMD_ENABLE_EVENT_HANDLERS:
+	case CMD_DISABLE_EVENT_HANDLERS:
+		printf("%s event handlers",(cmd==CMD_ENABLE_EVENT_HANDLERS)?"enable":"disable");
+		break;
+
+	case CMD_ENABLE_HOST_EVENT_HANDLER:
+	case CMD_DISABLE_HOST_EVENT_HANDLER:
+		printf("%s the event handler for a particular host",(cmd==CMD_ENABLE_HOST_EVENT_HANDLER)?"enable":"disable");
+		break;
+
+	case CMD_ENABLE_SVC_EVENT_HANDLER:
+	case CMD_DISABLE_SVC_EVENT_HANDLER:
+		printf("%s the event handler for a particular service",(cmd==CMD_ENABLE_SVC_EVENT_HANDLER)?"enable":"disable");
+		break;
+
+	case CMD_ENABLE_HOST_CHECK:
+	case CMD_DISABLE_HOST_CHECK:
+		printf("%s active checks of a particular host",(cmd==CMD_ENABLE_HOST_CHECK)?"enable":"disable");
+		break;
+
+	case CMD_STOP_OBSESSING_OVER_SVC_CHECKS:
+	case CMD_START_OBSESSING_OVER_SVC_CHECKS:
+		printf("%s obsessing over service checks",(cmd==CMD_STOP_OBSESSING_OVER_SVC_CHECKS)?"stop":"start");
+		break;
+
+	case CMD_REMOVE_HOST_ACKNOWLEDGEMENT:
+	case CMD_REMOVE_SVC_ACKNOWLEDGEMENT:
+		printf("remove a %s acknowledgement",(cmd==CMD_REMOVE_HOST_ACKNOWLEDGEMENT)?"host":"service");
+		break;
+
+	case CMD_SCHEDULE_HOST_DOWNTIME:
+	case CMD_SCHEDULE_SVC_DOWNTIME:
+		printf("schedule downtime for a particular %s",(cmd==CMD_SCHEDULE_HOST_DOWNTIME)?"host":"service");
+		break;
+
+	case CMD_PROCESS_HOST_CHECK_RESULT:
+	case CMD_PROCESS_SERVICE_CHECK_RESULT:
+		printf("submit a passive check result for a particular %s",(cmd==CMD_PROCESS_HOST_CHECK_RESULT)?"host":"service");
+		break;
+
+	case CMD_ENABLE_HOST_FLAP_DETECTION:
+	case CMD_DISABLE_HOST_FLAP_DETECTION:
+		printf("%s flap detection for a particular host",(cmd==CMD_ENABLE_HOST_FLAP_DETECTION)?"enable":"disable");
+		break;
+
+	case CMD_ENABLE_SVC_FLAP_DETECTION:
+	case CMD_DISABLE_SVC_FLAP_DETECTION:
+		printf("%s flap detection for a particular service",(cmd==CMD_ENABLE_SVC_FLAP_DETECTION)?"enable":"disable");
+		break;
+
+	case CMD_ENABLE_FLAP_DETECTION:
+	case CMD_DISABLE_FLAP_DETECTION:
+		printf("%s flap detection for hosts and services",(cmd==CMD_ENABLE_FLAP_DETECTION)?"enable":"disable");
+		break;
+
+	case CMD_ENABLE_HOSTGROUP_SVC_NOTIFICATIONS:
+	case CMD_DISABLE_HOSTGROUP_SVC_NOTIFICATIONS:
+		printf("%s notifications for all services in a particular hostgroup",(cmd==CMD_ENABLE_HOSTGROUP_SVC_NOTIFICATIONS)?"enable":"disable");
+		break;
+
+	case CMD_ENABLE_HOSTGROUP_HOST_NOTIFICATIONS:
+	case CMD_DISABLE_HOSTGROUP_HOST_NOTIFICATIONS:
+		printf("%s notifications for all hosts in a particular hostgroup",(cmd==CMD_ENABLE_HOSTGROUP_HOST_NOTIFICATIONS)?"enable":"disable");
+		break;
+
+	case CMD_ENABLE_HOSTGROUP_SVC_CHECKS:
+	case CMD_DISABLE_HOSTGROUP_SVC_CHECKS:
+		printf("%s active checks of all services in a particular hostgroup",(cmd==CMD_ENABLE_HOSTGROUP_SVC_CHECKS)?"enable":"disable");
+		break;
+
+	case CMD_DEL_HOST_DOWNTIME:
+	case CMD_DEL_SVC_DOWNTIME:
+		printf("cancel scheduled downtime for a particular %s",(cmd==CMD_DEL_HOST_DOWNTIME)?"host":"service");
+		break;
+
+	case CMD_ENABLE_FAILURE_PREDICTION:
+	case CMD_DISABLE_FAILURE_PREDICTION:
+		printf("%s failure prediction for hosts and service",(cmd==CMD_ENABLE_FAILURE_PREDICTION)?"enable":"disable");
+		break;
+
+	case CMD_ENABLE_PERFORMANCE_DATA:
+	case CMD_DISABLE_PERFORMANCE_DATA:
+		printf("%s performance data processing for hosts and services",(cmd==CMD_ENABLE_PERFORMANCE_DATA)?"enable":"disable");
+		break;
+
+	case CMD_SCHEDULE_HOSTGROUP_HOST_DOWNTIME:
+		printf("schedule downtime for all hosts in a particular hostgroup");
+		break;
+
+	case CMD_SCHEDULE_HOSTGROUP_SVC_DOWNTIME:
+		printf("schedule downtime for all services in a particular hostgroup");
+		break;
+
+	case CMD_START_EXECUTING_HOST_CHECKS:
+	case CMD_STOP_EXECUTING_HOST_CHECKS:
+		printf("%s executing host checks",(cmd==CMD_START_EXECUTING_HOST_CHECKS)?"start":"stop");
+		break;
+
+	case CMD_START_ACCEPTING_PASSIVE_HOST_CHECKS:
+	case CMD_STOP_ACCEPTING_PASSIVE_HOST_CHECKS:
+		printf("%s accepting passive host checks",(cmd==CMD_START_ACCEPTING_PASSIVE_HOST_CHECKS)?"start":"stop");
+		break;
+
+	case CMD_ENABLE_PASSIVE_HOST_CHECKS:
+	case CMD_DISABLE_PASSIVE_HOST_CHECKS:
+		printf("%s accepting passive checks for a particular host",(cmd==CMD_ENABLE_PASSIVE_HOST_CHECKS)?"start":"stop");
+		break;
+
+	case CMD_START_OBSESSING_OVER_HOST_CHECKS:
+	case CMD_STOP_OBSESSING_OVER_HOST_CHECKS:
+		printf("%s obsessing over host checks",(cmd==CMD_START_OBSESSING_OVER_HOST_CHECKS)?"start":"stop");
+		break;
+
+	case CMD_SCHEDULE_HOST_CHECK:
+		printf("schedule a host check");
+		break;
+
+	case CMD_START_OBSESSING_OVER_SVC:
+	case CMD_STOP_OBSESSING_OVER_SVC:
+		printf("%s obsessing over a particular service",(cmd==CMD_START_OBSESSING_OVER_SVC)?"start":"stop");
+		break;
+
+	case CMD_START_OBSESSING_OVER_HOST:
+	case CMD_STOP_OBSESSING_OVER_HOST:
+		printf("%s obsessing over a particular host",(cmd==CMD_START_OBSESSING_OVER_HOST)?"start":"stop");
+		break;
+
+	case CMD_ENABLE_SERVICEGROUP_SVC_NOTIFICATIONS:
+	case CMD_DISABLE_SERVICEGROUP_SVC_NOTIFICATIONS:
+		printf("%s notifications for all services in a particular servicegroup",(cmd==CMD_ENABLE_SERVICEGROUP_SVC_NOTIFICATIONS)?"enable":"disable");
+		break;
+
+	case CMD_ENABLE_SERVICEGROUP_HOST_NOTIFICATIONS:
+	case CMD_DISABLE_SERVICEGROUP_HOST_NOTIFICATIONS:
+		printf("%s notifications for all hosts in a particular servicegroup",(cmd==CMD_ENABLE_SERVICEGROUP_HOST_NOTIFICATIONS)?"enable":"disable");
+		break;
+
+	case CMD_ENABLE_SERVICEGROUP_SVC_CHECKS:
+	case CMD_DISABLE_SERVICEGROUP_SVC_CHECKS:
+		printf("%s active checks of all services in a particular servicegroup",(cmd==CMD_ENABLE_SERVICEGROUP_SVC_CHECKS)?"enable":"disable");
+		break;
+
+	case CMD_SCHEDULE_SERVICEGROUP_HOST_DOWNTIME:
+		printf("schedule downtime for all hosts in a particular servicegroup");
+		break;
+
+	case CMD_SCHEDULE_SERVICEGROUP_SVC_DOWNTIME:
+		printf("schedule downtime for all services in a particular servicegroup");
+		break;
+
+	default:
+		printf("execute an unknown command.  Shame on you!</DIV>");
+		return;
+	        }
+
+	printf("</DIV></p>\n");
+
+	printf("<p>\n");
+	printf("<div align='center'>\n");
+
+	printf("<table border=0 width=90%%>\n");
+	printf("<tr>\n");
+	printf("<td align=center valign=top>\n");
+
+	printf("<DIV ALIGN=CENTER CLASS='optBoxTitle'>Command Options</DIV>\n");
+
+	printf("<TABLE CELLSPACING=0 CELLPADDING=0 BORDER=1 CLASS='optBox'>\n");
+	printf("<TR><TD CLASS='optBoxItem'>\n");
+	printf("<form method='post' action='%s'>\n", COMMAND_CGI);
+	printf("<TABLE CELLSPACING=0 CELLPADDING=0 CLASS='optBox'>\n");
+
+	printf("<tr><td><INPUT TYPE='HIDDEN' NAME='cmd_typ' VALUE='%d'><INPUT TYPE='HIDDEN' NAME='cmd_mod' VALUE='%d'></td></tr>\n",cmd,CMDMODE_COMMIT);
+
+	switch(cmd){
+
+	case CMD_ADD_HOST_COMMENT:
+	case CMD_ACKNOWLEDGE_HOST_PROBLEM:
+		printf("<tr><td CLASS='optBoxRequiredItem'>Host Name:</td><td><b>");
+		printf("<INPUT TYPE='TEXT' NAME='host' VALUE='%s'>",host_name);
+		printf("</b></td></tr>\n");
+		if(cmd==CMD_ACKNOWLEDGE_HOST_PROBLEM){
+			printf("<tr><td CLASS='optBoxItem'>Sticky Acknowledgement:</td><td><b>");
+			printf("<INPUT TYPE='checkbox' NAME='sticky_ack' CHECKED>");
+			printf("</b></td></tr>\n");
+			printf("<tr><td CLASS='optBoxItem'>Send Notification:</td><td><b>");
+			printf("<INPUT TYPE='checkbox' NAME='send_notification' CHECKED>");
+			printf("</b></td></tr>\n");
+		        }
+		printf("<tr><td CLASS='optBoxItem'>Persistent%s:</td><td><b>",(cmd==CMD_ACKNOWLEDGE_HOST_PROBLEM)?" Comment":"");
+		printf("<INPUT TYPE='checkbox' NAME='persistent' CHECKED>");
+		printf("</b></td></tr>\n");
+		printf("<tr><td CLASS='optBoxRequiredItem'>Author (Your Name):</td><td><b>");
+		printf("<INPUT TYPE'TEXT' NAME='com_author' VALUE='%s'>",comment_author);
+		printf("</b></td></tr>\n");
+		printf("<tr><td CLASS='optBoxRequiredItem'>Comment:</td><td><b>");
+		printf("<INPUT TYPE='TEXT' NAME='com_data' VALUE='%s' SIZE=40>",comment_data);
+		printf("</b></td></tr>\n");
+		break;
+		
+	case CMD_ADD_SVC_COMMENT:
+	case CMD_ACKNOWLEDGE_SVC_PROBLEM:
+		printf("<tr><td CLASS='optBoxRequiredItem'>Host Name:</td><td><b>");
+		printf("<INPUT TYPE='TEXT' NAME='host' VALUE='%s'>",host_name);
+		printf("</b></td></tr>\n");
+		printf("<tr><td CLASS='optBoxRequiredItem'>Service:</td><td><b>");
+		printf("<INPUT TYPE='TEXT' NAME='service' VALUE='%s'>",service_desc);
+		if(cmd==CMD_ACKNOWLEDGE_SVC_PROBLEM){
+			printf("<tr><td CLASS='optBoxItem'>Sticky Acknowledgement:</td><td><b>");
+			printf("<INPUT TYPE='checkbox' NAME='sticky_ack' CHECKED>");
+			printf("</b></td></tr>\n");
+			printf("<tr><td CLASS='optBoxItem'>Send Notification:</td><td><b>");
+			printf("<INPUT TYPE='checkbox' NAME='send_notification' CHECKED>");
+			printf("</b></td></tr>\n");
+		        }
+		printf("<tr><td CLASS='optBoxItem'>Persistent%s:</td><td><b>",(cmd==CMD_ACKNOWLEDGE_SVC_PROBLEM)?" Comment":"");
+		printf("<INPUT TYPE='checkbox' NAME='persistent' CHECKED>");
+		printf("</b></td></tr>\n");
+		printf("<tr><td CLASS='optBoxRequiredItem'>Author (Your Name):</td><td><b>");
+		printf("<INPUT TYPE='TEXT' NAME='com_author' VALUE='%s'>",comment_author);
+		printf("</b></td></tr>\n");
+		printf("<tr><td CLASS='optBoxRequiredItem'>Comment:</td><td><b>");
+		printf("<INPUT TYPE='TEXT' NAME='com_data' VALUE='%s' SIZE=40>",comment_data);
+		printf("</b></td></tr>\n");
+		break;
+
+	case CMD_DEL_HOST_COMMENT:
+	case CMD_DEL_SVC_COMMENT:
+		printf("<tr><td CLASS='optBoxRequiredItem'>Comment ID:</td><td><b>");
+		printf("<INPUT TYPE='TEXT' NAME='com_id' VALUE='%lu'>",comment_id);
+		printf("</b></td></tr>\n");
+		break;
+		
+	case CMD_DELAY_HOST_NOTIFICATION:
+		printf("<tr><td CLASS='optBoxRequiredItem'>Host Name:</td><td><b>");
+		printf("<INPUT TYPE='TEXT' NAME='host' VALUE='%s'>",host_name);
+		printf("</b></td></tr>\n");
+		printf("<tr><td CLASS='optBoxRequiredItem'>Notification Delay (minutes from now):</td><td><b>");
+		printf("<INPUT TYPE='TEXT' NAME='not_dly' VALUE='%d'>",notification_delay);
+		printf("</b></td></tr>\n");
+		break;
+
+	case CMD_DELAY_SVC_NOTIFICATION:
+		printf("<tr><td CLASS='optBoxRequiredItem'>Host Name:</td><td><b>");
+		printf("<INPUT TYPE='TEXT' NAME='host' VALUE='%s'>",host_name);
+		printf("</b></td></tr>\n");
+		printf("<tr><td CLASS='optBoxRequiredItem'>Service:</td><td><b>");
+		printf("<INPUT TYPE='TEXT' NAME='service' VALUE='%s'>",service_desc);
+		printf("<tr><td CLASS='optBoxRequiredItem'>Notification Delay (minutes from now):</td><td><b>");
+		printf("<INPUT TYPE='TEXT' NAME='not_dly' VALUE='%d'>",notification_delay);
+		printf("</b></td></tr>\n");
+		break;
+
+	case CMD_SCHEDULE_SVC_CHECK:
+	case CMD_SCHEDULE_HOST_CHECK:
+	case CMD_SCHEDULE_HOST_SVC_CHECKS:
+		printf("<tr><td CLASS='optBoxRequiredItem'>Host Name:</td><td><b>");
+		printf("<INPUT TYPE='TEXT' NAME='host' VALUE='%s'>",host_name);
+		printf("</b></td></tr>\n");
+		if(cmd==CMD_SCHEDULE_SVC_CHECK){
+			printf("<tr><td CLASS='optBoxRequiredItem'>Service:</td><td><b>");
+			printf("<INPUT TYPE='TEXT' NAME='service' VALUE='%s'>",service_desc);
+			printf("</b></td></tr>\n");
+		        }
+		time(&t);
+		get_time_string(&t,buffer,sizeof(buffer)-1,SHORT_DATE_TIME);
+		printf("<tr><td CLASS='optBoxRequiredItem'>Check Time:</td><td><b>");
+		printf("<INPUT TYPE='TEXT' NAME='start_time' VALUE='%s'>",buffer);
+		printf("</b></td></tr>\n");
+		printf("<tr><td CLASS='optBoxItem'>Force Check:</td><td><b>");
+		printf("<INPUT TYPE='checkbox' NAME='force_check' CHECKED>");
+		printf("</b></td></tr>\n");
+		break;
+
+	case CMD_ENABLE_SVC_CHECK:
+	case CMD_DISABLE_SVC_CHECK:
+	case CMD_DEL_ALL_SVC_COMMENTS:
+	case CMD_ENABLE_SVC_NOTIFICATIONS:
+	case CMD_DISABLE_SVC_NOTIFICATIONS:
+	case CMD_ENABLE_PASSIVE_SVC_CHECKS:
+	case CMD_DISABLE_PASSIVE_SVC_CHECKS:
+	case CMD_ENABLE_SVC_EVENT_HANDLER:
+	case CMD_DISABLE_SVC_EVENT_HANDLER:
+	case CMD_REMOVE_SVC_ACKNOWLEDGEMENT:
+	case CMD_ENABLE_SVC_FLAP_DETECTION:
+	case CMD_DISABLE_SVC_FLAP_DETECTION:
+	case CMD_START_OBSESSING_OVER_SVC:
+	case CMD_STOP_OBSESSING_OVER_SVC:
+		printf("<tr><td CLASS='optBoxRequiredItem'>Host Name:</td><td><b>");
+		printf("<INPUT TYPE='TEXT' NAME='host' VALUE='%s'>",host_name);
+		printf("</b></td></tr>\n");
+		printf("<tr><td CLASS='optBoxRequiredItem'>Service:</td><td><b>");
+		printf("<INPUT TYPE='TEXT' NAME='service' VALUE='%s'>",service_desc);
+		printf("</b></td></tr>\n");
+		break;
+		
+	case CMD_ENABLE_HOST_SVC_CHECKS:
+	case CMD_DISABLE_HOST_SVC_CHECKS:
+	case CMD_DEL_ALL_HOST_COMMENTS:
+	case CMD_ENABLE_HOST_NOTIFICATIONS:
+	case CMD_DISABLE_HOST_NOTIFICATIONS:
+	case CMD_ENABLE_ALL_NOTIFICATIONS_BEYOND_HOST:
+	case CMD_DISABLE_ALL_NOTIFICATIONS_BEYOND_HOST:
+	case CMD_ENABLE_HOST_SVC_NOTIFICATIONS:
+	case CMD_DISABLE_HOST_SVC_NOTIFICATIONS:
+	case CMD_ENABLE_HOST_EVENT_HANDLER:
+	case CMD_DISABLE_HOST_EVENT_HANDLER:
+	case CMD_ENABLE_HOST_CHECK:
+	case CMD_DISABLE_HOST_CHECK:
+	case CMD_REMOVE_HOST_ACKNOWLEDGEMENT:
+	case CMD_ENABLE_HOST_FLAP_DETECTION:
+	case CMD_DISABLE_HOST_FLAP_DETECTION:
+	case CMD_ENABLE_PASSIVE_HOST_CHECKS:
+	case CMD_DISABLE_PASSIVE_HOST_CHECKS:
+	case CMD_START_OBSESSING_OVER_HOST:
+	case CMD_STOP_OBSESSING_OVER_HOST:
+		printf("<tr><td CLASS='optBoxRequiredItem'>Host Name:</td><td><b>");
+		printf("<INPUT TYPE='TEXT' NAME='host' VALUE='%s'>",host_name);
+		printf("</b></td></tr>\n");
+		if(cmd==CMD_ENABLE_HOST_SVC_CHECKS || cmd==CMD_DISABLE_HOST_SVC_CHECKS || cmd==CMD_ENABLE_HOST_SVC_NOTIFICATIONS || cmd==CMD_DISABLE_HOST_SVC_NOTIFICATIONS){
+			printf("<tr><td CLASS='optBoxItem'>%s For Host Too:</td><td><b>",(cmd==CMD_ENABLE_HOST_SVC_CHECKS || cmd==CMD_ENABLE_HOST_SVC_NOTIFICATIONS)?"Enable":"Disable");
+			printf("<INPUT TYPE='checkbox' NAME='ahas'>");
+			printf("</b></td></tr>\n");
+		        }
+		if(cmd==CMD_ENABLE_HOST_NOTIFICATIONS || cmd==CMD_DISABLE_HOST_NOTIFICATIONS){
+			printf("<tr><td CLASS='optBoxItem'>%s Notifications For Child Hosts Too:</td><td><b>",(cmd==CMD_ENABLE_HOST_NOTIFICATIONS)?"Enable":"Disable");
+			printf("<INPUT TYPE='checkbox' NAME='ptc'>");
+			printf("</b></td></tr>\n");
+		        }
+		break;
+
+	case CMD_ENABLE_NOTIFICATIONS:
+	case CMD_DISABLE_NOTIFICATIONS:
+	case CMD_SHUTDOWN_PROCESS:
+	case CMD_RESTART_PROCESS:
+	case CMD_START_EXECUTING_SVC_CHECKS:
+	case CMD_STOP_EXECUTING_SVC_CHECKS:
+	case CMD_START_ACCEPTING_PASSIVE_SVC_CHECKS:
+	case CMD_STOP_ACCEPTING_PASSIVE_SVC_CHECKS:
+	case CMD_ENABLE_EVENT_HANDLERS:
+	case CMD_DISABLE_EVENT_HANDLERS:
+	case CMD_START_OBSESSING_OVER_SVC_CHECKS:
+	case CMD_STOP_OBSESSING_OVER_SVC_CHECKS:
+	case CMD_ENABLE_FLAP_DETECTION:
+	case CMD_DISABLE_FLAP_DETECTION:
+	case CMD_ENABLE_FAILURE_PREDICTION:
+	case CMD_DISABLE_FAILURE_PREDICTION:
+	case CMD_ENABLE_PERFORMANCE_DATA:
+	case CMD_DISABLE_PERFORMANCE_DATA:
+	case CMD_START_EXECUTING_HOST_CHECKS:
+	case CMD_STOP_EXECUTING_HOST_CHECKS:
+	case CMD_START_ACCEPTING_PASSIVE_HOST_CHECKS:
+	case CMD_STOP_ACCEPTING_PASSIVE_HOST_CHECKS:
+	case CMD_START_OBSESSING_OVER_HOST_CHECKS:
+	case CMD_STOP_OBSESSING_OVER_HOST_CHECKS:
+		printf("<tr><td CLASS='optBoxItem' colspan=2>There are no options for this command.<br>Click the 'Commit' button to submit the command.</td></tr>");
+		break;
+		
+	case CMD_PROCESS_HOST_CHECK_RESULT:
+	case CMD_PROCESS_SERVICE_CHECK_RESULT:
+		printf("<tr><td CLASS='optBoxRequiredItem'>Host Name:</td><td><b>");
+		printf("<INPUT TYPE='TEXT' NAME='host' VALUE='%s'>",host_name);
+		printf("</b></td></tr>\n");
+		if(cmd==CMD_PROCESS_SERVICE_CHECK_RESULT){
+			printf("<tr><td CLASS='optBoxRequiredItem'>Service:</td><td><b>");
+			printf("<INPUT TYPE='TEXT' NAME='service' VALUE='%s'>",service_desc);
+			printf("</b></td></tr>\n");
+		        }
+		printf("<tr><td CLASS='optBoxRequiredItem'>Check Result:</td><td><b>");
+		printf("<SELECT NAME='plugin_state'>");
+		if(cmd==CMD_PROCESS_SERVICE_CHECK_RESULT){
+			printf("<OPTION VALUE=%d SELECTED>OK\n",STATE_OK);
+			printf("<OPTION VALUE=%d>WARNING\n",STATE_WARNING);
+			printf("<OPTION VALUE=%d>UNKNOWN\n",STATE_UNKNOWN);
+			printf("<OPTION VALUE=%d>CRITICAL\n",STATE_CRITICAL);
+		        }
+		else{
+			printf("<OPTION VALUE=0 SELECTED>UP\n");
+			printf("<OPTION VALUE=1>DOWN\n");
+			printf("<OPTION VALUE=2>UNREACHABLE\n");
+		        }
+		printf("</SELECT>\n");
+		printf("</b></td></tr>\n");
+		printf("<tr><td CLASS='optBoxRequiredItem'>Check Output:</td><td><b>");
+		printf("<INPUT TYPE='TEXT' NAME='plugin_output' VALUE=''>");
+		printf("</b></td></tr>\n");
+		printf("<tr><td CLASS='optBoxItem'>Performance Data:</td><td><b>");
+		printf("<INPUT TYPE='TEXT' NAME='performance_data' VALUE=''>");
+		printf("</b></td></tr>\n");
+		break;
+		
+	case CMD_SCHEDULE_HOST_DOWNTIME:
+	case CMD_SCHEDULE_SVC_DOWNTIME:
+
+		printf("<tr><td CLASS='optBoxRequiredItem'>Host Name:</td><td><b>");
+		printf("<INPUT TYPE='TEXT' NAME='host' VALUE='%s'>",host_name);
+		printf("</b></td></tr>\n");
+		if(cmd==CMD_SCHEDULE_SVC_DOWNTIME){
+			printf("<tr><td CLASS='optBoxRequiredItem'>Service:</td><td><b>");
+			printf("<INPUT TYPE='TEXT' NAME='service' VALUE='%s'>",service_desc);
+		        }
+		printf("<tr><td CLASS='optBoxRequiredItem'>Author (Your Name):</td><td><b>");
+		printf("<INPUT TYPE='TEXT' NAME='com_author' VALUE='%s'>",comment_author);
+		printf("</b></td></tr>\n");
+		printf("<tr><td CLASS='optBoxRequiredItem'>Comment:</td><td><b>");
+		printf("<INPUT TYPE='TEXT' NAME='com_data' VALUE='%s' SIZE=40>",comment_data);
+		printf("</b></td></tr>\n");
+
+		printf("<tr><td CLASS='optBoxItem'><br></td></tr>\n");
+
+		printf("<tr><td CLASS='optBoxItem'>Triggered By:</td><td>\n");
+		printf("<select name='trigger'>\n");
+		printf("<option value='0'>N/A\n");
+
+		/* read scheduled downtime */
+		read_downtime_data(get_cgi_config_location());
+		for(temp_downtime=scheduled_downtime_list;temp_downtime!=NULL;temp_downtime=temp_downtime->next){
+			if(temp_downtime->type!=HOST_DOWNTIME)
+				continue;
+			printf("<option value='%lu'>",temp_downtime->downtime_id);
+			get_time_string(&temp_downtime->start_time,start_time,sizeof(start_time),SHORT_DATE_TIME);
+			printf("ID: %lu, Host '%s' starting @ %s\n",temp_downtime->downtime_id,temp_downtime->host_name,start_time);
+		        }
+		for(temp_downtime=scheduled_downtime_list;temp_downtime!=NULL;temp_downtime=temp_downtime->next){
+			if(temp_downtime->type!=SERVICE_DOWNTIME)
+				continue;
+			printf("<option value='%lu'>",temp_downtime->downtime_id);
+			get_time_string(&temp_downtime->start_time,start_time,sizeof(start_time),SHORT_DATE_TIME);
+			printf("ID: %lu, Service '%s' on host '%s' starting @ %s \n",temp_downtime->downtime_id,temp_downtime->service_description,temp_downtime->host_name,start_time);
+		        }
+
+		printf("</select>\n");
+		printf("</td></tr>\n");
+
+		printf("<tr><td CLASS='optBoxItem'><br></td></tr>\n");
+
+		time(&t);
+		get_time_string(&t,buffer,sizeof(buffer)-1,SHORT_DATE_TIME);
+		printf("<tr><td CLASS='optBoxRequiredItem'>Start Time:</td><td><b>");
+		printf("<INPUT TYPE='TEXT' NAME='start_time' VALUE='%s'>",buffer);
+		printf("</b></td></tr>\n");
+		t+=(unsigned long)7200;
+		get_time_string(&t,buffer,sizeof(buffer)-1,SHORT_DATE_TIME);
+		printf("<tr><td CLASS='optBoxRequiredItem'>End Time:</td><td><b>");
+		printf("<INPUT TYPE='TEXT' NAME='end_time' VALUE='%s'>",buffer);
+		printf("</b></td></tr>\n");
+		printf("<tr><td CLASS='optBoxItem'>Type:</td><td><b>");
+		printf("<SELECT NAME='fixed'>");
+		printf("<OPTION VALUE=1>Fixed\n");
+		printf("<OPTION VALUE=0>Flexible\n");
+		printf("</SELECT>\n");
+		printf("</b></td></tr>\n");
+
+		printf("<tr><td CLASS='optBoxItem'>If Flexible, Duration:</td><td>");
+		printf("<table border=0><tr>\n");
+		printf("<td align=right><INPUT TYPE='TEXT' NAME='hours' VALUE='2' SIZE=2 MAXLENGTH=2></td>\n");
+		printf("<td align=left>Hours</td>\n");
+		printf("<td align=right><INPUT TYPE='TEXT' NAME='minutes' VALUE='0' SIZE=2 MAXLENGTH=2></td>\n");
+		printf("<td align=left>Minutes</td>\n");
+		printf("</tr></table>\n");
+		printf("</td></tr>\n");
+
+		printf("<tr><td CLASS='optBoxItem'><br></td></tr>\n");
+
+		if(cmd==CMD_SCHEDULE_HOST_DOWNTIME){
+			printf("<tr><td CLASS='optBoxItem'>Child Hosts:</td><td><b>");
+			printf("<SELECT name='childoptions'>");
+			printf("<option value='0'>Do nothing with child hosts\n");
+			printf("<option value='1'>Schedule triggered downtime for all child hosts\n");
+			printf("<option value='2'>Schedule non-triggered downtime for all child hosts\n");
+			printf("</SELECT>\n");
+			printf("</b></td></tr>\n");
+		        }
+
+		printf("<tr><td CLASS='optBoxItem'><br></td></tr>\n");
+
+		break;
+
+	case CMD_ENABLE_HOSTGROUP_SVC_NOTIFICATIONS:
+	case CMD_DISABLE_HOSTGROUP_SVC_NOTIFICATIONS:
+	case CMD_ENABLE_HOSTGROUP_HOST_NOTIFICATIONS:
+	case CMD_DISABLE_HOSTGROUP_HOST_NOTIFICATIONS:
+	case CMD_ENABLE_HOSTGROUP_SVC_CHECKS:
+	case CMD_DISABLE_HOSTGROUP_SVC_CHECKS:
+		printf("<tr><td CLASS='optBoxRequiredItem'>Hostgroup Name:</td><td><b>");
+		printf("<INPUT TYPE='TEXT' NAME='hostgroup' VALUE='%s'>",hostgroup_name);
+		printf("</b></td></tr>\n");
+		if(cmd==CMD_ENABLE_HOSTGROUP_SVC_CHECKS || cmd==CMD_DISABLE_HOSTGROUP_SVC_CHECKS || cmd==CMD_ENABLE_HOSTGROUP_SVC_NOTIFICATIONS || cmd==CMD_DISABLE_HOSTGROUP_SVC_NOTIFICATIONS){
+			printf("<tr><td CLASS='optBoxItem'>%s For Hosts Too:</td><td><b>",(cmd==CMD_ENABLE_HOSTGROUP_SVC_CHECKS || cmd==CMD_ENABLE_HOSTGROUP_SVC_NOTIFICATIONS)?"Enable":"Disable");
+			printf("<INPUT TYPE='checkbox' NAME='ahas'>");
+			printf("</b></td></tr>\n");
+		        }
+		break;
+		
+	case CMD_ENABLE_SERVICEGROUP_SVC_NOTIFICATIONS:
+	case CMD_DISABLE_SERVICEGROUP_SVC_NOTIFICATIONS:
+	case CMD_ENABLE_SERVICEGROUP_HOST_NOTIFICATIONS:
+	case CMD_DISABLE_SERVICEGROUP_HOST_NOTIFICATIONS:
+	case CMD_ENABLE_SERVICEGROUP_SVC_CHECKS:
+	case CMD_DISABLE_SERVICEGROUP_SVC_CHECKS:
+		printf("<tr><td CLASS='optBoxRequiredItem'>Servicegroup Name:</td><td><b>");
+		printf("<INPUT TYPE='TEXT' NAME='servicegroup' VALUE='%s'>",servicegroup_name);
+		printf("</b></td></tr>\n");
+		if(cmd==CMD_ENABLE_SERVICEGROUP_SVC_CHECKS || cmd==CMD_DISABLE_SERVICEGROUP_SVC_CHECKS || cmd==CMD_ENABLE_SERVICEGROUP_SVC_NOTIFICATIONS || cmd==CMD_DISABLE_SERVICEGROUP_SVC_NOTIFICATIONS){
+			printf("<tr><td CLASS='optBoxItem'>%s For Hosts Too:</td><td><b>",(cmd==CMD_ENABLE_SERVICEGROUP_SVC_CHECKS || cmd==CMD_ENABLE_SERVICEGROUP_SVC_NOTIFICATIONS)?"Enable":"Disable");
+			printf("<INPUT TYPE='checkbox' NAME='ahas'>");
+			printf("</b></td></tr>\n");
+		        }
+		break;
+		
+	case CMD_DEL_HOST_DOWNTIME:
+	case CMD_DEL_SVC_DOWNTIME:
+		printf("<tr><td CLASS='optBoxRequiredItem'>Scheduled Downtime ID:</td><td><b>");
+		printf("<INPUT TYPE='TEXT' NAME='down_id' VALUE='%lu'>",downtime_id);
+		printf("</b></td></tr>\n");
+		break;
+
+
+	case CMD_SCHEDULE_HOSTGROUP_HOST_DOWNTIME:
+	case CMD_SCHEDULE_HOSTGROUP_SVC_DOWNTIME:
+	case CMD_SCHEDULE_SERVICEGROUP_HOST_DOWNTIME:
+	case CMD_SCHEDULE_SERVICEGROUP_SVC_DOWNTIME:
+
+		if(cmd==CMD_SCHEDULE_HOSTGROUP_HOST_DOWNTIME || cmd==CMD_SCHEDULE_HOSTGROUP_SVC_DOWNTIME){
+			printf("<tr><td CLASS='optBoxRequiredItem'>Hostgroup Name:</td><td><b>");
+			printf("<INPUT TYPE='TEXT' NAME='hostgroup' VALUE='%s'>",hostgroup_name);
+			printf("</b></td></tr>\n");
+		        }
+		else{
+			printf("<tr><td CLASS='optBoxRequiredItem'>Servicegroup Name:</td><td><b>");
+			printf("<INPUT TYPE='TEXT' NAME='servicegroup' VALUE='%s'>",servicegroup_name);
+			printf("</b></td></tr>\n");
+		        }
+		printf("<tr><td CLASS='optBoxRequiredItem'>Author (Your Name):</td><td><b>");
+		printf("<INPUT TYPE='TEXT' NAME='com_author' VALUE='%s'>",comment_author);
+		printf("</b></td></tr>\n");
+		printf("<tr><td CLASS='optBoxRequiredItem'>Comment:</td><td><b>");
+		printf("<INPUT TYPE='TEXT' NAME='com_data' VALUE='%s' SIZE=40>",comment_data);
+		printf("</b></td></tr>\n");
+		time(&t);
+		get_time_string(&t,buffer,sizeof(buffer)-1,SHORT_DATE_TIME);
+		printf("<tr><td CLASS='optBoxRequiredItem'>Start Time:</td><td><b>");
+		printf("<INPUT TYPE='TEXT' NAME='start_time' VALUE='%s'>",buffer);
+		printf("</b></td></tr>\n");
+		t+=(unsigned long)7200;
+		get_time_string(&t,buffer,sizeof(buffer)-1,SHORT_DATE_TIME);
+		printf("<tr><td CLASS='optBoxRequiredItem'>End Time:</td><td><b>");
+		printf("<INPUT TYPE='TEXT' NAME='end_time' VALUE='%s'>",buffer);
+		printf("</b></td></tr>\n");
+		printf("<tr><td CLASS='optBoxItem'>Type:</td><td><b>");
+		printf("<SELECT NAME='fixed'>");
+		printf("<OPTION VALUE=1>Fixed\n");
+		printf("<OPTION VALUE=0>Flexible\n");
+		printf("</SELECT>\n");
+		printf("</b></td></tr>\n");
+
+		printf("<tr><td CLASS='optBoxItem'>If Flexible, Duration:</td><td>");
+		printf("<table border=0><tr>\n");
+		printf("<td align=right><INPUT TYPE='TEXT' NAME='hours' VALUE='2' SIZE=2 MAXLENGTH=2></td>\n");
+		printf("<td align=left>Hours</td>\n");
+		printf("<td align=right><INPUT TYPE='TEXT' NAME='minutes' VALUE='0' SIZE=2 MAXLENGTH=2></td>\n");
+		printf("<td align=left>Minutes</td>\n");
+		printf("</tr></table>\n");
+		printf("</td></tr>\n");
+		if(cmd==CMD_SCHEDULE_HOSTGROUP_SVC_DOWNTIME || cmd==CMD_SCHEDULE_SERVICEGROUP_SVC_DOWNTIME){
+			printf("<tr><td CLASS='optBoxItem'>Schedule Downtime For Hosts Too:</td><td><b>");
+			printf("<INPUT TYPE='checkbox' NAME='ahas'>");
+			printf("</b></td></tr>\n");
+		        }
+		break;
+
+	default:
+		printf("<tr><td CLASS='optBoxItem'>This should not be happening... :-(</td><td></td></tr>\n");
+	        }
+
+
+	printf("<tr><td CLASS='optBoxItem' COLSPAN=2></td></tr>\n");
+	printf("<tr><td CLASS='optBoxItem'></td><td CLASS='optBoxItem'><INPUT TYPE='submit' NAME='btnSubmit' VALUE='Commit'> <INPUT TYPE='reset' VALUE='Reset'></td></tr>\n");
+
+	printf("</table>\n");
+	printf("</form>\n");	
+	printf("</td>\n");
+	printf("</tr>\n");
+	printf("</table>\n");
+
+	printf("</td>\n");
+	printf("<td align=center valign=top width=50%%>\n");
+
+	/* show information about the command... */
+	show_command_help(cmd);
+	
+	printf("</td>\n");
+	printf("</tr>\n");
+	printf("</table>\n");
+
+	printf("</div>\n");
+	printf("</p>\n");
+
+
+	printf("<P><DIV CLASS='infoMessage'>Please enter all required information before committing the command.<br>Required fields are marked in red.<br>Failure to supply all required values will result in an error.</DIV></P>");
+
+	return;
+        }
+
+
+void commit_command_data(int cmd){
+	char *error_string=NULL;
+	int result=OK;
+	int authorized=FALSE;
+	service *temp_service;
+	host *temp_host;
+	hostgroup *temp_hostgroup;
+	comment *temp_comment;
+	scheduled_downtime *temp_downtime;
+	servicegroup *temp_servicegroup=NULL;
+
+
+	/* get authentication information */
+	get_authentication_information(&current_authdata);
+
+	switch(cmd){
+	case CMD_ADD_HOST_COMMENT:
+	case CMD_ACKNOWLEDGE_HOST_PROBLEM:
+
+		/* make sure we have author name, and comment data... */
+		if(!strcmp(comment_author,"")){
+			if(!error_string)
+				error_string=strdup("Author was not entered");
+			}
+		if(!strcmp(comment_data,"")){
+			if(!error_string)
+				error_string=strdup("Comment was not entered");
+			}
+
+		/* clean up the comment data */
+		clean_comment_data(comment_author);
+		clean_comment_data(comment_data);
+
+		/* see if the user is authorized to issue a command... */
+		temp_host=find_host(host_name);
+		if(is_authorized_for_host_commands(temp_host,&current_authdata)==TRUE)
+			authorized=TRUE;
+		break;
+		
+	case CMD_ADD_SVC_COMMENT:
+	case CMD_ACKNOWLEDGE_SVC_PROBLEM:
+
+		/* make sure we have author name, and comment data... */
+		if(!strcmp(comment_author,"")){
+			if(!error_string)
+				error_string=strdup("Author was not entered");
+			}
+		if(!strcmp(comment_data,"")){
+			if(!error_string)
+				error_string=strdup("Comment was not entered");
+			}
+
+		/* clean up the comment data */
+		clean_comment_data(comment_author);
+		clean_comment_data(comment_data);
+
+		/* see if the user is authorized to issue a command... */
+		temp_service=find_service(host_name,service_desc);
+		if(is_authorized_for_service_commands(temp_service,&current_authdata)==TRUE)
+			authorized=TRUE;
+		break;
+
+	case CMD_DEL_HOST_COMMENT:
+	case CMD_DEL_SVC_COMMENT:
+
+		/* check the sanity of the comment id */
+		if(comment_id==0){
+			if(!error_string)
+				error_string=strdup("Comment id cannot be 0");
+			}
+
+		/* read comments */
+		read_comment_data(get_cgi_config_location());
+
+		/* find the comment */
+		if(cmd==CMD_DEL_HOST_COMMENT)
+			temp_comment=find_host_comment(comment_id);
+		else
+			temp_comment=find_service_comment(comment_id);
+
+		/* see if the user is authorized to issue a command... */
+		if(cmd==CMD_DEL_HOST_COMMENT && temp_comment!=NULL){
+			temp_host=find_host(temp_comment->host_name);
+			if(is_authorized_for_host_commands(temp_host,&current_authdata)==TRUE)
+				authorized=TRUE;
+		        }
+		if(cmd==CMD_DEL_SVC_COMMENT && temp_comment!=NULL){
+			temp_service=find_service(temp_comment->host_name,temp_comment->service_description);
+			if(is_authorized_for_service_commands(temp_service,&current_authdata)==TRUE)
+				authorized=TRUE;
+		        }
+
+		/* free comment data */
+		free_comment_data();
+
+		break;
+		
+	case CMD_DEL_HOST_DOWNTIME:
+	case CMD_DEL_SVC_DOWNTIME:
+
+		/* check the sanity of the downtime id */
+		if(downtime_id==0){
+			if(!error_string)
+				error_string=strdup("Downtime id cannot be 0");
+			}
+
+		/* read scheduled downtime */
+		read_downtime_data(get_cgi_config_location());
+
+		/* find the downtime entry */
+		if(cmd==CMD_DEL_HOST_DOWNTIME)
+			temp_downtime=find_host_downtime(downtime_id);
+		else
+			temp_downtime=find_service_downtime(downtime_id);
+
+		/* see if the user is authorized to issue a command... */
+		if(cmd==CMD_DEL_HOST_DOWNTIME && temp_downtime!=NULL){
+			temp_host=find_host(temp_downtime->host_name);
+			if(is_authorized_for_host_commands(temp_host,&current_authdata)==TRUE)
+				authorized=TRUE;
+		        }
+		if(cmd==CMD_DEL_SVC_DOWNTIME && temp_downtime!=NULL){
+			temp_service=find_service(temp_downtime->host_name,temp_downtime->service_description);
+			if(is_authorized_for_service_commands(temp_service,&current_authdata)==TRUE)
+				authorized=TRUE;
+		        }
+
+		/* free downtime data */
+		free_downtime_data();
+
+		break;
+		
+	case CMD_SCHEDULE_SVC_CHECK:
+	case CMD_ENABLE_SVC_CHECK:
+	case CMD_DISABLE_SVC_CHECK:
+	case CMD_DEL_ALL_SVC_COMMENTS:
+	case CMD_ENABLE_SVC_NOTIFICATIONS:
+	case CMD_DISABLE_SVC_NOTIFICATIONS:
+	case CMD_ENABLE_PASSIVE_SVC_CHECKS:
+	case CMD_DISABLE_PASSIVE_SVC_CHECKS:
+	case CMD_ENABLE_SVC_EVENT_HANDLER:
+	case CMD_DISABLE_SVC_EVENT_HANDLER:
+	case CMD_REMOVE_SVC_ACKNOWLEDGEMENT:
+	case CMD_PROCESS_SERVICE_CHECK_RESULT:
+	case CMD_SCHEDULE_SVC_DOWNTIME:
+	case CMD_DELAY_SVC_NOTIFICATION:
+	case CMD_ENABLE_SVC_FLAP_DETECTION:
+	case CMD_DISABLE_SVC_FLAP_DETECTION:
+	case CMD_START_OBSESSING_OVER_SVC:
+	case CMD_STOP_OBSESSING_OVER_SVC:
+
+		/* make sure we have author name and comment data... */
+		if(cmd==CMD_SCHEDULE_SVC_DOWNTIME){
+			if(!strcmp(comment_data,"")){
+				if(!error_string)
+					error_string=strdup("Comment was not entered");
+				}
+			else if(!strcmp(comment_author,"")){
+				if(!error_string)
+					error_string=strdup("Author was not entered");
+				}
+			}
+
+		/* see if the user is authorized to issue a command... */
+		temp_service=find_service(host_name,service_desc);
+		if(is_authorized_for_service_commands(temp_service,&current_authdata)==TRUE)
+			authorized=TRUE;
+
+		/* make sure we have passive check info (if necessary) */
+		if(cmd==CMD_PROCESS_SERVICE_CHECK_RESULT && !strcmp(plugin_output,"")){
+			if(!error_string)
+				error_string=strdup("Plugin output cannot be blank");
+			}
+
+		/* make sure we have a notification delay (if necessary) */
+		if(cmd==CMD_DELAY_SVC_NOTIFICATION && notification_delay<=0){
+			if(!error_string)
+				error_string=strdup("Notification delay must be greater than 0");
+			}
+
+		/* clean up the comment data if scheduling downtime */
+		if(cmd==CMD_SCHEDULE_SVC_DOWNTIME){
+			clean_comment_data(comment_author);
+			clean_comment_data(comment_data);
+		        }
+
+		/* make sure we have check time (if necessary) */
+		if(cmd==CMD_SCHEDULE_SVC_CHECK && start_time==(time_t)0){
+			if(!error_string)
+				error_string=strdup("Start time must be non-zero");
+			}
+
+		/* make sure we have start/end times for downtime (if necessary) */
+		if(cmd==CMD_SCHEDULE_SVC_DOWNTIME && (start_time==(time_t)0 || end_time==(time_t)0 || end_time<start_time)){
+			if(!error_string)
+				error_string=strdup("Start or end time not valid");
+			}
+
+		break;
+		
+	case CMD_ENABLE_NOTIFICATIONS:
+	case CMD_DISABLE_NOTIFICATIONS:
+	case CMD_SHUTDOWN_PROCESS:
+	case CMD_RESTART_PROCESS:
+	case CMD_START_EXECUTING_SVC_CHECKS:
+	case CMD_STOP_EXECUTING_SVC_CHECKS:
+	case CMD_START_ACCEPTING_PASSIVE_SVC_CHECKS:
+	case CMD_STOP_ACCEPTING_PASSIVE_SVC_CHECKS:
+	case CMD_ENABLE_EVENT_HANDLERS:
+	case CMD_DISABLE_EVENT_HANDLERS:
+	case CMD_START_OBSESSING_OVER_SVC_CHECKS:
+	case CMD_STOP_OBSESSING_OVER_SVC_CHECKS:
+	case CMD_ENABLE_FLAP_DETECTION:
+	case CMD_DISABLE_FLAP_DETECTION:
+	case CMD_ENABLE_FAILURE_PREDICTION:
+	case CMD_DISABLE_FAILURE_PREDICTION:
+	case CMD_ENABLE_PERFORMANCE_DATA:
+	case CMD_DISABLE_PERFORMANCE_DATA:
+	case CMD_START_EXECUTING_HOST_CHECKS:
+	case CMD_STOP_EXECUTING_HOST_CHECKS:
+	case CMD_START_ACCEPTING_PASSIVE_HOST_CHECKS:
+	case CMD_STOP_ACCEPTING_PASSIVE_HOST_CHECKS:
+	case CMD_START_OBSESSING_OVER_HOST_CHECKS:
+	case CMD_STOP_OBSESSING_OVER_HOST_CHECKS:
+
+		/* see if the user is authorized to issue a command... */
+		if(is_authorized_for_system_commands(&current_authdata)==TRUE)
+			authorized=TRUE;
+		break;
+		
+	case CMD_ENABLE_HOST_SVC_CHECKS:
+	case CMD_DISABLE_HOST_SVC_CHECKS:
+	case CMD_DEL_ALL_HOST_COMMENTS:
+	case CMD_SCHEDULE_HOST_SVC_CHECKS:
+	case CMD_ENABLE_HOST_NOTIFICATIONS:
+	case CMD_DISABLE_HOST_NOTIFICATIONS:
+	case CMD_ENABLE_ALL_NOTIFICATIONS_BEYOND_HOST:
+	case CMD_DISABLE_ALL_NOTIFICATIONS_BEYOND_HOST:
+	case CMD_ENABLE_HOST_SVC_NOTIFICATIONS:
+	case CMD_DISABLE_HOST_SVC_NOTIFICATIONS:
+	case CMD_ENABLE_HOST_EVENT_HANDLER:
+	case CMD_DISABLE_HOST_EVENT_HANDLER:
+	case CMD_ENABLE_HOST_CHECK:
+	case CMD_DISABLE_HOST_CHECK:
+	case CMD_REMOVE_HOST_ACKNOWLEDGEMENT:
+	case CMD_SCHEDULE_HOST_DOWNTIME:
+	case CMD_DELAY_HOST_NOTIFICATION:
+	case CMD_ENABLE_HOST_FLAP_DETECTION:
+	case CMD_DISABLE_HOST_FLAP_DETECTION:
+	case CMD_PROCESS_HOST_CHECK_RESULT:
+	case CMD_ENABLE_PASSIVE_HOST_CHECKS:
+	case CMD_DISABLE_PASSIVE_HOST_CHECKS:
+	case CMD_SCHEDULE_HOST_CHECK:
+	case CMD_START_OBSESSING_OVER_HOST:
+	case CMD_STOP_OBSESSING_OVER_HOST:
+
+		/* make sure we have author name and comment data... */
+		if(cmd==CMD_SCHEDULE_HOST_DOWNTIME){
+			if(!strcmp(comment_data,"")){
+				if(!error_string)
+					error_string=strdup("Comment was not entered");
+				}
+			else if(!strcmp(comment_author,"")){
+				if(!error_string)
+					error_string=strdup("Author was not entered");
+				}
+			}
+
+		/* see if the user is authorized to issue a command... */
+		temp_host=find_host(host_name);
+		if(is_authorized_for_host_commands(temp_host,&current_authdata)==TRUE)
+			authorized=TRUE;
+
+		/* clean up the comment data if scheduling downtime */
+		if(cmd==CMD_SCHEDULE_HOST_DOWNTIME){
+			clean_comment_data(comment_author);
+			clean_comment_data(comment_data);
+		        }
+
+		/* make sure we have a notification delay (if necessary) */
+		if(cmd==CMD_DELAY_HOST_NOTIFICATION && notification_delay<=0){
+			if(!error_string)
+				error_string=strdup("Notification delay must be greater than 0");
+			}
+
+		/* make sure we have start/end times for downtime (if necessary) */
+		if(cmd==CMD_SCHEDULE_HOST_DOWNTIME && (start_time==(time_t)0 || end_time==(time_t)0 || start_time>end_time)){
+			if(!error_string)
+				error_string=strdup("Start or end time not valid");
+			}
+
+		/* make sure we have check time (if necessary) */
+		if((cmd==CMD_SCHEDULE_HOST_CHECK || cmd==CMD_SCHEDULE_HOST_SVC_CHECKS)&& start_time==(time_t)0){
+			if(!error_string)
+				error_string=strdup("Start time must be non-zero");
+			}
+
+		/* make sure we have passive check info (if necessary) */
+		if(cmd==CMD_PROCESS_HOST_CHECK_RESULT && !strcmp(plugin_output,"")){
+			if(!error_string)
+				error_string=strdup("Plugin output cannot be blank");
+			}
+
+		break;
+
+	case CMD_ENABLE_HOSTGROUP_SVC_NOTIFICATIONS:
+	case CMD_DISABLE_HOSTGROUP_SVC_NOTIFICATIONS:
+	case CMD_ENABLE_HOSTGROUP_HOST_NOTIFICATIONS:
+	case CMD_DISABLE_HOSTGROUP_HOST_NOTIFICATIONS:
+	case CMD_ENABLE_HOSTGROUP_SVC_CHECKS:
+	case CMD_DISABLE_HOSTGROUP_SVC_CHECKS:
+	case CMD_SCHEDULE_HOSTGROUP_HOST_DOWNTIME:
+	case CMD_SCHEDULE_HOSTGROUP_SVC_DOWNTIME:
+
+		/* make sure we have author and comment data */
+		if(cmd==CMD_SCHEDULE_HOSTGROUP_HOST_DOWNTIME || cmd==CMD_SCHEDULE_HOSTGROUP_SVC_DOWNTIME) {
+			if(!strcmp(comment_data,"")){
+				if(!error_string)
+					error_string=strdup("Comment was not entered");
+				}
+			else if(!strcmp(comment_author,"")){
+				if(!error_string)
+					error_string=strdup("Author was not entered");
+				}
+			}
+
+		/* make sure we have start/end times for downtime */
+		if((cmd==CMD_SCHEDULE_HOSTGROUP_HOST_DOWNTIME || cmd==CMD_SCHEDULE_HOSTGROUP_SVC_DOWNTIME) && (start_time==(time_t)0 || end_time==(time_t)0 || start_time>end_time)){
+			if(!error_string)
+				error_string=strdup("Start or end time not valid");
+			}
+
+		/* see if the user is authorized to issue a command... */
+		temp_hostgroup=find_hostgroup(hostgroup_name);
+		if(is_authorized_for_hostgroup(temp_hostgroup,&current_authdata)==TRUE)
+			authorized=TRUE;
+
+		/* clean up the comment data if scheduling downtime */
+		if(cmd==CMD_SCHEDULE_HOSTGROUP_HOST_DOWNTIME || cmd==CMD_SCHEDULE_HOSTGROUP_SVC_DOWNTIME){
+			clean_comment_data(comment_author);
+			clean_comment_data(comment_data);
+		        }
+
+		break;
+
+	case CMD_ENABLE_SERVICEGROUP_SVC_NOTIFICATIONS:
+	case CMD_DISABLE_SERVICEGROUP_SVC_NOTIFICATIONS:
+	case CMD_ENABLE_SERVICEGROUP_HOST_NOTIFICATIONS:
+	case CMD_DISABLE_SERVICEGROUP_HOST_NOTIFICATIONS:
+	case CMD_ENABLE_SERVICEGROUP_SVC_CHECKS:
+	case CMD_DISABLE_SERVICEGROUP_SVC_CHECKS:
+	case CMD_SCHEDULE_SERVICEGROUP_HOST_DOWNTIME:
+	case CMD_SCHEDULE_SERVICEGROUP_SVC_DOWNTIME:
+
+		/* make sure we have author and comment data */
+		if(cmd==CMD_SCHEDULE_SERVICEGROUP_HOST_DOWNTIME || cmd==CMD_SCHEDULE_SERVICEGROUP_SVC_DOWNTIME) {
+			if(!strcmp(comment_data,"")){
+				if(!error_string)
+					error_string=strdup("Comment was not entered");
+				}
+			else if(!strcmp(comment_author,"")){
+				if(!error_string)
+					error_string=strdup("Author was not entered");
+				}
+			}
+
+		/* make sure we have start/end times for downtime */
+		if((cmd==CMD_SCHEDULE_SERVICEGROUP_HOST_DOWNTIME || cmd==CMD_SCHEDULE_SERVICEGROUP_SVC_DOWNTIME) && (start_time==(time_t)0 || end_time==(time_t)0 || start_time>end_time)){
+			if(!error_string)
+				error_string=strdup("Start or end time not valid");
+			}
+
+		/* see if the user is authorized to issue a command... */
+
+		temp_servicegroup=find_servicegroup(servicegroup_name);
+		if(is_authorized_for_servicegroup(temp_servicegroup,&current_authdata)==TRUE)
+			authorized=TRUE;
+
+		break;
+
+	default:
+		if(!error_string)error_string=strdup("An error occurred while processing your command!");
+	        }
+
+
+	/* to be safe, we are going to REQUIRE that the authentication functionality is enabled... */
+	if(use_authentication==FALSE){
+		if(content_type==WML_CONTENT)
+			printf("<p>Error: Authentication is not enabled!</p>\n");
+		else{
+			printf("<P>\n");
+			printf("<DIV CLASS='errorMessage'>Sorry Dave, I can't let you do that...</DIV><br>");
+			printf("<DIV CLASS='errorDescription'>");
+			printf("It seems that you have chosen to not use the authentication functionality of the CGIs.<br><br>");
+			printf("I don't want to be personally responsible for what may happen as a result of allowing unauthorized users to issue commands to Nagios,");
+			printf("so you'll have to disable this safeguard if you are really stubborn and want to invite trouble.<br><br>");
+			printf("<strong>Read the section on CGI authentication in the HTML documentation to learn how you can enable authentication and why you should want to.</strong>\n");
+			printf("</DIV>\n");
+			printf("</P>\n");
+		        }
+	        }
+
+	/* the user is not authorized to issue the given command */
+	else if(authorized==FALSE){
+		if(content_type==WML_CONTENT)
+			printf("<p>Error: You're not authorized to commit that command!</p>\n");
+		else{
+			printf("<P><DIV CLASS='errorMessage'>Sorry, but you are not authorized to commit the specified command.</DIV></P>\n");
+			printf("<P><DIV CLASS='errorDescription'>Read the section of the documentation that deals with authentication and authorization in the CGIs for more information.<BR><BR>\n");
+			printf("<A HREF='javascript:window.history.go(-2)'>Return from whence you came</A></DIV></P>\n");
+		        }
+	        }
+
+	/* some error occurred (data was probably missing) */
+	else if(error_string){
+		if(content_type==WML_CONTENT)
+			printf("<p>%s</p>\n", error_string);
+		else{
+			printf("<P><DIV CLASS='errorMessage'>%s</DIV></P>\n", error_string);
+			free(error_string);
+			printf("<P><DIV CLASS='errorDescription'>Go <A HREF='javascript:window.history.go(-1)'>back</A> and verify that you entered all required information correctly.<BR>\n");
+			printf("<A HREF='javascript:window.history.go(-2)'>Return from whence you came</A></DIV></P>\n");
+		        }
+	        }
+
+	/* if Nagios isn't checking external commands, don't do anything... */
+	else if(check_external_commands==FALSE){
+		if(content_type==WML_CONTENT)
+			printf("<p>Error: Nagios is not checking external commands!</p>\n");
+		else{
+			printf("<P><DIV CLASS='errorMessage'>Sorry, but Nagios is currently not checking for external commands, so your command will not be committed!</DIV></P>\n");
+			printf("<P><DIV CLASS='errorDescription'>Read the documentation for information on how to enable external commands...<BR><BR>\n");
+			printf("<A HREF='javascript:window.history.go(-2)'>Return from whence you came</A></DIV></P>\n");
+		        }
+	        }
+	
+	/* everything looks okay, so let's go ahead and commit the command... */
+	else{
+
+		/* commit the command */
+		result=commit_command(cmd);
+
+		if(result==OK){
+			if(content_type==WML_CONTENT)
+				printf("<p>Your command was submitted sucessfully...</p>\n");
+			else{
+				printf("<P><DIV CLASS='infoMessage'>Your command request was successfully submitted to Nagios for processing.<BR><BR>\n");
+				printf("Note: It may take a while before the command is actually processed.<BR><BR>\n");
+				printf("<A HREF='javascript:window.history.go(-2)'>Done</A></DIV></P>");
+			        }
+		        }
+		else{
+			if(content_type==WML_CONTENT)
+				printf("<p>An error occurred while committing your command!</p>\n");
+			else{
+				printf("<P><DIV CLASS='errorMessage'>An error occurred while attempting to commit your command for processing.<BR><BR>\n");
+				printf("<A HREF='javascript:window.history.go(-2)'>Return from whence you came</A></DIV></P>\n");
+			        }
+		        }
+	        }
+
+	return;
+        }
+
+
+/* commits a command for processing */
+int commit_command(int cmd){
+	char command_buffer[MAX_INPUT_BUFFER];
+	time_t current_time;
+	time_t scheduled_time;
+	time_t notification_time;
+	int result;
+
+	/* get the current time */
+	time(&current_time);
+
+	/* get the scheduled time */
+	scheduled_time=current_time+(schedule_delay*60);
+
+	/* get the notification time */
+	notification_time=current_time+(notification_delay*60);
+
+	/* decide how to form the command line... */
+	switch(cmd){
+
+	case CMD_ADD_HOST_COMMENT:
+		snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] ADD_HOST_COMMENT;%s;%d;%s;%s\n",current_time,host_name,(persistent_comment==TRUE)?1:0,comment_author,comment_data);
+		break;
+		
+	case CMD_ADD_SVC_COMMENT:
+		snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] ADD_SVC_COMMENT;%s;%s;%d;%s;%s\n",current_time,host_name,service_desc,(persistent_comment==TRUE)?1:0,comment_author,comment_data);
+		break;
+
+	case CMD_DEL_HOST_COMMENT:
+		snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] DEL_HOST_COMMENT;%lu\n",current_time,comment_id);
+		break;
+		
+	case CMD_DEL_SVC_COMMENT:
+		snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] DEL_SVC_COMMENT;%lu\n",current_time,comment_id);
+		break;
+		
+	case CMD_DELAY_HOST_NOTIFICATION:
+		snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] DELAY_HOST_NOTIFICATION;%s;%lu\n",current_time,host_name,notification_time);
+		break;
+
+	case CMD_DELAY_SVC_NOTIFICATION:
+		snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] DELAY_SVC_NOTIFICATION;%s;%s;%lu\n",current_time,host_name,service_desc,notification_time);
+		break;
+
+	case CMD_SCHEDULE_SVC_CHECK:
+		snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] SCHEDULE_%sSVC_CHECK;%s;%s;%lu\n",current_time,(force_check==TRUE)?"FORCED_":"",host_name,service_desc,start_time);
+		break;
+
+	case CMD_ENABLE_SVC_CHECK:
+	case CMD_DISABLE_SVC_CHECK:
+		snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] %s_SVC_CHECK;%s;%s\n",current_time,(cmd==CMD_ENABLE_SVC_CHECK)?"ENABLE":"DISABLE",host_name,service_desc);
+		break;
+		
+	case CMD_DISABLE_NOTIFICATIONS:
+		snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] DISABLE_NOTIFICATIONS;%lu\n",current_time,scheduled_time);
+		break;
+		
+	case CMD_ENABLE_NOTIFICATIONS:
+		snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] ENABLE_NOTIFICATIONS;%lu\n",current_time,scheduled_time);
+		break;
+		
+	case CMD_SHUTDOWN_PROCESS:
+	case CMD_RESTART_PROCESS:
+		snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] %s_PROGRAM;%lu\n",current_time,(cmd==CMD_SHUTDOWN_PROCESS)?"SHUTDOWN":"RESTART",scheduled_time);
+		break;
+
+	case CMD_ENABLE_HOST_SVC_CHECKS:
+	case CMD_DISABLE_HOST_SVC_CHECKS:
+		if(affect_host_and_services==FALSE)
+			snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] %s_HOST_SVC_CHECKS;%s\n",current_time,(cmd==CMD_ENABLE_HOST_SVC_CHECKS)?"ENABLE":"DISABLE",host_name);
+		else
+			snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] %s_HOST_SVC_CHECKS;%s\n[%lu] %s_HOST_CHECK;%s\n",current_time,(cmd==CMD_ENABLE_HOST_SVC_CHECKS)?"ENABLE":"DISABLE",host_name,current_time,(cmd==CMD_ENABLE_HOST_SVC_CHECKS)?"ENABLE":"DISABLE",host_name);
+		break;
+		
+	case CMD_SCHEDULE_HOST_SVC_CHECKS:
+		snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] SCHEDULE_%sHOST_SVC_CHECKS;%s;%lu\n",current_time,(force_check==TRUE)?"FORCED_":"",host_name,scheduled_time);
+		break;
+
+	case CMD_DEL_ALL_HOST_COMMENTS:
+		snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] DEL_ALL_HOST_COMMENTS;%s\n",current_time,host_name);
+		break;
+		
+	case CMD_DEL_ALL_SVC_COMMENTS:
+		snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] DEL_ALL_SVC_COMMENTS;%s;%s\n",current_time,host_name,service_desc);
+		break;
+
+	case CMD_ENABLE_SVC_NOTIFICATIONS:
+	case CMD_DISABLE_SVC_NOTIFICATIONS:
+		snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] %s_SVC_NOTIFICATIONS;%s;%s\n",current_time,(cmd==CMD_ENABLE_SVC_NOTIFICATIONS)?"ENABLE":"DISABLE",host_name,service_desc);
+		break;
+		
+	case CMD_ENABLE_HOST_NOTIFICATIONS:
+	case CMD_DISABLE_HOST_NOTIFICATIONS:
+		if(propagate_to_children==TRUE)
+			snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] %s_HOST_AND_CHILD_NOTIFICATIONS;%s\n",current_time,(cmd==CMD_ENABLE_HOST_NOTIFICATIONS)?"ENABLE":"DISABLE",host_name);
+		else
+			snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] %s_HOST_NOTIFICATIONS;%s\n",current_time,(cmd==CMD_ENABLE_HOST_NOTIFICATIONS)?"ENABLE":"DISABLE",host_name);
+		break;
+		
+	case CMD_ENABLE_ALL_NOTIFICATIONS_BEYOND_HOST:
+	case CMD_DISABLE_ALL_NOTIFICATIONS_BEYOND_HOST:
+		snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] %s_ALL_NOTIFICATIONS_BEYOND_HOST;%s\n",current_time,(cmd==CMD_ENABLE_ALL_NOTIFICATIONS_BEYOND_HOST)?"ENABLE":"DISABLE",host_name);
+		break;
+		
+	case CMD_ENABLE_HOST_SVC_NOTIFICATIONS:
+	case CMD_DISABLE_HOST_SVC_NOTIFICATIONS:
+		if(affect_host_and_services==FALSE)
+			snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] %s_HOST_SVC_NOTIFICATIONS;%s\n",current_time,(cmd==CMD_ENABLE_HOST_SVC_NOTIFICATIONS)?"ENABLE":"DISABLE",host_name);
+		else
+			snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] %s_HOST_SVC_NOTIFICATIONS;%s\n[%lu] %s_HOST_NOTIFICATIONS;%s\n",current_time,(cmd==CMD_ENABLE_HOST_SVC_NOTIFICATIONS)?"ENABLE":"DISABLE",host_name,current_time,(cmd==CMD_ENABLE_HOST_SVC_NOTIFICATIONS)?"ENABLE":"DISABLE",host_name);
+		break;
+		
+	case CMD_ACKNOWLEDGE_HOST_PROBLEM:
+		snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] ACKNOWLEDGE_HOST_PROBLEM;%s;%d;%d;%d;%s;%s\n",current_time,host_name,(sticky_ack==TRUE)?ACKNOWLEDGEMENT_STICKY:ACKNOWLEDGEMENT_NORMAL,(send_notification==TRUE)?1:0,(persistent_comment==TRUE)?1:0,comment_author,comment_data);
+		break;
+		
+	case CMD_ACKNOWLEDGE_SVC_PROBLEM:
+		snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] ACKNOWLEDGE_SVC_PROBLEM;%s;%s;%d;%d;%d;%s;%s\n",current_time,host_name,service_desc,(sticky_ack==TRUE)?ACKNOWLEDGEMENT_STICKY:ACKNOWLEDGEMENT_NORMAL,(send_notification==TRUE)?1:0,(persistent_comment==TRUE)?1:0,comment_author,comment_data);
+		break;
+
+	case CMD_START_EXECUTING_SVC_CHECKS:
+	case CMD_STOP_EXECUTING_SVC_CHECKS:
+		snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] %s_EXECUTING_SVC_CHECKS;\n",current_time,(cmd==CMD_START_EXECUTING_SVC_CHECKS)?"START":"STOP");
+		break;
+
+	case CMD_START_ACCEPTING_PASSIVE_SVC_CHECKS:
+	case CMD_STOP_ACCEPTING_PASSIVE_SVC_CHECKS:
+		snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] %s_ACCEPTING_PASSIVE_SVC_CHECKS;\n",current_time,(cmd==CMD_START_ACCEPTING_PASSIVE_SVC_CHECKS)?"START":"STOP");
+		break;
+
+	case CMD_ENABLE_PASSIVE_SVC_CHECKS:
+	case CMD_DISABLE_PASSIVE_SVC_CHECKS:
+		snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] %s_PASSIVE_SVC_CHECKS;%s;%s\n",current_time,(cmd==CMD_ENABLE_PASSIVE_SVC_CHECKS)?"ENABLE":"DISABLE",host_name,service_desc);
+		break;
+		
+	case CMD_ENABLE_EVENT_HANDLERS:
+	case CMD_DISABLE_EVENT_HANDLERS:
+		snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] %s_EVENT_HANDLERS;\n",current_time,(cmd==CMD_ENABLE_EVENT_HANDLERS)?"ENABLE":"DISABLE");
+		break;
+
+	case CMD_ENABLE_SVC_EVENT_HANDLER:
+	case CMD_DISABLE_SVC_EVENT_HANDLER:
+		snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] %s_SVC_EVENT_HANDLER;%s;%s\n",current_time,(cmd==CMD_ENABLE_SVC_EVENT_HANDLER)?"ENABLE":"DISABLE",host_name,service_desc);
+		break;
+		
+	case CMD_ENABLE_HOST_EVENT_HANDLER:
+	case CMD_DISABLE_HOST_EVENT_HANDLER:
+		snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] %s_HOST_EVENT_HANDLER;%s\n",current_time,(cmd==CMD_ENABLE_HOST_EVENT_HANDLER)?"ENABLE":"DISABLE",host_name);
+		break;
+		
+	case CMD_ENABLE_HOST_CHECK:
+	case CMD_DISABLE_HOST_CHECK:
+		snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] %s_HOST_CHECK;%s\n",current_time,(cmd==CMD_ENABLE_HOST_CHECK)?"ENABLE":"DISABLE",host_name);
+		break;
+		
+	case CMD_START_OBSESSING_OVER_SVC_CHECKS:
+	case CMD_STOP_OBSESSING_OVER_SVC_CHECKS:
+		snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] %s_OBSESSING_OVER_SVC_CHECKS;\n",current_time,(cmd==CMD_START_OBSESSING_OVER_SVC_CHECKS)?"START":"STOP");
+		break;
+		
+	case CMD_REMOVE_HOST_ACKNOWLEDGEMENT:
+		snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] REMOVE_HOST_ACKNOWLEDGEMENT;%s\n",current_time,host_name);
+		break;
+		
+	case CMD_REMOVE_SVC_ACKNOWLEDGEMENT:
+		snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] REMOVE_SVC_ACKNOWLEDGEMENT;%s;%s\n",current_time,host_name,service_desc);
+		break;
+		
+	case CMD_PROCESS_SERVICE_CHECK_RESULT:
+		snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] PROCESS_SERVICE_CHECK_RESULT;%s;%s;%d;%s|%s\n",current_time,host_name,service_desc,plugin_state,plugin_output,performance_data);
+		break;
+		
+	case CMD_PROCESS_HOST_CHECK_RESULT:
+		snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] PROCESS_HOST_CHECK_RESULT;%s;%d;%s|%s\n",current_time,host_name,plugin_state,plugin_output,performance_data);
+		break;
+		
+	case CMD_SCHEDULE_HOST_DOWNTIME:
+		if(child_options==1)
+			snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] SCHEDULE_AND_PROPAGATE_TRIGGERED_HOST_DOWNTIME;%s;%lu;%lu;%d;%lu;%lu;%s;%s\n",current_time,host_name,start_time,end_time,(fixed==TRUE)?1:0,triggered_by,duration,comment_author,comment_data);
+		else if(child_options==2)
+			snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] SCHEDULE_AND_PROPAGATE_HOST_DOWNTIME;%s;%lu;%lu;%d;%lu;%lu;%s;%s\n",current_time,host_name,start_time,end_time,(fixed==TRUE)?1:0,triggered_by,duration,comment_author,comment_data);
+		else
+			snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] SCHEDULE_HOST_DOWNTIME;%s;%lu;%lu;%d;%lu;%lu;%s;%s\n",current_time,host_name,start_time,end_time,(fixed==TRUE)?1:0,triggered_by,duration,comment_author,comment_data);
+		break;
+		
+	case CMD_SCHEDULE_SVC_DOWNTIME:
+		snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] SCHEDULE_SVC_DOWNTIME;%s;%s;%lu;%lu;%d;%lu;%lu;%s;%s\n",current_time,host_name,service_desc,start_time,end_time,(fixed==TRUE)?1:0,triggered_by,duration,comment_author,comment_data);
+		break;
+		
+	case CMD_ENABLE_HOST_FLAP_DETECTION:
+	case CMD_DISABLE_HOST_FLAP_DETECTION:
+		snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] %s_HOST_FLAP_DETECTION;%s\n",current_time,(cmd==CMD_ENABLE_HOST_FLAP_DETECTION)?"ENABLE":"DISABLE",host_name);
+		break;
+		
+	case CMD_ENABLE_SVC_FLAP_DETECTION:
+	case CMD_DISABLE_SVC_FLAP_DETECTION:
+		snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] %s_SVC_FLAP_DETECTION;%s;%s\n",current_time,(cmd==CMD_ENABLE_SVC_FLAP_DETECTION)?"ENABLE":"DISABLE",host_name,service_desc);
+		break;
+		
+	case CMD_ENABLE_FLAP_DETECTION:
+	case CMD_DISABLE_FLAP_DETECTION:
+		snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] %s_FLAP_DETECTION\n",current_time,(cmd==CMD_ENABLE_FLAP_DETECTION)?"ENABLE":"DISABLE");
+		break;
+		
+	case CMD_DEL_HOST_DOWNTIME:
+	case CMD_DEL_SVC_DOWNTIME:
+		snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] DEL_%s_DOWNTIME;%lu\n",current_time,(cmd==CMD_DEL_HOST_DOWNTIME)?"HOST":"SVC",downtime_id);
+		break;
+
+	case CMD_ENABLE_FAILURE_PREDICTION:
+	case CMD_DISABLE_FAILURE_PREDICTION:
+		snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] %s_FAILURE_PREDICTION\n",current_time,(cmd==CMD_ENABLE_FAILURE_PREDICTION)?"ENABLE":"DISABLE");
+		break;
+		
+	case CMD_ENABLE_PERFORMANCE_DATA:
+	case CMD_DISABLE_PERFORMANCE_DATA:
+		snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] %s_PERFORMANCE_DATA\n",current_time,(cmd==CMD_ENABLE_PERFORMANCE_DATA)?"ENABLE":"DISABLE");
+		break;
+		
+	case CMD_START_EXECUTING_HOST_CHECKS:
+	case CMD_STOP_EXECUTING_HOST_CHECKS:
+		snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] %s_EXECUTING_HOST_CHECKS;\n",current_time,(cmd==CMD_START_EXECUTING_HOST_CHECKS)?"START":"STOP");
+		break;
+
+	case CMD_START_ACCEPTING_PASSIVE_HOST_CHECKS:
+	case CMD_STOP_ACCEPTING_PASSIVE_HOST_CHECKS:
+		snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] %s_ACCEPTING_PASSIVE_HOST_CHECKS;\n",current_time,(cmd==CMD_START_ACCEPTING_PASSIVE_HOST_CHECKS)?"START":"STOP");
+		break;
+
+	case CMD_ENABLE_PASSIVE_HOST_CHECKS:
+	case CMD_DISABLE_PASSIVE_HOST_CHECKS:
+		snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] %s_PASSIVE_HOST_CHECKS;%s\n",current_time,(cmd==CMD_ENABLE_PASSIVE_HOST_CHECKS)?"ENABLE":"DISABLE",host_name);
+		break;
+
+	case CMD_START_OBSESSING_OVER_HOST_CHECKS:
+	case CMD_STOP_OBSESSING_OVER_HOST_CHECKS:
+		snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] %s_OBSESSING_OVER_HOST_CHECKS;\n",current_time,(cmd==CMD_START_OBSESSING_OVER_HOST_CHECKS)?"START":"STOP");
+		break;
+
+	case CMD_SCHEDULE_HOST_CHECK:
+		snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] SCHEDULE_%sHOST_CHECK;%s;%lu\n",current_time,(force_check==TRUE)?"FORCED_":"",host_name,start_time);
+		break;
+
+	case CMD_START_OBSESSING_OVER_SVC:
+	case CMD_STOP_OBSESSING_OVER_SVC:
+		snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] %s_OBSESSING_OVER_SVC;%s;%s\n",current_time,(cmd==CMD_START_OBSESSING_OVER_SVC)?"START":"STOP",host_name,service_desc);
+		break;
+
+	case CMD_START_OBSESSING_OVER_HOST:
+	case CMD_STOP_OBSESSING_OVER_HOST:
+		snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] %s_OBSESSING_OVER_HOST;%s\n",current_time,(cmd==CMD_START_OBSESSING_OVER_HOST)?"START":"STOP",host_name);
+		break;
+
+
+		/***** HOSTGROUP COMMANDS *****/
+
+	case CMD_ENABLE_HOSTGROUP_SVC_NOTIFICATIONS:
+	case CMD_DISABLE_HOSTGROUP_SVC_NOTIFICATIONS:
+		if(affect_host_and_services==FALSE)
+			snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] %s_HOSTGROUP_SVC_NOTIFICATIONS;%s\n",current_time,(cmd==CMD_ENABLE_HOSTGROUP_SVC_NOTIFICATIONS)?"ENABLE":"DISABLE",hostgroup_name);
+		else
+			snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] %s_HOSTGROUP_SVC_NOTIFICATIONS;%s\n[%lu] %s_HOSTGROUP_HOST_NOTIFICATIONS;%s\n",current_time,(cmd==CMD_ENABLE_HOSTGROUP_SVC_NOTIFICATIONS)?"ENABLE":"DISABLE",hostgroup_name,current_time,(cmd==CMD_ENABLE_HOSTGROUP_SVC_NOTIFICATIONS)?"ENABLE":"DISABLE",hostgroup_name);
+		break;
+
+	case CMD_ENABLE_HOSTGROUP_HOST_NOTIFICATIONS:
+	case CMD_DISABLE_HOSTGROUP_HOST_NOTIFICATIONS:
+		snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] %s_HOSTGROUP_HOST_NOTIFICATIONS;%s\n",current_time,(cmd==CMD_ENABLE_HOSTGROUP_HOST_NOTIFICATIONS)?"ENABLE":"DISABLE",hostgroup_name);
+		break;
+
+	case CMD_ENABLE_HOSTGROUP_SVC_CHECKS:
+	case CMD_DISABLE_HOSTGROUP_SVC_CHECKS:
+		if(affect_host_and_services==FALSE)
+			snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] %s_HOSTGROUP_SVC_CHECKS;%s\n",current_time,(cmd==CMD_ENABLE_HOSTGROUP_SVC_CHECKS)?"ENABLE":"DISABLE",hostgroup_name);
+		else
+			snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] %s_HOSTGROUP_SVC_CHECKS;%s\n[%lu] %s_HOSTGROUP_HOST_CHECKS;%s\n",current_time,(cmd==CMD_ENABLE_HOSTGROUP_SVC_CHECKS)?"ENABLE":"DISABLE",hostgroup_name,current_time,(cmd==CMD_ENABLE_HOSTGROUP_SVC_CHECKS)?"ENABLE":"DISABLE",hostgroup_name);
+		break;
+
+	case CMD_SCHEDULE_HOSTGROUP_HOST_DOWNTIME:
+		snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] SCHEDULE_HOSTGROUP_HOST_DOWNTIME;%s;%lu;%lu;%d;0;%lu;%s;%s\n",current_time,hostgroup_name,start_time,end_time,(fixed==TRUE)?1:0,duration,comment_author,comment_data);
+		break;
+
+	case CMD_SCHEDULE_HOSTGROUP_SVC_DOWNTIME:
+		if(affect_host_and_services==FALSE)
+			snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] SCHEDULE_HOSTGROUP_SVC_DOWNTIME;%s;%lu;%lu;%d;0;%lu;%s;%s\n",current_time,hostgroup_name,start_time,end_time,(fixed==TRUE)?1:0,duration,comment_author,comment_data);
+		else
+			snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] SCHEDULE_HOSTGROUP_SVC_DOWNTIME;%s;%lu;%lu;%d;0;%lu;%s;%s\n[%lu] SCHEDULE_HOSTGROUP_HOST_DOWNTIME;%s;%lu;%lu;%d;%lu;%s;%s\n",current_time,hostgroup_name,start_time,end_time,(fixed==TRUE)?1:0,duration,comment_author,comment_data,current_time,hostgroup_name,start_time,end_time,(fixed==TRUE)?1:0,duration,comment_author,comment_data);
+		break;
+
+
+		/***** SERVICEGROUP COMMANDS *****/
+
+	case CMD_ENABLE_SERVICEGROUP_SVC_NOTIFICATIONS:
+	case CMD_DISABLE_SERVICEGROUP_SVC_NOTIFICATIONS:
+		if(affect_host_and_services==FALSE)
+			snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] %s_SERVICEGROUP_SVC_NOTIFICATIONS;%s\n",current_time,(cmd==CMD_ENABLE_SERVICEGROUP_SVC_NOTIFICATIONS)?"ENABLE":"DISABLE",servicegroup_name);
+		else
+			snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] %s_SERVICEGROUP_SVC_NOTIFICATIONS;%s\n[%lu] %s_SERVICEGROUP_HOST_NOTIFICATIONS;%s\n",current_time,(cmd==CMD_ENABLE_SERVICEGROUP_SVC_NOTIFICATIONS)?"ENABLE":"DISABLE",servicegroup_name,current_time,(cmd==CMD_ENABLE_SERVICEGROUP_SVC_NOTIFICATIONS)?"ENABLE":"DISABLE",servicegroup_name);
+		break;
+
+	case CMD_ENABLE_SERVICEGROUP_HOST_NOTIFICATIONS:
+	case CMD_DISABLE_SERVICEGROUP_HOST_NOTIFICATIONS:
+		snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] %s_SERVICEGROUP_HOST_NOTIFICATIONS;%s\n",current_time,(cmd==CMD_ENABLE_SERVICEGROUP_HOST_NOTIFICATIONS)?"ENABLE":"DISABLE",servicegroup_name);
+		break;
+
+	case CMD_ENABLE_SERVICEGROUP_SVC_CHECKS:
+	case CMD_DISABLE_SERVICEGROUP_SVC_CHECKS:
+		if(affect_host_and_services==FALSE)
+			snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] %s_SERVICEGROUP_SVC_CHECKS;%s\n",current_time,(cmd==CMD_ENABLE_SERVICEGROUP_SVC_CHECKS)?"ENABLE":"DISABLE",servicegroup_name);
+		else
+			snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] %s_SERVICEGROUP_SVC_CHECKS;%s\n[%lu] %s_SERVICEGROUP_HOST_CHECKS;%s\n",current_time,(cmd==CMD_ENABLE_SERVICEGROUP_SVC_CHECKS)?"ENABLE":"DISABLE",servicegroup_name,current_time,(cmd==CMD_ENABLE_SERVICEGROUP_SVC_CHECKS)?"ENABLE":"DISABLE",servicegroup_name);
+		break;
+
+	case CMD_SCHEDULE_SERVICEGROUP_HOST_DOWNTIME:
+		snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] SCHEDULE_SERVICEGROUP_HOST_DOWNTIME;%s;%lu;%lu;%d;0;%lu;%s;%s\n",current_time,servicegroup_name,start_time,end_time,(fixed==TRUE)?1:0,duration,comment_author,comment_data);
+		break;
+
+	case CMD_SCHEDULE_SERVICEGROUP_SVC_DOWNTIME:
+		if(affect_host_and_services==FALSE)
+			snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] SCHEDULE_SERVICEGROUP_SVC_DOWNTIME;%s;%lu;%lu;%d;0;%lu;%s;%s\n",current_time,servicegroup_name,start_time,end_time,(fixed==TRUE)?1:0,duration,comment_author,comment_data);
+		else
+			snprintf(command_buffer,sizeof(command_buffer)-1,"[%lu] SCHEDULE_SERVICEGROUP_SVC_DOWNTIME;%s;%lu;%lu;%d;0;%lu;%s;%s\n[%lu] SCHEDULE_SERVICEGROUP_HOST_DOWNTIME;%s;%lu;%lu;%d;%lu;%s;%s\n",current_time,servicegroup_name,start_time,end_time,(fixed==TRUE)?1:0,duration,comment_author,comment_data,current_time,servicegroup_name,start_time,end_time,(fixed==TRUE)?1:0,duration,comment_author,comment_data);
+		break;
+
+	default:
+		return ERROR;
+		break;
+	        }
+
+	/* make sure command buffer is terminated */
+	command_buffer[sizeof(command_buffer)-1]='\x0';
+
+	/* write the command to the command file */
+	result=write_command_to_file(command_buffer);
+
+	return result;
+        }
+
+
+
+/* write a command entry to the command file */
+int write_command_to_file(char *cmd){
+	FILE *fp;
+	struct stat statbuf;
+
+	/* bail out if the external command file doesn't exist */
+	if(stat(command_file,&statbuf)){
+
+		if(content_type==WML_CONTENT)
+			printf("<p>Error: Could not stat() external command file!</p>\n");
+		else{
+			printf("<P><DIV CLASS='errorMessage'>Error: Could not stat() command file '%s'!</DIV></P>\n",command_file);
+			printf("<P><DIV CLASS='errorDescription'>");
+			printf("The external command file may be missing, Nagios may not be running, and/or Nagios may not be checking external commands.\n");
+			printf("</DIV></P>\n");
+			}
+
+		return ERROR;
+	        }
+
+ 	/* open the command for writing (since this is a pipe, it will really be appended) */
+	fp=fopen(command_file,"w");
+	if(fp==NULL){
+
+		if(content_type==WML_CONTENT)
+			printf("<p>Error: Could not open command file for update!</p>\n");
+		else{
+			printf("<P><DIV CLASS='errorMessage'>Error: Could not open command file '%s' for update!</DIV></P>\n",command_file);
+			printf("<P><DIV CLASS='errorDescription'>");
+			printf("The permissions on the external command file and/or directory may be incorrect.  Read the FAQs on how to setup proper permissions.\n");
+			printf("</DIV></P>\n");
+			}
+
+		return ERROR;
+	        }
+
+	/* write the command to file */
+	fputs(cmd,fp);
+
+	/* flush buffer */
+	fflush(fp);
+
+	fclose(fp);
+
+	return OK;
+        }
+
+
+/* strips out semicolons from comment data */
+void clean_comment_data(char *buffer){
+	int x;
+	int y;
+
+	y=(int)strlen(buffer);
+	
+	for(x=0;x<y;x++){
+		if(buffer[x]==';')
+			buffer[x]=' ';
+	        }
+
+	return;
+        }
+
+
+/* display information about a command */
+void show_command_help(cmd){
+
+	printf("<DIV ALIGN=CENTER CLASS='descriptionTitle'>Command Description</DIV>\n");
+	printf("<TABLE BORDER=1 CELLSPACING=0 CELLPADDING=0 CLASS='commandDescription'>\n");
+	printf("<TR><TD CLASS='commandDescription'>\n");
+
+	/* decide what information to print out... */
+	switch(cmd){
+
+	case CMD_ADD_HOST_COMMENT:
+		printf("This command is used to add a comment for the specified host.  If you work with other administrators, you may find it useful to share information about a host\n");
+		printf("that is having problems if more than one of you may be working on it.  If you do not check the 'persistent' option, the comment will be automatically be deleted\n");
+		printf("the next time Nagios is restarted.\n");
+		break;
+		
+	case CMD_ADD_SVC_COMMENT:
+		printf("This command is used to add a comment for the specified service.  If you work with other administrators, you may find it useful to share information about a host\n");
+		printf("or service that is having problems if more than one of you may be working on it.  If you do not check the 'persistent' option, the comment will automatically be\n");
+		printf("deleted the next time Nagios is restarted.\n");
+		break;
+
+	case CMD_DEL_HOST_COMMENT:
+		printf("This command is used to delete a specific host comment.\n");
+		break;
+		
+	case CMD_DEL_SVC_COMMENT:
+		printf("This command is used to delete a specific service comment.\n");
+		break;
+		
+	case CMD_DELAY_HOST_NOTIFICATION:
+		printf("This command is used to delay the next problem notification that is sent out for the specified host.  The notification delay will be disregarded if\n");
+		printf("the host changes state before the next notification is scheduled to be sent out.  This command has no effect if the host is currently UP.\n");
+		break;
+
+	case CMD_DELAY_SVC_NOTIFICATION:
+		printf("This command is used to delay the next problem notification that is sent out for the specified service.  The notification delay will be disregarded if\n");
+		printf("the service changes state before the next notification is scheduled to be sent out.  This command has no effect if the service is currently in an OK state.\n");
+		break;
+
+	case CMD_SCHEDULE_SVC_CHECK:
+		printf("This command is used to schedule the next check of a particular service.  Nagios will re-queue the service to be checked at the time you specify.\n");
+		printf("If you select the <i>force check</i> option, Nagios will force a check of the service regardless of both what time the scheduled check occurs and whether or not checks are enabled for the service.\n");
+		break;
+
+	case CMD_ENABLE_SVC_CHECK:
+		printf("This command is used to enable active checks of a service.\n");
+		break;
+		
+	case CMD_DISABLE_SVC_CHECK:
+		printf("This command is used to disable active checks of a service.\n");
+		break;
+		
+	case CMD_DISABLE_NOTIFICATIONS:
+		printf("This command is used to disable host and service notifications on a program-wide basis.\n");
+		break;
+		
+	case CMD_ENABLE_NOTIFICATIONS:
+		printf("This command is used to enable host and service notifications on a program-wide basis.\n");
+		break;
+		
+	case CMD_SHUTDOWN_PROCESS:
+		printf("This command is used to shutdown the Nagios process. Note: Once the Nagios has been shutdown, it cannot be restarted via the web interface!\n");
+		break;
+
+	case CMD_RESTART_PROCESS:
+		printf("This command is used to restart the Nagios process.   Executing a restart command is equivalent to sending the process a HUP signal.\n");
+		printf("All information will be flushed from memory, the configuration files will be re-read, and Nagios will start monitoring with the new configuration information.\n");
+		break;
+
+	case CMD_ENABLE_HOST_SVC_CHECKS:
+		printf("This command is used to enable active checks of all services associated with the specified host.  This <i>does not</i> enable checks of the host unless you check the 'Enable for host too' option.\n");
+		break;
+		
+	case CMD_DISABLE_HOST_SVC_CHECKS:
+		printf("This command is used to disable active checks of all services associated with the specified host.  When a service is disabled Nagios will not monitor the service.  Doing this will prevent any notifications being sent out for\n");
+		printf("the specified service while it is disabled.  In order to have Nagios check the service in the future you will have to re-enable the service.\n");
+		printf("Note that disabling service checks may not necessarily prevent notifications from being sent out about the host which those services are associated with.  This <i>does not</i> disable checks of the host unless you check the 'Disable for host too' option.\n");
+		break;
+		
+	case CMD_SCHEDULE_HOST_SVC_CHECKS:
+		printf("This command is used to scheduled the next check of all services on the specified host.  If you select the <i>force check</i> option, Nagios will force a check of all services on the host regardless of both what time the scheduled checks occur and whether or not checks are enabled for those services.\n");
+		break;
+
+	case CMD_DEL_ALL_HOST_COMMENTS:
+		printf("This command is used to delete all comments associated with the specified host.\n");
+		break;
+		
+	case CMD_DEL_ALL_SVC_COMMENTS:
+		printf("This command is used to delete all comments associated with the specified service.\n");
+		break;
+
+	case CMD_ENABLE_SVC_NOTIFICATIONS:
+		printf("This command is used to enable notifications for the specified service.  Notifications will only be sent out for the\n");
+		printf("service state types you defined in your service definition.\n");
+		break;
+
+	case CMD_DISABLE_SVC_NOTIFICATIONS:
+		printf("This command is used to prevent notifications from being sent out for the specified service.  You will have to re-enable notifications\n");
+		printf("for this service before any alerts can be sent out in the future.\n");
+		break;
+
+	case CMD_ENABLE_HOST_NOTIFICATIONS:
+		printf("This command is used to enable notifications for the specified host.  Notifications will only be sent out for the\n");
+		printf("host state types you defined in your host definition.  Note that this command <i>does not</i> enable notifications\n");
+		printf("for services associated with this host.\n");
+		break;
+
+	case CMD_DISABLE_HOST_NOTIFICATIONS:
+		printf("This command is used to prevent notifications from being sent out for the specified host.  You will have to re-enable notifications for this host\n");
+		printf("before any alerts can be sent out in the future.  Note that this command <i>does not</i> disable notifications for services associated with this host.\n");
+		break;
+
+	case CMD_ENABLE_ALL_NOTIFICATIONS_BEYOND_HOST:
+		printf("This command is used to enable notifications for all hosts and services that lie \"beyond\" the specified host\n");
+		printf("(from the view of Nagios).\n");
+		break;
+
+	case CMD_DISABLE_ALL_NOTIFICATIONS_BEYOND_HOST:
+		printf("This command is used to temporarily prevent notifications from being sent out for all hosts and services that lie\n");
+		printf("\"beyone\" the specified host (from the view of Nagios).\n");
+		break;
+		
+	case CMD_ENABLE_HOST_SVC_NOTIFICATIONS:
+		printf("This command is used to enable notifications for all services on the specified host.  Notifications will only be sent out for the\n");
+		printf("service state types you defined in your service definition.  This <i>does not</i> enable notifications for the host unless you check the 'Enable for host too' option.\n");
+		break;
+
+	case CMD_DISABLE_HOST_SVC_NOTIFICATIONS:
+		printf("This command is used to prevent notifications from being sent out for all services on the specified host.  You will have to re-enable notifications for\n");
+		printf("all services associated with this host before any alerts can be sent out in the future.  This <i>does not</i> prevent notifications from being sent out about the host unless you check the 'Disable for host too' option.\n");
+		break;
+
+	case CMD_ACKNOWLEDGE_HOST_PROBLEM:
+		printf("This command is used to acknowledge a host problem.  When a host problem is acknowledged, future notifications about problems are temporarily disabled until the host changes from its current state.\n");
+		printf("If you want acknowledgement to disable notifications until the host recovers, check the 'Sticky Acknowledgement' checkbox.\n");
+		printf("Contacts for this host will receive a notification about the acknowledgement, so they are aware that someone is working on the problem.  Additionally, a comment will also be added to the host.\n");
+		printf("Make sure to enter your name and fill in a brief description of what you are doing in the comment field.  If you would like the host comment to be retained between restarts of Nagios, check\n");
+		printf("the 'Persistent Comment' checkbox.  If you do not want an acknowledgement notification sent out to the appropriate contacts, uncheck the 'Send Notification' checkbox.\n");
+		break;
+
+	case CMD_ACKNOWLEDGE_SVC_PROBLEM:
+		printf("This command is used to acknowledge a service problem.  When a service problem is acknowledged, future notifications about problems are temporarily disabled until the service changes from its current state.\n");
+		printf("If you want acknowledgement to disable notifications until the service recovers, check the 'Sticky Acknowledgement' checkbox.\n");
+		printf("Contacts for this service will receive a notification about the acknowledgement, so they are aware that someone is working on the problem.  Additionally, a comment will also be added to the service.\n");
+		printf("Make sure to enter your name and fill in a brief description of what you are doing in the comment field.  If you would like the service comment to be retained between restarts of Nagios, check\n");
+		printf("the 'Persistent Comment' checkbox.  If you do not want an acknowledgement notification sent out to the appropriate contacts, uncheck the 'Send Notification' checkbox.\n");
+		break;
+
+	case CMD_START_EXECUTING_SVC_CHECKS:
+		printf("This command is used to resume execution of active service checks on a program-wide basis.  Individual services which are disabled will still not be checked.\n");
+		break;
+
+	case CMD_STOP_EXECUTING_SVC_CHECKS:
+		printf("This command is used to temporarily stop Nagios from actively executing any service checks.  This will have the side effect of preventing any notifications from being sent out (for any and all services and hosts).\n");
+		printf("Service checks will not be executed again until you issue a command to resume service check execution.\n");
+		break;
+
+	case CMD_START_ACCEPTING_PASSIVE_SVC_CHECKS:
+		printf("This command is used to make Nagios start accepting passive service check results that it finds in the external command file\n");
+		break;
+
+	case CMD_STOP_ACCEPTING_PASSIVE_SVC_CHECKS:
+		printf("This command is use to make Nagios stop accepting passive service check results that it finds in the external command file.  All passive check results that are found will be ignored.\n");
+		break;
+
+	case CMD_ENABLE_PASSIVE_SVC_CHECKS:
+		printf("This command is used to allow Nagios to accept passive service check results that it finds in the external command file for this particular service.\n");
+		break;
+
+	case CMD_DISABLE_PASSIVE_SVC_CHECKS:
+		printf("This command is used to stop Nagios accepting passive service check results that it finds in the external command file for this particular service.  All passive check results that are found for this service will be ignored.\n");
+		break;
+
+	case CMD_ENABLE_EVENT_HANDLERS:
+		printf("This command is used to allow Nagios to run host and service event handlers.\n");
+		break;
+
+	case CMD_DISABLE_EVENT_HANDLERS:
+		printf("This command is used to temporarily prevent Nagios from running any host or service event handlers.\n");
+		break;
+
+	case CMD_ENABLE_SVC_EVENT_HANDLER:
+		printf("This command is used to allow Nagios to run the service event handler for a particular service when necessary (if one is defined).\n");
+		break;
+
+	case CMD_DISABLE_SVC_EVENT_HANDLER:
+		printf("This command is used to temporarily prevent Nagios from running the service event handler for a particular service.\n");
+		break;
+
+	case CMD_ENABLE_HOST_EVENT_HANDLER:
+		printf("This command is used to allow Nagios to run the host event handler for a particular service when necessary (if one is defined).\n");
+		break;
+
+	case CMD_DISABLE_HOST_EVENT_HANDLER:
+		printf("This command is used to temporarily prevent Nagios from running the host event handler for a particular host.\n");
+		break;
+
+	case CMD_ENABLE_HOST_CHECK:
+		printf("This command is used to enable active checks of this host.\n");
+		break;
+
+	case CMD_DISABLE_HOST_CHECK:
+		printf("This command is used to temporarily prevent Nagios from actively checking the status of a particular host.  If Nagios needs to check the status of this host, it will assume that it is in the same state that it was in before checks were disabled.\n");
+		break;
+
+	case CMD_START_OBSESSING_OVER_SVC_CHECKS:
+		printf("This command is used to have Nagios start obsessing over service checks.  Read the documentation on distributed monitoring for more information on this.\n");
+		break;
+
+	case CMD_STOP_OBSESSING_OVER_SVC_CHECKS:
+		printf("This command is used stop Nagios from obsessing over service checks.\n");
+		break;
+
+	case CMD_REMOVE_HOST_ACKNOWLEDGEMENT:
+		printf("This command is used to remove an acknowledgement for a particular host problem.  Once the acknowledgement is removed, notifications may start being\n");
+		printf("sent out about the host problem.  Note: Removing the acknowledgement does <i>not</i> remove the host comment that was originally associated\n");
+		printf("with the acknowledgement.  You'll have to remove that as well if that's what you want.\n");
+		break;
+
+	case CMD_REMOVE_SVC_ACKNOWLEDGEMENT:
+		printf("This command is used to remove an acknowledgement for a particular service problem.  Once the acknowledgement is removed, notifications may start being\n");
+		printf("sent out about the service problem.  Note: Removing the acknowledgement does <i>not</i> remove the service comment that was originally associated\n");
+		printf("with the acknowledgement.  You'll have to remove that as well if that's what you want.\n");
+		break;
+
+	case CMD_PROCESS_SERVICE_CHECK_RESULT:
+		printf("This command is used to submit a passive check result for a particular service.  It is particularly useful for resetting security-related services to OK states once they have been dealt with.\n");
+		break;
+
+	case CMD_PROCESS_HOST_CHECK_RESULT:
+		printf("This command is used to submit a passive check result for a particular host.\n");
+		break;
+
+	case CMD_SCHEDULE_HOST_DOWNTIME:
+		printf("This command is used to schedule downtime for a particular host.  During the specified downtime, Nagios will not send notifications out about the host.\n");
+		printf("When the scheduled downtime expires, Nagios will send out notifications for this host as it normally would.  Scheduled downtimes are preserved\n");
+		printf("across program shutdowns and restarts.  Both the start and end times should be specified in the following format:  <b>mm/dd/yyyy hh:mm:ss</b>.\n");
+		printf("If you select the <i>fixed</i> option, the downtime will be in effect between the start and end times you specify.  If you do not select the <i>fixed</i>\n");
+		printf("option, Nagios will treat this as \"flexible\" downtime.  Flexible downtime starts when the host goes down or becomes unreachable (sometime between the\n");
+		printf("start and end times you specified) and lasts as long as the duration of time you enter.  The duration fields do not apply for fixed downtime.\n");
+		break;
+
+	case CMD_SCHEDULE_SVC_DOWNTIME:
+		printf("This command is used to schedule downtime for a particular service.  During the specified downtime, Nagios will not send notifications out about the service.\n");
+		printf("When the scheduled downtime expires, Nagios will send out notifications for this service as it normally would.  Scheduled downtimes are preserved\n");
+		printf("across program shutdowns and restarts.  Both the start and end times should be specified in the following format:  <b>mm/dd/yyyy hh:mm:ss</b>.\n");
+		printf("option, Nagios will treat this as \"flexible\" downtime.  Flexible downtime starts when the service enters a non-OK state (sometime between the\n");
+		printf("start and end times you specified) and lasts as long as the duration of time you enter.  The duration fields do not apply for fixed downtime.\n");
+		break;
+
+	case CMD_ENABLE_HOST_FLAP_DETECTION:
+		printf("This command is used to enable flap detection for a specific host.  If flap detection is disabled on a program-wide basis, this will have no effect,\n");
+		break;
+
+	case CMD_DISABLE_HOST_FLAP_DETECTION:
+		printf("This command is used to disable flap detection for a specific host.\n");
+		break;
+
+	case CMD_ENABLE_SVC_FLAP_DETECTION:
+		printf("This command is used to enable flap detection for a specific service.  If flap detection is disabled on a program-wide basis, this will have no effect,\n");
+		break;
+
+	case CMD_DISABLE_SVC_FLAP_DETECTION:
+		printf("This command is used to disable flap detection for a specific service.\n");
+		break;
+
+	case CMD_ENABLE_FLAP_DETECTION:
+		printf("This command is used to enable flap detection for hosts and services on a program-wide basis.  Individual hosts and services may have flap detection disabled.\n");
+		break;
+
+	case CMD_DISABLE_FLAP_DETECTION:
+		printf("This command is used to disable flap detection for hosts and services on a program-wide basis.\n");
+		break;
+
+	case CMD_ENABLE_HOSTGROUP_SVC_NOTIFICATIONS:
+		printf("This command is used to enable notifications for all services in the specified hostgroup.  Notifications will only be sent out for the\n");
+		printf("service state types you defined in your service definitions.  This <i>does not</i> enable notifications for the hosts in this hostgroup unless you check the 'Enable for hosts too' option.\n");
+		break;
+
+	case CMD_DISABLE_HOSTGROUP_SVC_NOTIFICATIONS:
+		printf("This command is used to prevent notifications from being sent out for all services in the specified hostgroup.  You will have to re-enable notifications for\n");
+		printf("all services in this hostgroup before any alerts can be sent out in the future.  This <i>does not</i> prevent notifications from being sent out about the hosts in this hostgroup unless you check the 'Disable for hosts too' option.\n");
+		break;
+
+	case CMD_ENABLE_HOSTGROUP_HOST_NOTIFICATIONS:
+		printf("This command is used to enable notifications for all hosts in the specified hostgroup.  Notifications will only be sent out for the\n");
+		printf("host state types you defined in your host definitions.\n");
+		break;
+
+	case CMD_DISABLE_HOSTGROUP_HOST_NOTIFICATIONS:
+		printf("This command is used to prevent notifications from being sent out for all hosts in the specified hostgroup.  You will have to re-enable notifications for\n");
+		printf("all hosts in this hostgroup before any alerts can be sent out in the future.\n");
+		break;
+
+	case CMD_ENABLE_HOSTGROUP_SVC_CHECKS:
+		printf("This command is used to enable active checks of all services in the specified hostgroup.  This <i>does not</i> enable active checks of the hosts in the hostgroup unless you check the 'Enable for hosts too' option.\n");
+		break;
+		
+	case CMD_DISABLE_HOSTGROUP_SVC_CHECKS:
+		printf("This command is used to disable active checks of all services in the specified hostgroup.  This <i>does not</i> disable checks of the hosts in the hostgroup unless you check the 'Disable for hosts too' option.\n");
+		break;
+
+	case CMD_DEL_HOST_DOWNTIME:
+		printf("This command is used to cancel active or pending scheduled downtime for the specified host.\n");
+		break;
+
+	case CMD_DEL_SVC_DOWNTIME:
+		printf("This command is used to cancel active or pending scheduled downtime for the specified service.\n");
+		break;
+
+	case CMD_ENABLE_FAILURE_PREDICTION:
+		printf("This command is used to enable failure prediction for hosts and services on a program-wide basis.  Individual hosts and services may have failure prediction disabled.\n");
+		break;
+
+	case CMD_DISABLE_FAILURE_PREDICTION:
+		printf("This command is used to disable failure prediction for hosts and services on a program-wide basis.\n");
+		break;
+
+	case CMD_ENABLE_PERFORMANCE_DATA:
+		printf("This command is used to enable the processing of performance data for hosts and services on a program-wide basis.  Individual hosts and services may have performance data processing disabled.\n");
+		break;
+
+	case CMD_DISABLE_PERFORMANCE_DATA:
+		printf("This command is used to disable the processing of performance data for hosts and services on a program-wide basis.\n");
+		break;
+
+	case CMD_SCHEDULE_HOSTGROUP_HOST_DOWNTIME:
+		printf("This command is used to schedule downtime for all hosts in a particular hostgroup.  During the specified downtime, Nagios will not send notifications out about the hosts.\n");
+		printf("When the scheduled downtime expires, Nagios will send out notifications for the hosts as it normally would.  Scheduled downtimes are preserved\n");
+		printf("across program shutdowns and restarts.  Both the start and end times should be specified in the following format:  <b>mm/dd/yyyy hh:mm:ss</b>.\n");
+		printf("If you select the <i>fixed</i> option, the downtime will be in effect between the start and end times you specify.  If you do not select the <i>fixed</i>\n");
+		printf("option, Nagios will treat this as \"flexible\" downtime.  Flexible downtime starts when a host goes down or becomes unreachable (sometime between the\n");
+		printf("start and end times you specified) and lasts as long as the duration of time you enter.  The duration fields do not apply for fixed dowtime.\n");
+		break;
+
+	case CMD_SCHEDULE_HOSTGROUP_SVC_DOWNTIME:
+		printf("This command is used to schedule downtime for all services in a particular hostgroup.  During the specified downtime, Nagios will not send notifications out about the services.\n");
+		printf("When the scheduled downtime expires, Nagios will send out notifications for the services as it normally would.  Scheduled downtimes are preserved\n");
+		printf("across program shutdowns and restarts.  Both the start and end times should be specified in the following format:  <b>mm/dd/yyyy hh:mm:ss</b>.\n");
+		printf("If you select the <i>fixed</i> option, the downtime will be in effect between the start and end times you specify.  If you do not select the <i>fixed</i>\n");
+		printf("option, Nagios will treat this as \"flexible\" downtime.  Flexible downtime starts when a service enters a non-OK state (sometime between the\n");
+		printf("start and end times you specified) and lasts as long as the duration of time you enter.  The duration fields do not apply for fixed dowtime.\n");
+		printf("Note that scheduling downtime for services does not automatically schedule downtime for the hosts those services are associated with.  If you want to also schedule downtime for all hosts in the hostgroup, check the 'Schedule downtime for hosts too' option.\n");
+		break;
+
+	case CMD_START_EXECUTING_HOST_CHECKS:
+		printf("This command is used to enable active host checks on a program-wide basis.\n");
+		break;
+
+	case CMD_STOP_EXECUTING_HOST_CHECKS:
+		printf("This command is used to disable active host checks on a program-wide basis.\n");
+		break;
+
+	case CMD_START_ACCEPTING_PASSIVE_HOST_CHECKS:
+		printf("This command is used to have Nagios start obsessing over host checks.  Read the documentation on distributed monitoring for more information on this.\n");
+		break;
+
+	case CMD_STOP_ACCEPTING_PASSIVE_HOST_CHECKS:
+		printf("This command is used to stop Nagios from obsessing over host checks.\n");
+		break;
+
+	case CMD_ENABLE_PASSIVE_HOST_CHECKS:
+		printf("This command is used to allow Nagios to accept passive host check results that it finds in the external command file for a particular host.\n");
+		break;
+
+	case CMD_DISABLE_PASSIVE_HOST_CHECKS:
+		printf("This command is used to stop Nagios from accepting passive host check results that it finds in the external command file for a particular host.  All passive check results that are found for this host will be ignored.\n");
+		break;
+
+	case CMD_START_OBSESSING_OVER_HOST_CHECKS:
+		printf("This command is used to have Nagios start obsessing over host checks.  Read the documentation on distributed monitoring for more information on this.\n");
+		break;
+
+	case CMD_STOP_OBSESSING_OVER_HOST_CHECKS:
+		printf("This command is used to stop Nagios from obsessing over host checks.\n");
+		break;
+
+	case CMD_SCHEDULE_HOST_CHECK:
+		printf("This command is used to schedule the next check of a particular host.  Nagios will re-queue the host to be checked at the time you specify.\n");
+		printf("If you select the <i>force check</i> option, Nagios will force a check of the host regardless of both what time the scheduled check occurs and whether or not checks are enabled for the host.\n");
+		break;
+
+	case CMD_START_OBSESSING_OVER_SVC:
+		printf("This command is used to have Nagios start obsessing over a particular service.\n");
+		break;
+
+	case CMD_STOP_OBSESSING_OVER_SVC:
+		printf("This command is used to stop Nagios from obsessing over a particular service.\n");
+		break;
+
+	case CMD_START_OBSESSING_OVER_HOST:
+		printf("This command is used to have Nagios start obsessing over a particular host.\n");
+		break;
+
+	case CMD_STOP_OBSESSING_OVER_HOST:
+		printf("This command is used to stop Nagios from obsessing over a particular host.\n");
+		break;
+
+	case CMD_ENABLE_SERVICEGROUP_SVC_NOTIFICATIONS:
+		printf("This command is used to enable notifications for all services in the specified servicegroup.  Notifications will only be sent out for the\n");
+		printf("service state types you defined in your service definitions.  This <i>does not</i> enable notifications for the hosts in this servicegroup unless you check the 'Enable for hosts too' option.\n");
+		break;
+
+	case CMD_DISABLE_SERVICEGROUP_SVC_NOTIFICATIONS:
+		printf("This command is used to prevent notifications from being sent out for all services in the specified servicegroup.  You will have to re-enable notifications for\n");
+		printf("all services in this servicegroup before any alerts can be sent out in the future.  This <i>does not</i> prevent notifications from being sent out about the hosts in this servicegroup unless you check the 'Disable for hosts too' option.\n");
+		break;
+
+	case CMD_ENABLE_SERVICEGROUP_HOST_NOTIFICATIONS:
+		printf("This command is used to enable notifications for all hosts in the specified servicegroup.  Notifications will only be sent out for the\n");
+		printf("host state types you defined in your host definitions.\n");
+		break;
+
+	case CMD_DISABLE_SERVICEGROUP_HOST_NOTIFICATIONS:
+		printf("This command is used to prevent notifications from being sent out for all hosts in the specified servicegroup.  You will have to re-enable notifications for\n");
+		printf("all hosts in this servicegroup before any alerts can be sent out in the future.\n");
+		break;
+
+	case CMD_ENABLE_SERVICEGROUP_SVC_CHECKS:
+		printf("This command is used to enable active checks of all services in the specified servicegroup.  This <i>does not</i> enable active checks of the hosts in the servicegroup unless you check the 'Enable for hosts too' option.\n");
+		break;
+		
+	case CMD_DISABLE_SERVICEGROUP_SVC_CHECKS:
+		printf("This command is used to disable active checks of all services in the specified servicegroup.  This <i>does not</i> disable checks of the hosts in the servicegroup unless you check the 'Disable for hosts too' option.\n");
+		break;
+
+	case CMD_SCHEDULE_SERVICEGROUP_HOST_DOWNTIME:
+		printf("This command is used to schedule downtime for all hosts in a particular servicegroup.  During the specified downtime, Nagios will not send notifications out about the hosts.\n");
+		printf("When the scheduled downtime expires, Nagios will send out notifications for the hosts as it normally would.  Scheduled downtimes are preserved\n");
+		printf("across program shutdowns and restarts.  Both the start and end times should be specified in the following format:  <b>mm/dd/yyyy hh:mm:ss</b>.\n");
+		printf("If you select the <i>fixed</i> option, the downtime will be in effect between the start and end times you specify.  If you do not select the <i>fixed</i>\n");
+		printf("option, Nagios will treat this as \"flexible\" downtime.  Flexible downtime starts when a host goes down or becomes unreachable (sometime between the\n");
+		printf("start and end times you specified) and lasts as long as the duration of time you enter.  The duration fields do not apply for fixed dowtime.\n");
+		break;
+
+	case CMD_SCHEDULE_SERVICEGROUP_SVC_DOWNTIME:
+		printf("This command is used to schedule downtime for all services in a particular servicegroup.  During the specified downtime, Nagios will not send notifications out about the services.\n");
+		printf("When the scheduled downtime expires, Nagios will send out notifications for the services as it normally would.  Scheduled downtimes are preserved\n");
+		printf("across program shutdowns and restarts.  Both the start and end times should be specified in the following format:  <b>mm/dd/yyyy hh:mm:ss</b>.\n");
+		printf("If you select the <i>fixed</i> option, the downtime will be in effect between the start and end times you specify.  If you do not select the <i>fixed</i>\n");
+		printf("option, Nagios will treat this as \"flexible\" downtime.  Flexible downtime starts when a service enters a non-OK state (sometime between the\n");
+		printf("start and end times you specified) and lasts as long as the duration of time you enter.  The duration fields do not apply for fixed dowtime.\n");
+		printf("Note that scheduling downtime for services does not automatically schedule downtime for the hosts those services are associated with.  If you want to also schedule downtime for all hosts in the servicegroup, check the 'Schedule downtime for hosts too' option.\n");
+		break;
+
+	default:
+		printf("Sorry, but no information is available for this command.");
+	        }
+
+	printf("</TD></TR>\n");
+	printf("</TABLE>\n");
+
+	return;
+        }
+
+
+
+/* converts a time string to a UNIX timestamp, respecting the date_format option */
+int string_to_time(char *buffer, time_t *t){
+	struct tm lt;
+
+
+	/* Initialize some variables just in case they don't get parsed
+	   by the sscanf() call.  A better solution is to also check the
+	   CGI input for validity, but this should suffice to prevent
+	   strange problems if the input is not valid. 
+	   Jan 15 2003  Steve Bonds */
+	lt.tm_mon=0;
+	lt.tm_mday=1;
+	lt.tm_year=1900;
+	lt.tm_hour=0;
+	lt.tm_min=0;
+	lt.tm_sec=0;
+	lt.tm_wday=0;
+	lt.tm_yday=0;
+
+	if(date_format==DATE_FORMAT_EURO)
+		sscanf(buffer,"%02d-%02d-%04d %02d:%02d:%02d",&lt.tm_mday,&lt.tm_mon,&lt.tm_year,&lt.tm_hour,&lt.tm_min,&lt.tm_sec);
+	else if(date_format==DATE_FORMAT_ISO8601 || date_format==DATE_FORMAT_STRICT_ISO8601)
+		sscanf(buffer,"%04d-%02d-%02d%*[ T]%02d:%02d:%02d",&lt.tm_year,&lt.tm_mon,&lt.tm_mday,&lt.tm_hour,&lt.tm_min,&lt.tm_sec);
+	else
+		sscanf(buffer,"%02d-%02d-%04d %02d:%02d:%02d",&lt.tm_mon,&lt.tm_mday,&lt.tm_year,&lt.tm_hour,&lt.tm_min,&lt.tm_sec);
+
+	lt.tm_mon--;
+	lt.tm_year-=1900;
+
+	/* tell mktime() to try and compute DST automatically */
+	lt.tm_isdst=-1;
+
+	*t=mktime(&lt);
+
+	return OK;
+        }
diff -urNad nagios2-2.6~/cgi/histogram.c nagios2-2.6/cgi/histogram.c
--- nagios2-2.6~/cgi/histogram.c	2006-03-21 21:31:46.000000000 +0000
+++ nagios2-2.6/cgi/histogram.c	2008-05-26 16:01:40.000000000 +0000
@@ -406,9 +406,9 @@
 			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);
+			printf("<input type='hidden' name='host' value='%s'>\n",url_encode(host_name));
 			if(display_type==DISPLAY_SERVICE_HISTOGRAM)
-				printf("<input type='hidden' name='service' value='%s'>\n",svc_description);
+				printf("<input type='hidden' name='service' value='%s'>\n",url_encode(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");
@@ -788,9 +788,9 @@
 
 			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);
+			printf("<input type='hidden' name='host' value='%s'>\n",url_encode(host_name));
 			if(display_type==DISPLAY_SERVICE_HISTOGRAM)
-				printf("<input type='hidden' name='service' value='%s'>\n",svc_description);
+				printf("<input type='hidden' name='service' value='%s'>\n",url_encode(svc_description));
 
 			printf("<tr><td class='reportSelectSubTitle' align=right>Report Period:</td>\n");
 			printf("<td class='reportSelectItem'>\n");
diff -urNad nagios2-2.6~/cgi/history.c nagios2-2.6/cgi/history.c
--- nagios2-2.6~/cgi/history.c	2006-03-21 21:31:46.000000000 +0000
+++ nagios2-2.6/cgi/history.c	2008-05-26 16:01:40.000000000 +0000
@@ -201,9 +201,9 @@
 
 		printf("<table border=0 CLASS='optBox'>\n");
 		printf("<form method=\"GET\" action=\"%s\">\n",HISTORY_CGI);
-		printf("<input type='hidden' name='host' value='%s'>\n",(show_all_hosts==TRUE)?"all":host_name);
+		printf("<input type='hidden' name='host' value='%s'>\n",(show_all_hosts==TRUE)?"all":url_encode(host_name));
 		if(display_type==DISPLAY_SERVICES)
-			printf("<input type='hidden' name='service' value='%s'>\n",svc_description);
+			printf("<input type='hidden' name='service' value='%s'>\n",url_encode(svc_description));
 		printf("<input type='hidden' name='archive' value='%d'>\n",log_archive);
 
 		printf("<tr>\n");
diff -urNad nagios2-2.6~/cgi/notifications.c nagios2-2.6/cgi/notifications.c
--- nagios2-2.6~/cgi/notifications.c	2006-10-09 15:59:02.000000000 +0000
+++ nagios2-2.6/cgi/notifications.c	2008-05-26 16:01:40.000000000 +0000
@@ -212,11 +212,11 @@
 		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);
+			printf("<input type='hidden' name='host' value='%s'>\n",url_encode(query_host_name));
+			printf("<input type='hidden' name='service' value='%s'>\n",url_encode(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='%s' value='%s'>\n",(query_type==FIND_HOST)?"host":"contact",url_encode((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)
diff -urNad nagios2-2.6~/cgi/status.c nagios2-2.6/cgi/status.c
--- nagios2-2.6~/cgi/status.c	2006-10-09 15:59:02.000000000 +0000
+++ nagios2-2.6/cgi/status.c	2008-05-26 16:01:40.000000000 +0000
@@ -817,11 +817,11 @@
 	printf("<TH CLASS='serviceTotals'>");
 	printf("<A CLASS='serviceTotals' HREF='%s?",STATUS_CGI);
 	if(display_type==DISPLAY_HOSTS)
-		printf("host=%s",host_name);
+		printf("host=%s",url_encode(host_name));
 	else if(display_type==DISPLAY_SERVICEGROUPS)
-		printf("servicegroup=%s&style=detail",servicegroup_name);
+		printf("servicegroup=%s&style=detail",url_encode(servicegroup_name));
 	else
-		printf("hostgroup=%s&style=detail",hostgroup_name);
+		printf("hostgroup=%s&style=detail",url_encode(hostgroup_name));
 	printf("&servicestatustypes=%d",SERVICE_OK);
 	printf("&hoststatustypes=%d'>",host_status_types);
 	printf("Ok</A></TH>\n");
@@ -829,11 +829,11 @@
 	printf("<TH CLASS='serviceTotals'>");
 	printf("<A CLASS='serviceTotals' HREF='%s?",STATUS_CGI);
 	if(display_type==DISPLAY_HOSTS)
-		printf("host=%s",host_name);
+		printf("host=%s",url_encode(host_name));
 	else if(display_type==DISPLAY_SERVICEGROUPS)
-		printf("servicegroup=%s&style=detail",servicegroup_name);
+		printf("servicegroup=%s&style=detail",url_encode(servicegroup_name));
 	else
-		printf("hostgroup=%s&style=detail",hostgroup_name);
+		printf("hostgroup=%s&style=detail",url_encode(hostgroup_name));
 	printf("&servicestatustypes=%d",SERVICE_WARNING);
 	printf("&hoststatustypes=%d'>",host_status_types);
 	printf("Warning</A></TH>\n");
@@ -841,11 +841,11 @@
 	printf("<TH CLASS='serviceTotals'>");
 	printf("<A CLASS='serviceTotals' HREF='%s?",STATUS_CGI);
 	if(display_type==DISPLAY_HOSTS)
-		printf("host=%s",host_name);
+		printf("host=%s",url_encode(host_name));
 	else if(display_type==DISPLAY_SERVICEGROUPS)
-		printf("servicegroup=%s&style=detail",servicegroup_name);
+		printf("servicegroup=%s&style=detail",url_encode(servicegroup_name));
 	else
-		printf("hostgroup=%s&style=detail",hostgroup_name);
+		printf("hostgroup=%s&style=detail",url_encode(hostgroup_name));
 	printf("&servicestatustypes=%d",SERVICE_UNKNOWN);
 	printf("&hoststatustypes=%d'>",host_status_types);
 	printf("Unknown</A></TH>\n");
@@ -853,11 +853,11 @@
 	printf("<TH CLASS='serviceTotals'>");
 	printf("<A CLASS='serviceTotals' HREF='%s?",STATUS_CGI);
 	if(display_type==DISPLAY_HOSTS)
-		printf("host=%s",host_name);
+		printf("host=%s",url_encode(host_name));
 	else if(display_type==DISPLAY_SERVICEGROUPS)
-		printf("servicegroup=%s&style=detail",servicegroup_name);
+		printf("servicegroup=%s&style=detail",url_encode(servicegroup_name));
 	else
-		printf("hostgroup=%s&style=detail",hostgroup_name);
+		printf("hostgroup=%s&style=detail",url_encode(hostgroup_name));
 	printf("&servicestatustypes=%d",SERVICE_CRITICAL);
 	printf("&hoststatustypes=%d'>",host_status_types);
 	printf("Critical</A></TH>\n");
@@ -865,11 +865,11 @@
 	printf("<TH CLASS='serviceTotals'>");
 	printf("<A CLASS='serviceTotals' HREF='%s?",STATUS_CGI);
 	if(display_type==DISPLAY_HOSTS)
-		printf("host=%s",host_name);
+		printf("host=%s",url_encode(host_name));
 	else if(display_type==DISPLAY_SERVICEGROUPS)
-		printf("servicegroup=%s&style=detail",servicegroup_name);
+		printf("servicegroup=%s&style=detail",url_encode(servicegroup_name));
 	else
-		printf("hostgroup=%s&style=detail",hostgroup_name);
+		printf("hostgroup=%s&style=detail",url_encode(hostgroup_name));
 	printf("&servicestatustypes=%d",SERVICE_PENDING);
 	printf("&hoststatustypes=%d'>",host_status_types);
 	printf("Pending</A></TH>\n");
@@ -906,11 +906,11 @@
 	printf("<TH CLASS='serviceTotals'>");
 	printf("<A CLASS='serviceTotals' HREF='%s?",STATUS_CGI);
 	if(display_type==DISPLAY_HOSTS)
-		printf("host=%s",host_name);
+		printf("host=%s",url_encode(host_name));
 	else if(display_type==DISPLAY_SERVICEGROUPS)
-		printf("servicegroup=%s&style=detail",servicegroup_name);
+		printf("servicegroup=%s&style=detail",url_encode(servicegroup_name));
 	else
-		printf("hostgroup=%s&style=detail",hostgroup_name);
+		printf("hostgroup=%s&style=detail",url_encode(hostgroup_name));
 	printf("&servicestatustypes=%d",SERVICE_UNKNOWN|SERVICE_WARNING|SERVICE_CRITICAL);
 	printf("&hoststatustypes=%d'>",host_status_types);
 	printf("<I>All Problems</I></A></TH>\n");
@@ -918,11 +918,11 @@
 	printf("<TH CLASS='serviceTotals'>");
 	printf("<A CLASS='serviceTotals' HREF='%s?",STATUS_CGI);
 	if(display_type==DISPLAY_HOSTS)
-		printf("host=%s",host_name);
+		printf("host=%s",url_encode(host_name));
 	else if(display_type==DISPLAY_SERVICEGROUPS)
-		printf("servicegroup=%s&style=detail",servicegroup_name);
+		printf("servicegroup=%s&style=detail",url_encode(servicegroup_name));
 	else
-		printf("hostgroup=%s&style=detail",hostgroup_name);
+		printf("hostgroup=%s&style=detail",url_encode(hostgroup_name));
 	printf("&hoststatustypes=%d'>",host_status_types);
 	printf("<I>All Types</I></A></TH>\n");
 
@@ -1031,11 +1031,11 @@
 	printf("<TH CLASS='hostTotals'>");
 	printf("<A CLASS='hostTotals' HREF='%s?",STATUS_CGI);
 	if(display_type==DISPLAY_HOSTS)
-		printf("host=%s",host_name);
+		printf("host=%s",url_encode(host_name));
 	else if(display_type==DISPLAY_SERVICEGROUPS)
-		printf("servicegroup=%s",servicegroup_name);
+		printf("servicegroup=%s",url_encode(servicegroup_name));
 	else{
-		printf("hostgroup=%s",hostgroup_name);
+		printf("hostgroup=%s",url_encode(hostgroup_name));
 		if((service_status_types!=all_service_status_types) || group_style_type==STYLE_DETAIL)
 			printf("&style=detail");
 		else if(group_style_type==STYLE_HOST_DETAIL)
@@ -1049,11 +1049,11 @@
 	printf("<TH CLASS='hostTotals'>");
 	printf("<A CLASS='hostTotals' HREF='%s?",STATUS_CGI);
 	if(display_type==DISPLAY_HOSTS)
-		printf("host=%s",host_name);
+		printf("host=%s",url_encode(host_name));
 	else if(display_type==DISPLAY_SERVICEGROUPS)
-		printf("servicegroup=%s",servicegroup_name);
+		printf("servicegroup=%s",url_encode(servicegroup_name));
 	else{
-		printf("hostgroup=%s",hostgroup_name);
+		printf("hostgroup=%s",url_encode(hostgroup_name));
 		if((service_status_types!=all_service_status_types) || group_style_type==STYLE_DETAIL)
 			printf("&style=detail");
 		else if(group_style_type==STYLE_HOST_DETAIL)
@@ -1067,11 +1067,11 @@
 	printf("<TH CLASS='hostTotals'>");
 	printf("<A CLASS='hostTotals' HREF='%s?",STATUS_CGI);
 	if(display_type==DISPLAY_HOSTS)
-		printf("host=%s",host_name);
+		printf("host=%s",url_encode(host_name));
 	else if(display_type==DISPLAY_SERVICEGROUPS)
-		printf("servicegroup=%s",servicegroup_name);
+		printf("servicegroup=%s",url_encode(servicegroup_name));
 	else{
-		printf("hostgroup=%s",hostgroup_name);
+		printf("hostgroup=%s",url_encode(hostgroup_name));
 		if((service_status_types!=all_service_status_types) || group_style_type==STYLE_DETAIL)
 			printf("&style=detail");
 		else if(group_style_type==STYLE_HOST_DETAIL)
@@ -1085,11 +1085,11 @@
 	printf("<TH CLASS='hostTotals'>");
 	printf("<A CLASS='hostTotals' HREF='%s?",STATUS_CGI);
 	if(display_type==DISPLAY_HOSTS)
-		printf("host=%s",host_name);
+		printf("host=%s",url_encode(host_name));
 	else if(display_type==DISPLAY_SERVICEGROUPS)
-		printf("servicegroup=%s",servicegroup_name);
+		printf("servicegroup=%s",url_encode(servicegroup_name));
 	else{
-		printf("hostgroup=%s",hostgroup_name);
+		printf("hostgroup=%s",url_encode(hostgroup_name));
 		if((service_status_types!=all_service_status_types) || group_style_type==STYLE_DETAIL)
 			printf("&style=detail");
 		else if(group_style_type==STYLE_HOST_DETAIL)
@@ -1128,11 +1128,11 @@
 	printf("<TH CLASS='hostTotals'>");
 	printf("<A CLASS='hostTotals' HREF='%s?",STATUS_CGI);
 	if(display_type==DISPLAY_HOSTS)
-		printf("host=%s",host_name);
+		printf("host=%s",url_encode(host_name));
 	else if(display_type==DISPLAY_SERVICEGROUPS)
-		printf("servicegroup=%s",servicegroup_name);
+		printf("servicegroup=%s",url_encode(servicegroup_name));
 	else{
-		printf("hostgroup=%s",hostgroup_name);
+		printf("hostgroup=%s",url_encode(hostgroup_name));
 		if((service_status_types!=all_service_status_types) || group_style_type==STYLE_DETAIL)
 			printf("&style=detail");
 		else if(group_style_type==STYLE_HOST_DETAIL)
@@ -1146,11 +1146,11 @@
 	printf("<TH CLASS='hostTotals'>");
 	printf("<A CLASS='hostTotals' HREF='%s?",STATUS_CGI);
 	if(display_type==DISPLAY_HOSTS)
-		printf("host=%s",host_name);
+		printf("host=%s",url_encode(host_name));
 	else if(display_type==DISPLAY_SERVICEGROUPS)
-		printf("servicegroup=%s",servicegroup_name);
+		printf("servicegroup=%s",url_encode(servicegroup_name));
 	else{
-		printf("hostgroup=%s",hostgroup_name);
+		printf("hostgroup=%s",url_encode(hostgroup_name));
 		if((service_status_types!=all_service_status_types) || group_style_type==STYLE_DETAIL)
 			printf("&style=detail");
 		else if(group_style_type==STYLE_HOST_DETAIL)
@@ -1257,7 +1257,7 @@
 		if(show_all_servicegroups==TRUE)
 			printf("All Service Groups");
 		else
-			printf("Service Group '%s'",servicegroup_name);
+			printf("Service Group '%s'",url_encode(servicegroup_name));
 	        }
 	else{
 		if(show_all_hostgroups==TRUE)
@@ -1304,11 +1304,11 @@
 	snprintf(temp_url,sizeof(temp_url)-1,"%s?",STATUS_CGI);
 	temp_url[sizeof(temp_url)-1]='\x0';
 	if(display_type==DISPLAY_HOSTS)
-		snprintf(temp_buffer,sizeof(temp_buffer)-1,"host=%s",host_name);
+		snprintf(temp_buffer,sizeof(temp_buffer)-1,"host=%s",url_encode(host_name));
 	else if(display_type==DISPLAY_SERVICEGROUPS)
-		snprintf(temp_buffer,sizeof(temp_buffer)-1,"servicegroup=%s&style=detail",servicegroup_name);
+		snprintf(temp_buffer,sizeof(temp_buffer)-1,"servicegroup=%s&style=detail",url_encode(servicegroup_name));
 	else
-		snprintf(temp_buffer,sizeof(temp_buffer)-1,"hostgroup=%s&style=detail",hostgroup_name);
+		snprintf(temp_buffer,sizeof(temp_buffer)-1,"hostgroup=%s&style=detail",url_encode(hostgroup_name));
 	temp_buffer[sizeof(temp_buffer)-1]='\x0';
 	strncat(temp_url,temp_buffer,sizeof(temp_url)-strlen(temp_url)-1);
 	temp_url[sizeof(temp_url)-1]='\x0';
@@ -1855,7 +1855,7 @@
 
 	snprintf(temp_url,sizeof(temp_url)-1,"%s?",STATUS_CGI);
 	temp_url[sizeof(temp_url)-1]='\x0';
-	snprintf(temp_buffer,sizeof(temp_buffer)-1,"hostgroup=%s&style=hostdetail",hostgroup_name);
+	snprintf(temp_buffer,sizeof(temp_buffer)-1,"hostgroup=%s&style=hostdetail",url_encode(hostgroup_name));
 	temp_buffer[sizeof(temp_buffer)-1]='\x0';
 	strncat(temp_url,temp_buffer,sizeof(temp_url)-strlen(temp_url)-1);
 	temp_url[sizeof(temp_url)-1]='\x0';
diff -urNad nagios2-2.6~/cgi/status.c.orig nagios2-2.6/cgi/status.c.orig
--- nagios2-2.6~/cgi/status.c.orig	1970-01-01 00:00:00.000000000 +0000
+++ nagios2-2.6/cgi/status.c.orig	2006-10-09 15:59:02.000000000 +0000
@@ -0,0 +1,4561 @@
+/**************************************************************************
+ *
+ * STATUS.C -  Nagios Status CGI
+ *
+ * Copyright (c) 1999-2006 Ethan Galstad (nagios at nagios.org)
+ * Last Modified: 10-09-2006
+ *
+ * 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/comments.h"
+#include "../include/statusdata.h"
+
+#include "../include/cgiutils.h"
+#include "../include/getcgi.h"
+#include "../include/cgiauth.h"
+
+extern int             refresh_rate;
+extern time_t          program_start;
+
+extern char main_config_file[MAX_FILENAME_LENGTH];
+extern char url_html_path[MAX_FILENAME_LENGTH];
+extern char url_docs_path[MAX_FILENAME_LENGTH];
+extern char url_images_path[MAX_FILENAME_LENGTH];
+extern char url_stylesheets_path[MAX_FILENAME_LENGTH];
+extern char url_logo_images_path[MAX_FILENAME_LENGTH];
+extern char url_media_path[MAX_FILENAME_LENGTH];
+extern char log_file[MAX_FILENAME_LENGTH];
+
+extern char *service_critical_sound;
+extern char *service_warning_sound;
+extern char *service_unknown_sound;
+extern char *host_down_sound;
+extern char *host_unreachable_sound;
+extern char *normal_sound;
+
+extern int suppress_alert_window;
+
+extern host *host_list;
+extern service *service_list;
+extern hostgroup *hostgroup_list;
+extern servicegroup *servicegroup_list;
+extern hoststatus *hoststatus_list;
+extern servicestatus *servicestatus_list;
+
+
+#define MAX_MESSAGE_BUFFER		4096
+
+#define DISPLAY_HOSTS			0
+#define DISPLAY_HOSTGROUPS		1
+#define DISPLAY_SERVICEGROUPS           2
+
+#define STYLE_OVERVIEW			0
+#define STYLE_DETAIL			1
+#define STYLE_SUMMARY			2
+#define STYLE_GRID                      3
+#define STYLE_HOST_DETAIL               4
+
+/* HOSTSORT structure */
+typedef struct hostsort_struct{
+	hoststatus *hststatus;
+	struct hostsort_struct *next;
+        }hostsort;
+
+/* SERVICESORT structure */
+typedef struct servicesort_struct{
+	servicestatus *svcstatus;
+	struct servicesort_struct *next;
+        }servicesort;
+
+hostsort *hostsort_list=NULL;
+servicesort *servicesort_list=NULL;
+
+int sort_services(int,int);						/* sorts services */
+int sort_hosts(int,int);                                                /* sorts hosts */
+int compare_servicesort_entries(int,int,servicesort *,servicesort *);	/* compares service sort entries */
+int compare_hostsort_entries(int,int,hostsort *,hostsort *);            /* compares host sort entries */
+void free_servicesort_list(void);
+void free_hostsort_list(void);
+
+void show_host_status_totals(void);
+void show_service_status_totals(void);
+void show_service_detail(void);
+void show_host_detail(void);
+void show_servicegroup_overviews(void);
+void show_servicegroup_overview(servicegroup *);
+void show_servicegroup_summaries(void);
+void show_servicegroup_summary(servicegroup *,int);
+void show_servicegroup_host_totals_summary(servicegroup *);
+void show_servicegroup_service_totals_summary(servicegroup *);
+void show_servicegroup_grids(void);
+void show_servicegroup_grid(servicegroup *);
+void show_hostgroup_overviews(void);
+void show_hostgroup_overview(hostgroup *);
+void show_servicegroup_hostgroup_member_overview(hoststatus *,int,void *);
+void show_servicegroup_hostgroup_member_service_status_totals(char *,void *);
+void show_hostgroup_summaries(void);
+void show_hostgroup_summary(hostgroup *,int);
+void show_hostgroup_host_totals_summary(hostgroup *);
+void show_hostgroup_service_totals_summary(hostgroup *);
+void show_hostgroup_grids(void);
+void show_hostgroup_grid(hostgroup *);
+
+void show_filters(void);
+
+int passes_host_properties_filter(hoststatus *);
+int passes_service_properties_filter(servicestatus *);
+
+void document_header(int);
+void document_footer(void);
+int process_cgivars(void);
+
+
+authdata current_authdata;
+time_t current_time;
+
+char alert_message[MAX_MESSAGE_BUFFER];
+char *host_name=NULL;
+char *hostgroup_name=NULL;
+char *servicegroup_name=NULL;
+char *service_filter=NULL;
+int host_alert=FALSE;
+int show_all_hosts=TRUE;
+int show_all_hostgroups=TRUE;
+int show_all_servicegroups=TRUE;
+int display_type=DISPLAY_HOSTS;
+int overview_columns=3;
+int max_grid_width=8;
+int group_style_type=STYLE_OVERVIEW;
+int navbar_search=FALSE;
+
+int service_status_types=SERVICE_PENDING|SERVICE_OK|SERVICE_UNKNOWN|SERVICE_WARNING|SERVICE_CRITICAL;
+int all_service_status_types=SERVICE_PENDING|SERVICE_OK|SERVICE_UNKNOWN|SERVICE_WARNING|SERVICE_CRITICAL;
+
+int host_status_types=HOST_PENDING|HOST_UP|HOST_DOWN|HOST_UNREACHABLE;
+int all_host_status_types=HOST_PENDING|HOST_UP|HOST_DOWN|HOST_UNREACHABLE;
+
+int all_service_problems=SERVICE_UNKNOWN|SERVICE_WARNING|SERVICE_CRITICAL;
+int all_host_problems=HOST_DOWN|HOST_UNREACHABLE;
+
+unsigned long host_properties=0L;
+unsigned long service_properties=0L;
+
+
+
+
+int sort_type=SORT_NONE;
+int sort_option=SORT_HOSTNAME;
+
+int problem_hosts_down=0;
+int problem_hosts_unreachable=0;
+int problem_services_critical=0;
+int problem_services_warning=0;
+int problem_services_unknown=0;
+
+int embedded=FALSE;
+int display_header=TRUE;
+
+
+
+int main(void){
+	int result=OK;
+	char *sound=NULL;
+	host *temp_host=NULL;
+	hostgroup *temp_hostgroup=NULL;
+	servicegroup *temp_servicegroup=NULL;
+	
+	time(&current_time);
+
+	/* 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;
+                }
+
+	/* read all status data */
+	result=read_all_status_data(get_cgi_config_location(),READ_ALL_STATUS_DATA);
+	if(result==ERROR){
+		document_header(FALSE);
+		status_data_error();
+		document_footer();
+		free_memory();
+		return ERROR;
+                }
+
+	document_header(TRUE);
+
+	/* read in all host and service comments */
+	read_comment_data(get_cgi_config_location());
+
+	/* get authentication information */
+	get_authentication_information(&current_authdata);
+
+	/* if a navbar search was performed, find the host by name, address or partial name */
+	if(navbar_search==TRUE){
+		if((temp_host=find_host(host_name))==NULL){
+			for(temp_host=host_list;temp_host!=NULL;temp_host=temp_host->next){
+				if(is_authorized_for_host(temp_host,&current_authdata)==FALSE)
+					continue;
+				if(!strcmp(host_name,temp_host->address)){
+					free(host_name);
+					host_name=strdup(temp_host->name);
+					break;
+			                }
+		                }
+			if(temp_host==NULL){
+				for(temp_host=host_list;temp_host!=NULL;temp_host=temp_host->next){
+					if(is_authorized_for_host(temp_host,&current_authdata)==FALSE)
+						continue;
+					if((strstr(temp_host->name,host_name)==temp_host->name) || !strncasecmp(temp_host->name,host_name,strlen(host_name))){
+						free(host_name);
+						host_name=strdup(temp_host->name);
+						break;
+			                        }
+		                        }
+			        }
+			}
+			/* last effort, search hostgroups then servicegroups */
+			if(temp_host==NULL){
+				if((temp_hostgroup=find_hostgroup(host_name))!=NULL){
+					display_type=DISPLAY_HOSTGROUPS;
+					show_all_hostgroups=FALSE;
+					free(host_name);
+					hostgroup_name=strdup(temp_hostgroup->group_name);
+					}
+				else if((temp_servicegroup=find_servicegroup(host_name))!=NULL){
+					display_type=DISPLAY_SERVICEGROUPS;
+					show_all_servicegroups=FALSE;
+					free(host_name);
+					servicegroup_name=strdup(temp_servicegroup->group_name);
+				}
+			}
+	        }
+
+	if(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");
+
+		/* info table */
+		display_info_table("Current Network Status",TRUE,&current_authdata);
+
+		printf("<TABLE BORDER=1 CELLPADDING=0 CELLSPACING=0 CLASS='linkBox'>\n");
+		printf("<TR><TD CLASS='linkBox'>\n");
+
+		if(display_type==DISPLAY_HOSTS){
+			printf("<a href='%s?host=%s'>View History For %s</a><br>\n",HISTORY_CGI,(show_all_hosts==TRUE)?"all":url_encode(host_name),(show_all_hosts==TRUE)?"all hosts":"This Host");
+			printf("<a href='%s?host=%s'>View Notifications For %s</a>\n",NOTIFICATIONS_CGI,(show_all_hosts==TRUE)?"all":url_encode(host_name),(show_all_hosts==TRUE)?"All Hosts":"This Host");
+			if(show_all_hosts==FALSE)
+				printf("<br><a href='%s?host=all'>View Service Status Detail For All Hosts</a>\n",STATUS_CGI);
+			else
+				printf("<br><a href='%s?hostgroup=all&style=hostdetail'>View Host Status Detail For All Hosts</a>\n",STATUS_CGI);
+	                }
+		else if(display_type==DISPLAY_SERVICEGROUPS){
+			if(show_all_servicegroups==FALSE){
+
+				if(group_style_type==STYLE_OVERVIEW || group_style_type==STYLE_GRID || group_style_type==STYLE_SUMMARY)
+					printf("<a href='%s?servicegroup=%s&style=detail'>View Service Status Detail For This Service Group</a><br>\n",STATUS_CGI,url_encode(servicegroup_name));
+				if(group_style_type==STYLE_DETAIL || group_style_type==STYLE_GRID || group_style_type==STYLE_SUMMARY)
+					printf("<a href='%s?servicegroup=%s&style=overview'>View Status Overview For This Service Group</a><br>\n",STATUS_CGI,url_encode(servicegroup_name));
+				if(group_style_type==STYLE_DETAIL || group_style_type==STYLE_OVERVIEW || group_style_type==STYLE_GRID)
+					printf("<a href='%s?servicegroup=%s&style=summary'>View Status Summary For This Service Group</a><br>\n",STATUS_CGI,url_encode(servicegroup_name));
+				if(group_style_type==STYLE_DETAIL || group_style_type==STYLE_OVERVIEW || group_style_type==STYLE_SUMMARY)
+					printf("<a href='%s?servicegroup=%s&style=grid'>View Service Status Grid For This Service Group</a><br>\n",STATUS_CGI,url_encode(servicegroup_name));
+
+				if(group_style_type==STYLE_DETAIL)
+					printf("<a href='%s?servicegroup=all&style=detail'>View Service Status Detail For All Service Groups</a><br>\n",STATUS_CGI);
+				if(group_style_type==STYLE_OVERVIEW)
+					printf("<a href='%s?servicegroup=all&style=overview'>View Status Overview For All Service Groups</a><br>\n",STATUS_CGI);
+				if(group_style_type==STYLE_SUMMARY)
+					printf("<a href='%s?servicegroup=all&style=summary'>View Status Summary For All Service Groups</a><br>\n",STATUS_CGI);
+				if(group_style_type==STYLE_GRID)
+					printf("<a href='%s?servicegroup=all&style=grid'>View Service Status Grid For All Service Groups</a><br>\n",STATUS_CGI);
+
+			        }
+			else{
+				if(group_style_type==STYLE_OVERVIEW || group_style_type==STYLE_GRID || group_style_type==STYLE_SUMMARY)
+					printf("<a href='%s?servicegroup=all&style=detail'>View Service Status Detail For All Service Groups</a><br>\n",STATUS_CGI);
+				if(group_style_type==STYLE_DETAIL || group_style_type==STYLE_GRID || group_style_type==STYLE_SUMMARY)
+					printf("<a href='%s?servicegroup=all&style=overview'>View Status Overview For All Service Groups</a><br>\n",STATUS_CGI);
+				if(group_style_type==STYLE_DETAIL || group_style_type==STYLE_OVERVIEW || group_style_type==STYLE_GRID)
+					printf("<a href='%s?servicegroup=all&style=summary'>View Status Summary For All Service Groups</a><br>\n",STATUS_CGI);
+				if(group_style_type==STYLE_DETAIL || group_style_type==STYLE_OVERVIEW || group_style_type==STYLE_SUMMARY)
+					printf("<a href='%s?servicegroup=all&style=grid'>View Service Status Grid For All Service Groups</a><br>\n",STATUS_CGI);
+			        }
+		
+		        }
+		else{
+			if(show_all_hostgroups==FALSE){
+
+				if(group_style_type==STYLE_DETAIL)
+					printf("<a href='%s?hostgroup=all&style=detail'>View Service Status Detail For All Host Groups</a><br>\n",STATUS_CGI);
+				if(group_style_type==STYLE_HOST_DETAIL)
+					printf("<a href='%s?hostgroup=all&style=hostdetail'>View Host Status Detail For All Host Groups</a><br>\n",STATUS_CGI);
+				if(group_style_type==STYLE_OVERVIEW)
+					printf("<a href='%s?hostgroup=all&style=overview'>View Status Overview For All Host Groups</a><br>\n",STATUS_CGI);
+				if(group_style_type==STYLE_SUMMARY)
+					printf("<a href='%s?hostgroup=all&style=summary'>View Status Summary For All Host Groups</a><br>\n",STATUS_CGI);
+				if(group_style_type==STYLE_GRID)
+					printf("<a href='%s?hostgroup=all&style=grid'>View Status Grid For All Host Groups</a><br>\n",STATUS_CGI);
+
+				if(group_style_type==STYLE_OVERVIEW || group_style_type==STYLE_SUMMARY || group_style_type==STYLE_GRID || group_style_type==STYLE_HOST_DETAIL)
+					printf("<a href='%s?hostgroup=%s&style=detail'>View Service Status Detail For This Host Group</a><br>\n",STATUS_CGI,url_encode(hostgroup_name));
+				if(group_style_type==STYLE_OVERVIEW || group_style_type==STYLE_DETAIL || group_style_type==STYLE_SUMMARY || group_style_type==STYLE_GRID)
+					printf("<a href='%s?hostgroup=%s&style=hostdetail'>View Host Status Detail For This Host Group</a><br>\n",STATUS_CGI,url_encode(hostgroup_name));
+				if(group_style_type==STYLE_DETAIL || group_style_type==STYLE_SUMMARY || group_style_type==STYLE_GRID || group_style_type==STYLE_HOST_DETAIL)
+					printf("<a href='%s?hostgroup=%s&style=overview'>View Status Overview For This Host Group</a><br>\n",STATUS_CGI,url_encode(hostgroup_name));
+				if(group_style_type==STYLE_OVERVIEW || group_style_type==STYLE_DETAIL || group_style_type==STYLE_GRID || group_style_type==STYLE_HOST_DETAIL)
+					printf("<a href='%s?hostgroup=%s&style=summary'>View Status Summary For This Host Group</a><br>\n",STATUS_CGI,url_encode(hostgroup_name));
+				if(group_style_type==STYLE_OVERVIEW || group_style_type==STYLE_DETAIL || group_style_type==STYLE_SUMMARY || group_style_type==STYLE_HOST_DETAIL)
+					printf("<a href='%s?hostgroup=%s&style=grid'>View Status Grid For This Host Group</a><br>\n",STATUS_CGI,url_encode(hostgroup_name));
+		                }
+			else{
+				if(group_style_type==STYLE_OVERVIEW || group_style_type==STYLE_SUMMARY || group_style_type==STYLE_GRID || group_style_type==STYLE_HOST_DETAIL)
+					printf("<a href='%s?hostgroup=all&style=detail'>View Service Status Detail For All Host Groups</a><br>\n",STATUS_CGI);
+				if(group_style_type==STYLE_OVERVIEW || group_style_type==STYLE_DETAIL || group_style_type==STYLE_SUMMARY || group_style_type==STYLE_GRID)
+					printf("<a href='%s?hostgroup=all&style=hostdetail'>View Host Status Detail For All Host Groups</a><br>\n",STATUS_CGI);
+				if(group_style_type==STYLE_DETAIL || group_style_type==STYLE_SUMMARY || group_style_type==STYLE_GRID || group_style_type==STYLE_HOST_DETAIL)
+					printf("<a href='%s?hostgroup=all&style=overview'>View Status Overview For All Host Groups</a><br>\n",STATUS_CGI);
+				if(group_style_type==STYLE_OVERVIEW || group_style_type==STYLE_DETAIL || group_style_type==STYLE_GRID || group_style_type==STYLE_HOST_DETAIL)
+					printf("<a href='%s?hostgroup=all&style=summary'>View Status Summary For All Host Groups</a><br>\n",STATUS_CGI);
+				if(group_style_type==STYLE_OVERVIEW || group_style_type==STYLE_DETAIL || group_style_type==STYLE_SUMMARY || group_style_type==STYLE_HOST_DETAIL)
+					printf("<a href='%s?hostgroup=all&style=grid'>View Status Grid For All Host Groups</a><br>\n",STATUS_CGI);
+		                }
+	                }
+
+		printf("</TD></TR>\n");
+		printf("</TABLE>\n");
+
+		printf("</td>\n");
+
+		/* middle column of top row */
+		printf("<td align=center valign=top width=33%%>\n");
+		show_host_status_totals();
+		printf("</td>\n");
+
+		/* right hand column of top row */
+		printf("<td align=center valign=top width=33%%>\n");
+		show_service_status_totals();
+		printf("</td>\n");
+
+		/* display context-sensitive help */
+		printf("<td align=right valign=bottom>\n");
+		if(display_type==DISPLAY_HOSTS)
+			display_context_help(CONTEXTHELP_STATUS_DETAIL);
+		else if(display_type==DISPLAY_SERVICEGROUPS){
+			if(group_style_type==STYLE_HOST_DETAIL)
+				display_context_help(CONTEXTHELP_STATUS_DETAIL);
+			else if(group_style_type==STYLE_OVERVIEW)
+				display_context_help(CONTEXTHELP_STATUS_SGOVERVIEW);
+			else if(group_style_type==STYLE_SUMMARY)
+				display_context_help(CONTEXTHELP_STATUS_SGSUMMARY);
+			else if(group_style_type==STYLE_GRID)
+				display_context_help(CONTEXTHELP_STATUS_SGGRID);
+		        }
+		else{
+			if(group_style_type==STYLE_HOST_DETAIL)
+				display_context_help(CONTEXTHELP_STATUS_HOST_DETAIL);
+			else if(group_style_type==STYLE_OVERVIEW)
+				display_context_help(CONTEXTHELP_STATUS_HGOVERVIEW);
+			else if(group_style_type==STYLE_SUMMARY)
+				display_context_help(CONTEXTHELP_STATUS_HGSUMMARY);
+			else if(group_style_type==STYLE_GRID)
+				display_context_help(CONTEXTHELP_STATUS_HGGRID);
+		        }
+		printf("</td>\n");
+
+		/* end of top table */
+		printf("</tr>\n");
+		printf("</table>\n");
+	        }
+
+
+	/* embed sound tag if necessary... */
+	if(problem_hosts_unreachable>0 && host_unreachable_sound!=NULL)
+		sound=host_unreachable_sound;
+	else if(problem_hosts_down>0 && host_down_sound!=NULL)
+		sound=host_down_sound;
+	else if(problem_services_critical>0 && service_critical_sound!=NULL)
+		sound=service_critical_sound;
+	else if(problem_services_warning>0 && service_warning_sound!=NULL)
+		sound=service_warning_sound;
+	else if(problem_services_unknown>0 && service_unknown_sound!=NULL)
+		sound=service_unknown_sound;
+	else if(problem_services_unknown==0 && problem_services_warning==0 && problem_services_critical==0 && problem_hosts_down==0 && problem_hosts_unreachable==0 && normal_sound!=NULL)
+		sound=normal_sound;
+	if(sound!=NULL){
+		printf("<object type=\"application/x-mplayer2\" height=\"-\" width=\"0\">");
+		printf("<param name=\"filename\" value=\"%s%s\">",url_media_path,sound);
+		printf("<param name=\"autostart\" value=\"1\">");
+		printf("<param name=\"playcount\" value=\"1\">");
+		printf("</object>");
+		}
+
+
+	/* bottom portion of screen - service or hostgroup detail */
+	if(display_type==DISPLAY_HOSTS)
+		show_service_detail();
+	else if(display_type==DISPLAY_SERVICEGROUPS){
+		if(group_style_type==STYLE_OVERVIEW)
+			show_servicegroup_overviews();
+		else if(group_style_type==STYLE_SUMMARY)
+			show_servicegroup_summaries();
+		else if(group_style_type==STYLE_GRID)
+			show_servicegroup_grids();
+		else
+			show_service_detail();
+	        }
+	else{
+		if(group_style_type==STYLE_OVERVIEW)
+			show_hostgroup_overviews();
+		else if(group_style_type==STYLE_SUMMARY)
+			show_hostgroup_summaries();
+		else if(group_style_type==STYLE_GRID)
+			show_hostgroup_grids();
+		else if(group_style_type==STYLE_HOST_DETAIL)
+			show_host_detail();
+		else
+			show_service_detail();
+	        }
+
+	document_footer();
+
+	/* free all allocated memory */
+	free_memory();
+	free_comment_data();
+
+	/* free memory allocated to the sort lists */
+	free_servicesort_list();
+	free_hostsort_list();
+
+	return OK;
+        }
+
+
+void document_header(int use_stylesheet){
+	char date_time[MAX_DATETIME_LENGTH];
+	time_t expire_time;
+
+	printf("Cache-Control: no-store\r\n");
+	printf("Pragma: no-cache\r\n");
+	printf("Refresh: %d\r\n",refresh_rate);
+
+	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("Current Network Status\n");
+	printf("</title>\n");
+
+	if(use_stylesheet==TRUE){
+		printf("<LINK REL='stylesheet' TYPE='text/css' HREF='%s%s'>",url_stylesheets_path,COMMON_CSS);
+		printf("<LINK REL='stylesheet' TYPE='text/css' HREF='%s%s'>",url_stylesheets_path,STATUS_CSS);
+	        }
+
+	printf("</head>\n");
+
+	printf("<body CLASS='status'>\n");
+
+	/* include user SSI header */
+	include_ssi_files(STATUS_CGI,SSI_HEADER);
+
+	return;
+        }
+
+
+void document_footer(void){
+
+	if(embedded==TRUE)
+		return;
+
+	/* include user SSI footer */
+	include_ssi_files(STATUS_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 navbar search argument */
+		else if(!strcmp(variables[x],"navbarsearch")){
+			x++;
+			if(variables[x]==NULL){
+				error=TRUE;
+				break;
+			        }
+			navbar_search=TRUE;
+		        }
+
+		/* we found the hostgroup argument */
+		else if(!strcmp(variables[x],"hostgroup")){
+			display_type=DISPLAY_HOSTGROUPS;
+			x++;
+			if(variables[x]==NULL){
+				error=TRUE;
+				break;
+			        }
+
+			hostgroup_name=strdup(variables[x]);
+
+			if(hostgroup_name!=NULL && !strcmp(hostgroup_name,"all"))
+				show_all_hostgroups=TRUE;
+			else
+				show_all_hostgroups=FALSE;
+		        }
+
+		/* we found the servicegroup argument */
+		else if(!strcmp(variables[x],"servicegroup")){
+			display_type=DISPLAY_SERVICEGROUPS;
+			x++;
+			if(variables[x]==NULL){
+				error=TRUE;
+				break;
+			        }
+
+			servicegroup_name=strdup(variables[x]);
+
+			if(servicegroup_name!=NULL && !strcmp(servicegroup_name,"all"))
+				show_all_servicegroups=TRUE;
+			else
+				show_all_servicegroups=FALSE;
+		        }
+
+		/* we found the host argument */
+		else if(!strcmp(variables[x],"host")){
+			display_type=DISPLAY_HOSTS;
+			x++;
+			if(variables[x]==NULL){
+				error=TRUE;
+				break;
+			        }
+
+			host_name=strdup(variables[x]);
+
+			if(host_name!=NULL && !strcmp(host_name,"all"))
+				show_all_hosts=TRUE;
+			else
+				show_all_hosts=FALSE;
+		        }
+
+		/* we found the columns argument */
+		else if(!strcmp(variables[x],"columns")){
+			x++;
+			if(variables[x]==NULL){
+				error=TRUE;
+				break;
+			        }
+
+			overview_columns=atoi(variables[x]);
+			if(overview_columns<=0)
+				overview_columns=1;
+		        }
+
+		/* we found the service status type argument */
+		else if(!strcmp(variables[x],"servicestatustypes")){
+			x++;
+			if(variables[x]==NULL){
+				error=TRUE;
+				break;
+			        }
+
+			service_status_types=atoi(variables[x]);
+		        }
+
+		/* we found the host status type argument */
+		else if(!strcmp(variables[x],"hoststatustypes")){
+			x++;
+			if(variables[x]==NULL){
+				error=TRUE;
+				break;
+			        }
+
+			host_status_types=atoi(variables[x]);
+		        }
+
+		/* we found the service properties argument */
+		else if(!strcmp(variables[x],"serviceprops")){
+			x++;
+			if(variables[x]==NULL){
+				error=TRUE;
+				break;
+			        }
+
+			service_properties=strtoul(variables[x],NULL,10);
+		        }
+
+		/* we found the host properties argument */
+		else if(!strcmp(variables[x],"hostprops")){
+			x++;
+			if(variables[x]==NULL){
+				error=TRUE;
+				break;
+			        }
+
+			host_properties=strtoul(variables[x],NULL,10);
+		        }
+
+		/* we found the host or service group style argument */
+		else if(!strcmp(variables[x],"style")){
+			x++;
+			if(variables[x]==NULL){
+				error=TRUE;
+				break;
+			        }
+
+			if(!strcmp(variables[x],"overview"))
+				group_style_type=STYLE_OVERVIEW;
+			else if(!strcmp(variables[x],"detail"))
+				group_style_type=STYLE_DETAIL;
+			else if(!strcmp(variables[x],"summary"))
+				group_style_type=STYLE_SUMMARY;
+			else if(!strcmp(variables[x],"grid"))
+				group_style_type=STYLE_GRID;
+			else if(!strcmp(variables[x],"hostdetail"))
+				group_style_type=STYLE_HOST_DETAIL;
+			else
+				group_style_type=STYLE_DETAIL;
+		        }
+
+		/* we found the sort type argument */
+		else if(!strcmp(variables[x],"sorttype")){
+			x++;
+			if(variables[x]==NULL){
+				error=TRUE;
+				break;
+			        }
+
+			sort_type=atoi(variables[x]);
+		        }
+
+		/* we found the sort option argument */
+		else if(!strcmp(variables[x],"sortoption")){
+			x++;
+			if(variables[x]==NULL){
+				error=TRUE;
+				break;
+			        }
+
+			sort_option=atoi(variables[x]);
+		        }
+
+		/* 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;
+
+		/* servicefilter cgi var */
+                else if(!strcmp(variables[x],"servicefilter")){
+                        x++;
+                        if(variables[x]==NULL){
+                                error=TRUE;
+                                break;
+                                }
+                        service_filter=strdup(variables[x]);
+                        }
+	        }
+
+	/* free memory allocated to the CGI variables */
+	free_cgivars(variables);
+
+	return error;
+        }
+
+
+
+/* display table with service status totals... */
+void show_service_status_totals(void){
+	int total_ok=0;
+	int total_warning=0;
+	int total_unknown=0;
+	int total_critical=0;
+	int total_pending=0;
+	int total_services=0;
+	int total_problems=0;
+	servicestatus *temp_servicestatus;
+	service *temp_service;
+	host *temp_host;
+	int count_service;
+
+
+	/* check the status of all services... */
+	for(temp_servicestatus=servicestatus_list;temp_servicestatus!=NULL;temp_servicestatus=temp_servicestatus->next){
+
+		/* find the host and service... */
+		temp_host=find_host(temp_servicestatus->host_name);
+		temp_service=find_service(temp_servicestatus->host_name,temp_servicestatus->description);
+
+		/* make sure user has rights to see this service... */
+		if(is_authorized_for_service(temp_service,&current_authdata)==FALSE)
+			continue;
+
+		count_service=0;
+
+		if(display_type==DISPLAY_HOSTS && (show_all_hosts==TRUE || !strcmp(host_name,temp_servicestatus->host_name)))
+			count_service=1;
+		else if(display_type==DISPLAY_SERVICEGROUPS && (show_all_servicegroups==TRUE || (is_service_member_of_servicegroup(find_servicegroup(servicegroup_name),temp_service)==TRUE)))
+			count_service=1;
+		else if(display_type==DISPLAY_HOSTGROUPS && (show_all_hostgroups==TRUE || (is_host_member_of_hostgroup(find_hostgroup(hostgroup_name),temp_host)==TRUE)))
+			count_service=1;
+
+		if(count_service){
+
+			if(temp_servicestatus->status==SERVICE_CRITICAL){
+				total_critical++;
+				if(temp_servicestatus->problem_has_been_acknowledged==FALSE && temp_servicestatus->checks_enabled==TRUE && temp_servicestatus->notifications_enabled==TRUE && temp_servicestatus->scheduled_downtime_depth==0)
+					problem_services_critical++;
+			        }
+			else if(temp_servicestatus->status==SERVICE_WARNING){
+				total_warning++;
+				if(temp_servicestatus->problem_has_been_acknowledged==FALSE && temp_servicestatus->checks_enabled==TRUE && temp_servicestatus->notifications_enabled==TRUE && temp_servicestatus->scheduled_downtime_depth==0)
+					problem_services_warning++;
+			        }
+			else if(temp_servicestatus->status==SERVICE_UNKNOWN){
+				total_unknown++;
+				if(temp_servicestatus->problem_has_been_acknowledged==FALSE && temp_servicestatus->checks_enabled==TRUE && temp_servicestatus->notifications_enabled==TRUE && temp_servicestatus->scheduled_downtime_depth==0)
+					problem_services_unknown++;
+			        }
+			else if(temp_servicestatus->status==SERVICE_OK)
+				total_ok++;
+			else if(temp_servicestatus->status==SERVICE_PENDING)
+				total_pending++;
+			else
+				total_ok++;
+		        }
+	        }
+
+	total_services=total_ok+total_unknown+total_warning+total_critical+total_pending;
+	total_problems=total_unknown+total_warning+total_critical;
+
+
+	printf("<DIV CLASS='serviceTotals'>Service Status Totals</DIV>\n");
+
+	printf("<TABLE BORDER=0 CELLSPACING=0 CELLPADDING=0>\n");
+	printf("<TR><TD>\n");
+
+	printf("<TABLE BORDER=1 CLASS='serviceTotals'>\n");
+	printf("<TR>\n");
+
+	printf("<TH CLASS='serviceTotals'>");
+	printf("<A CLASS='serviceTotals' HREF='%s?",STATUS_CGI);
+	if(display_type==DISPLAY_HOSTS)
+		printf("host=%s",host_name);
+	else if(display_type==DISPLAY_SERVICEGROUPS)
+		printf("servicegroup=%s&style=detail",servicegroup_name);
+	else
+		printf("hostgroup=%s&style=detail",hostgroup_name);
+	printf("&servicestatustypes=%d",SERVICE_OK);
+	printf("&hoststatustypes=%d'>",host_status_types);
+	printf("Ok</A></TH>\n");
+
+	printf("<TH CLASS='serviceTotals'>");
+	printf("<A CLASS='serviceTotals' HREF='%s?",STATUS_CGI);
+	if(display_type==DISPLAY_HOSTS)
+		printf("host=%s",host_name);
+	else if(display_type==DISPLAY_SERVICEGROUPS)
+		printf("servicegroup=%s&style=detail",servicegroup_name);
+	else
+		printf("hostgroup=%s&style=detail",hostgroup_name);
+	printf("&servicestatustypes=%d",SERVICE_WARNING);
+	printf("&hoststatustypes=%d'>",host_status_types);
+	printf("Warning</A></TH>\n");
+
+	printf("<TH CLASS='serviceTotals'>");
+	printf("<A CLASS='serviceTotals' HREF='%s?",STATUS_CGI);
+	if(display_type==DISPLAY_HOSTS)
+		printf("host=%s",host_name);
+	else if(display_type==DISPLAY_SERVICEGROUPS)
+		printf("servicegroup=%s&style=detail",servicegroup_name);
+	else
+		printf("hostgroup=%s&style=detail",hostgroup_name);
+	printf("&servicestatustypes=%d",SERVICE_UNKNOWN);
+	printf("&hoststatustypes=%d'>",host_status_types);
+	printf("Unknown</A></TH>\n");
+
+	printf("<TH CLASS='serviceTotals'>");
+	printf("<A CLASS='serviceTotals' HREF='%s?",STATUS_CGI);
+	if(display_type==DISPLAY_HOSTS)
+		printf("host=%s",host_name);
+	else if(display_type==DISPLAY_SERVICEGROUPS)
+		printf("servicegroup=%s&style=detail",servicegroup_name);
+	else
+		printf("hostgroup=%s&style=detail",hostgroup_name);
+	printf("&servicestatustypes=%d",SERVICE_CRITICAL);
+	printf("&hoststatustypes=%d'>",host_status_types);
+	printf("Critical</A></TH>\n");
+
+	printf("<TH CLASS='serviceTotals'>");
+	printf("<A CLASS='serviceTotals' HREF='%s?",STATUS_CGI);
+	if(display_type==DISPLAY_HOSTS)
+		printf("host=%s",host_name);
+	else if(display_type==DISPLAY_SERVICEGROUPS)
+		printf("servicegroup=%s&style=detail",servicegroup_name);
+	else
+		printf("hostgroup=%s&style=detail",hostgroup_name);
+	printf("&servicestatustypes=%d",SERVICE_PENDING);
+	printf("&hoststatustypes=%d'>",host_status_types);
+	printf("Pending</A></TH>\n");
+
+	printf("</TR>\n");
+
+	printf("<TR>\n");
+
+
+	/* total services ok */
+	printf("<TD CLASS='serviceTotals%s'>%d</TD>\n",(total_ok>0)?"OK":"",total_ok);
+
+	/* total services in warning state */
+	printf("<TD CLASS='serviceTotals%s'>%d</TD>\n",(total_warning>0)?"WARNING":"",total_warning);
+
+	/* total services in unknown state */
+	printf("<TD CLASS='serviceTotals%s'>%d</TD>\n",(total_unknown>0)?"UNKNOWN":"",total_unknown);
+
+	/* total services in critical state */
+	printf("<TD CLASS='serviceTotals%s'>%d</TD>\n",(total_critical>0)?"CRITICAL":"",total_critical);
+
+	/* total services in pending state */
+	printf("<TD CLASS='serviceTotals%s'>%d</TD>\n",(total_pending>0)?"PENDING":"",total_pending);
+
+
+	printf("</TR>\n");
+	printf("</TABLE>\n");
+
+	printf("</TD></TR><TR><TD ALIGN=CENTER>\n");
+
+	printf("<TABLE BORDER=1 CLASS='serviceTotals'>\n");
+	printf("<TR>\n");
+
+	printf("<TH CLASS='serviceTotals'>");
+	printf("<A CLASS='serviceTotals' HREF='%s?",STATUS_CGI);
+	if(display_type==DISPLAY_HOSTS)
+		printf("host=%s",host_name);
+	else if(display_type==DISPLAY_SERVICEGROUPS)
+		printf("servicegroup=%s&style=detail",servicegroup_name);
+	else
+		printf("hostgroup=%s&style=detail",hostgroup_name);
+	printf("&servicestatustypes=%d",SERVICE_UNKNOWN|SERVICE_WARNING|SERVICE_CRITICAL);
+	printf("&hoststatustypes=%d'>",host_status_types);
+	printf("<I>All Problems</I></A></TH>\n");
+
+	printf("<TH CLASS='serviceTotals'>");
+	printf("<A CLASS='serviceTotals' HREF='%s?",STATUS_CGI);
+	if(display_type==DISPLAY_HOSTS)
+		printf("host=%s",host_name);
+	else if(display_type==DISPLAY_SERVICEGROUPS)
+		printf("servicegroup=%s&style=detail",servicegroup_name);
+	else
+		printf("hostgroup=%s&style=detail",hostgroup_name);
+	printf("&hoststatustypes=%d'>",host_status_types);
+	printf("<I>All Types</I></A></TH>\n");
+
+
+	printf("</TR><TR>\n");
+
+	/* total service problems */
+	printf("<TD CLASS='serviceTotals%s'>%d</TD>\n",(total_problems>0)?"PROBLEMS":"",total_problems);
+
+	/* total services */
+	printf("<TD CLASS='serviceTotals'>%d</TD>\n",total_services);
+
+	printf("</TR>\n");
+	printf("</TABLE>\n");
+
+	printf("</TD></TR>\n");
+	printf("</TABLE>\n");
+
+	printf("</DIV>\n");
+
+	return;
+        }
+
+
+/* display a table with host status totals... */
+void show_host_status_totals(void){
+	int total_up=0;
+	int total_down=0;
+	int total_unreachable=0;
+	int total_pending=0;
+	int total_hosts=0;
+	int total_problems=0;
+	hoststatus *temp_hoststatus;
+	host *temp_host;
+	servicestatus *temp_servicestatus;
+	service *temp_service;
+	int count_host;
+
+
+	/* check the status of all hosts... */
+	for(temp_hoststatus=hoststatus_list;temp_hoststatus!=NULL;temp_hoststatus=temp_hoststatus->next){
+
+		/* find the host... */
+		temp_host=find_host(temp_hoststatus->host_name);
+
+		/* make sure user has rights to view this host */
+		if(is_authorized_for_host(temp_host,&current_authdata)==FALSE)
+			continue;
+
+		count_host=0;
+
+		if(display_type==DISPLAY_HOSTS && (show_all_hosts==TRUE || !strcmp(host_name,temp_hoststatus->host_name)))
+			count_host=1;
+		else if(display_type==DISPLAY_SERVICEGROUPS){
+			if(show_all_servicegroups==TRUE)
+				count_host=1;
+			else{
+				for(temp_servicestatus=servicestatus_list;temp_servicestatus!=NULL;temp_servicestatus=temp_servicestatus->next){
+					if(strcmp(temp_servicestatus->host_name,temp_hoststatus->host_name))
+						continue;
+					temp_service=find_service(temp_servicestatus->host_name,temp_servicestatus->description);
+					if(is_authorized_for_service(temp_service,&current_authdata)==FALSE)
+						continue;
+					count_host=1;
+					break;
+				        }
+			        }
+		        }
+		else if(display_type==DISPLAY_HOSTGROUPS && (show_all_hostgroups==TRUE || (is_host_member_of_hostgroup(find_hostgroup(hostgroup_name),temp_host)==TRUE)))
+			count_host=1;
+
+		if(count_host){
+
+			if(temp_hoststatus->status==HOST_UP)
+				total_up++;
+			else if(temp_hoststatus->status==HOST_DOWN){
+				total_down++;
+				if(temp_hoststatus->problem_has_been_acknowledged==FALSE && temp_hoststatus->notifications_enabled==TRUE && temp_hoststatus->checks_enabled==TRUE && temp_hoststatus->scheduled_downtime_depth==0)
+					problem_hosts_down++;
+			        }
+			else if(temp_hoststatus->status==HOST_UNREACHABLE){
+				total_unreachable++;
+				if(temp_hoststatus->problem_has_been_acknowledged==FALSE && temp_hoststatus->notifications_enabled==TRUE && temp_hoststatus->checks_enabled==TRUE && temp_hoststatus->scheduled_downtime_depth==0)
+					problem_hosts_unreachable++;
+			        }
+
+			else if(temp_hoststatus->status==HOST_PENDING)
+				total_pending++;
+			else
+				total_up++;
+		        }
+	        }
+
+	total_hosts=total_up+total_down+total_unreachable+total_pending;
+	total_problems=total_down+total_unreachable;
+
+	printf("<DIV CLASS='hostTotals'>Host Status Totals</DIV>\n");
+
+	printf("<TABLE BORDER=0 CELLSPACING=0 CELLPADDING=0>\n");
+	printf("<TR><TD>\n");
+
+
+	printf("<TABLE BORDER=1 CLASS='hostTotals'>\n");
+	printf("<TR>\n");
+
+	printf("<TH CLASS='hostTotals'>");
+	printf("<A CLASS='hostTotals' HREF='%s?",STATUS_CGI);
+	if(display_type==DISPLAY_HOSTS)
+		printf("host=%s",host_name);
+	else if(display_type==DISPLAY_SERVICEGROUPS)
+		printf("servicegroup=%s",servicegroup_name);
+	else{
+		printf("hostgroup=%s",hostgroup_name);
+		if((service_status_types!=all_service_status_types) || group_style_type==STYLE_DETAIL)
+			printf("&style=detail");
+		else if(group_style_type==STYLE_HOST_DETAIL)
+			printf("&style=hostdetail");
+	        }
+	if(service_status_types!=all_service_status_types)
+		printf("&servicestatustypes=%d",service_status_types);
+	printf("&hoststatustypes=%d'>",HOST_UP);
+	printf("Up</A></TH>\n");
+
+	printf("<TH CLASS='hostTotals'>");
+	printf("<A CLASS='hostTotals' HREF='%s?",STATUS_CGI);
+	if(display_type==DISPLAY_HOSTS)
+		printf("host=%s",host_name);
+	else if(display_type==DISPLAY_SERVICEGROUPS)
+		printf("servicegroup=%s",servicegroup_name);
+	else{
+		printf("hostgroup=%s",hostgroup_name);
+		if((service_status_types!=all_service_status_types) || group_style_type==STYLE_DETAIL)
+			printf("&style=detail");
+		else if(group_style_type==STYLE_HOST_DETAIL)
+			printf("&style=hostdetail");
+	        }
+	if(service_status_types!=all_service_status_types)
+		printf("&servicestatustypes=%d",service_status_types);
+	printf("&hoststatustypes=%d'>",HOST_DOWN);
+	printf("Down</A></TH>\n");
+
+	printf("<TH CLASS='hostTotals'>");
+	printf("<A CLASS='hostTotals' HREF='%s?",STATUS_CGI);
+	if(display_type==DISPLAY_HOSTS)
+		printf("host=%s",host_name);
+	else if(display_type==DISPLAY_SERVICEGROUPS)
+		printf("servicegroup=%s",servicegroup_name);
+	else{
+		printf("hostgroup=%s",hostgroup_name);
+		if((service_status_types!=all_service_status_types) || group_style_type==STYLE_DETAIL)
+			printf("&style=detail");
+		else if(group_style_type==STYLE_HOST_DETAIL)
+			printf("&style=hostdetail");
+	        }
+	if(service_status_types!=all_service_status_types)
+		printf("&servicestatustypes=%d",service_status_types);
+	printf("&hoststatustypes=%d'>",HOST_UNREACHABLE);
+	printf("Unreachable</A></TH>\n");
+
+	printf("<TH CLASS='hostTotals'>");
+	printf("<A CLASS='hostTotals' HREF='%s?",STATUS_CGI);
+	if(display_type==DISPLAY_HOSTS)
+		printf("host=%s",host_name);
+	else if(display_type==DISPLAY_SERVICEGROUPS)
+		printf("servicegroup=%s",servicegroup_name);
+	else{
+		printf("hostgroup=%s",hostgroup_name);
+		if((service_status_types!=all_service_status_types) || group_style_type==STYLE_DETAIL)
+			printf("&style=detail");
+		else if(group_style_type==STYLE_HOST_DETAIL)
+			printf("&style=hostdetail");
+	        }
+	if(service_status_types!=all_service_status_types)
+		printf("&servicestatustypes=%d",service_status_types);
+	printf("&hoststatustypes=%d'>",HOST_PENDING);
+	printf("Pending</A></TH>\n");
+
+	printf("</TR>\n");
+
+
+	printf("<TR>\n");
+
+	/* total hosts up */
+	printf("<TD CLASS='hostTotals%s'>%d</TD>\n",(total_up>0)?"UP":"",total_up);
+
+	/* total hosts down */
+	printf("<TD CLASS='hostTotals%s'>%d</TD>\n",(total_down>0)?"DOWN":"",total_down);
+
+	/* total hosts unreachable */
+	printf("<TD CLASS='hostTotals%s'>%d</TD>\n",(total_unreachable>0)?"UNREACHABLE":"",total_unreachable);
+
+	/* total hosts pending */
+	printf("<TD CLASS='hostTotals%s'>%d</TD>\n",(total_pending>0)?"PENDING":"",total_pending);
+
+	printf("</TR>\n");
+	printf("</TABLE>\n");
+
+	printf("</TD></TR><TR><TD ALIGN=CENTER>\n");
+
+	printf("<TABLE BORDER=1 CLASS='hostTotals'>\n");
+	printf("<TR>\n");
+
+	printf("<TH CLASS='hostTotals'>");
+	printf("<A CLASS='hostTotals' HREF='%s?",STATUS_CGI);
+	if(display_type==DISPLAY_HOSTS)
+		printf("host=%s",host_name);
+	else if(display_type==DISPLAY_SERVICEGROUPS)
+		printf("servicegroup=%s",servicegroup_name);
+	else{
+		printf("hostgroup=%s",hostgroup_name);
+		if((service_status_types!=all_service_status_types) || group_style_type==STYLE_DETAIL)
+			printf("&style=detail");
+		else if(group_style_type==STYLE_HOST_DETAIL)
+			printf("&style=hostdetail");
+	        }
+	if(service_status_types!=all_service_status_types)
+		printf("&servicestatustypes=%d",service_status_types);
+	printf("&hoststatustypes=%d'>",HOST_DOWN|HOST_UNREACHABLE);
+	printf("<I>All Problems</I></A></TH>\n");
+
+	printf("<TH CLASS='hostTotals'>");
+	printf("<A CLASS='hostTotals' HREF='%s?",STATUS_CGI);
+	if(display_type==DISPLAY_HOSTS)
+		printf("host=%s",host_name);
+	else if(display_type==DISPLAY_SERVICEGROUPS)
+		printf("servicegroup=%s",servicegroup_name);
+	else{
+		printf("hostgroup=%s",hostgroup_name);
+		if((service_status_types!=all_service_status_types) || group_style_type==STYLE_DETAIL)
+			printf("&style=detail");
+		else if(group_style_type==STYLE_HOST_DETAIL)
+			printf("&style=hostdetail");
+	        }
+	if(service_status_types!=all_service_status_types)
+		printf("&servicestatustypes=%d",service_status_types);
+	printf("'>");
+	printf("<I>All Types</I></A></TH>\n");
+
+	printf("</TR><TR>\n");
+
+	/* total hosts with problems */
+	printf("<TD CLASS='hostTotals%s'>%d</TD>\n",(total_problems>0)?"PROBLEMS":"",total_problems);
+
+	/* total hosts */
+	printf("<TD CLASS='hostTotals'>%d</TD>\n",total_hosts);
+
+	printf("</TR>\n");
+	printf("</TABLE>\n");
+
+	printf("</TD></TR>\n");
+	printf("</TABLE>\n");
+
+	printf("</DIV>\n");
+
+	return;
+        }
+
+
+
+/* display a detailed listing of the status of all services... */
+void show_service_detail(void){
+	regex_t preg;
+	time_t t;
+	char date_time[MAX_DATETIME_LENGTH];
+	char state_duration[48];
+	char status[MAX_INPUT_BUFFER];
+	char temp_buffer[MAX_INPUT_BUFFER];
+	char temp_url[MAX_INPUT_BUFFER];
+	char *status_class="";
+	char *status_bg_class="";
+	char *host_status_bg_class="";
+	char *last_host="";
+	int new_host=FALSE;
+	servicestatus *temp_status=NULL;
+	hostgroup *temp_hostgroup=NULL;
+	servicegroup *temp_servicegroup=NULL;
+	hostextinfo *temp_hostextinfo=NULL;
+	serviceextinfo *temp_serviceextinfo=NULL;
+	hoststatus *temp_hoststatus=NULL;
+	host *temp_host=NULL;
+	service *temp_service=NULL;
+	int odd=0;
+	int total_comments=0;
+	int user_has_seen_something=FALSE;
+	servicesort *temp_servicesort=NULL;
+	int use_sort=FALSE;
+	int result=OK;
+	int first_entry=TRUE;
+	int days;
+	int hours;
+	int minutes;
+	int seconds;
+	int duration_error=FALSE;
+	int total_entries=0;
+	int show_service=FALSE;
+
+
+	/* sort the service list if necessary */
+	if(sort_type!=SORT_NONE){
+		result=sort_services(sort_type,sort_option);
+		if(result==ERROR)
+			use_sort=FALSE;
+		else
+			use_sort=TRUE;
+	        }
+	else
+		use_sort=FALSE;
+
+
+	printf("<P>\n");
+
+	printf("<table border=0 width=100%%>\n");
+	printf("<tr>\n");
+
+	printf("<td valign=top align=left width=33%%>\n");
+
+	if(display_header==TRUE)
+		show_filters();
+
+	printf("</td>");
+
+	printf("<td valign=top align=center width=33%%>\n");
+
+	printf("<DIV ALIGN=CENTER CLASS='statusTitle'>Service Status Details For ");
+	if(display_type==DISPLAY_HOSTS){
+		if(show_all_hosts==TRUE)
+			printf("All Hosts");
+		else
+			printf("Host '%s'",host_name);
+	        }
+	else if(display_type==DISPLAY_SERVICEGROUPS){
+		if(show_all_servicegroups==TRUE)
+			printf("All Service Groups");
+		else
+			printf("Service Group '%s'",servicegroup_name);
+	        }
+	else{
+		if(show_all_hostgroups==TRUE)
+			printf("All Host Groups");
+		else
+			printf("Host Group '%s'",hostgroup_name);
+	        }
+	printf("</DIV>\n");
+
+	if(use_sort==TRUE){
+		printf("<DIV ALIGN=CENTER CLASS='statusSort'>Entries sorted by <b>");
+		if(sort_option==SORT_HOSTNAME)
+			printf("host name");
+		else if(sort_option==SORT_SERVICENAME)
+			printf("service name");
+		else if(sort_option==SORT_SERVICESTATUS)
+			printf("service status");
+		else if(sort_option==SORT_LASTCHECKTIME)
+			printf("last check time");
+		else if(sort_option==SORT_CURRENTATTEMPT)
+			printf("attempt number");
+		else if(sort_option==SORT_STATEDURATION)
+			printf("state duration");
+		printf("</b> (%s)\n",(sort_type==SORT_ASCENDING)?"ascending":"descending");
+		printf("</DIV>\n");
+	        }
+
+	if(service_filter!=NULL)
+		printf("<DIV ALIGN=CENTER CLASS='statusSort'>Filtered By Services Matching \'%s\'</DIV>",service_filter);
+
+	printf("<br>");
+
+	printf("</td>\n");
+
+	printf("<td valign=top align=right width=33%%></td>\n");
+	
+	printf("</tr>\n");
+	printf("</table>\n");
+
+
+
+
+
+	snprintf(temp_url,sizeof(temp_url)-1,"%s?",STATUS_CGI);
+	temp_url[sizeof(temp_url)-1]='\x0';
+	if(display_type==DISPLAY_HOSTS)
+		snprintf(temp_buffer,sizeof(temp_buffer)-1,"host=%s",host_name);
+	else if(display_type==DISPLAY_SERVICEGROUPS)
+		snprintf(temp_buffer,sizeof(temp_buffer)-1,"servicegroup=%s&style=detail",servicegroup_name);
+	else
+		snprintf(temp_buffer,sizeof(temp_buffer)-1,"hostgroup=%s&style=detail",hostgroup_name);
+	temp_buffer[sizeof(temp_buffer)-1]='\x0';
+	strncat(temp_url,temp_buffer,sizeof(temp_url)-strlen(temp_url)-1);
+	temp_url[sizeof(temp_url)-1]='\x0';
+	if(service_status_types!=all_service_status_types){
+		snprintf(temp_buffer,sizeof(temp_buffer)-1,"&servicestatustypes=%d",service_status_types);
+		temp_buffer[sizeof(temp_buffer)-1]='\x0';
+		strncat(temp_url,temp_buffer,sizeof(temp_url)-strlen(temp_url)-1);
+		temp_url[sizeof(temp_url)-1]='\x0';
+	        }
+	if(host_status_types!=all_host_status_types){
+		snprintf(temp_buffer,sizeof(temp_buffer)-1,"&hoststatustypes=%d",host_status_types);
+		temp_buffer[sizeof(temp_buffer)-1]='\x0';
+		strncat(temp_url,temp_buffer,sizeof(temp_url)-strlen(temp_url)-1);
+		temp_url[sizeof(temp_url)-1]='\x0';
+	        }
+	if(service_properties!=0){
+		snprintf(temp_buffer,sizeof(temp_buffer)-1,"&serviceprops=%lu",service_properties);
+		temp_buffer[sizeof(temp_buffer)-1]='\x0';
+		strncat(temp_url,temp_buffer,sizeof(temp_url)-strlen(temp_url)-1);
+		temp_url[sizeof(temp_url)-1]='\x0';
+	        }
+	if(host_properties!=0){
+		snprintf(temp_buffer,sizeof(temp_buffer)-1,"&hostprops=%lu",host_properties);
+		temp_buffer[sizeof(temp_buffer)-1]='\x0';
+		strncat(temp_url,temp_buffer,sizeof(temp_url)-strlen(temp_url)-1);
+		temp_url[sizeof(temp_url)-1]='\x0';
+	        }
+
+	/* the main list of services */
+	printf("<TABLE BORDER=0 width=100%% CLASS='status'>\n");
+	printf("<TR>\n");
+
+	printf("<TH CLASS='status'>Host&nbsp;<A HREF='%s&sorttype=%d&sortoption=%d'><IMG SRC='%s%s' BORDER=0 ALT='Sort by host name (ascending)' TITLE='Sort by host name (ascending)'></A><A HREF='%s&sorttype=%d&sortoption=%d'><IMG SRC='%s%s' BORDER=0 ALT='Sort by host name (descending)' TITLE='Sort by host name (descending)'></A></TH>",temp_url,SORT_ASCENDING,SORT_HOSTNAME,url_images_path,UP_ARROW_ICON,temp_url,SORT_DESCENDING,SORT_HOSTNAME,url_images_path,DOWN_ARROW_ICON);
+
+	printf("<TH CLASS='status'>Service&nbsp;<A HREF='%s&sorttype=%d&sortoption=%d'><IMG SRC='%s%s' BORDER=0 ALT='Sort by service name (ascending)' TITLE='Sort by service name (ascending)'></A><A HREF='%s&sorttype=%d&sortoption=%d'><IMG SRC='%s%s' BORDER=0 ALT='Sort by service name (descending)' TITLE='Sort by service name (descending)'></A></TH>",temp_url,SORT_ASCENDING,SORT_SERVICENAME,url_images_path,UP_ARROW_ICON,temp_url,SORT_DESCENDING,SORT_SERVICENAME,url_images_path,DOWN_ARROW_ICON);
+
+	printf("<TH CLASS='status'>Status&nbsp;<A HREF='%s&sorttype=%d&sortoption=%d'><IMG SRC='%s%s' BORDER=0 ALT='Sort by service status (ascending)' TITLE='Sort by service status (ascending)'></A><A HREF='%s&sorttype=%d&sortoption=%d'><IMG SRC='%s%s' BORDER=0 ALT='Sort by service status (descending)' TITLE='Sort by service status (descending)'></A></TH>",temp_url,SORT_ASCENDING,SORT_SERVICESTATUS,url_images_path,UP_ARROW_ICON,temp_url,SORT_DESCENDING,SORT_SERVICESTATUS,url_images_path,DOWN_ARROW_ICON);
+
+	printf("<TH CLASS='status'>Last Check&nbsp;<A HREF='%s&sorttype=%d&sortoption=%d'><IMG SRC='%s%s' BORDER=0 ALT='Sort by last check time (ascending)' TITLE='Sort by last check time (ascending)'></A><A HREF='%s&sorttype=%d&sortoption=%d'><IMG SRC='%s%s' BORDER=0 ALT='Sort by last check time (descending)' TITLE='Sort by last check time (descending)'></A></TH>",temp_url,SORT_ASCENDING,SORT_LASTCHECKTIME,url_images_path,UP_ARROW_ICON,temp_url,SORT_DESCENDING,SORT_LASTCHECKTIME,url_images_path,DOWN_ARROW_ICON);
+
+	printf("<TH CLASS='status'>Duration&nbsp;<A HREF='%s&sorttype=%d&sortoption=%d'><IMG SRC='%s%s' BORDER=0 ALT='Sort by state duration (ascending)' TITLE='Sort by state duration (ascending)'></A><A HREF='%s&sorttype=%d&sortoption=%d'><IMG SRC='%s%s' BORDER=0 ALT='Sort by state duration time (descending)' TITLE='Sort by state duration time (descending)'></A></TH>",temp_url,SORT_ASCENDING,SORT_STATEDURATION,url_images_path,UP_ARROW_ICON,temp_url,SORT_DESCENDING,SORT_STATEDURATION,url_images_path,DOWN_ARROW_ICON);
+
+	printf("<TH CLASS='status'>Attempt&nbsp;<A HREF='%s&sorttype=%d&sortoption=%d'><IMG SRC='%s%s' BORDER=0 ALT='Sort by current attempt (ascending)' TITLE='Sort by current attempt (ascending)'></A><A HREF='%s&sorttype=%d&sortoption=%d'><IMG SRC='%s%s' BORDER=0 ALT='Sort by current attempt (descending)' TITLE='Sort by current attempt (descending)'></A></TH>",temp_url,SORT_ASCENDING,SORT_CURRENTATTEMPT,url_images_path,UP_ARROW_ICON,temp_url,SORT_DESCENDING,SORT_CURRENTATTEMPT,url_images_path,DOWN_ARROW_ICON);
+
+	printf("<TH CLASS='status'>Status Information</TH>\n");
+	printf("</TR>\n");
+
+
+	if(service_filter!=NULL)
+		regcomp(&preg,service_filter,0);
+
+	temp_hostgroup=find_hostgroup(hostgroup_name);
+	temp_servicegroup=find_servicegroup(servicegroup_name);
+
+	/* check all services... */
+	while(1){
+
+		/* get the next service to display */
+		if(use_sort==TRUE){
+			if(first_entry==TRUE)
+				temp_servicesort=servicesort_list;
+			else
+				temp_servicesort=temp_servicesort->next;
+			if(temp_servicesort==NULL)
+				break;
+			temp_status=temp_servicesort->svcstatus;
+	                }
+		else{
+			if(first_entry==TRUE)
+				temp_status=servicestatus_list;
+			else
+				temp_status=temp_status->next;
+		        }
+
+		if(temp_status==NULL)
+			break;
+
+		first_entry=FALSE;
+
+		/* find the service  */
+		temp_service=find_service(temp_status->host_name,temp_status->description);
+
+		/* if we couldn't find the service, go to the next service */
+		if(temp_service==NULL)
+			continue;
+
+		/* find the host */
+		temp_host=find_host(temp_service->host_name);
+
+		/* make sure user has rights to see this... */
+		if(is_authorized_for_service(temp_service,&current_authdata)==FALSE)
+			continue;
+
+		user_has_seen_something=TRUE;
+
+		/* get the host status information */
+		temp_hoststatus=find_hoststatus(temp_service->host_name);
+
+		/* see if we should display services for hosts with tis type of status */
+		if(!(host_status_types & temp_hoststatus->status))
+			continue;
+
+		/* see if we should display this type of service status */
+		if(!(service_status_types & temp_status->status))
+			continue;	
+
+		/* check host properties filter */
+		if(passes_host_properties_filter(temp_hoststatus)==FALSE)
+			continue;
+
+		/* check service properties filter */
+		if(passes_service_properties_filter(temp_status)==FALSE)
+			continue;
+
+		/* servicefilter cgi var */
+                if(service_filter!=NULL)
+			if(regexec(&preg,temp_status->description,0,NULL,0))
+				continue;
+
+		show_service=FALSE;
+
+		if(display_type==DISPLAY_HOSTS){
+			if(show_all_hosts==TRUE)
+				show_service=TRUE;
+			else if(!strcmp(host_name,temp_status->host_name))
+				show_service=TRUE;
+		        }
+
+		else if(display_type==DISPLAY_HOSTGROUPS){
+			if(show_all_hostgroups==TRUE)
+				show_service=TRUE;
+			else if(is_host_member_of_hostgroup(temp_hostgroup,temp_host)==TRUE)
+				show_service=TRUE;
+		        }
+
+		else if(display_type==DISPLAY_SERVICEGROUPS){
+			if(show_all_servicegroups==TRUE)
+				show_service=TRUE;
+			else if(is_service_member_of_servicegroup(temp_servicegroup,temp_service)==TRUE)
+				show_service=TRUE;
+		        }
+
+		if(show_service==TRUE){
+
+			if(strcmp(last_host,temp_status->host_name))
+				new_host=TRUE;
+			else
+				new_host=FALSE;
+
+			if(new_host==TRUE){
+				if(strcmp(last_host,"")){
+					printf("<TR><TD colspan=6></TD></TR>\n");
+					printf("<TR><TD colspan=6></TD></TR>\n");
+				        }
+			        }
+
+			if(odd)
+				odd=0;
+			else
+				odd=1;
+
+			/* keep track of total number of services we're displaying */
+			total_entries++;
+
+		        /* get the last service check time */
+			t=temp_status->last_check;
+			get_time_string(&t,date_time,(int)sizeof(date_time),SHORT_DATE_TIME);
+			if((unsigned long)temp_status->last_check==0L)
+				strcpy(date_time,"N/A");
+
+			if(temp_status->status==SERVICE_PENDING){
+				strncpy(status,"PENDING",sizeof(status));
+				status_class="PENDING";
+				status_bg_class=(odd)?"Even":"Odd";
+		                }
+			else if(temp_status->status==SERVICE_OK){
+				strncpy(status,"OK",sizeof(status));
+				status_class="OK";
+				status_bg_class=(odd)?"Even":"Odd";
+		                }
+			else if(temp_status->status==SERVICE_WARNING){
+				strncpy(status,"WARNING",sizeof(status));
+				status_class="WARNING";
+				if(temp_status->problem_has_been_acknowledged==TRUE)
+					status_bg_class="BGWARNINGACK";
+				else if(temp_status->scheduled_downtime_depth>0)
+					status_bg_class="BGWARNINGSCHED";
+				else
+					status_bg_class="BGWARNING";
+		                }
+			else if(temp_status->status==SERVICE_UNKNOWN){
+				strncpy(status,"UNKNOWN",sizeof(status));
+				status_class="UNKNOWN";
+				if(temp_status->problem_has_been_acknowledged==TRUE)
+					status_bg_class="BGUNKNOWNACK";
+				else if(temp_status->scheduled_downtime_depth>0)
+					status_bg_class="BGUNKNOWNSCHED";
+				else
+					status_bg_class="BGUNKNOWN";
+		                }
+			else if(temp_status->status==SERVICE_CRITICAL){
+				strncpy(status,"CRITICAL",sizeof(status));
+				status_class="CRITICAL";
+				if(temp_status->problem_has_been_acknowledged==TRUE)
+					status_bg_class="BGCRITICALACK";
+				else if(temp_status->scheduled_downtime_depth>0)
+					status_bg_class="BGCRITICALSCHED";
+				else
+					status_bg_class="BGCRITICAL";
+		                }
+			status[sizeof(status)-1]='\x0';
+
+
+			printf("<TR>\n");
+
+			/* host name column */
+			if(new_host==TRUE){
+
+				/* find extended information for this host */
+				temp_hostextinfo=find_hostextinfo(temp_status->host_name);
+
+				if(temp_hoststatus->status==HOST_DOWN){
+					if(temp_hoststatus->problem_has_been_acknowledged==TRUE)
+						host_status_bg_class="HOSTDOWNACK";
+					else if(temp_hoststatus->scheduled_downtime_depth>0)
+						host_status_bg_class="HOSTDOWNSCHED";
+					else
+						host_status_bg_class="HOSTDOWN";
+				        }
+				else if(temp_hoststatus->status==HOST_UNREACHABLE){
+					if(temp_hoststatus->problem_has_been_acknowledged==TRUE)
+						host_status_bg_class="HOSTUNREACHABLEACK";
+					else if(temp_hoststatus->scheduled_downtime_depth>0)
+						host_status_bg_class="HOSTUNREACHABLESCHED";
+					else
+						host_status_bg_class="HOSTUNREACHABLE";
+				        }
+				else
+					host_status_bg_class=(odd)?"Even":"Odd";
+
+				printf("<TD CLASS='status%s'>",host_status_bg_class);
+
+				printf("<TABLE BORDER=0 WIDTH='100%%' cellpadding=0 cellspacing=0>\n");
+				printf("<TR>\n");
+				printf("<TD ALIGN=LEFT>\n");
+				printf("<TABLE BORDER=0 cellpadding=0 cellspacing=0>\n");
+				printf("<TR>\n");
+				printf("<TD align=left valign=center CLASS='status%s'><A HREF='%s?type=%d&host=%s'>%s</A></TD>\n",host_status_bg_class,EXTINFO_CGI,DISPLAY_HOST_INFO,url_encode(temp_status->host_name),temp_status->host_name);
+				printf("</TR>\n");
+				printf("</TABLE>\n");
+				printf("</TD>\n");
+				printf("<TD align=right valign=center>\n");
+				printf("<TABLE BORDER=0 cellpadding=0 cellspacing=0>\n");
+				printf("<TR>\n");
+				total_comments=number_of_host_comments(temp_host->name);
+				if(temp_hoststatus->problem_has_been_acknowledged==TRUE){
+					printf("<TD ALIGN=center valign=center><A HREF='%s?type=%d&host=%s#comments'><IMG SRC='%s%s' BORDER=0 WIDTH=%d HEIGHT=%d ALT='This host problem has been acknowledged' TITLE='This host problem has been acknowledged'></A></TD>",EXTINFO_CGI,DISPLAY_HOST_INFO,url_encode(temp_status->host_name),url_images_path,ACKNOWLEDGEMENT_ICON,STATUS_ICON_WIDTH,STATUS_ICON_HEIGHT);
+			                }
+				if(total_comments>0)
+					printf("<TD ALIGN=center valign=center><A HREF='%s?type=%d&host=%s#comments'><IMG SRC='%s%s' BORDER=0 WIDTH=%d HEIGHT=%d ALT='This host has %d comment%s associated with it' TITLE='This host has %d comment%s associated with it'></A></TD>",EXTINFO_CGI,DISPLAY_HOST_INFO,url_encode(temp_status->host_name),url_images_path,COMMENT_ICON,STATUS_ICON_WIDTH,STATUS_ICON_HEIGHT,total_comments,(total_comments==1)?"":"s",total_comments,(total_comments==1)?"":"s");
+				if(temp_hoststatus->notifications_enabled==FALSE){
+					printf("<TD ALIGN=center valign=center><A HREF='%s?type=%d&host=%s'><IMG SRC='%s%s' BORDER=0 WIDTH=%d HEIGHT=%d ALT='Notifications for this host have been disabled' TITLE='Notifications for this host have been disabled'></A></TD>",EXTINFO_CGI,DISPLAY_HOST_INFO,url_encode(temp_status->host_name),url_images_path,NOTIFICATIONS_DISABLED_ICON,STATUS_ICON_WIDTH,STATUS_ICON_HEIGHT);
+			                }
+				if(temp_hoststatus->checks_enabled==FALSE){
+					printf("<TD ALIGN=center valign=center><A HREF='%s?type=%d&host=%s'><IMG SRC='%s%s' BORDER=0 WIDTH=%d HEIGHT=%d ALT='Checks of this host have been disabled'd TITLE='Checks of this host have been disabled'></A></TD>",EXTINFO_CGI,DISPLAY_HOST_INFO,url_encode(temp_status->host_name),url_images_path,DISABLED_ICON,STATUS_ICON_WIDTH,STATUS_ICON_HEIGHT);
+				        }
+				if(temp_hoststatus->is_flapping==TRUE){
+					printf("<TD ALIGN=center valign=center><A HREF='%s?type=%d&host=%s'><IMG SRC='%s%s' BORDER=0 WIDTH=%d HEIGHT=%d ALT='This host is flapping between states' TITLE='This host is flapping between states'></A></TD>",EXTINFO_CGI,DISPLAY_HOST_INFO,url_encode(temp_status->host_name),url_images_path,FLAPPING_ICON,STATUS_ICON_WIDTH,STATUS_ICON_HEIGHT);
+				        }
+				if(temp_hoststatus->scheduled_downtime_depth>0){
+					printf("<TD ALIGN=center valign=center><A HREF='%s?type=%d&host=%s'><IMG SRC='%s%s' BORDER=0 WIDTH=%d HEIGHT=%d ALT='This host is currently in a period of scheduled downtime' TITLE='This host is currently in a period of scheduled downtime'></A></TD>",EXTINFO_CGI,DISPLAY_HOST_INFO,url_encode(temp_status->host_name),url_images_path,SCHEDULED_DOWNTIME_ICON,STATUS_ICON_WIDTH,STATUS_ICON_HEIGHT);
+				        }
+				if(temp_hostextinfo!=NULL){
+					if(temp_hostextinfo->notes_url!=NULL){
+						printf("<TD align=center valign=center>");
+						printf("<A HREF='");
+						print_extra_host_url(temp_hostextinfo->host_name,temp_hostextinfo->notes_url);
+						printf("' TARGET='_blank'>");
+						printf("<IMG SRC='%s%s' BORDER=0 WIDTH=%d HEIGHT=%d ALT='%s' TITLE='%s'>",url_images_path,NOTES_ICON,STATUS_ICON_WIDTH,STATUS_ICON_HEIGHT,"View Extra Host Notes","View Extra Host Notes");
+						printf("</A>");
+						printf("</TD>\n");
+					        }
+					if(temp_hostextinfo->action_url!=NULL){
+						printf("<TD align=center valign=center>");
+						printf("<A HREF='");
+						print_extra_host_url(temp_hostextinfo->host_name,temp_hostextinfo->action_url);
+						printf("' TARGET='_blank'>");
+						printf("<IMG SRC='%s%s' BORDER=0 WIDTH=%d HEIGHT=%d ALT='%s' TITLE='%s'>",url_images_path,ACTION_ICON,STATUS_ICON_WIDTH,STATUS_ICON_HEIGHT,"Perform Extra Host Actions","Perform Extra Host Actions");
+						printf("</A>");
+						printf("</TD>\n");
+					        }
+					if(temp_hostextinfo->icon_image!=NULL){
+						printf("<TD align=center valign=center>");
+						printf("<A HREF='%s?type=%d&host=%s'>",EXTINFO_CGI,DISPLAY_HOST_INFO,url_encode(temp_status->host_name));
+						printf("<IMG SRC='%s",url_logo_images_path);
+						print_extra_host_url(temp_hostextinfo->host_name,temp_hostextinfo->icon_image);
+						printf("' BORDER=0 WIDTH=%d HEIGHT=%d ALT='%s' TITLE='%s'>",STATUS_ICON_WIDTH,STATUS_ICON_HEIGHT,(temp_hostextinfo->icon_image_alt==NULL)?"":temp_hostextinfo->icon_image_alt,(temp_hostextinfo->icon_image_alt==NULL)?"":temp_hostextinfo->icon_image_alt);
+						printf("</A>");
+						printf("</TD>\n");
+					        }
+				        }
+				printf("</TR>\n");
+				printf("</TABLE>\n");
+				printf("</TD>\n");
+				printf("</TR>\n");
+				printf("</TABLE>\n");
+			        }
+			else
+				printf("<TD>");
+			printf("</TD>\n");
+
+			/* service name column */
+			printf("<TD CLASS='status%s'>",status_bg_class);
+			printf("<TABLE BORDER=0 WIDTH='100%%' CELLSPACING=0 CELLPADDING=0>");
+			printf("<TR>");
+			printf("<TD ALIGN=LEFT>");
+			printf("<TABLE BORDER=0 CELLSPACING=0 CELLPADDING=0>\n");
+			printf("<TR>\n");
+			printf("<TD ALIGN=LEFT valign=center CLASS='status%s'><A HREF='%s?type=%d&host=%s",status_bg_class,EXTINFO_CGI,DISPLAY_SERVICE_INFO,url_encode(temp_status->host_name));
+			printf("&service=%s'>%s</A></TD>",url_encode(temp_status->description),temp_status->description);
+			printf("</TR>\n");
+			printf("</TABLE>\n");
+			printf("</TD>\n");
+			printf("<TD ALIGN=RIGHT CLASS='status%s'>\n",status_bg_class);
+			printf("<TABLE BORDER=0 cellspacing=0 cellpadding=0>\n");
+			printf("<TR>\n");
+			total_comments=number_of_service_comments(temp_service->host_name,temp_service->description);
+			if(total_comments>0){
+				printf("<TD ALIGN=center valign=center><A HREF='%s?type=%d&host=%s",EXTINFO_CGI,DISPLAY_SERVICE_INFO,url_encode(temp_status->host_name));
+				printf("&service=%s#comments'><IMG SRC='%s%s' BORDER=0 WIDTH=%d HEIGHT=%d ALT='This service has %d comment%s associated with it' TITLE='This service has %d comment%s associated with it'></A></TD>",url_encode(temp_status->description),url_images_path,COMMENT_ICON,STATUS_ICON_WIDTH,STATUS_ICON_HEIGHT,total_comments,(total_comments==1)?"":"s",total_comments,(total_comments==1)?"":"s");
+			        }
+			if(temp_status->problem_has_been_acknowledged==TRUE){
+				printf("<TD ALIGN=center valign=center><A HREF='%s?type=%d&host=%s",EXTINFO_CGI,DISPLAY_SERVICE_INFO,url_encode(temp_status->host_name));
+				printf("&service=%s#comments'><IMG SRC='%s%s' BORDER=0 WIDTH=%d HEIGHT=%d ALT='This service problem has been acknowledged' TITLE='This service problem has been acknowledged'></A></TD>",url_encode(temp_status->description),url_images_path,ACKNOWLEDGEMENT_ICON,STATUS_ICON_WIDTH,STATUS_ICON_HEIGHT);
+			        }
+			if(temp_status->checks_enabled==FALSE && temp_status->accept_passive_service_checks==FALSE){
+				printf("<TD ALIGN=center valign=center><A HREF='%s?type=%d&host=%s",EXTINFO_CGI,DISPLAY_SERVICE_INFO,url_encode(temp_status->host_name));
+				printf("&service=%s'><IMG SRC='%s%s' BORDER=0 WIDTH=%d HEIGHT=%d ALT='Active and passive checks have been disabled for this service' TITLE='Active and passive checks have been disabled for this service'></A></TD>",url_encode(temp_status->description),url_images_path,DISABLED_ICON,STATUS_ICON_WIDTH,STATUS_ICON_HEIGHT);
+			        }
+			else if(temp_status->checks_enabled==FALSE){
+				printf("<TD ALIGN=center valign=center><A HREF='%s?type=%d&host=%s",EXTINFO_CGI,DISPLAY_SERVICE_INFO,url_encode(temp_status->host_name));
+				printf("&service=%s'><IMG SRC='%s%s' BORDER=0 WIDTH=%d HEIGHT=%d ALT='Active checks of the service have been disabled - only passive checks are being accepted' TITLE='Active checks of the service have been disabled - only passive checks are being accepted'></A></TD>",url_encode(temp_status->description),url_images_path,PASSIVE_ONLY_ICON,STATUS_ICON_WIDTH,STATUS_ICON_HEIGHT);
+			        }
+			if(temp_status->notifications_enabled==FALSE){
+				printf("<TD ALIGN=center valign=center><A HREF='%s?type=%d&host=%s",EXTINFO_CGI,DISPLAY_SERVICE_INFO,url_encode(temp_status->host_name));
+				printf("&service=%s'><IMG SRC='%s%s' BORDER=0 WIDTH=%d HEIGHT=%d ALT='Notifications for this service have been disabled' TITLE='Notifications for this service have been disabled'></A></TD>",url_encode(temp_status->description),url_images_path,NOTIFICATIONS_DISABLED_ICON,STATUS_ICON_WIDTH,STATUS_ICON_HEIGHT);
+			        }
+			if(temp_status->is_flapping==TRUE){
+				printf("<TD ALIGN=center valign=center><A HREF='%s?type=%d&host=%s",EXTINFO_CGI,DISPLAY_SERVICE_INFO,url_encode(temp_status->host_name));
+				printf("&service=%s'><IMG SRC='%s%s' BORDER=0 WIDTH=%d HEIGHT=%d ALT='This service is flapping between states' TITLE='This service is flapping between states'></A></TD>",url_encode(temp_status->description),url_images_path,FLAPPING_ICON,STATUS_ICON_WIDTH,STATUS_ICON_HEIGHT);
+			        }
+			if(temp_status->scheduled_downtime_depth>0){
+				printf("<TD ALIGN=center valign=center><A HREF='%s?type=%d&host=%s",EXTINFO_CGI,DISPLAY_SERVICE_INFO,url_encode(temp_status->host_name));
+				printf("&service=%s'><IMG SRC='%s%s' BORDER=0 WIDTH=%d HEIGHT=%d ALT='This service is currently in a period of scheduled downtime' TITLE='This service is currently in a period of scheduled downtime'></A></TD>",url_encode(temp_status->description),url_images_path,SCHEDULED_DOWNTIME_ICON,STATUS_ICON_WIDTH,STATUS_ICON_HEIGHT);
+			        }
+			temp_serviceextinfo=find_serviceextinfo(temp_service->host_name,temp_service->description);
+			if(temp_serviceextinfo!=NULL){
+				if(temp_serviceextinfo->notes_url!=NULL){
+					printf("<TD align=center valign=center>");
+					printf("<A HREF='");
+					print_extra_service_url(temp_service->host_name,temp_service->description,temp_serviceextinfo->notes_url);
+					printf("' TARGET='_blank'>");
+					printf("<IMG SRC='%s%s' BORDER=0 WIDTH=%d HEIGHT=%d ALT='%s' TITLE='%s'>",url_images_path,NOTES_ICON,STATUS_ICON_WIDTH,STATUS_ICON_HEIGHT,"View Extra Service Notes","View Extra Service Notes");
+					printf("</A>");
+					printf("</TD>\n");
+					}
+				if(temp_serviceextinfo->action_url!=NULL){
+					printf("<TD align=center valign=center>");
+					printf("<A HREF='");
+					print_extra_service_url(temp_service->host_name,temp_service->description,temp_serviceextinfo->action_url);
+					printf("' TARGET='_blank'>");
+					printf("<IMG SRC='%s%s' BORDER=0 WIDTH=%d HEIGHT=%d ALT='%s' TITLE='%s'>",url_images_path,ACTION_ICON,STATUS_ICON_WIDTH,STATUS_ICON_HEIGHT,"Perform Extra Service Actions","Perform Extra Service Actions");
+					printf("</A>");
+					printf("</TD>\n");
+					}
+				if(temp_serviceextinfo->icon_image!=NULL){
+					printf("<TD ALIGN=center valign=center>");
+					printf("<A HREF='%s?type=%d&host=%s",EXTINFO_CGI,DISPLAY_SERVICE_INFO,url_encode(temp_service->host_name));
+					printf("&service=%s'>",url_encode(temp_service->description));
+					printf("<IMG SRC='%s",url_logo_images_path);
+					print_extra_service_url(temp_service->host_name,temp_service->description,temp_serviceextinfo->icon_image);
+					printf("' BORDER=0 WIDTH=%d HEIGHT=%d ALT='%s' TITLE='%s'>",STATUS_ICON_WIDTH,STATUS_ICON_HEIGHT,(temp_serviceextinfo->icon_image_alt==NULL)?"":temp_serviceextinfo->icon_image_alt,(temp_serviceextinfo->icon_image_alt==NULL)?"":temp_serviceextinfo->icon_image_alt);
+					printf("</A>");
+					printf("</TD>\n");
+				        }
+			        }
+			printf("</TR>\n");
+			printf("</TABLE>\n");
+			printf("</TD>\n");
+			printf("</TR>");
+			printf("</TABLE>");
+			printf("</TD>\n");
+
+			/* state duration calculation... */
+			t=0;
+			duration_error=FALSE;
+			if(temp_status->last_state_change==(time_t)0){
+				if(program_start>current_time)
+					duration_error=TRUE;
+				else
+					t=current_time-program_start;
+			        }
+			else{
+				if(temp_status->last_state_change>current_time)
+					duration_error=TRUE;
+				else
+					t=current_time-temp_status->last_state_change;
+			        }
+			get_time_breakdown((unsigned long)t,&days,&hours,&minutes,&seconds);
+			if(duration_error==TRUE)
+				snprintf(state_duration,sizeof(state_duration)-1,"???");
+			else
+				snprintf(state_duration,sizeof(state_duration)-1,"%2dd %2dh %2dm %2ds%s",days,hours,minutes,seconds,(temp_status->last_state_change==(time_t)0)?"+":"");
+			state_duration[sizeof(state_duration)-1]='\x0';
+
+                        /* the rest of the columns... */
+			printf("<TD CLASS='status%s'>%s</TD>\n",status_class,status);
+			printf("<TD CLASS='status%s' nowrap>%s</TD>\n",status_bg_class,date_time);
+			printf("<TD CLASS='status%s' nowrap>%s</TD>\n",status_bg_class,state_duration);
+			printf("<TD CLASS='status%s'>%d/%d</TD>\n",status_bg_class,temp_status->current_attempt,temp_status->max_attempts);
+			printf("<TD CLASS='status%s'>%s&nbsp;</TD>\n",status_bg_class,(temp_status->plugin_output==NULL)?"":temp_status->plugin_output);
+
+			printf("</TR>\n");
+
+			last_host=temp_status->host_name;
+		        }
+
+	        }
+
+	printf("</TABLE>\n");
+
+	/* if user couldn't see anything, print out some helpful info... */
+	if(user_has_seen_something==FALSE){
+
+		if(servicestatus_list!=NULL){
+			printf("<P><DIV CLASS='errorMessage'>It appears as though you do not have permission to view information for any of the services you requested...</DIV></P>\n");
+			printf("<P><DIV CLASS='errorDescription'>If you believe this is an error, check the HTTP server authentication requirements for accessing this CGI<br>");
+			printf("and check the authorization options in your CGI configuration file.</DIV></P>\n");
+		        }
+		else{
+			printf("<P><DIV CLASS='infoMessage'>There doesn't appear to be any service status information in the status log...<br><br>\n");
+			printf("Make sure that Nagios is running and that you have specified the location of you status log correctly in the configuration files.</DIV></P>\n");
+		        }
+	        }
+
+	else
+		printf("<BR><DIV CLASS='itemTotalsTitle'>%d Matching Service Entries Displayed</DIV>\n",total_entries);
+
+	return;
+        }
+
+
+
+
+/* display a detailed listing of the status of all hosts... */
+void show_host_detail(void){
+	time_t t;
+	char date_time[MAX_DATETIME_LENGTH];
+	char state_duration[48];
+	char status[MAX_INPUT_BUFFER];
+	char temp_buffer[MAX_INPUT_BUFFER];
+	char temp_url[MAX_INPUT_BUFFER];
+	char *status_class="";
+	char *status_bg_class="";
+	hoststatus *temp_status=NULL;
+	hostgroup *temp_hostgroup=NULL;
+	hostextinfo *temp_hostextinfo=NULL;
+	host *temp_host=NULL;
+	hostsort *temp_hostsort=NULL;
+	int odd=0;
+	int total_comments=0;
+	int user_has_seen_something=FALSE;
+	int use_sort=FALSE;
+	int result=OK;
+	int first_entry=TRUE;
+	int days;
+	int hours;
+	int minutes;
+	int seconds;
+	int duration_error=FALSE;
+	int total_entries=0;
+
+
+	/* sort the host list if necessary */
+	if(sort_type!=SORT_NONE){
+		result=sort_hosts(sort_type,sort_option);
+		if(result==ERROR)
+			use_sort=FALSE;
+		else
+			use_sort=TRUE;
+	        }
+	else
+		use_sort=FALSE;
+
+
+	printf("<P>\n");
+
+	printf("<table border=0 width=100%%>\n");
+	printf("<tr>\n");
+
+	printf("<td valign=top align=left width=33%%>\n");
+
+	show_filters();
+
+	printf("</td>");
+
+	printf("<td valign=top align=center width=33%%>\n");
+
+	printf("<DIV ALIGN=CENTER CLASS='statusTitle'>Host Status Details For ");
+	if(show_all_hostgroups==TRUE)
+		printf("All Host Groups");
+	else
+		printf("Host Group '%s'",hostgroup_name);
+	printf("</DIV>\n");
+
+	if(use_sort==TRUE){
+		printf("<DIV ALIGN=CENTER CLASS='statusSort'>Entries sorted by <b>");
+		if(sort_option==SORT_HOSTNAME)
+			printf("host name");
+		else if(sort_option==SORT_HOSTSTATUS)
+			printf("host status");
+		else if(sort_option==SORT_LASTCHECKTIME)
+			printf("last check time");
+		else if(sort_option==SORT_CURRENTATTEMPT)
+			printf("attempt number");
+		else if(sort_option==SORT_STATEDURATION)
+			printf("state duration");
+		printf("</b> (%s)\n",(sort_type==SORT_ASCENDING)?"ascending":"descending");
+		printf("</DIV>\n");
+	        }
+
+	printf("<br>");
+
+	printf("</td>\n");
+
+	printf("<td valign=top align=right width=33%%></td>\n");
+	
+	printf("</tr>\n");
+	printf("</table>\n");
+
+
+
+
+
+	snprintf(temp_url,sizeof(temp_url)-1,"%s?",STATUS_CGI);
+	temp_url[sizeof(temp_url)-1]='\x0';
+	snprintf(temp_buffer,sizeof(temp_buffer)-1,"hostgroup=%s&style=hostdetail",hostgroup_name);
+	temp_buffer[sizeof(temp_buffer)-1]='\x0';
+	strncat(temp_url,temp_buffer,sizeof(temp_url)-strlen(temp_url)-1);
+	temp_url[sizeof(temp_url)-1]='\x0';
+	if(service_status_types!=all_service_status_types){
+		snprintf(temp_buffer,sizeof(temp_buffer)-1,"&servicestatustypes=%d",service_status_types);
+		temp_buffer[sizeof(temp_buffer)-1]='\x0';
+		strncat(temp_url,temp_buffer,sizeof(temp_url)-strlen(temp_url)-1);
+		temp_url[sizeof(temp_url)-1]='\x0';
+	        }
+	if(host_status_types!=all_host_status_types){
+		snprintf(temp_buffer,sizeof(temp_buffer)-1,"&hoststatustypes=%d",host_status_types);
+		temp_buffer[sizeof(temp_buffer)-1]='\x0';
+		strncat(temp_url,temp_buffer,sizeof(temp_url)-strlen(temp_url)-1);
+		temp_url[sizeof(temp_url)-1]='\x0';
+	        }
+	if(service_properties!=0){
+		snprintf(temp_buffer,sizeof(temp_buffer)-1,"&serviceprops=%lu",service_properties);
+		temp_buffer[sizeof(temp_buffer)-1]='\x0';
+		strncat(temp_url,temp_buffer,sizeof(temp_url)-strlen(temp_url)-1);
+		temp_url[sizeof(temp_url)-1]='\x0';
+	        }
+	if(host_properties!=0){
+		snprintf(temp_buffer,sizeof(temp_buffer)-1,"&hostprops=%lu",host_properties);
+		temp_buffer[sizeof(temp_buffer)-1]='\x0';
+		strncat(temp_url,temp_buffer,sizeof(temp_url)-strlen(temp_url)-1);
+		temp_url[sizeof(temp_url)-1]='\x0';
+	        }
+
+
+	/* the main list of hosts */
+	printf("<DIV ALIGN='center'>\n");
+	printf("<TABLE BORDER=0 CLASS='status' WIDTH=100%%>\n");
+	printf("<TR>\n");
+
+	printf("<TH CLASS='status'>Host&nbsp;<A HREF='%s&sorttype=%d&sortoption=%d'><IMG SRC='%s%s' BORDER=0 ALT='Sort by host name (ascending)' TITLE='Sort by host name (ascending)'></A><A HREF='%s&sorttype=%d&sortoption=%d'><IMG SRC='%s%s' BORDER=0 ALT='Sort by host name (descending)' TITLE='Sort by host name (descending)'></A></TH>",temp_url,SORT_ASCENDING,SORT_HOSTNAME,url_images_path,UP_ARROW_ICON,temp_url,SORT_DESCENDING,SORT_HOSTNAME,url_images_path,DOWN_ARROW_ICON);
+
+	printf("<TH CLASS='status'>Status&nbsp;<A HREF='%s&sorttype=%d&sortoption=%d'><IMG SRC='%s%s' BORDER=0 ALT='Sort by host status (ascending)' TITLE='Sort by host status (ascending)'></A><A HREF='%s&sorttype=%d&sortoption=%d'><IMG SRC='%s%s' BORDER=0 ALT='Sort by host status (descending)' TITLE='Sort by host status (descending)'></A></TH>",temp_url,SORT_ASCENDING,SORT_HOSTSTATUS,url_images_path,UP_ARROW_ICON,temp_url,SORT_DESCENDING,SORT_HOSTSTATUS,url_images_path,DOWN_ARROW_ICON);
+
+	printf("<TH CLASS='status'>Last Check&nbsp;<A HREF='%s&sorttype=%d&sortoption=%d'><IMG SRC='%s%s' BORDER=0 ALT='Sort by last check time (ascending)' TITLE='Sort by last check time (ascending)'></A><A HREF='%s&sorttype=%d&sortoption=%d'><IMG SRC='%s%s' BORDER=0 ALT='Sort by last check time (descending)' TITLE='Sort by last check time (descending)'></A></TH>",temp_url,SORT_ASCENDING,SORT_LASTCHECKTIME,url_images_path,UP_ARROW_ICON,temp_url,SORT_DESCENDING,SORT_LASTCHECKTIME,url_images_path,DOWN_ARROW_ICON);
+
+	printf("<TH CLASS='status'>Duration&nbsp;<A HREF='%s&sorttype=%d&sortoption=%d'><IMG SRC='%s%s' BORDER=0 ALT='Sort by state duration (ascending)' TITLE='Sort by state duration (ascending)'></A><A HREF='%s&sorttype=%d&sortoption=%d'><IMG SRC='%s%s' BORDER=0 ALT='Sort by state duration time (descending)' TITLE='Sort by state duration time (descending)'></A></TH>",temp_url,SORT_ASCENDING,SORT_STATEDURATION,url_images_path,UP_ARROW_ICON,temp_url,SORT_DESCENDING,SORT_STATEDURATION,url_images_path,DOWN_ARROW_ICON);
+
+	printf("<TH CLASS='status'>Status Information</TH>\n");
+	printf("</TR>\n");
+
+
+	/* check all hosts... */
+	while(1){
+
+		/* get the next service to display */
+		if(use_sort==TRUE){
+			if(first_entry==TRUE)
+				temp_hostsort=hostsort_list;
+			else
+				temp_hostsort=temp_hostsort->next;
+			if(temp_hostsort==NULL)
+				break;
+			temp_status=temp_hostsort->hststatus;
+	                }
+		else{
+			if(first_entry==TRUE)
+				temp_status=hoststatus_list;
+			else
+				temp_status=temp_status->next;
+		        }
+
+		if(temp_status==NULL)
+			break;
+
+		first_entry=FALSE;
+
+		/* find the host  */
+		temp_host=find_host(temp_status->host_name);
+
+		/* if we couldn't find the host, go to the next status entry */
+		if(temp_host==NULL)
+			continue;
+
+		/* make sure user has rights to see this... */
+		if(is_authorized_for_host(temp_host,&current_authdata)==FALSE)
+			continue;
+
+		user_has_seen_something=TRUE;
+
+		/* see if we should display services for hosts with this type of status */
+		if(!(host_status_types & temp_status->status))
+			continue;
+
+		/* check host properties filter */
+		if(passes_host_properties_filter(temp_status)==FALSE)
+			continue;
+
+
+		/* see if this host is a member of the hostgroup */
+		if(show_all_hostgroups==FALSE){
+			temp_hostgroup=find_hostgroup(hostgroup_name);
+			if(temp_hostgroup==NULL)
+				continue;
+			if(is_host_member_of_hostgroup(temp_hostgroup,temp_host)==FALSE)
+				continue;
+	                }
+	
+		total_entries++;
+
+
+		if(display_type==DISPLAY_HOSTGROUPS){
+
+			if(odd)
+				odd=0;
+			else
+				odd=1;
+
+			
+		        /* get the last host check time */
+			t=temp_status->last_check;
+			get_time_string(&t,date_time,(int)sizeof(date_time),SHORT_DATE_TIME);
+			if((unsigned long)temp_status->last_check==0L)
+				strcpy(date_time,"N/A");
+
+			if(temp_status->status==HOST_PENDING){
+				strncpy(status,"PENDING",sizeof(status));
+				status_class="PENDING";
+				status_bg_class=(odd)?"Even":"Odd";
+		                }
+			else if(temp_status->status==HOST_UP){
+				strncpy(status,"UP",sizeof(status));
+				status_class="HOSTUP";
+				status_bg_class=(odd)?"Even":"Odd";
+		                }
+			else if(temp_status->status==HOST_DOWN){
+				strncpy(status,"DOWN",sizeof(status));
+				status_class="HOSTDOWN";
+				if(temp_status->problem_has_been_acknowledged==TRUE)
+					status_bg_class="BGDOWNACK";
+				else if(temp_status->scheduled_downtime_depth>0)
+					status_bg_class="BGDOWNSCHED";
+				else
+					status_bg_class="BGDOWN";
+		                }
+			else if(temp_status->status==HOST_UNREACHABLE){
+				strncpy(status,"UNREACHABLE",sizeof(status));
+				status_class="HOSTUNREACHABLE";
+				if(temp_status->problem_has_been_acknowledged==TRUE)
+					status_bg_class="BGUNREACHABLEACK";
+				else if(temp_status->scheduled_downtime_depth>0)
+					status_bg_class="BGUNREACHABLESCHED";
+				else
+					status_bg_class="BGUNREACHABLE";
+		                }
+			status[sizeof(status)-1]='\x0';
+
+
+			printf("<TR>\n");
+
+
+			/**** host name column ****/
+
+			/* find extended information for this host */
+			temp_hostextinfo=find_hostextinfo(temp_status->host_name);
+
+			printf("<TD CLASS='status%s'>",status_class);
+
+			printf("<TABLE BORDER=0 WIDTH='100%%' cellpadding=0 cellspacing=0>\n");
+			printf("<TR>\n");
+			printf("<TD ALIGN=LEFT>\n");
+			printf("<TABLE BORDER=0 cellpadding=0 cellspacing=0>\n");
+			printf("<TR>\n");
+			printf("<TD align=left valign=center CLASS='status%s'><A HREF='%s?type=%d&host=%s'>%s</A>&nbsp;</TD>\n",status_class,EXTINFO_CGI,DISPLAY_HOST_INFO,url_encode(temp_status->host_name),temp_status->host_name);
+			printf("</TR>\n");
+			printf("</TABLE>\n");
+			printf("</TD>\n");
+			printf("<TD align=right valign=center>\n");
+			printf("<TABLE BORDER=0 cellpadding=0 cellspacing=0>\n");
+			printf("<TR>\n");
+			total_comments=number_of_host_comments(temp_host->name);
+			if(temp_status->problem_has_been_acknowledged==TRUE){
+				printf("<TD ALIGN=center valign=center><A HREF='%s?type=%d&host=%s#comments'><IMG SRC='%s%s' BORDER=0 WIDTH=%d HEIGHT=%d ALT='This host problem has been acknowledged' TITLE='This host problem has been acknowledged'></A></TD>",EXTINFO_CGI,DISPLAY_HOST_INFO,url_encode(temp_status->host_name),url_images_path,ACKNOWLEDGEMENT_ICON,STATUS_ICON_WIDTH,STATUS_ICON_HEIGHT);
+		                }
+			if(total_comments>0)
+				printf("<TD ALIGN=center valign=center><A HREF='%s?type=%d&host=%s#comments'><IMG SRC='%s%s' BORDER=0 WIDTH=%d HEIGHT=%d ALT='This host has %d comment%s associated with it' TITLE='This host has %d comment%s associated with it'></A></TD>",EXTINFO_CGI,DISPLAY_HOST_INFO,url_encode(temp_status->host_name),url_images_path,COMMENT_ICON,STATUS_ICON_WIDTH,STATUS_ICON_HEIGHT,total_comments,(total_comments==1)?"":"s",total_comments,(total_comments==1)?"":"s");
+			if(temp_status->notifications_enabled==FALSE){
+				printf("<TD ALIGN=center valign=center><A HREF='%s?type=%d&host=%s'><IMG SRC='%s%s' BORDER=0 WIDTH=%d HEIGHT=%d ALT='Notifications for this host have been disabled' TITLE='Notifications for this host have been disabled'></A></TD>",EXTINFO_CGI,DISPLAY_HOST_INFO,url_encode(temp_status->host_name),url_images_path,NOTIFICATIONS_DISABLED_ICON,STATUS_ICON_WIDTH,STATUS_ICON_HEIGHT);
+		                }
+			if(temp_status->checks_enabled==FALSE){
+				printf("<TD ALIGN=center valign=center><A HREF='%s?type=%d&host=%s'><IMG SRC='%s%s' BORDER=0 WIDTH=%d HEIGHT=%d ALT='Checks of this host have been disabled' TITLE='Checks of this host have been disabled'></A></TD>",EXTINFO_CGI,DISPLAY_HOST_INFO,url_encode(temp_status->host_name),url_images_path,DISABLED_ICON,STATUS_ICON_WIDTH,STATUS_ICON_HEIGHT);
+			        }
+			if(temp_status->is_flapping==TRUE){
+				printf("<TD ALIGN=center valign=center><A HREF='%s?type=%d&host=%s'><IMG SRC='%s%s' BORDER=0 WIDTH=%d HEIGHT=%d ALT='This host is flapping between states' TITLE='This host is flapping between states'></A></TD>",EXTINFO_CGI,DISPLAY_HOST_INFO,url_encode(temp_status->host_name),url_images_path,FLAPPING_ICON,STATUS_ICON_WIDTH,STATUS_ICON_HEIGHT);
+			        }
+			if(temp_status->scheduled_downtime_depth>0){
+				printf("<TD ALIGN=center valign=center><A HREF='%s?type=%d&host=%s'><IMG SRC='%s%s' BORDER=0 WIDTH=%d HEIGHT=%d ALT='This host is currently in a period of scheduled downtime' TITLE='This host is currently in a period of scheduled downtime'></A></TD>",EXTINFO_CGI,DISPLAY_HOST_INFO,url_encode(temp_status->host_name),url_images_path,SCHEDULED_DOWNTIME_ICON,STATUS_ICON_WIDTH,STATUS_ICON_HEIGHT);
+			        }
+			if(temp_hostextinfo!=NULL){
+				if(temp_hostextinfo->notes_url!=NULL){
+					printf("<TD align=center valign=center>");
+					printf("<A HREF='");
+					print_extra_host_url(temp_hostextinfo->host_name,temp_hostextinfo->notes_url);
+					printf("' TARGET='_blank'>");
+					printf("<IMG SRC='%s%s' BORDER=0 WIDTH=%d HEIGHT=%d ALT='%s' TITLE='%s'>",url_images_path,NOTES_ICON,STATUS_ICON_WIDTH,STATUS_ICON_HEIGHT,"View Extra Host Notes","View Extra Host Notes");
+					printf("</A>");
+					printf("</TD>\n");
+				        }
+				if(temp_hostextinfo->action_url!=NULL){
+					printf("<TD align=center valign=center>");
+					printf("<A HREF='");
+					print_extra_host_url(temp_hostextinfo->host_name,temp_hostextinfo->action_url);
+					printf("' TARGET='_blank'>");
+					printf("<IMG SRC='%s%s' BORDER=0 WIDTH=%d HEIGHT=%d ALT='%s' TITLE='%s'>",url_images_path,ACTION_ICON,STATUS_ICON_WIDTH,STATUS_ICON_HEIGHT,"Perform Extra Host Actions","Perform Extra Host Actions");
+					printf("</A>");
+					printf("</TD>\n");
+				        }
+				if(temp_hostextinfo->icon_image!=NULL){
+					printf("<TD align=center valign=center>");
+					printf("<A HREF='%s?type=%d&host=%s'>",EXTINFO_CGI,DISPLAY_HOST_INFO,url_encode(temp_status->host_name));
+					printf("<IMG SRC='%s",url_logo_images_path);
+					print_extra_host_url(temp_hostextinfo->host_name,temp_hostextinfo->icon_image);
+					printf("' BORDER=0 WIDTH=%d HEIGHT=%d ALT='%s' TITLE='%s'>",STATUS_ICON_WIDTH,STATUS_ICON_HEIGHT,(temp_hostextinfo->icon_image_alt==NULL)?"":temp_hostextinfo->icon_image_alt,(temp_hostextinfo->icon_image_alt==NULL)?"":temp_hostextinfo->icon_image_alt);
+					printf("</A>");
+					printf("</TD>\n");
+				        }
+			        }
+			printf("<TD><a href='%s?host=%s'><img src='%s%s' border=0 alt='View Service Details For This Host' title='View Service Details For This Host'></a></TD>\n",STATUS_CGI,url_encode(temp_status->host_name),url_images_path,STATUS_DETAIL_ICON);
+			printf("</TR>\n");
+			printf("</TABLE>\n");
+			printf("</TD>\n");
+			printf("</TR>\n");
+			printf("</TABLE>\n");
+
+			printf("</TD>\n");
+
+
+			/* state duration calculation... */
+			t=0;
+			duration_error=FALSE;
+			if(temp_status->last_state_change==(time_t)0){
+				if(program_start>current_time)
+					duration_error=TRUE;
+				else
+					t=current_time-program_start;
+			        }
+			else{
+				if(temp_status->last_state_change>current_time)
+					duration_error=TRUE;
+				else
+					t=current_time-temp_status->last_state_change;
+			        }
+			get_time_breakdown((unsigned long)t,&days,&hours,&minutes,&seconds);
+			if(duration_error==TRUE)
+				snprintf(state_duration,sizeof(state_duration)-1,"???");
+			else
+				snprintf(state_duration,sizeof(state_duration)-1,"%2dd %2dh %2dm %2ds%s",days,hours,minutes,seconds,(temp_status->last_state_change==(time_t)0)?"+":"");
+			state_duration[sizeof(state_duration)-1]='\x0';
+
+                        /* the rest of the columns... */
+			printf("<TD CLASS='status%s'>%s</TD>\n",status_class,status);
+			printf("<TD CLASS='status%s' nowrap>%s</TD>\n",status_bg_class,date_time);
+			printf("<TD CLASS='status%s' nowrap>%s</TD>\n",status_bg_class,state_duration);
+			printf("<TD CLASS='status%s'>%s&nbsp;</TD>\n",status_bg_class,(temp_status->plugin_output==NULL)?"":temp_status->plugin_output);
+
+			printf("</TR>\n");
+		        }
+
+	        }
+
+	printf("</TABLE>\n");
+	printf("</DIV>\n");
+
+	/* if user couldn't see anything, print out some helpful info... */
+	if(user_has_seen_something==FALSE){
+
+		if(hoststatus_list!=NULL){
+			printf("<P><DIV CLASS='errorMessage'>It appears as though you do not have permission to view information for any of the hosts you requested...</DIV></P>\n");
+			printf("<P><DIV CLASS='errorDescription'>If you believe this is an error, check the HTTP server authentication requirements for accessing this CGI<br>");
+			printf("and check the authorization options in your CGI configuration file.</DIV></P>\n");
+		        }
+		else{
+			printf("<P><DIV CLASS='infoMessage'>There doesn't appear to be any host status information in the status log...<br><br>\n");
+			printf("Make sure that Nagios is running and that you have specified the location of you status log correctly in the configuration files.</DIV></P>\n");
+		        }
+	        }
+
+	else
+		printf("<BR><DIV CLASS='itemTotalsTitle'>%d Matching Host Entries Displayed</DIV>\n",total_entries);
+
+	return;
+        }
+
+
+
+
+/* show an overview of servicegroup(s)... */
+void show_servicegroup_overviews(void){
+	servicegroup *temp_servicegroup=NULL;
+	int current_column;
+	int user_has_seen_something=FALSE;
+	int servicegroup_error=FALSE;
+
+
+	printf("<P>\n");
+
+	printf("<table border=0 width=100%%>\n");
+	printf("<tr>\n");
+
+	printf("<td valign=top align=left width=33%%>\n");
+
+	show_filters();
+
+	printf("</td>");
+
+	printf("<td valign=top align=center width=33%%>\n");
+
+	printf("<DIV ALIGN=CENTER CLASS='statusTitle'>Service Overview For ");
+	if(show_all_servicegroups==TRUE)
+		printf("All Service Groups");
+	else
+		printf("Service Group '%s'",servicegroup_name);
+	printf("</DIV>\n");
+
+	printf("<br>");
+
+	printf("</td>\n");
+
+	printf("<td valign=top align=right width=33%%></td>\n");
+	
+	printf("</tr>\n");
+	printf("</table>\n");
+
+	printf("</P>\n");
+
+
+	/* display status overviews for all servicegroups */
+	if(show_all_servicegroups==TRUE){
+
+
+		printf("<DIV ALIGN=center>\n");
+		printf("<TABLE BORDER=0 CELLPADDING=10>\n");
+
+		current_column=1;
+
+		/* loop through all servicegroups... */
+		for(temp_servicegroup=servicegroup_list;temp_servicegroup!=NULL;temp_servicegroup=temp_servicegroup->next){
+
+			/* make sure the user is authorized to view at least one host in this servicegroup */
+			if(is_authorized_for_servicegroup(temp_servicegroup,&current_authdata)==FALSE)
+				continue;
+
+			if(current_column==1)
+				printf("<TR>\n");
+			printf("<TD VALIGN=top ALIGN=center>\n");
+				
+			show_servicegroup_overview(temp_servicegroup);
+
+			user_has_seen_something=TRUE;
+
+			printf("</TD>\n");
+			if(current_column==overview_columns)
+				printf("</TR>\n");
+
+			if(current_column<overview_columns)
+				current_column++;
+			else
+				current_column=1;
+		        }
+
+		if(current_column!=1){
+
+			for(;current_column<=overview_columns;current_column++)
+				printf("<TD></TD>\n");
+			printf("</TR>\n");
+		        }
+
+		printf("</TABLE>\n");
+		printf("</DIV>\n");
+	        }
+
+	/* else display overview for just a specific servicegroup */
+	else{
+
+		temp_servicegroup=find_servicegroup(servicegroup_name);
+		if(temp_servicegroup!=NULL){
+
+			printf("<P>\n");
+			printf("<DIV ALIGN=CENTER>\n");
+			printf("<TABLE BORDER=0 CELLPADDING=0 CELLSPACING=0><TR><TD ALIGN=CENTER>\n");
+			
+			if(is_authorized_for_servicegroup(temp_servicegroup,&current_authdata)==TRUE){
+
+				show_servicegroup_overview(temp_servicegroup);
+				
+				user_has_seen_something=TRUE;
+			        }
+
+			printf("</TD></TR></TABLE>\n");
+			printf("</DIV>\n");
+			printf("</P>\n");
+		        }
+		else{
+			printf("<DIV CLASS='errorMessage'>Sorry, but service group '%s' doesn't seem to exist...</DIV>",servicegroup_name);
+			servicegroup_error=TRUE;
+		        }
+	        }
+
+	/* if user couldn't see anything, print out some helpful info... */
+	if(user_has_seen_something==FALSE && servicegroup_error==FALSE){
+
+		printf("<p>\n");
+		printf("<div align='center'>\n");
+
+		if(servicegroup_list!=NULL){
+			printf("<DIV CLASS='errorMessage'>It appears as though you do not have permission to view information for any of the hosts you requested...</DIV>\n");
+			printf("<DIV CLASS='errorDescription'>If you believe this is an error, check the HTTP server authentication requirements for accessing this CGI<br>");
+			printf("and check the authorization options in your CGI configuration file.</DIV>\n");
+		        }
+		else{
+			printf("<DIV CLASS='errorMessage'>There are no service groups defined.</DIV>\n");
+			}
+
+		printf("</div>\n");
+		printf("</p>\n");
+	        }
+
+	return;
+        }
+
+
+
+/* shows an overview of a specific servicegroup... */
+void show_servicegroup_overview(servicegroup *temp_servicegroup){
+	servicegroupmember *temp_member;
+	host *temp_host;
+	host *last_host;
+	hoststatus *temp_hoststatus=NULL;
+	int odd=0;
+
+
+	printf("<DIV CLASS='status'>\n");
+	printf("<A HREF='%s?servicegroup=%s&style=detail'>%s</A>",STATUS_CGI,url_encode(temp_servicegroup->group_name),temp_servicegroup->alias);
+	printf(" (<A HREF='%s?type=%d&servicegroup=%s'>%s</A>)",EXTINFO_CGI,DISPLAY_SERVICEGROUP_INFO,url_encode(temp_servicegroup->group_name),temp_servicegroup->group_name);
+	printf("</DIV>\n");
+
+	printf("<DIV CLASS='status'>\n");
+	printf("<table border=1 CLASS='status'>\n");
+
+	printf("<TR>\n");
+	printf("<TH CLASS='status'>Host</TH><TH CLASS='status'>Status</TH><TH CLASS='status'>Services</TH><TH CLASS='status'>Actions</TH>\n");
+	printf("</TR>\n");
+
+	/* find all hosts that have services that are members of the servicegroup */
+	last_host=NULL;
+	for(temp_member=temp_servicegroup->members;temp_member!=NULL;temp_member=temp_member->next){
+
+		/* find the host */
+		temp_host=find_host(temp_member->host_name);
+		if(temp_host==NULL)
+			continue;
+
+		/* skip this if it isn't a new host... */
+		if(temp_host==last_host)
+			continue;
+
+		/* find the host status */
+		temp_hoststatus=find_hoststatus(temp_host->name);
+		if(temp_hoststatus==NULL)
+			continue;
+
+		/* make sure we only display hosts of the specified status levels */
+		if(!(host_status_types & temp_hoststatus->status))
+			continue;
+
+		/* make sure we only display hosts that have the desired properties */
+		if(passes_host_properties_filter(temp_hoststatus)==FALSE)
+			continue;
+
+		if(odd)
+			odd=0;
+		else
+			odd=1;
+
+		show_servicegroup_hostgroup_member_overview(temp_hoststatus,odd,temp_servicegroup);
+
+		last_host=temp_host;
+	        }
+
+	printf("</table>\n");
+	printf("</DIV>\n");
+
+	return;
+        }
+
+
+
+/* show a summary of servicegroup(s)... */
+void show_servicegroup_summaries(void){
+	servicegroup *temp_servicegroup=NULL;
+	int user_has_seen_something=FALSE;
+	int servicegroup_error=FALSE;
+	int odd=0;
+
+
+	printf("<P>\n");
+
+	printf("<table border=0 width=100%%>\n");
+	printf("<tr>\n");
+
+	printf("<td valign=top align=left width=33%%>\n");
+
+	show_filters();
+
+	printf("</td>");
+
+	printf("<td valign=top align=center width=33%%>\n");
+
+	printf("<DIV ALIGN=CENTER CLASS='statusTitle'>Status Summary For ");
+	if(show_all_servicegroups==TRUE)
+		printf("All Service Groups");
+	else
+		printf("Service Group '%s'",servicegroup_name);
+	printf("</DIV>\n");
+
+	printf("<br>");
+
+	printf("</td>\n");
+
+	printf("<td valign=top align=right width=33%%></td>\n");
+	
+	printf("</tr>\n");
+	printf("</table>\n");
+
+	printf("</P>\n");
+
+
+	printf("<DIV ALIGN=center>\n");
+	printf("<table border=1 CLASS='status'>\n");
+
+	printf("<TR>\n");
+	printf("<TH CLASS='status'>Service Group</TH><TH CLASS='status'>Host Status Totals</TH><TH CLASS='status'>Service Status Totals</TH>\n");
+	printf("</TR>\n");
+
+	/* display status summary for all servicegroups */
+	if(show_all_servicegroups==TRUE){
+
+		/* loop through all servicegroups... */
+		for(temp_servicegroup=servicegroup_list;temp_servicegroup!=NULL;temp_servicegroup=temp_servicegroup->next){
+
+			/* make sure the user is authorized to view at least one host in this servicegroup */
+			if(is_authorized_for_servicegroup(temp_servicegroup,&current_authdata)==FALSE)
+				continue;
+
+			if(odd==0)
+				odd=1;
+			else
+				odd=0;
+
+			/* show summary for this servicegroup */
+			show_servicegroup_summary(temp_servicegroup,odd);
+
+			user_has_seen_something=TRUE;
+		        }
+
+	        }
+
+	/* else just show summary for a specific servicegroup */
+	else{
+		temp_servicegroup=find_servicegroup(servicegroup_name);
+		if(temp_servicegroup==NULL)
+			servicegroup_error=TRUE;
+		else{
+			show_servicegroup_summary(temp_servicegroup,1);
+			user_has_seen_something=TRUE;
+		        }
+	        }
+
+	printf("</TABLE>\n");
+	printf("</DIV>\n");
+
+	/* if user couldn't see anything, print out some helpful info... */
+	if(user_has_seen_something==FALSE && servicegroup_error==FALSE){
+
+		printf("<P><DIV ALIGN=CENTER>\n");
+
+		if(servicegroup_list!=NULL){
+			printf("<DIV CLASS='errorMessage'>It appears as though you do not have permission to view information for any of the hosts you requested...</DIV>\n");
+			printf("<DIV CLASS='errorDescription'>If you believe this is an error, check the HTTP server authentication requirements for accessing this CGI<br>");
+			printf("and check the authorization options in your CGI configuration file.</DIV>\n");
+		        }
+		else{
+			printf("<DIV CLASS='errorMessage'>There are no service groups defined.</DIV>\n");
+			}
+
+		printf("</DIV></P>\n");
+	        }
+
+	/* we couldn't find the servicegroup */
+	else if(servicegroup_error==TRUE){
+		printf("<P><DIV ALIGN=CENTER>\n");
+		printf("<DIV CLASS='errorMessage'>Sorry, but servicegroup '%s' doesn't seem to exist...</DIV>\n",servicegroup_name);
+		printf("</DIV></P>\n");
+	        }
+
+	return;
+        }
+
+
+
+/* displays status summary information for a specific servicegroup */
+void show_servicegroup_summary(servicegroup *temp_servicegroup,int odd){
+	char *status_bg_class="";
+
+	if(odd==1)
+		status_bg_class="Even";
+	else
+		status_bg_class="Odd";
+
+	printf("<TR CLASS='status%s'><TD CLASS='status%s'>\n",status_bg_class,status_bg_class);
+	printf("<A HREF='%s?servicegroup=%s&style=overview'>%s</A> ",STATUS_CGI,url_encode(temp_servicegroup->group_name),temp_servicegroup->alias);
+	printf("(<A HREF='%s?type=%d&servicegroup=%s'>%s</a>)",EXTINFO_CGI,DISPLAY_SERVICEGROUP_INFO,url_encode(temp_servicegroup->group_name),temp_servicegroup->group_name);
+	printf("</TD>");
+				
+	printf("<TD CLASS='status%s' ALIGN=CENTER VALIGN=CENTER>",status_bg_class);
+	show_servicegroup_host_totals_summary(temp_servicegroup);
+	printf("</TD>");
+
+	printf("<TD CLASS='status%s' ALIGN=CENTER VALIGN=CENTER>",status_bg_class);
+	show_servicegroup_service_totals_summary(temp_servicegroup);
+	printf("</TD>");
+
+	printf("</TR>\n");
+
+	return;
+        }
+
+
+
+/* shows host total summary information for a specific servicegroup */
+void show_servicegroup_host_totals_summary(servicegroup *temp_servicegroup){
+	servicegroupmember *temp_member;
+	int total_up=0;
+	int total_down=0;
+	int total_unreachable=0;
+	int total_pending=0;
+	hoststatus *temp_hoststatus;
+	host *temp_host;
+	host *last_host;
+
+	last_host=NULL;
+	for(temp_member=temp_servicegroup->members;temp_member!=NULL;temp_member=temp_member->next){
+
+		/* find the host */
+		temp_host=find_host(temp_member->host_name);
+		if(temp_host==NULL)
+			continue;
+
+		/* skip this if it isn't a new host... */
+		if(temp_host==last_host)
+			continue;
+
+		/* find the host status */
+		temp_hoststatus=find_hoststatus(temp_host->name);
+		if(temp_hoststatus==NULL)
+			continue;
+
+		/* make sure we only display hosts of the specified status levels */
+		if(!(host_status_types & temp_hoststatus->status))
+			continue;
+
+		/* make sure we only display hosts that have the desired properties */
+		if(passes_host_properties_filter(temp_hoststatus)==FALSE)
+			continue;
+
+		if(temp_hoststatus->status==HOST_UP)
+			total_up++;
+		else if(temp_hoststatus->status==HOST_DOWN)
+			total_down++;
+		else if(temp_hoststatus->status==HOST_UNREACHABLE)
+			total_unreachable++;
+		else
+			total_pending++;
+
+		last_host=temp_host;
+	        }
+
+	printf("<TABLE BORDER=0>\n");
+
+	if(total_up>0)
+		printf("<TR><TD CLASS='miniStatusUP'><A HREF='%s?servicegroup=%s&style=detail&&hoststatustypes=%d&hostprops=%lu'>%d UP</A></TD></TR>\n",STATUS_CGI,url_encode(temp_servicegroup->group_name),HOST_UP,host_properties,total_up);
+	if(total_down>0)
+		printf("<TR><TD CLASS='miniStatusDOWN'><A HREF='%s?servicegroup=%s&style=detail&hoststatustypes=%d&hostprops=%lu'>%d DOWN</A></TD></TR>\n",STATUS_CGI,url_encode(temp_servicegroup->group_name),HOST_DOWN,host_properties,total_down);
+	if(total_unreachable>0)
+		printf("<TR><TD CLASS='miniStatusUNREACHABLE'><A HREF='%s?servicegroup=%s&style=detail&hoststatustypes=%d&hostprops=%lu'>%d UNREACHABLE</A></TD></TR>\n",STATUS_CGI,url_encode(temp_servicegroup->group_name),HOST_UNREACHABLE,host_properties,total_unreachable);
+	if(total_pending>0)
+		printf("<TR><TD CLASS='miniStatusPENDING'><A HREF='%s?servicegroup=%s&style=detail&hoststatustypes=%d&hostprops=%lu'>%d PENDING</A></TD></TR>\n",STATUS_CGI,url_encode(temp_servicegroup->group_name),HOST_PENDING,host_properties,total_pending);
+
+	printf("</TABLE>\n");
+
+	if((total_up + total_down + total_unreachable + total_pending)==0)
+		printf("No matching hosts");
+
+	return;
+        }
+
+
+
+/* shows service total summary information for a specific servicegroup */
+void show_servicegroup_service_totals_summary(servicegroup *temp_servicegroup){
+	servicegroupmember *temp_member;
+	int total_ok=0;
+	int total_warning=0;
+	int total_unknown=0;
+	int total_critical=0;
+	int total_pending=0;
+	servicestatus *temp_servicestatus;
+	service *temp_service;
+	hoststatus *temp_hoststatus;
+
+
+	/* check all services... */
+	for(temp_member=temp_servicegroup->members;temp_member!=NULL;temp_member=temp_member->next){
+
+		/* find the service */
+		temp_service=find_service(temp_member->host_name,temp_member->service_description);
+		if(temp_service==NULL)
+			continue;
+
+		/* find the service status */
+		temp_servicestatus=find_servicestatus(temp_service->host_name,temp_service->description);
+		if(temp_servicestatus==NULL)
+			continue;
+
+		/* find the status of the associated host */
+		temp_hoststatus=find_hoststatus(temp_servicestatus->host_name);
+		if(temp_hoststatus==NULL)
+			continue;
+
+		/* make sure we only display hosts of the specified status levels */
+		if(!(host_status_types & temp_hoststatus->status))
+			continue;
+
+		/* make sure we only display hosts that have the desired properties */
+		if(passes_host_properties_filter(temp_hoststatus)==FALSE)
+			continue;
+
+		/* make sure we only display services of the specified status levels */
+		if(!(service_status_types & temp_servicestatus->status))
+			continue;
+
+		/* make sure we only display services that have the desired properties */
+		if(passes_service_properties_filter(temp_servicestatus)==FALSE)
+			continue;
+
+		if(temp_servicestatus->status==SERVICE_CRITICAL)
+			total_critical++;
+		else if(temp_servicestatus->status==SERVICE_WARNING)
+			total_warning++;
+		else if(temp_servicestatus->status==SERVICE_UNKNOWN)
+			total_unknown++;
+		else if(temp_servicestatus->status==SERVICE_OK)
+			total_ok++;
+		else if(temp_servicestatus->status==SERVICE_PENDING)
+			total_pending++;
+		else
+			total_ok++;
+	        }
+
+
+	printf("<TABLE BORDER=0>\n");
+
+	if(total_ok>0)
+		printf("<TR><TD CLASS='miniStatusOK'><A HREF='%s?servicegroup=%s&style=detail&&servicestatustypes=%d&hoststatustypes=%d&serviceprops=%lu&hostprops=%lu'>%d OK</A></TD></TR>\n",STATUS_CGI,url_encode(temp_servicegroup->group_name),SERVICE_OK,host_status_types,service_properties,host_properties,total_ok);
+	if(total_warning>0)
+		printf("<TR><TD CLASS='miniStatusWARNING'><A HREF='%s?servicegroup=%s&style=detail&servicestatustypes=%d&hoststatustypes=%d&serviceprops=%lu&hostprops=%lu'>%d WARNING</A></TD></TR>\n",STATUS_CGI,url_encode(temp_servicegroup->group_name),SERVICE_WARNING,host_status_types,service_properties,host_properties,total_warning);
+	if(total_unknown>0)
+		printf("<TR><TD CLASS='miniStatusUNKNOWN'><A HREF='%s?servicegroup=%s&style=detail&servicestatustypes=%d&hoststatustypes=%d&serviceprops=%lu&hostprops=%lu'>%d UNKNOWN</A></TD></TR>\n",STATUS_CGI,url_encode(temp_servicegroup->group_name),SERVICE_UNKNOWN,host_status_types,service_properties,host_properties,total_unknown);
+	if(total_critical>0)
+		printf("<TR><TD CLASS='miniStatusCRITICAL'><A HREF='%s?servicegroup=%s&style=detail&servicestatustypes=%d&hoststatustypes=%d&serviceprops=%lu&hostprops=%lu'>%d CRITICAL</A></TD></TR>\n",STATUS_CGI,url_encode(temp_servicegroup->group_name),SERVICE_CRITICAL,host_status_types,service_properties,host_properties,total_critical);
+	if(total_pending>0)
+		printf("<TR><TD CLASS='miniStatusPENDING'><A HREF='%s?servicegroup=%s&style=detail&servicestatustypes=%d&hoststatustypes=%d&serviceprops=%lu&hostprops=%lu'>%d PENDING</A></TD></TR>\n",STATUS_CGI,url_encode(temp_servicegroup->group_name),SERVICE_PENDING,host_status_types,service_properties,host_properties,total_pending);
+
+	printf("</TABLE>\n");
+
+	if((total_ok + total_warning + total_unknown + total_critical + total_pending)==0)
+		printf("No matching services");
+
+	return;
+        }
+
+
+
+/* show a grid layout of servicegroup(s)... */
+void show_servicegroup_grids(void){
+	servicegroup *temp_servicegroup=NULL;
+	int user_has_seen_something=FALSE;
+	int servicegroup_error=FALSE;
+	int odd=0;
+
+
+	printf("<P>\n");
+
+	printf("<table border=0 width=100%%>\n");
+	printf("<tr>\n");
+
+	printf("<td valign=top align=left width=33%%>\n");
+
+	show_filters();
+
+	printf("</td>");
+
+	printf("<td valign=top align=center width=33%%>\n");
+
+	printf("<DIV ALIGN=CENTER CLASS='statusTitle'>Status Grid For ");
+	if(show_all_servicegroups==TRUE)
+		printf("All Service Groups");
+	else
+		printf("Service Group '%s'",servicegroup_name);
+	printf("</DIV>\n");
+
+	printf("<br>");
+
+	printf("</td>\n");
+
+	printf("<td valign=top align=right width=33%%></td>\n");
+	
+	printf("</tr>\n");
+	printf("</table>\n");
+
+	printf("</P>\n");
+
+
+	/* display status grids for all servicegroups */
+	if(show_all_servicegroups==TRUE){
+
+		/* loop through all servicegroups... */
+		for(temp_servicegroup=servicegroup_list;temp_servicegroup!=NULL;temp_servicegroup=temp_servicegroup->next){
+
+			/* make sure the user is authorized to view at least one host in this servicegroup */
+			if(is_authorized_for_servicegroup(temp_servicegroup,&current_authdata)==FALSE)
+				continue;
+
+			if(odd==0)
+				odd=1;
+			else
+				odd=0;
+
+			/* show grid for this servicegroup */
+			show_servicegroup_grid(temp_servicegroup);
+
+			user_has_seen_something=TRUE;
+		        }
+
+	        }
+
+	/* else just show grid for a specific servicegroup */
+	else{
+		temp_servicegroup=find_servicegroup(servicegroup_name);
+		if(temp_servicegroup==NULL)
+			servicegroup_error=TRUE;
+		else{
+			show_servicegroup_grid(temp_servicegroup);
+			user_has_seen_something=TRUE;
+		        }
+	        }
+
+	/* if user couldn't see anything, print out some helpful info... */
+	if(user_has_seen_something==FALSE && servicegroup_error==FALSE){
+
+		printf("<P><DIV ALIGN=CENTER>\n");
+
+		if(servicegroup_list!=NULL){
+			printf("<DIV CLASS='errorMessage'>It appears as though you do not have permission to view information for any of the hosts you requested...</DIV>\n");
+			printf("<DIV CLASS='errorDescription'>If you believe this is an error, check the HTTP server authentication requirements for accessing this CGI<br>");
+			printf("and check the authorization options in your CGI configuration file.</DIV>\n");
+		        }
+		else{
+			printf("<DIV CLASS='errorMessage'>There are no service groups defined.</DIV>\n");
+			}
+
+		printf("</DIV></P>\n");
+	        }
+
+	/* we couldn't find the servicegroup */
+	else if(servicegroup_error==TRUE){
+		printf("<P><DIV ALIGN=CENTER>\n");
+		printf("<DIV CLASS='errorMessage'>Sorry, but servicegroup '%s' doesn't seem to exist...</DIV>\n",servicegroup_name);
+		printf("</DIV></P>\n");
+	        }
+
+	return;
+        }
+
+
+/* displays status grid for a specific servicegroup */
+void show_servicegroup_grid(servicegroup *temp_servicegroup){
+	char *status_bg_class="";
+	char *host_status_class="";
+	char *service_status_class="";
+	servicegroupmember *temp_member;
+	servicegroupmember *temp_member2;
+	host *temp_host;
+	host *last_host;
+	hoststatus *temp_hoststatus;
+	servicestatus *temp_servicestatus;
+	hostextinfo *temp_hostextinfo;
+	int odd=0;
+	int current_item;
+
+
+	printf("<P>\n");
+	printf("<DIV ALIGN=CENTER>\n");
+
+	printf("<DIV CLASS='status'><A HREF='%s?servicegroup=%s&style=detail'>%s</A>",STATUS_CGI,url_encode(temp_servicegroup->group_name),temp_servicegroup->alias);
+	printf(" (<A HREF='%s?type=%d&servicegroup=%s'>%s</A>)</DIV>",EXTINFO_CGI,DISPLAY_SERVICEGROUP_INFO,url_encode(temp_servicegroup->group_name),temp_servicegroup->group_name);
+
+	printf("<TABLE BORDER=1 CLASS='status' ALIGN=CENTER>\n");
+	printf("<TR><TH CLASS='status'>Host</TH><TH CLASS='status'>Services</a></TH><TH CLASS='status'>Actions</TH></TR>\n");
+
+	/* find all hosts that have services that are members of the servicegroup */
+	last_host=NULL;
+	for(temp_member=temp_servicegroup->members;temp_member!=NULL;temp_member=temp_member->next){
+
+		/* find the host */
+		temp_host=find_host(temp_member->host_name);
+		if(temp_host==NULL)
+			continue;
+
+		/* get the status of the host */
+		temp_hoststatus=find_hoststatus(temp_host->name);
+		if(temp_hoststatus==NULL)
+			continue;
+
+		/* skip this if it isn't a new host... */
+		if(temp_host==last_host)
+			continue;
+
+		if(odd==1){
+			status_bg_class="Even";
+			odd=0;
+		        }
+		else{
+			status_bg_class="Odd";
+			odd=1;
+		        }
+
+		printf("<TR CLASS='status%s'>\n",status_bg_class);
+
+		if(temp_hoststatus->status==HOST_DOWN)
+			host_status_class="HOSTDOWN";
+		else if(temp_hoststatus->status==HOST_UNREACHABLE)
+			host_status_class="HOSTUNREACHABLE";
+		else
+			host_status_class=status_bg_class;
+
+		printf("<TD CLASS='status%s'>",host_status_class);
+
+		printf("<TABLE BORDER=0 WIDTH='100%%' cellpadding=0 cellspacing=0>\n");
+		printf("<TR>\n");
+		printf("<TD ALIGN=LEFT>\n");
+		printf("<TABLE BORDER=0 cellpadding=0 cellspacing=0>\n");
+		printf("<TR>\n");
+		printf("<TD align=left valign=center CLASS='status%s'>",host_status_class);
+		printf("<A HREF='%s?type=%d&host=%s'>%s</A>\n",EXTINFO_CGI,DISPLAY_HOST_INFO,url_encode(temp_host->name),temp_host->name);
+		printf("</TD>\n");
+		printf("</TR>\n");
+		printf("</TABLE>\n");
+		printf("</TD>\n");
+		printf("<TD align=right valign=center nowrap>\n");
+		printf("<TABLE BORDER=0 cellpadding=0 cellspacing=0>\n");
+		printf("<TR>\n");
+
+		temp_hostextinfo=find_hostextinfo(temp_host->name);
+		if(temp_hostextinfo!=NULL){
+			if(temp_hostextinfo->icon_image!=NULL){
+				printf("<TD align=center valign=center>");
+				printf("<A HREF='%s?type=%d&host=%s'>\n",EXTINFO_CGI,DISPLAY_HOST_INFO,url_encode(temp_host->name));
+				printf("<IMG SRC='%s",url_logo_images_path);
+				print_extra_host_url(temp_hostextinfo->host_name,temp_hostextinfo->icon_image);
+				printf("' BORDER=0 WIDTH=%d HEIGHT=%d ALT='%s' TITLE='%s'>",STATUS_ICON_WIDTH,STATUS_ICON_HEIGHT,(temp_hostextinfo->icon_image_alt==NULL)?"":temp_hostextinfo->icon_image_alt,(temp_hostextinfo->icon_image_alt==NULL)?"":temp_hostextinfo->icon_image_alt);
+				printf("</A>");
+				printf("<TD>\n");
+			        }
+		        }
+
+		printf("</TR>\n");
+		printf("</TABLE>\n");
+		printf("</TD>\n");
+		printf("</TR>\n");
+		printf("</TABLE>\n");
+
+		printf("</TD>\n");
+
+		printf("<TD CLASS='status%s'>",host_status_class);
+
+		/* display all services on the host that are part of the hostgroup */
+		current_item=1;
+		for(temp_member2=temp_member;temp_member2!=NULL;temp_member2=temp_member2->next){
+
+			/* bail out if we've reached the end of the services that are associated with this servicegroup */
+			if(strcmp(temp_member2->host_name,temp_host->name))
+				break;
+
+			if(current_item>max_grid_width && max_grid_width>0){
+				printf("<BR>\n");
+				current_item=1;
+		                }
+
+			/* get the status of the service */
+			temp_servicestatus=find_servicestatus(temp_member2->host_name,temp_member2->service_description);
+			if(temp_servicestatus==NULL)
+				service_status_class="NULL";
+			else if(temp_servicestatus->status==SERVICE_OK)
+				service_status_class="OK";
+			else if(temp_servicestatus->status==SERVICE_WARNING)
+				service_status_class="WARNING";
+			else if(temp_servicestatus->status==SERVICE_UNKNOWN)
+				service_status_class="UNKNOWN";
+			else if(temp_servicestatus->status==SERVICE_CRITICAL)
+				service_status_class="CRITICAL";
+			else
+				service_status_class="PENDING";
+
+			printf("<A HREF='%s?type=%d&host=%s",EXTINFO_CGI,DISPLAY_SERVICE_INFO,url_encode(temp_servicestatus->host_name));
+			printf("&service=%s' CLASS='status%s'>%s</A>&nbsp;",url_encode(temp_servicestatus->description),service_status_class,temp_servicestatus->description);
+
+			current_item++;
+	                }
+
+		/* actions */
+		printf("<TD CLASS='status%s'>",host_status_class);
+
+		printf("<A HREF='%s?type=%d&host=%s'>\n",EXTINFO_CGI,DISPLAY_HOST_INFO,url_encode(temp_host->name));
+		printf("<IMG SRC='%s%s' BORDER=0 WIDTH=%d HEIGHT=%d ALT='%s' TITLE='%s'>",url_images_path,DETAIL_ICON,STATUS_ICON_WIDTH,STATUS_ICON_HEIGHT,"View Extended Information For This Host","View Extended Information For This Host");
+		printf("</A>");
+
+		if(temp_hostextinfo!=NULL){
+			if(temp_hostextinfo->notes_url!=NULL){
+				printf("<A HREF='");
+				print_extra_host_url(temp_hostextinfo->host_name,temp_hostextinfo->notes_url);
+				printf("' TARGET='_blank'>");
+				printf("<IMG SRC='%s%s' BORDER=0 WIDTH=%d HEIGHT=%d ALT='%s' TITLE='%s'>",url_images_path,NOTES_ICON,STATUS_ICON_WIDTH,STATUS_ICON_HEIGHT,"View Extra Host Notes","View Extra Host Notes");
+				printf("</A>");
+			        }
+			if(temp_hostextinfo->action_url!=NULL){
+				printf("<A HREF='");
+				print_extra_host_url(temp_hostextinfo->host_name,temp_hostextinfo->action_url);
+				printf("' TARGET='_blank'>");
+				printf("<IMG SRC='%s%s' BORDER=0 WIDTH=%d HEIGHT=%d ALT='%s' TITLE='%s'>",url_images_path,ACTION_ICON,STATUS_ICON_WIDTH,STATUS_ICON_HEIGHT,"Perform Extra Host Actions","Perform Extra Host Actions");
+				printf("</A>");
+			        }
+		        }
+
+		printf("<a href='%s?host=%s'><img src='%s%s' border=0 alt='View Service Details For This Host' title='View Service Details For This Host'></a>\n",STATUS_CGI,url_encode(temp_host->name),url_images_path,STATUS_DETAIL_ICON);
+
+#ifdef USE_STATUSMAP
+		printf("<A HREF='%s?host=%s'><IMG SRC='%s%s' BORDER=0 WIDTH=%d HEIGHT=%d ALT='%s' TITLE='%s'></A>",STATUSMAP_CGI,url_encode(temp_host->name),url_images_path,STATUSMAP_ICON,STATUS_ICON_WIDTH,STATUS_ICON_HEIGHT,"Locate Host On Map","Locate Host On Map");
+#endif
+		printf("</TD>\n");
+		printf("</TR>\n");
+
+		last_host=temp_host;
+		}
+
+	printf("</TABLE>\n");
+	printf("</DIV>\n");
+	printf("</P>\n");
+
+	return;
+        }
+
+
+
+/* show an overview of hostgroup(s)... */
+void show_hostgroup_overviews(void){
+	hostgroup *temp_hostgroup=NULL;
+	int current_column;
+	int user_has_seen_something=FALSE;
+	int hostgroup_error=FALSE;
+
+
+	printf("<P>\n");
+
+	printf("<table border=0 width=100%%>\n");
+	printf("<tr>\n");
+
+	printf("<td valign=top align=left width=33%%>\n");
+
+	show_filters();
+
+	printf("</td>");
+
+	printf("<td valign=top align=center width=33%%>\n");
+
+	printf("<DIV ALIGN=CENTER CLASS='statusTitle'>Service Overview For ");
+	if(show_all_hostgroups==TRUE)
+		printf("All Host Groups");
+	else
+		printf("Host Group '%s'",hostgroup_name);
+	printf("</DIV>\n");
+
+	printf("<br>");
+
+	printf("</td>\n");
+
+	printf("<td valign=top align=right width=33%%></td>\n");
+	
+	printf("</tr>\n");
+	printf("</table>\n");
+
+	printf("</P>\n");
+
+
+	/* display status overviews for all hostgroups */
+	if(show_all_hostgroups==TRUE){
+
+
+		printf("<DIV ALIGN=center>\n");
+		printf("<TABLE BORDER=0 CELLPADDING=10>\n");
+
+		current_column=1;
+
+		/* loop through all hostgroups... */
+		for(temp_hostgroup=hostgroup_list;temp_hostgroup!=NULL;temp_hostgroup=temp_hostgroup->next){
+
+			/* make sure the user is authorized to view this hostgroup */
+			if(is_authorized_for_hostgroup(temp_hostgroup,&current_authdata)==FALSE)
+				continue;
+
+			if(current_column==1)
+				printf("<TR>\n");
+			printf("<TD VALIGN=top ALIGN=center>\n");
+				
+			show_hostgroup_overview(temp_hostgroup);
+
+			user_has_seen_something=TRUE;
+
+			printf("</TD>\n");
+			if(current_column==overview_columns)
+				printf("</TR>\n");
+
+			if(current_column<overview_columns)
+				current_column++;
+			else
+				current_column=1;
+		        }
+
+		if(current_column!=1){
+
+			for(;current_column<=overview_columns;current_column++)
+				printf("<TD></TD>\n");
+			printf("</TR>\n");
+		        }
+
+		printf("</TABLE>\n");
+		printf("</DIV>\n");
+	        }
+
+	/* else display overview for just a specific hostgroup */
+	else{
+
+		temp_hostgroup=find_hostgroup(hostgroup_name);
+		if(temp_hostgroup!=NULL){
+
+			printf("<P>\n");
+			printf("<DIV ALIGN=CENTER>\n");
+			printf("<TABLE BORDER=0 CELLPADDING=0 CELLSPACING=0><TR><TD ALIGN=CENTER>\n");
+			
+			if(is_authorized_for_hostgroup(temp_hostgroup,&current_authdata)==TRUE){
+
+				show_hostgroup_overview(temp_hostgroup);
+				
+				user_has_seen_something=TRUE;
+			        }
+
+			printf("</TD></TR></TABLE>\n");
+			printf("</DIV>\n");
+			printf("</P>\n");
+		        }
+		else{
+			printf("<DIV CLASS='errorMessage'>Sorry, but host group '%s' doesn't seem to exist...</DIV>",hostgroup_name);
+			hostgroup_error=TRUE;
+		        }
+	        }
+
+	/* if user couldn't see anything, print out some helpful info... */
+	if(user_has_seen_something==FALSE && hostgroup_error==FALSE){
+
+		printf("<p>\n");
+		printf("<div align='center'>\n");
+
+		if(hoststatus_list!=NULL){
+			printf("<DIV CLASS='errorMessage'>It appears as though you do not have permission to view information for any of the hosts you requested...</DIV>\n");
+			printf("<DIV CLASS='errorDescription'>If you believe this is an error, check the HTTP server authentication requirements for accessing this CGI<br>");
+			printf("and check the authorization options in your CGI configuration file.</DIV>\n");
+		        }
+		else{
+			printf("<DIV CLASS='infoMessage'>There doesn't appear to be any host status information in the status log...<br><br>\n");
+			printf("Make sure that Nagios is running and that you have specified the location of you status log correctly in the configuration files.</DIV>\n");
+		        }
+
+		printf("</div>\n");
+		printf("</p>\n");
+	        }
+
+	return;
+        }
+
+
+
+/* shows an overview of a specific hostgroup... */
+void show_hostgroup_overview(hostgroup *hstgrp){
+	hostgroupmember *temp_member;
+	host *temp_host;
+	hoststatus *temp_hoststatus=NULL;
+	int odd=0;
+
+	/* make sure the user is authorized to view this hostgroup */
+	if(is_authorized_for_hostgroup(hstgrp,&current_authdata)==FALSE)
+		return;
+
+	printf("<DIV CLASS='status'>\n");
+	printf("<A HREF='%s?hostgroup=%s&style=detail'>%s</A>",STATUS_CGI,url_encode(hstgrp->group_name),hstgrp->alias);
+	printf(" (<A HREF='%s?type=%d&hostgroup=%s'>%s</A>)",EXTINFO_CGI,DISPLAY_HOSTGROUP_INFO,url_encode(hstgrp->group_name),hstgrp->group_name);
+	printf("</DIV>\n");
+
+	printf("<DIV CLASS='status'>\n");
+	printf("<table border=1 CLASS='status'>\n");
+
+	printf("<TR>\n");
+	printf("<TH CLASS='status'>Host</TH><TH CLASS='status'>Status</TH><TH CLASS='status'>Services</TH><TH CLASS='status'>Actions</TH>\n");
+	printf("</TR>\n");
+
+	/* find all the hosts that belong to the hostgroup */
+	for(temp_member=hstgrp->members;temp_member!=NULL;temp_member=temp_member->next){
+
+		/* find the host... */
+		temp_host=find_host(temp_member->host_name);
+		if(temp_host==NULL)
+			continue;
+
+		/* find the host status */
+		temp_hoststatus=find_hoststatus(temp_host->name);
+		if(temp_hoststatus==NULL)
+			continue;
+
+		/* make sure we only display hosts of the specified status levels */
+		if(!(host_status_types & temp_hoststatus->status))
+			continue;
+
+		/* make sure we only display hosts that have the desired properties */
+		if(passes_host_properties_filter(temp_hoststatus)==FALSE)
+			continue;
+
+		if(odd)
+			odd=0;
+		else
+			odd=1;
+
+		show_servicegroup_hostgroup_member_overview(temp_hoststatus,odd,NULL);
+	        }
+
+	printf("</table>\n");
+	printf("</DIV>\n");
+
+	return;
+        }
+
+ 
+
+/* shows a host status overview... */
+void show_servicegroup_hostgroup_member_overview(hoststatus *hststatus,int odd,void *data){
+	char status[MAX_INPUT_BUFFER];
+	char *status_bg_class="";
+	char *status_class="";
+	hostextinfo *temp_hostextinfo;
+
+	if(hststatus->status==HOST_PENDING){
+		strncpy(status,"PENDING",sizeof(status));
+		status_class="HOSTPENDING";
+		status_bg_class=(odd)?"Even":"Odd";
+	        }
+	else if(hststatus->status==HOST_UP){
+		strncpy(status,"UP",sizeof(status));
+		status_class="HOSTUP";
+		status_bg_class=(odd)?"Even":"Odd";
+	        }
+	else if(hststatus->status==HOST_DOWN){
+		strncpy(status,"DOWN",sizeof(status));
+		status_class="HOSTDOWN";
+		status_bg_class="HOSTDOWN";
+	        }
+	else if(hststatus->status==HOST_UNREACHABLE){
+		strncpy(status,"UNREACHABLE",sizeof(status));
+		status_class="HOSTUNREACHABLE";
+		status_bg_class="HOSTUNREACHABLE";
+	        }
+
+	status[sizeof(status)-1]='\x0';
+
+	printf("<TR CLASS='status%s'>\n",status_bg_class);
+
+	/* find extended information for this host */
+	temp_hostextinfo=find_hostextinfo(hststatus->host_name);
+
+	printf("<TD CLASS='status%s'>\n",status_bg_class);
+
+	printf("<TABLE BORDER=0 WIDTH=100%% cellpadding=0 cellspacing=0>\n");
+	printf("<TR CLASS='status%s'>\n",status_bg_class);
+	printf("<TD CLASS='status%s'><A HREF='%s?host=%s&style=detail'>%s</A></TD>\n",status_bg_class,STATUS_CGI,url_encode(hststatus->host_name),hststatus->host_name);
+
+	if(temp_hostextinfo!=NULL){
+		if(temp_hostextinfo->icon_image!=NULL){
+			printf("<TD CLASS='status%s' WIDTH=5></TD>\n",status_bg_class);
+			printf("<TD CLASS='status%s' ALIGN=right>",status_bg_class);
+			printf("<a href='%s?type=%d&host=%s'>",EXTINFO_CGI,DISPLAY_HOST_INFO,url_encode(hststatus->host_name));
+			printf("<IMG SRC='%s",url_logo_images_path);
+			print_extra_host_url(temp_hostextinfo->host_name,temp_hostextinfo->icon_image);
+			printf("' BORDER=0 WIDTH=%d HEIGHT=%d ALT='%s' TITLE='%s'>",STATUS_ICON_WIDTH,STATUS_ICON_HEIGHT,(temp_hostextinfo->icon_image_alt==NULL)?"":temp_hostextinfo->icon_image_alt,(temp_hostextinfo->icon_image_alt==NULL)?"":temp_hostextinfo->icon_image_alt);
+			printf("</A>");
+			printf("</TD>\n");
+	                }
+	        }
+	printf("</TR>\n");
+	printf("</TABLE>\n");
+	printf("</TD>\n");
+
+	printf("<td CLASS='status%s'>%s</td>\n",status_class,status);
+
+	printf("<td CLASS='status%s'>\n",status_bg_class);
+	show_servicegroup_hostgroup_member_service_status_totals(hststatus->host_name,data);
+	printf("</td>\n");
+
+	printf("<td valign=center CLASS='status%s'>",status_bg_class);
+	printf("<a href='%s?type=%d&host=%s'><img src='%s%s' border=0 alt='View Extended Information For This Host' title='View Extended Information For This Host'></a>\n",EXTINFO_CGI,DISPLAY_HOST_INFO,url_encode(hststatus->host_name),url_images_path,DETAIL_ICON);
+	if(temp_hostextinfo!=NULL){
+		if(temp_hostextinfo->notes_url!=NULL){
+			printf("<A HREF='");
+			print_extra_host_url(temp_hostextinfo->host_name,temp_hostextinfo->notes_url);
+			printf("' TARGET='_blank'>");
+			printf("<IMG SRC='%s%s' BORDER=0 WIDTH=%d HEIGHT=%d ALT='%s' TITLE='%s'>",url_images_path,NOTES_ICON,STATUS_ICON_WIDTH,STATUS_ICON_HEIGHT,"View Extra Host Notes","View Extra Host Notes");
+			printf("</A>");
+		        }
+		if(temp_hostextinfo->action_url!=NULL){
+			printf("<A HREF='");
+			print_extra_host_url(temp_hostextinfo->host_name,temp_hostextinfo->action_url);
+			printf("' TARGET='_blank'>");
+			printf("<IMG SRC='%s%s' BORDER=0 WIDTH=%d HEIGHT=%d ALT='%s' TITLE='%s'>",url_images_path,ACTION_ICON,STATUS_ICON_WIDTH,STATUS_ICON_HEIGHT,"Perform Extra Host Actions","Perform Extra Host Actions");
+			printf("</A>");
+		        }
+	        }
+	printf("<a href='%s?host=%s'><img src='%s%s' border=0 alt='View Service Details For This Host' title='View Service Details For This Host'></a>\n",STATUS_CGI,url_encode(hststatus->host_name),url_images_path,STATUS_DETAIL_ICON);
+#ifdef USE_STATUSMAP
+	printf("<A HREF='%s?host=%s'><IMG SRC='%s%s' BORDER=0 WIDTH=%d HEIGHT=%d ALT='%s' TITLE='%s'></A>",STATUSMAP_CGI,url_encode(hststatus->host_name),url_images_path,STATUSMAP_ICON,STATUS_ICON_WIDTH,STATUS_ICON_HEIGHT,"Locate Host On Map","Locate Host On Map");
+#endif
+	printf("</TD>");
+
+	printf("</TR>\n");
+
+	return;
+        }
+
+
+
+void show_servicegroup_hostgroup_member_service_status_totals(char *host_name,void *data){
+	int total_ok=0;
+	int total_warning=0;
+	int total_unknown=0;
+	int total_critical=0;
+	int total_pending=0;
+	servicestatus *temp_servicestatus;
+	service *temp_service;
+	servicegroup *temp_servicegroup=NULL;
+	char temp_buffer[MAX_INPUT_BUFFER];
+
+
+	if(display_type==DISPLAY_SERVICEGROUPS)
+		temp_servicegroup=(servicegroup *)data;
+
+	/* check all services... */
+	for(temp_servicestatus=servicestatus_list;temp_servicestatus!=NULL;temp_servicestatus=temp_servicestatus->next){
+
+		if(!strcmp(host_name,temp_servicestatus->host_name)){
+
+			/* make sure the user is authorized to see this service... */
+			temp_service=find_service(temp_servicestatus->host_name,temp_servicestatus->description);
+			if(is_authorized_for_service(temp_service,&current_authdata)==FALSE)
+				continue;
+
+			if(display_type==DISPLAY_SERVICEGROUPS){
+
+				/* is this service a member of the servicegroup? */
+				if(is_service_member_of_servicegroup(temp_servicegroup,temp_service)==FALSE)
+					continue;
+			        }
+
+			/* make sure we only display services of the specified status levels */
+			if(!(service_status_types & temp_servicestatus->status))
+				continue;
+
+			/* make sure we only display services that have the desired properties */
+			if(passes_service_properties_filter(temp_servicestatus)==FALSE)
+				continue;
+
+			if(temp_servicestatus->status==SERVICE_CRITICAL)
+				total_critical++;
+			else if(temp_servicestatus->status==SERVICE_WARNING)
+				total_warning++;
+			else if(temp_servicestatus->status==SERVICE_UNKNOWN)
+				total_unknown++;
+			else if(temp_servicestatus->status==SERVICE_OK)
+				total_ok++;
+			else if(temp_servicestatus->status==SERVICE_PENDING)
+				total_pending++;
+			else
+				total_ok++;
+		        }
+	        }
+
+
+	printf("<TABLE BORDER=0 WIDTH=100%%>\n");
+
+	if(display_type==DISPLAY_SERVICEGROUPS)
+		snprintf(temp_buffer,sizeof(temp_buffer)-1,"servicegroup=%s&style=detail",url_encode(temp_servicegroup->group_name));
+	else
+		snprintf(temp_buffer,sizeof(temp_buffer)-1,"host=%s",url_encode(host_name));
+	temp_buffer[sizeof(temp_buffer)-1]='\x0';
+
+	if(total_ok>0)
+		printf("<TR><TD CLASS='miniStatusOK'><A HREF='%s?%s&servicestatustypes=%d&hoststatustypes=%d&serviceprops=%lu&hostprops=%lu'>%d OK</A></TD></TR>\n",STATUS_CGI,temp_buffer,SERVICE_OK,host_status_types,service_properties,host_properties,total_ok);
+	if(total_warning>0)
+		printf("<TR><TD CLASS='miniStatusWARNING'><A HREF='%s?%s&servicestatustypes=%d&hoststatustypes=%d&serviceprops=%lu&hostprops=%lu'>%d WARNING</A></TD></TR>\n",STATUS_CGI,temp_buffer,SERVICE_WARNING,host_status_types,service_properties,host_properties,total_warning);
+	if(total_unknown>0)
+		printf("<TR><TD CLASS='miniStatusUNKNOWN'><A HREF='%s?%s&servicestatustypes=%d&hoststatustypes=%d&serviceprops=%lu&hostprops=%lu'>%d UNKNOWN</A></TD></TR>\n",STATUS_CGI,temp_buffer,SERVICE_UNKNOWN,host_status_types,service_properties,host_properties,total_unknown);
+	if(total_critical>0)
+		printf("<TR><TD CLASS='miniStatusCRITICAL'><A HREF='%s?%s&servicestatustypes=%d&hoststatustypes=%d&serviceprops=%lu&hostprops=%lu'>%d CRITICAL</A></TD></TR>\n",STATUS_CGI,temp_buffer,SERVICE_CRITICAL,host_status_types,service_properties,host_properties,total_critical);
+	if(total_pending>0)
+		printf("<TR><TD CLASS='miniStatusPENDING'><A HREF='%s?%s&servicestatustypes=%d&hoststatustypes=%d&serviceprops=%lu&hostprops=%lu'>%d PENDING</A></TD></TR>\n",STATUS_CGI,temp_buffer,SERVICE_PENDING,host_status_types,service_properties,host_properties,total_pending);
+
+	printf("</TABLE>\n");
+
+	if((total_ok + total_warning + total_unknown + total_critical + total_pending)==0)
+		printf("No matching services");
+
+	return;
+        }
+
+
+
+/* show a summary of hostgroup(s)... */
+void show_hostgroup_summaries(void){
+	hostgroup *temp_hostgroup=NULL;
+	int user_has_seen_something=FALSE;
+	int hostgroup_error=FALSE;
+	int odd=0;
+
+
+	printf("<P>\n");
+
+	printf("<table border=0 width=100%%>\n");
+	printf("<tr>\n");
+
+	printf("<td valign=top align=left width=33%%>\n");
+
+	show_filters();
+
+	printf("</td>");
+
+	printf("<td valign=top align=center width=33%%>\n");
+
+	printf("<DIV ALIGN=CENTER CLASS='statusTitle'>Status Summary For ");
+	if(show_all_hostgroups==TRUE)
+		printf("All Host Groups");
+	else
+		printf("Host Group '%s'",hostgroup_name);
+	printf("</DIV>\n");
+
+	printf("<br>");
+
+	printf("</td>\n");
+
+	printf("<td valign=top align=right width=33%%></td>\n");
+	
+	printf("</tr>\n");
+	printf("</table>\n");
+
+	printf("</P>\n");
+
+
+	printf("<DIV ALIGN=center>\n");
+	printf("<table border=1 CLASS='status'>\n");
+
+	printf("<TR>\n");
+	printf("<TH CLASS='status'>Host Group</TH><TH CLASS='status'>Host Status Totals</TH><TH CLASS='status'>Service Status Totals</TH>\n");
+	printf("</TR>\n");
+
+	/* display status summary for all hostgroups */
+	if(show_all_hostgroups==TRUE){
+
+		/* loop through all hostgroups... */
+		for(temp_hostgroup=hostgroup_list;temp_hostgroup!=NULL;temp_hostgroup=temp_hostgroup->next){
+
+			/* make sure the user is authorized to view this hostgroup */
+			if(is_authorized_for_hostgroup(temp_hostgroup,&current_authdata)==FALSE)
+				continue;
+
+			if(odd==0)
+				odd=1;
+			else
+				odd=0;
+
+			/* show summary for this hostgroup */
+			show_hostgroup_summary(temp_hostgroup,odd);
+
+			user_has_seen_something=TRUE;
+		        }
+
+	        }
+
+	/* else just show summary for a specific hostgroup */
+	else{
+		temp_hostgroup=find_hostgroup(hostgroup_name);
+		if(temp_hostgroup==NULL)
+			hostgroup_error=TRUE;
+		else{
+			show_hostgroup_summary(temp_hostgroup,1);
+			user_has_seen_something=TRUE;
+		        }
+	        }
+
+	printf("</TABLE>\n");
+	printf("</DIV>\n");
+
+	/* if user couldn't see anything, print out some helpful info... */
+	if(user_has_seen_something==FALSE && hostgroup_error==FALSE){
+
+		printf("<P><DIV ALIGN=CENTER>\n");
+
+		if(hoststatus_list!=NULL){
+			printf("<DIV CLASS='errorMessage'>It appears as though you do not have permission to view information for any of the hosts you requested...</DIV>\n");
+			printf("<DIV CLASS='errorDescription'>If you believe this is an error, check the HTTP server authentication requirements for accessing this CGI<br>");
+			printf("and check the authorization options in your CGI configuration file.</DIV>\n");
+		        }
+		else{
+			printf("<DIV CLASS='infoMessage'>There doesn't appear to be any host status information in the status log...<br><br>\n");
+			printf("Make sure that Nagios is running and that you have specified the location of you status log correctly in the configuration files.</DIV>\n");
+		        }
+
+		printf("</DIV></P>\n");
+	        }
+
+	/* we couldn't find the hostgroup */
+	else if(hostgroup_error==TRUE){
+		printf("<P><DIV ALIGN=CENTER>\n");
+		printf("<DIV CLASS='errorMessage'>Sorry, but hostgroup '%s' doesn't seem to exist...</DIV>\n",hostgroup_name);
+		printf("</DIV></P>\n");
+	        }
+
+	return;
+        }
+
+
+
+/* displays status summary information for a specific hostgroup */
+void show_hostgroup_summary(hostgroup *temp_hostgroup,int odd){
+	char *status_bg_class="";
+
+	if(odd==1)
+		status_bg_class="Even";
+	else
+		status_bg_class="Odd";
+
+	printf("<TR CLASS='status%s'><TD CLASS='status%s'>\n",status_bg_class,status_bg_class);
+	printf("<A HREF='%s?hostgroup=%s&style=overview'>%s</A> ",STATUS_CGI,url_encode(temp_hostgroup->group_name),temp_hostgroup->alias);
+	printf("(<A HREF='%s?type=%d&hostgroup=%s'>%s</a>)",EXTINFO_CGI,DISPLAY_HOSTGROUP_INFO,url_encode(temp_hostgroup->group_name),temp_hostgroup->group_name);
+	printf("</TD>");
+				
+	printf("<TD CLASS='status%s' ALIGN=CENTER VALIGN=CENTER>",status_bg_class);
+	show_hostgroup_host_totals_summary(temp_hostgroup);
+	printf("</TD>");
+
+	printf("<TD CLASS='status%s' ALIGN=CENTER VALIGN=CENTER>",status_bg_class);
+	show_hostgroup_service_totals_summary(temp_hostgroup);
+	printf("</TD>");
+
+	printf("</TR>\n");
+
+	return;
+        }
+
+
+
+/* shows host total summary information for a specific hostgroup */
+void show_hostgroup_host_totals_summary(hostgroup *temp_hostgroup){
+	hostgroupmember *temp_member;
+	int total_up=0;
+	int total_down=0;
+	int total_unreachable=0;
+	int total_pending=0;
+	hoststatus *temp_hoststatus;
+	host *temp_host;
+
+	/* find all the hosts that belong to the hostgroup */
+	for(temp_member=temp_hostgroup->members;temp_member!=NULL;temp_member=temp_member->next){
+
+		/* find the host... */
+		temp_host=find_host(temp_member->host_name);
+		if(temp_host==NULL)
+			continue;
+
+		/* find the host status */
+		temp_hoststatus=find_hoststatus(temp_host->name);
+		if(temp_hoststatus==NULL)
+			continue;
+
+		/* make sure we only display hosts of the specified status levels */
+		if(!(host_status_types & temp_hoststatus->status))
+			continue;
+
+		/* make sure we only display hosts that have the desired properties */
+		if(passes_host_properties_filter(temp_hoststatus)==FALSE)
+			continue;
+
+		if(temp_hoststatus->status==HOST_UP)
+			total_up++;
+		else if(temp_hoststatus->status==HOST_DOWN)
+			total_down++;
+		else if(temp_hoststatus->status==HOST_UNREACHABLE)
+			total_unreachable++;
+		else
+			total_pending++;
+	        }
+
+	printf("<TABLE BORDER=0>\n");
+
+	if(total_up>0)
+		printf("<TR><TD CLASS='miniStatusUP'><A HREF='%s?hostgroup=%s&style=detail&&hoststatustypes=%d&hostprops=%lu'>%d UP</A></TD></TR>\n",STATUS_CGI,url_encode(temp_hostgroup->group_name),HOST_UP,host_properties,total_up);
+	if(total_down>0)
+		printf("<TR><TD CLASS='miniStatusDOWN'><A HREF='%s?hostgroup=%s&style=detail&hoststatustypes=%d&hostprops=%lu'>%d DOWN</A></TD></TR>\n",STATUS_CGI,url_encode(temp_hostgroup->group_name),HOST_DOWN,host_properties,total_down);
+	if(total_unreachable>0)
+		printf("<TR><TD CLASS='miniStatusUNREACHABLE'><A HREF='%s?hostgroup=%s&style=detail&hoststatustypes=%d&hostprops=%lu'>%d UNREACHABLE</A></TD></TR>\n",STATUS_CGI,url_encode(temp_hostgroup->group_name),HOST_UNREACHABLE,host_properties,total_unreachable);
+	if(total_pending>0)
+		printf("<TR><TD CLASS='miniStatusPENDING'><A HREF='%s?hostgroup=%s&style=detail&hoststatustypes=%d&hostprops=%lu'>%d PENDING</A></TD></TR>\n",STATUS_CGI,url_encode(temp_hostgroup->group_name),HOST_PENDING,host_properties,total_pending);
+
+	printf("</TABLE>\n");
+
+	if((total_up + total_down + total_unreachable + total_pending)==0)
+		printf("No matching hosts");
+
+	return;
+        }
+
+
+
+/* shows service total summary information for a specific hostgroup */
+void show_hostgroup_service_totals_summary(hostgroup *temp_hostgroup){
+	int total_ok=0;
+	int total_warning=0;
+	int total_unknown=0;
+	int total_critical=0;
+	int total_pending=0;
+	servicestatus *temp_servicestatus;
+	hoststatus *temp_hoststatus;
+	host *temp_host;
+
+
+	/* check all services... */
+	for(temp_servicestatus=servicestatus_list;temp_servicestatus!=NULL;temp_servicestatus=temp_servicestatus->next){
+
+		/* find the host this service is associated with */
+		temp_host=find_host(temp_servicestatus->host_name);
+		if(temp_host==NULL)
+			continue;
+
+		/* see if this service is associated with a host in the specified hostgroup */
+		if(is_host_member_of_hostgroup(temp_hostgroup,temp_host)==FALSE)
+			continue;
+
+		/* find the status of the associated host */
+		temp_hoststatus=find_hoststatus(temp_servicestatus->host_name);
+		if(temp_hoststatus==NULL)
+			continue;
+
+		/* make sure we only display hosts of the specified status levels */
+		if(!(host_status_types & temp_hoststatus->status))
+			continue;
+
+		/* make sure we only display hosts that have the desired properties */
+		if(passes_host_properties_filter(temp_hoststatus)==FALSE)
+			continue;
+
+		/* make sure we only display services of the specified status levels */
+		if(!(service_status_types & temp_servicestatus->status))
+			continue;
+
+		/* make sure we only display services that have the desired properties */
+		if(passes_service_properties_filter(temp_servicestatus)==FALSE)
+			continue;
+
+		if(temp_servicestatus->status==SERVICE_CRITICAL)
+			total_critical++;
+		else if(temp_servicestatus->status==SERVICE_WARNING)
+			total_warning++;
+		else if(temp_servicestatus->status==SERVICE_UNKNOWN)
+			total_unknown++;
+		else if(temp_servicestatus->status==SERVICE_OK)
+			total_ok++;
+		else if(temp_servicestatus->status==SERVICE_PENDING)
+			total_pending++;
+		else
+			total_ok++;
+	        }
+
+
+	printf("<TABLE BORDER=0>\n");
+
+	if(total_ok>0)
+		printf("<TR><TD CLASS='miniStatusOK'><A HREF='%s?hostgroup=%s&style=detail&&servicestatustypes=%d&hoststatustypes=%d&serviceprops=%lu&hostprops=%lu'>%d OK</A></TD></TR>\n",STATUS_CGI,url_encode(temp_hostgroup->group_name),SERVICE_OK,host_status_types,service_properties,host_properties,total_ok);
+	if(total_warning>0)
+		printf("<TR><TD CLASS='miniStatusWARNING'><A HREF='%s?hostgroup=%s&style=detail&servicestatustypes=%d&hoststatustypes=%d&serviceprops=%lu&hostprops=%lu'>%d WARNING</A></TD></TR>\n",STATUS_CGI,url_encode(temp_hostgroup->group_name),SERVICE_WARNING,host_status_types,service_properties,host_properties,total_warning);
+	if(total_unknown>0)
+		printf("<TR><TD CLASS='miniStatusUNKNOWN'><A HREF='%s?hostgroup=%s&style=detail&servicestatustypes=%d&hoststatustypes=%d&serviceprops=%lu&hostprops=%lu'>%d UNKNOWN</A></TD></TR>\n",STATUS_CGI,url_encode(temp_hostgroup->group_name),SERVICE_UNKNOWN,host_status_types,service_properties,host_properties,total_unknown);
+	if(total_critical>0)
+		printf("<TR><TD CLASS='miniStatusCRITICAL'><A HREF='%s?hostgroup=%s&style=detail&servicestatustypes=%d&hoststatustypes=%d&serviceprops=%lu&hostprops=%lu'>%d CRITICAL</A></TD></TR>\n",STATUS_CGI,url_encode(temp_hostgroup->group_name),SERVICE_CRITICAL,host_status_types,service_properties,host_properties,total_critical);
+	if(total_pending>0)
+		printf("<TR><TD CLASS='miniStatusPENDING'><A HREF='%s?hostgroup=%s&style=detail&servicestatustypes=%d&hoststatustypes=%d&serviceprops=%lu&hostprops=%lu'>%d PENDING</A></TD></TR>\n",STATUS_CGI,url_encode(temp_hostgroup->group_name),SERVICE_PENDING,host_status_types,service_properties,host_properties,total_pending);
+
+	printf("</TABLE>\n");
+
+	if((total_ok + total_warning + total_unknown + total_critical + total_pending)==0)
+		printf("No matching services");
+
+	return;
+        }
+
+
+
+/* show a grid layout of hostgroup(s)... */
+void show_hostgroup_grids(void){
+	hostgroup *temp_hostgroup=NULL;
+	int user_has_seen_something=FALSE;
+	int hostgroup_error=FALSE;
+	int odd=0;
+
+
+	printf("<P>\n");
+
+	printf("<table border=0 width=100%%>\n");
+	printf("<tr>\n");
+
+	printf("<td valign=top align=left width=33%%>\n");
+
+	show_filters();
+
+	printf("</td>");
+
+	printf("<td valign=top align=center width=33%%>\n");
+
+	printf("<DIV ALIGN=CENTER CLASS='statusTitle'>Status Grid For ");
+	if(show_all_hostgroups==TRUE)
+		printf("All Host Groups");
+	else
+		printf("Host Group '%s'",hostgroup_name);
+	printf("</DIV>\n");
+
+	printf("<br>");
+
+	printf("</td>\n");
+
+	printf("<td valign=top align=right width=33%%></td>\n");
+	
+	printf("</tr>\n");
+	printf("</table>\n");
+
+	printf("</P>\n");
+
+
+	/* display status grids for all hostgroups */
+	if(show_all_hostgroups==TRUE){
+
+		/* loop through all hostgroups... */
+		for(temp_hostgroup=hostgroup_list;temp_hostgroup!=NULL;temp_hostgroup=temp_hostgroup->next){
+
+			/* make sure the user is authorized to view this hostgroup */
+			if(is_authorized_for_hostgroup(temp_hostgroup,&current_authdata)==FALSE)
+				continue;
+
+			if(odd==0)
+				odd=1;
+			else
+				odd=0;
+
+			/* show grid for this hostgroup */
+			show_hostgroup_grid(temp_hostgroup);
+
+			user_has_seen_something=TRUE;
+		        }
+
+	        }
+
+	/* else just show grid for a specific hostgroup */
+	else{
+		temp_hostgroup=find_hostgroup(hostgroup_name);
+		if(temp_hostgroup==NULL)
+			hostgroup_error=TRUE;
+		else{
+			show_hostgroup_grid(temp_hostgroup);
+			user_has_seen_something=TRUE;
+		        }
+	        }
+
+	/* if user couldn't see anything, print out some helpful info... */
+	if(user_has_seen_something==FALSE && hostgroup_error==FALSE){
+
+		printf("<P><DIV ALIGN=CENTER>\n");
+
+		if(hoststatus_list!=NULL){
+			printf("<DIV CLASS='errorMessage'>It appears as though you do not have permission to view information for any of the hosts you requested...</DIV>\n");
+			printf("<DIV CLASS='errorDescription'>If you believe this is an error, check the HTTP server authentication requirements for accessing this CGI<br>");
+			printf("and check the authorization options in your CGI configuration file.</DIV>\n");
+		        }
+		else{
+			printf("<DIV CLASS='infoMessage'>There doesn't appear to be any host status information in the status log...<br><br>\n");
+			printf("Make sure that Nagios is running and that you have specified the location of you status log correctly in the configuration files.</DIV>\n");
+		        }
+
+		printf("</DIV></P>\n");
+	        }
+
+	/* we couldn't find the hostgroup */
+	else if(hostgroup_error==TRUE){
+		printf("<P><DIV ALIGN=CENTER>\n");
+		printf("<DIV CLASS='errorMessage'>Sorry, but hostgroup '%s' doesn't seem to exist...</DIV>\n",hostgroup_name);
+		printf("</DIV></P>\n");
+	        }
+
+	return;
+        }
+
+
+/* displays status grid for a specific hostgroup */
+void show_hostgroup_grid(hostgroup *temp_hostgroup){
+	hostgroupmember *temp_member;
+	char *status_bg_class="";
+	char *host_status_class="";
+	char *service_status_class="";
+	host *temp_host;
+	service *temp_service;
+	hoststatus *temp_hoststatus;
+	servicestatus *temp_servicestatus;
+	hostextinfo *temp_hostextinfo;
+	int odd=0;
+	int current_item;
+
+
+	printf("<P>\n");
+	printf("<DIV ALIGN=CENTER>\n");
+
+	printf("<DIV CLASS='status'><A HREF='%s?hostgroup=%s&style=detail'>%s</A>",STATUS_CGI,url_encode(temp_hostgroup->group_name),temp_hostgroup->alias);
+	printf(" (<A HREF='%s?type=%d&hostgroup=%s'>%s</A>)</DIV>",EXTINFO_CGI,DISPLAY_HOSTGROUP_INFO,url_encode(temp_hostgroup->group_name),temp_hostgroup->group_name);
+
+	printf("<TABLE BORDER=1 CLASS='status' ALIGN=CENTER>\n");
+	printf("<TR><TH CLASS='status'>Host</TH><TH CLASS='status'>Services</a></TH><TH CLASS='status'>Actions</TH></TR>\n");
+
+	/* find all the hosts that belong to the hostgroup */
+	for(temp_member=temp_hostgroup->members;temp_member!=NULL;temp_member=temp_member->next){
+
+		/* find the host... */
+		temp_host=find_host(temp_member->host_name);
+		if(temp_host==NULL)
+			continue;
+
+		/* find the host status */
+		temp_hoststatus=find_hoststatus(temp_host->name);
+		if(temp_hoststatus==NULL)
+			continue;
+
+		if(odd==1){
+			status_bg_class="Even";
+			odd=0;
+		        }
+		else{
+			status_bg_class="Odd";
+			odd=1;
+		        }
+
+		printf("<TR CLASS='status%s'>\n",status_bg_class);
+
+		/* get the status of the host */
+		if(temp_hoststatus->status==HOST_DOWN)
+			host_status_class="HOSTDOWN";
+		else if(temp_hoststatus->status==HOST_UNREACHABLE)
+			host_status_class="HOSTUNREACHABLE";
+		else
+			host_status_class=status_bg_class;
+
+		printf("<TD CLASS='status%s'>",host_status_class);
+
+		printf("<TABLE BORDER=0 WIDTH='100%%' cellpadding=0 cellspacing=0>\n");
+		printf("<TR>\n");
+		printf("<TD ALIGN=LEFT>\n");
+		printf("<TABLE BORDER=0 cellpadding=0 cellspacing=0>\n");
+		printf("<TR>\n");
+		printf("<TD align=left valign=center CLASS='status%s'>",host_status_class);
+		printf("<A HREF='%s?type=%d&host=%s'>%s</A>\n",EXTINFO_CGI,DISPLAY_HOST_INFO,url_encode(temp_host->name),temp_host->name);
+		printf("</TD>\n");
+		printf("</TR>\n");
+		printf("</TABLE>\n");
+		printf("</TD>\n");
+		printf("<TD align=right valign=center nowrap>\n");
+		printf("<TABLE BORDER=0 cellpadding=0 cellspacing=0>\n");
+		printf("<TR>\n");
+
+		temp_hostextinfo=find_hostextinfo(temp_host->name);
+		if(temp_hostextinfo!=NULL){
+			if(temp_hostextinfo->icon_image!=NULL){
+				printf("<TD align=center valign=center>");
+				printf("<A HREF='%s?type=%d&host=%s'>\n",EXTINFO_CGI,DISPLAY_HOST_INFO,url_encode(temp_host->name));
+				printf("<IMG SRC='%s",url_logo_images_path);
+				print_extra_host_url(temp_hostextinfo->host_name,temp_hostextinfo->icon_image);
+				printf("' BORDER=0 WIDTH=%d HEIGHT=%d ALT='%s' TITLE='%s'>",STATUS_ICON_WIDTH,STATUS_ICON_HEIGHT,(temp_hostextinfo->icon_image_alt==NULL)?"":temp_hostextinfo->icon_image_alt,(temp_hostextinfo->icon_image_alt==NULL)?"":temp_hostextinfo->icon_image_alt);
+				printf("</A>");
+				printf("<TD>\n");
+			        }
+		        }
+		printf("<TD>\n");
+
+		printf("</TR>\n");
+		printf("</TABLE>\n");
+		printf("</TD>\n");
+		printf("</TR>\n");
+		printf("</TABLE>\n");
+
+		printf("</TD>\n");
+
+		printf("<TD CLASS='status%s'>",host_status_class);
+
+		/* display all services on the host */
+		current_item=1;
+		for(temp_service=service_list;temp_service;temp_service=temp_service->next){
+
+			/* skip this service if it's not associate with the host */
+			if(strcmp(temp_service->host_name,temp_host->name))
+				continue;
+
+			if(current_item>max_grid_width && max_grid_width>0){
+				printf("<BR>\n");
+				current_item=1;
+			        }
+
+			/* get the status of the service */
+			temp_servicestatus=find_servicestatus(temp_service->host_name,temp_service->description);
+			if(temp_servicestatus==NULL)
+				service_status_class="NULL";
+			else if(temp_servicestatus->status==SERVICE_OK)
+				service_status_class="OK";
+			else if(temp_servicestatus->status==SERVICE_WARNING)
+				service_status_class="WARNING";
+			else if(temp_servicestatus->status==SERVICE_UNKNOWN)
+				service_status_class="UNKNOWN";
+			else if(temp_servicestatus->status==SERVICE_CRITICAL)
+				service_status_class="CRITICAL";
+			else
+				service_status_class="PENDING";
+
+			printf("<A HREF='%s?type=%d&host=%s",EXTINFO_CGI,DISPLAY_SERVICE_INFO,url_encode(temp_servicestatus->host_name));
+			printf("&service=%s' CLASS='status%s'>%s</A>&nbsp;",url_encode(temp_servicestatus->description),service_status_class,temp_servicestatus->description);
+
+			current_item++;
+		        }
+
+		printf("</TD>\n");
+
+		/* actions */
+		printf("<TD CLASS='status%s'>",host_status_class);
+
+		printf("<A HREF='%s?type=%d&host=%s'>\n",EXTINFO_CGI,DISPLAY_HOST_INFO,url_encode(temp_host->name));
+		printf("<IMG SRC='%s%s' BORDER=0 WIDTH=%d HEIGHT=%d ALT='%s' TITLE='%s'>",url_images_path,DETAIL_ICON,STATUS_ICON_WIDTH,STATUS_ICON_HEIGHT,"View Extended Information For This Host","View Extended Information For This Host");
+		printf("</A>");
+
+		if(temp_hostextinfo!=NULL){
+			if(temp_hostextinfo->notes_url!=NULL){
+				printf("<A HREF='");
+				print_extra_host_url(temp_hostextinfo->host_name,temp_hostextinfo->notes_url);
+				printf("' TARGET='_blank'>");
+				printf("<IMG SRC='%s%s' BORDER=0 WIDTH=%d HEIGHT=%d ALT='%s' TITLE='%s'>",url_images_path,NOTES_ICON,STATUS_ICON_WIDTH,STATUS_ICON_HEIGHT,"View Extra Host Notes","View Extra Host Notes");
+				printf("</A>");
+			        }
+			if(temp_hostextinfo->action_url!=NULL){
+				printf("<A HREF='");
+				print_extra_host_url(temp_hostextinfo->host_name,temp_hostextinfo->action_url);
+				printf("' TARGET='_blank'>");
+				printf("<IMG SRC='%s%s' BORDER=0 WIDTH=%d HEIGHT=%d ALT='%s' TITLE='%s'>",url_images_path,ACTION_ICON,STATUS_ICON_WIDTH,STATUS_ICON_HEIGHT,"Perform Extra Host Actions","Perform Extra Host Actions");
+				printf("</A>");
+			        }
+		        }
+
+		printf("<a href='%s?host=%s'><img src='%s%s' border=0 alt='View Service Details For This Host' title='View Service Details For This Host'></a>\n",STATUS_CGI,url_encode(temp_host->name),url_images_path,STATUS_DETAIL_ICON);
+#ifdef USE_STATUSMAP
+		printf("<A HREF='%s?host=%s'><IMG SRC='%s%s' BORDER=0 WIDTH=%d HEIGHT=%d ALT='%s' TITLE='%s'></A>",STATUSMAP_CGI,url_encode(temp_host->name),url_images_path,STATUSMAP_ICON,STATUS_ICON_WIDTH,STATUS_ICON_HEIGHT,"Locate Host On Map","Locate Host On Map");
+#endif
+		printf("</TD>\n");
+
+		printf("</TR>\n");
+		}
+
+	printf("</TABLE>\n");
+	printf("</DIV>\n");
+	printf("</P>\n");
+
+	return;
+        }
+
+
+
+
+/******************************************************************/
+/**********  SERVICE SORTING & FILTERING FUNCTIONS  ***************/
+/******************************************************************/
+
+
+/* sorts the service list */
+int sort_services(int s_type, int s_option){
+	servicesort *new_servicesort;
+	servicesort *last_servicesort;
+	servicesort *temp_servicesort;
+	servicestatus *temp_svcstatus;
+
+	if(s_type==SORT_NONE)
+		return ERROR;
+
+	if(servicestatus_list==NULL)
+		return ERROR;
+
+	/* sort all services status entries */
+	for(temp_svcstatus=servicestatus_list;temp_svcstatus!=NULL;temp_svcstatus=temp_svcstatus->next){
+
+		/* allocate memory for a new sort structure */
+		new_servicesort=(servicesort *)malloc(sizeof(servicesort));
+		if(new_servicesort==NULL)
+			return ERROR;
+
+		new_servicesort->svcstatus=temp_svcstatus;
+
+		last_servicesort=servicesort_list;
+		for(temp_servicesort=servicesort_list;temp_servicesort!=NULL;temp_servicesort=temp_servicesort->next){
+
+			if(compare_servicesort_entries(s_type,s_option,new_servicesort,temp_servicesort)==TRUE){
+				new_servicesort->next=temp_servicesort;
+				if(temp_servicesort==servicesort_list)
+					servicesort_list=new_servicesort;
+				else
+					last_servicesort->next=new_servicesort;
+				break;
+		                }
+			else
+				last_servicesort=temp_servicesort;
+	                }
+
+		if(servicesort_list==NULL){
+			new_servicesort->next=NULL;
+			servicesort_list=new_servicesort;
+	                }
+		else if(temp_servicesort==NULL){
+			new_servicesort->next=NULL;
+			last_servicesort->next=new_servicesort;
+	                }
+	        }
+
+	return OK;
+        }
+
+
+int compare_servicesort_entries(int s_type, int s_option, servicesort *new_servicesort, servicesort *temp_servicesort){
+	servicestatus *new_svcstatus;
+	servicestatus *temp_svcstatus;
+	time_t nt;
+	time_t tt;
+
+	new_svcstatus=new_servicesort->svcstatus;
+	temp_svcstatus=temp_servicesort->svcstatus;
+
+	if(s_type==SORT_ASCENDING){
+
+		if(s_option==SORT_LASTCHECKTIME){
+			if(new_svcstatus->last_check < temp_svcstatus->last_check)
+				return TRUE;
+			else
+				return FALSE;
+		        }
+		else if(s_option==SORT_CURRENTATTEMPT){
+			if(new_svcstatus->current_attempt < temp_svcstatus->current_attempt)
+				return TRUE;
+			else
+				return FALSE;
+		        }
+		else if(s_option==SORT_SERVICESTATUS){
+			if(new_svcstatus->status <= temp_svcstatus->status)
+				return TRUE;
+			else
+				return FALSE;
+		        }
+		else if(s_option==SORT_HOSTNAME){
+			if(strcasecmp(new_svcstatus->host_name,temp_svcstatus->host_name)<0)
+				return TRUE;
+			else
+				return FALSE;
+		        }
+		else if(s_option==SORT_SERVICENAME){
+			if(strcasecmp(new_svcstatus->description,temp_svcstatus->description)<0)
+				return TRUE;
+			else
+				return FALSE;
+		        }
+		else if(s_option==SORT_STATEDURATION){
+			if(new_svcstatus->last_state_change==(time_t)0)
+				nt=(program_start>current_time)?0:(current_time-program_start);
+			else
+				nt=(new_svcstatus->last_state_change>current_time)?0:(current_time-new_svcstatus->last_state_change);
+			if(temp_svcstatus->last_state_change==(time_t)0)
+				tt=(program_start>current_time)?0:(current_time-program_start);
+			else
+				tt=(temp_svcstatus->last_state_change>current_time)?0:(current_time-temp_svcstatus->last_state_change);
+			if(nt<tt)
+				return TRUE;
+			else
+				return FALSE;
+		        }
+	        }
+	else{
+		if(s_option==SORT_LASTCHECKTIME){
+			if(new_svcstatus->last_check > temp_svcstatus->last_check)
+				return TRUE;
+			else
+				return FALSE;
+		        }
+		else if(s_option==SORT_CURRENTATTEMPT){
+			if(new_svcstatus->current_attempt > temp_svcstatus->current_attempt)
+				return TRUE;
+			else
+				return FALSE;
+		        }
+		else if(s_option==SORT_SERVICESTATUS){
+			if(new_svcstatus->status > temp_svcstatus->status)
+				return TRUE;
+			else
+				return FALSE;
+		        }
+		else if(s_option==SORT_HOSTNAME){
+			if(strcasecmp(new_svcstatus->host_name,temp_svcstatus->host_name)>0)
+				return TRUE;
+			else
+				return FALSE;
+		        }
+		else if(s_option==SORT_SERVICENAME){
+			if(strcasecmp(new_svcstatus->description,temp_svcstatus->description)>0)
+				return TRUE;
+			else
+				return FALSE;
+		        }
+		else if(s_option==SORT_STATEDURATION){
+			if(new_svcstatus->last_state_change==(time_t)0)
+				nt=(program_start>current_time)?0:(current_time-program_start);
+			else
+				nt=(new_svcstatus->last_state_change>current_time)?0:(current_time-new_svcstatus->last_state_change);
+			if(temp_svcstatus->last_state_change==(time_t)0)
+				tt=(program_start>current_time)?0:(current_time-program_start);
+			else
+				tt=(temp_svcstatus->last_state_change>current_time)?0:(current_time-temp_svcstatus->last_state_change);
+			if(nt>tt)
+				return TRUE;
+			else
+				return FALSE;
+		        }
+	        }
+
+	return TRUE;
+        }
+
+
+
+/* sorts the host list */
+int sort_hosts(int s_type, int s_option){
+	hostsort *new_hostsort;
+	hostsort *last_hostsort;
+	hostsort *temp_hostsort;
+	hoststatus *temp_hststatus;
+
+	if(s_type==SORT_NONE)
+		return ERROR;
+
+	if(hoststatus_list==NULL)
+		return ERROR;
+
+	/* sort all hosts status entries */
+	for(temp_hststatus=hoststatus_list;temp_hststatus!=NULL;temp_hststatus=temp_hststatus->next){
+
+		/* allocate memory for a new sort structure */
+		new_hostsort=(hostsort *)malloc(sizeof(hostsort));
+		if(new_hostsort==NULL)
+			return ERROR;
+
+		new_hostsort->hststatus=temp_hststatus;
+
+		last_hostsort=hostsort_list;
+		for(temp_hostsort=hostsort_list;temp_hostsort!=NULL;temp_hostsort=temp_hostsort->next){
+
+			if(compare_hostsort_entries(s_type,s_option,new_hostsort,temp_hostsort)==TRUE){
+				new_hostsort->next=temp_hostsort;
+				if(temp_hostsort==hostsort_list)
+					hostsort_list=new_hostsort;
+				else
+					last_hostsort->next=new_hostsort;
+				break;
+		                }
+			else
+				last_hostsort=temp_hostsort;
+	                }
+
+		if(hostsort_list==NULL){
+			new_hostsort->next=NULL;
+			hostsort_list=new_hostsort;
+	                }
+		else if(temp_hostsort==NULL){
+			new_hostsort->next=NULL;
+			last_hostsort->next=new_hostsort;
+	                }
+	        }
+
+	return OK;
+        }
+
+
+int compare_hostsort_entries(int s_type, int s_option, hostsort *new_hostsort, hostsort *temp_hostsort){
+	hoststatus *new_hststatus;
+	hoststatus *temp_hststatus;
+	time_t nt;
+	time_t tt;
+
+	new_hststatus=new_hostsort->hststatus;
+	temp_hststatus=temp_hostsort->hststatus;
+
+	if(s_type==SORT_ASCENDING){
+
+		if(s_option==SORT_LASTCHECKTIME){
+			if(new_hststatus->last_check < temp_hststatus->last_check)
+				return TRUE;
+			else
+				return FALSE;
+		        }
+		else if(s_option==SORT_HOSTSTATUS){
+			if(new_hststatus->status <= temp_hststatus->status)
+				return TRUE;
+			else
+				return FALSE;
+		        }
+		else if(s_option==SORT_HOSTNAME){
+			if(strcasecmp(new_hststatus->host_name,temp_hststatus->host_name)<0)
+				return TRUE;
+			else
+				return FALSE;
+		        }
+		else if(s_option==SORT_STATEDURATION){
+			if(new_hststatus->last_state_change==(time_t)0)
+				nt=(program_start>current_time)?0:(current_time-program_start);
+			else
+				nt=(new_hststatus->last_state_change>current_time)?0:(current_time-new_hststatus->last_state_change);
+			if(temp_hststatus->last_state_change==(time_t)0)
+				tt=(program_start>current_time)?0:(current_time-program_start);
+			else
+				tt=(temp_hststatus->last_state_change>current_time)?0:(current_time-temp_hststatus->last_state_change);
+			if(nt<tt)
+				return TRUE;
+			else
+				return FALSE;
+		        }
+	        }
+	else{
+		if(s_option==SORT_LASTCHECKTIME){
+			if(new_hststatus->last_check > temp_hststatus->last_check)
+				return TRUE;
+			else
+				return FALSE;
+		        }
+		else if(s_option==SORT_HOSTSTATUS){
+			if(new_hststatus->status > temp_hststatus->status)
+				return TRUE;
+			else
+				return FALSE;
+		        }
+		else if(s_option==SORT_HOSTNAME){
+			if(strcasecmp(new_hststatus->host_name,temp_hststatus->host_name)>0)
+				return TRUE;
+			else
+				return FALSE;
+		        }
+		else if(s_option==SORT_STATEDURATION){
+			if(new_hststatus->last_state_change==(time_t)0)
+				nt=(program_start>current_time)?0:(current_time-program_start);
+			else
+				nt=(new_hststatus->last_state_change>current_time)?0:(current_time-new_hststatus->last_state_change);
+			if(temp_hststatus->last_state_change==(time_t)0)
+				tt=(program_start>current_time)?0:(current_time-program_start);
+			else
+				tt=(temp_hststatus->last_state_change>current_time)?0:(current_time-temp_hststatus->last_state_change);
+			if(nt>tt)
+				return TRUE;
+			else
+				return FALSE;
+		        }
+	        }
+
+	return TRUE;
+        }
+
+
+
+/* free all memory allocated to the servicesort structures */
+void free_servicesort_list(void){
+	servicesort *this_servicesort;
+	servicesort *next_servicesort;
+
+	/* free memory for the servicesort list */
+	for(this_servicesort=servicesort_list;this_servicesort!=NULL;this_servicesort=next_servicesort){
+		next_servicesort=this_servicesort->next;
+		free(this_servicesort);
+	        }
+
+	return;
+        }
+
+
+/* free all memory allocated to the hostsort structures */
+void free_hostsort_list(void){
+	hostsort *this_hostsort;
+	hostsort *next_hostsort;
+
+	/* free memory for the hostsort list */
+	for(this_hostsort=hostsort_list;this_hostsort!=NULL;this_hostsort=next_hostsort){
+		next_hostsort=this_hostsort->next;
+		free(this_hostsort);
+	        }
+
+	return;
+        }
+
+
+
+/* check host properties filter */
+int passes_host_properties_filter(hoststatus *temp_hoststatus){
+
+	if((host_properties & HOST_SCHEDULED_DOWNTIME) && temp_hoststatus->scheduled_downtime_depth<=0)
+		return FALSE;
+
+	if((host_properties & HOST_NO_SCHEDULED_DOWNTIME) && temp_hoststatus->scheduled_downtime_depth>0)
+		return FALSE;
+
+	if((host_properties & HOST_STATE_ACKNOWLEDGED) && temp_hoststatus->problem_has_been_acknowledged==FALSE)
+		return FALSE;
+
+	if((host_properties & HOST_STATE_UNACKNOWLEDGED) && temp_hoststatus->problem_has_been_acknowledged==TRUE)
+		return FALSE;
+
+	if((host_properties & HOST_CHECKS_DISABLED) && temp_hoststatus->checks_enabled==TRUE)
+		return FALSE;
+
+	if((host_properties & HOST_CHECKS_ENABLED) && temp_hoststatus->checks_enabled==FALSE)
+		return FALSE;
+
+	if((host_properties & HOST_EVENT_HANDLER_DISABLED) && temp_hoststatus->event_handler_enabled==TRUE)
+		return FALSE;
+
+	if((host_properties & HOST_EVENT_HANDLER_ENABLED) && temp_hoststatus->event_handler_enabled==FALSE)
+		return FALSE;
+
+	if((host_properties & HOST_FLAP_DETECTION_DISABLED) && temp_hoststatus->flap_detection_enabled==TRUE)
+		return FALSE;
+
+	if((host_properties & HOST_FLAP_DETECTION_ENABLED) && temp_hoststatus->flap_detection_enabled==FALSE)
+		return FALSE;
+
+	if((host_properties & HOST_IS_FLAPPING) && temp_hoststatus->is_flapping==FALSE)
+		return FALSE;
+
+	if((host_properties & HOST_IS_NOT_FLAPPING) && temp_hoststatus->is_flapping==TRUE)
+		return FALSE;
+
+	if((host_properties & HOST_NOTIFICATIONS_DISABLED) && temp_hoststatus->notifications_enabled==TRUE)
+		return FALSE;
+
+	if((host_properties & HOST_NOTIFICATIONS_ENABLED) && temp_hoststatus->notifications_enabled==FALSE)
+		return FALSE;
+
+	if((host_properties & HOST_PASSIVE_CHECKS_DISABLED) && temp_hoststatus->accept_passive_host_checks==TRUE)
+		return FALSE;
+
+	if((host_properties & HOST_PASSIVE_CHECKS_ENABLED) && temp_hoststatus->accept_passive_host_checks==FALSE)
+		return FALSE;
+
+	if((host_properties & HOST_PASSIVE_CHECK) && temp_hoststatus->check_type==HOST_CHECK_ACTIVE)
+		return FALSE;
+
+	if((host_properties & HOST_ACTIVE_CHECK) && temp_hoststatus->check_type==HOST_CHECK_PASSIVE)
+		return FALSE;
+
+	return TRUE;
+        }
+
+
+
+/* check service properties filter */
+int passes_service_properties_filter(servicestatus *temp_servicestatus){
+
+	if((service_properties & SERVICE_SCHEDULED_DOWNTIME) && temp_servicestatus->scheduled_downtime_depth<=0)
+		return FALSE;
+
+	if((service_properties & SERVICE_NO_SCHEDULED_DOWNTIME) && temp_servicestatus->scheduled_downtime_depth>0)
+		return FALSE;
+
+	if((service_properties & SERVICE_STATE_ACKNOWLEDGED) && temp_servicestatus->problem_has_been_acknowledged==FALSE)
+		return FALSE;
+
+	if((service_properties & SERVICE_STATE_UNACKNOWLEDGED) && temp_servicestatus->problem_has_been_acknowledged==TRUE)
+		return FALSE;
+
+	if((service_properties & SERVICE_CHECKS_DISABLED) && temp_servicestatus->checks_enabled==TRUE)
+		return FALSE;
+
+	if((service_properties & SERVICE_CHECKS_ENABLED) && temp_servicestatus->checks_enabled==FALSE)
+		return FALSE;
+
+	if((service_properties & SERVICE_EVENT_HANDLER_DISABLED) && temp_servicestatus->event_handler_enabled==TRUE)
+		return FALSE;
+
+	if((service_properties & SERVICE_EVENT_HANDLER_ENABLED) && temp_servicestatus->event_handler_enabled==FALSE)
+		return FALSE;
+
+	if((service_properties & SERVICE_FLAP_DETECTION_DISABLED) && temp_servicestatus->flap_detection_enabled==TRUE)
+		return FALSE;
+
+	if((service_properties & SERVICE_FLAP_DETECTION_ENABLED) && temp_servicestatus->flap_detection_enabled==FALSE)
+		return FALSE;
+
+	if((service_properties & SERVICE_IS_FLAPPING) && temp_servicestatus->is_flapping==FALSE)
+		return FALSE;
+
+	if((service_properties & SERVICE_IS_NOT_FLAPPING) && temp_servicestatus->is_flapping==TRUE)
+		return FALSE;
+
+	if((service_properties & SERVICE_NOTIFICATIONS_DISABLED) && temp_servicestatus->notifications_enabled==TRUE)
+		return FALSE;
+
+	if((service_properties & SERVICE_NOTIFICATIONS_ENABLED) && temp_servicestatus->notifications_enabled==FALSE)
+		return FALSE;
+
+	if((service_properties & SERVICE_PASSIVE_CHECKS_DISABLED) && temp_servicestatus->accept_passive_service_checks==TRUE)
+		return FALSE;
+
+	if((service_properties & SERVICE_PASSIVE_CHECKS_ENABLED) && temp_servicestatus->accept_passive_service_checks==FALSE)
+		return FALSE;
+
+	if((service_properties & SERVICE_PASSIVE_CHECK) && temp_servicestatus->check_type==SERVICE_CHECK_ACTIVE)
+		return FALSE;
+
+	if((service_properties & SERVICE_ACTIVE_CHECK) && temp_servicestatus->check_type==SERVICE_CHECK_PASSIVE)
+		return FALSE;
+
+	return TRUE;
+        }
+
+
+
+/* shows service and host filters in use */
+void show_filters(void){
+	int found=0;
+
+	/* show filters box if necessary */
+	if(host_properties!=0L || service_properties!=0L || host_status_types!=all_host_status_types || service_status_types!=all_service_status_types){
+
+		printf("<table border=1 class='filter' cellspacing=0 cellpadding=0>\n");
+		printf("<tr><td class='filter'>\n");
+		printf("<table border=0 cellspacing=2 cellpadding=0>\n");
+		printf("<tr><td colspan=2 valign=top align=left CLASS='filterTitle'>Display Filters:</td></tr>");
+		printf("<tr><td valign=top align=left CLASS='filterName'>Host Status Types:</td>");
+		printf("<td valign=top align=left CLASS='filterValue'>");
+		if(host_status_types==all_host_status_types)
+			printf("All");
+		else if(host_status_types==all_host_problems)
+			printf("All problems");
+		else{
+			found=0;
+			if(host_status_types & HOST_PENDING){
+				printf(" Pending");
+				found=1;
+		                }
+			if(host_status_types & HOST_UP){
+				printf("%s Up",(found==1)?" |":"");
+				found=1;
+		                }
+			if(host_status_types & HOST_DOWN){
+				printf("%s Down",(found==1)?" |":"");
+				found=1;
+		                }
+			if(host_status_types & HOST_UNREACHABLE)
+				printf("%s Unreachable",(found==1)?" |":"");
+	                }
+		printf("</td></tr>");
+		printf("<tr><td valign=top align=left CLASS='filterName'>Host Properties:</td>");
+		printf("<td valign=top align=left CLASS='filterValue'>");
+		if(host_properties==0)
+			printf("Any");
+		else{
+			found=0;
+			if(host_properties & HOST_SCHEDULED_DOWNTIME){
+				printf(" In Scheduled Downtime");
+				found=1;
+		                }
+			if(host_properties & HOST_NO_SCHEDULED_DOWNTIME){
+				printf("%s Not In Scheduled Downtime",(found==1)?" &amp;":"");
+				found=1;
+		                }
+			if(host_properties & HOST_STATE_ACKNOWLEDGED){
+				printf("%s Has Been Acknowledged",(found==1)?" &amp;":"");
+				found=1;
+		                }
+			if(host_properties & HOST_STATE_UNACKNOWLEDGED){
+				printf("%s Has Not Been Acknowledged",(found==1)?" &amp;":"");
+				found=1;
+		                }
+			if(host_properties & HOST_CHECKS_DISABLED){
+				printf("%s Checks Disabled",(found==1)?" &amp;":"");
+				found=1;
+		                }
+			if(host_properties & HOST_CHECKS_ENABLED){
+				printf("%s Checks Enabled",(found==1)?" &amp;":"");
+				found=1;
+		                }
+			if(host_properties & HOST_EVENT_HANDLER_DISABLED){
+				printf("%s Event Handler Disabled",(found==1)?" &amp;":"");
+				found=1;
+		                }
+			if(host_properties & HOST_EVENT_HANDLER_ENABLED){
+				printf("%s Event Handler Enabled",(found==1)?" &amp;":"");
+				found=1;
+		                }
+			if(host_properties & HOST_FLAP_DETECTION_DISABLED){
+				printf("%s Flap Detection Disabled",(found==1)?" &amp;":"");
+				found=1;
+		                }
+			if(host_properties & HOST_FLAP_DETECTION_ENABLED){
+				printf("%s Flap Detection Enabled",(found==1)?" &amp;":"");
+				found=1;
+		                }
+			if(host_properties & HOST_IS_FLAPPING){
+				printf("%s Is Flapping",(found==1)?" &amp;":"");
+				found=1;
+		                }
+			if(host_properties & HOST_IS_NOT_FLAPPING){
+				printf("%s Is Not Flapping",(found==1)?" &amp;":"");
+				found=1;
+		                }
+			if(host_properties & HOST_NOTIFICATIONS_DISABLED){
+				printf("%s Notifications Disabled",(found==1)?" &amp;":"");
+				found=1;
+		                }
+			if(host_properties & HOST_NOTIFICATIONS_ENABLED){
+				printf("%s Notifications Enabled",(found==1)?" &amp;":"");
+				found=1;
+		                }
+			if(host_properties & HOST_PASSIVE_CHECKS_DISABLED){
+				printf("%s Passive Checks Disabled",(found==1)?" &amp;":"");
+				found=1;
+		                }
+			if(host_properties & HOST_PASSIVE_CHECKS_ENABLED){
+				printf("%s Passive Checks Enabled",(found==1)?" &amp;":"");
+				found=1;
+		                }
+			if(host_properties & HOST_PASSIVE_CHECK){
+				printf("%s Passive Checks",(found==1)?" &amp;":"");
+				found=1;
+		                }
+			if(host_properties & HOST_ACTIVE_CHECK){
+				printf("%s Active Checks",(found==1)?" &amp;":"");
+				found=1;
+		                }
+	                }
+		printf("</td>");
+		printf("</tr>\n");
+
+
+		printf("<tr><td valign=top align=left CLASS='filterName'>Service Status Types:</td>");
+		printf("<td valign=top align=left CLASS='filterValue'>");
+		if(service_status_types==all_service_status_types)
+			printf("All");
+		else if(service_status_types==all_service_problems)
+			printf("All Problems");
+		else{
+			found=0;
+			if(service_status_types & SERVICE_PENDING){
+				printf(" Pending");
+				found=1;
+		                }
+			if(service_status_types & SERVICE_OK){
+				printf("%s Ok",(found==1)?" |":"");
+				found=1;
+		                }
+			if(service_status_types & SERVICE_UNKNOWN){
+				printf("%s Unknown",(found==1)?" |":"");
+				found=1;
+		                }
+			if(service_status_types & SERVICE_WARNING){
+				printf("%s Warning",(found==1)?" |":"");
+				found=1;
+		                }
+			if(service_status_types & SERVICE_CRITICAL){
+				printf("%s Critical",(found==1)?" |":"");
+				found=1;
+		                }
+	                }
+		printf("</td></tr>");
+		printf("<tr><td valign=top align=left CLASS='filterName'>Service Properties:</td>");
+		printf("<td valign=top align=left CLASS='filterValue'>");
+		if(service_properties==0)
+			printf("Any");
+		else{
+			found=0;
+			if(service_properties & SERVICE_SCHEDULED_DOWNTIME){
+				printf(" In Scheduled Downtime");
+				found=1;
+		                }
+			if(service_properties & SERVICE_NO_SCHEDULED_DOWNTIME){
+				printf("%s Not In Scheduled Downtime",(found==1)?" &amp;":"");
+				found=1;
+		                }
+			if(service_properties & SERVICE_STATE_ACKNOWLEDGED){
+				printf("%s Has Been Acknowledged",(found==1)?" &amp;":"");
+				found=1;
+		                }
+			if(service_properties & SERVICE_STATE_UNACKNOWLEDGED){
+				printf("%s Has Not Been Acknowledged",(found==1)?" &amp;":"");
+				found=1;
+		                }
+			if(service_properties & SERVICE_CHECKS_DISABLED){
+				printf("%s Active Checks Disabled",(found==1)?" &amp;":"");
+				found=1;
+		                }
+			if(service_properties & SERVICE_CHECKS_ENABLED){
+				printf("%s Active Checks Enabled",(found==1)?" &amp;":"");
+				found=1;
+		                }
+			if(service_properties & SERVICE_EVENT_HANDLER_DISABLED){
+				printf("%s Event Handler Disabled",(found==1)?" &amp;":"");
+				found=1;
+		                }
+			if(service_properties & SERVICE_EVENT_HANDLER_ENABLED){
+				printf("%s Event Handler Enabled",(found==1)?" &amp;":"");
+				found=1;
+		                }
+			if(service_properties & SERVICE_FLAP_DETECTION_DISABLED){
+				printf("%s Flap Detection Disabled",(found==1)?" &amp;":"");
+				found=1;
+		                }
+			if(service_properties & SERVICE_FLAP_DETECTION_ENABLED){
+				printf("%s Flap Detection Enabled",(found==1)?" &amp;":"");
+				found=1;
+		                }
+			if(service_properties & SERVICE_IS_FLAPPING){
+				printf("%s Is Flapping",(found==1)?" &amp;":"");
+				found=1;
+		                }
+			if(service_properties & SERVICE_IS_NOT_FLAPPING){
+				printf("%s Is Not Flapping",(found==1)?" &amp;":"");
+				found=1;
+		                }
+			if(service_properties & SERVICE_NOTIFICATIONS_DISABLED){
+				printf("%s Notifications Disabled",(found==1)?" &amp;":"");
+				found=1;
+		                }
+			if(service_properties & SERVICE_NOTIFICATIONS_ENABLED){
+				printf("%s Notifications Enabled",(found==1)?" &amp;":"");
+				found=1;
+		                }
+			if(service_properties & SERVICE_PASSIVE_CHECKS_DISABLED){
+				printf("%s Passive Checks Disabled",(found==1)?" &amp;":"");
+				found=1;
+		                }
+			if(service_properties & SERVICE_PASSIVE_CHECKS_ENABLED){
+				printf("%s Passive Checks Enabled",(found==1)?" &amp;":"");
+				found=1;
+		                }
+			if(service_properties & SERVICE_PASSIVE_CHECK){
+				printf("%s Passive Checks",(found==1)?" &amp;":"");
+				found=1;
+		                }
+			if(service_properties & SERVICE_ACTIVE_CHECK){
+				printf("%s Active Checks",(found==1)?" &amp;":"");
+				found=1;
+		                }
+	                }
+		printf("</td></tr>");
+		printf("</table>\n");
+
+		printf("</td></tr>");
+		printf("</table>\n");
+	        }
+
+	return;
+        }
diff -urNad nagios2-2.6~/cgi/statusmap.c nagios2-2.6/cgi/statusmap.c
--- nagios2-2.6~/cgi/statusmap.c	2006-03-21 21:31:46.000000000 +0000
+++ nagios2-2.6/cgi/statusmap.c	2008-05-26 16:01:40.000000000 +0000
@@ -696,7 +696,7 @@
 		printf("<table border=0 CLASS='optBox'>\n");
 		printf("<tr><td valign=top>\n");
 		printf("<form method=\"POST\" action=\"%s\">\n",STATUSMAP_CGI);
-		printf("<input type='hidden' name='host' value='%s'>\n",host_name);
+		printf("<input type='hidden' name='host' value='%s'>\n",url_encode(host_name));
 		printf("<input type='hidden' name='layout' value='%d'>\n",layout_method);
 
 		printf("</td><td valign=top>\n");
diff -urNad nagios2-2.6~/cgi/statusmap.c.orig nagios2-2.6/cgi/statusmap.c.orig
--- nagios2-2.6~/cgi/statusmap.c.orig	1970-01-01 00:00:00.000000000 +0000
+++ nagios2-2.6/cgi/statusmap.c.orig	2006-03-21 21:31:46.000000000 +0000
@@ -0,0 +1,2902 @@
+/*****************************************************************************
+ *
+ * STATUSMAP.C - Nagios Network Status Map CGI
+ *
+ * Copyright (c) 1999-2006 Ethan Galstad (nagios at nagios.org)
+ * Last Modified: 03-21-2006
+ *
+ * Description:
+ *
+ * This CGI will create a map of all hosts that are being monitored on your
+ * network.
+ *
+ * License:
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *****************************************************************************/
+
+#include "../include/config.h"
+#include "../include/common.h"
+#include "../include/objects.h"
+#include "../include/statusdata.h"
+
+#include "../include/cgiutils.h"
+#include "../include/getcgi.h"
+#include "../include/cgiauth.h"
+
+#include <gd.h>			/* Boutell's GD library function */
+#include <gdfonts.h>		/* GD library small font definition */
+
+extern int             refresh_rate;
+
+/*#define DEBUG*/
+
+#define UNKNOWN_GD2_ICON      "unknown.gd2"
+#define UNKNOWN_ICON_IMAGE    "unknown.gif"
+#define NAGIOS_GD2_ICON       "nagios.gd2"
+
+extern char main_config_file[MAX_FILENAME_LENGTH];
+extern char physical_images_path[MAX_FILENAME_LENGTH];
+extern char url_images_path[MAX_FILENAME_LENGTH];
+extern char url_logo_images_path[MAX_FILENAME_LENGTH];
+extern char url_stylesheets_path[MAX_FILENAME_LENGTH];
+
+extern host *host_list;
+extern hostgroup *hostgroup_list;
+extern service *service_list;
+extern hoststatus *hoststatus_list;
+extern servicestatus *servicestatus_list;
+
+extern char *statusmap_background_image;
+
+extern int default_statusmap_layout_method;
+
+#define DEFAULT_NODE_WIDTH		40
+#define DEFAULT_NODE_HEIGHT		65
+
+#define DEFAULT_NODE_VSPACING           15
+#define DEFAULT_NODE_HSPACING           45
+
+#define DEFAULT_PROXIMITY_WIDTH		1000
+#define DEFAULT_PROXIMITY_HEIGHT	800
+
+#define MINIMUM_PROXIMITY_WIDTH         250
+#define MINIMUM_PROXIMITY_HEIGHT        200
+
+#define COORDS_WARNING_WIDTH            650
+#define COORDS_WARNING_HEIGHT           60
+
+#define CIRCULAR_DRAWING_RADIUS         100
+
+#define CREATE_HTML	0
+#define CREATE_IMAGE	1
+
+#define LAYOUT_USER_SUPPLIED            0
+#define LAYOUT_SUBLAYERS                1
+#define LAYOUT_COLLAPSED_TREE           2
+#define LAYOUT_BALANCED_TREE            3
+#define LAYOUT_CIRCULAR                 4
+#define LAYOUT_CIRCULAR_MARKUP          5
+#define LAYOUT_CIRCULAR_BALLOON         6
+
+
+typedef struct layer_struct{
+	char *layer_name;
+	struct layer_struct *next;
+        }layer;
+
+
+void document_header(int);
+void document_footer(void);
+int process_cgivars(void);
+
+void display_page_header(void);
+void display_map(void);
+void calculate_host_coords(void);
+void calculate_total_image_bounds(void);
+void calculate_canvas_bounds(void);
+void calculate_canvas_bounds_from_host(char *);
+void calculate_scaling_factor(void);
+void find_eligible_hosts(void);
+void load_background_image(void);
+void draw_background_image(void);
+void draw_background_extras(void);
+void draw_host_links(void);
+void draw_hosts(void);
+void draw_host_text(char *,int,int);
+void draw_text(char *,int,int,int);
+void write_popup_code(void);
+void write_host_popup_text(host *);
+
+int initialize_graphics(void);
+gdImagePtr load_image_from_file(char *);
+void write_graphics(void);
+void cleanup_graphics(void);
+void draw_line(int,int,int,int,int);
+void draw_dotted_line(int,int,int,int,int);
+void draw_dashed_line(int,int,int,int,int);
+
+int is_host_in_layer_list(host *);
+int add_layer(char *);
+void free_layer_list(void);
+void print_layer_url(int);
+
+int number_of_host_layer_members(host *,int);
+int max_child_host_layer_members(host *);
+int host_child_depth_separation(host *, host *);
+int max_child_host_drawing_width(host *);
+int number_of_host_services(host *);
+
+void calculate_balanced_tree_coords(host *,int,int);
+void calculate_circular_coords(void);
+void calculate_circular_layer_coords(host *,double,double,int,int);
+
+void draw_circular_markup(void);
+void draw_circular_layer_markup(host *,double,double,int,int);
+
+
+char physical_logo_images_path[MAX_FILENAME_LENGTH];
+
+authdata current_authdata;
+
+int create_type=CREATE_HTML;
+
+gdImagePtr unknown_logo_image=NULL;
+gdImagePtr logo_image=NULL;
+gdImagePtr map_image=NULL;
+gdImagePtr background_image=NULL;
+int color_white=0;
+int color_black=0;
+int color_red=0;
+int color_lightred=0;
+int color_green=0;
+int color_lightgreen=0;
+int color_blue=0;
+int color_yellow=0;
+int color_orange=0;
+int color_grey=0;
+int color_lightgrey=0;
+
+int show_all_hosts=TRUE;
+char *host_name="all";
+
+int embedded=FALSE;
+int display_header=TRUE;
+int display_popups=TRUE;
+int use_links=TRUE;
+int use_text=TRUE;
+int use_highlights=TRUE;
+int user_supplied_canvas=FALSE;
+int user_supplied_scaling=FALSE;
+
+int layout_method=LAYOUT_USER_SUPPLIED;
+
+int proximity_width=DEFAULT_PROXIMITY_WIDTH;
+int proximity_height=DEFAULT_PROXIMITY_HEIGHT;
+
+int coordinates_were_specified=FALSE;   /* were any coordinates specified in extended host information entries? */
+
+int scaled_image_width=0;        /* size of the image actually displayed on the screen (after scaling) */
+int scaled_image_height=0;
+int canvas_width=0;              /* actual size of the image (or portion thereof) that we are drawing */
+int canvas_height=0;
+int total_image_width=0;         /* actual size of the image that would be created if we drew all hosts */
+int total_image_height=0;
+int max_image_width=0;           /* max image size the user wants (scaled) */
+int max_image_height=0;
+double scaling_factor=1.0;       /* scaling factor to use */
+double user_scaling_factor=1.0;  /* user-supplied scaling factor */
+int background_image_width=0;
+int background_image_height=0;
+
+int canvas_x=0;                     /* upper left coords of drawing canvas */
+int canvas_y=0;
+
+int bottom_margin=0;
+
+int draw_child_links=FALSE;
+int draw_parent_links=FALSE;
+
+int draw_nagios_icon=FALSE;    /* should we drawn the Nagios process icon? */
+int nagios_icon_x=0;           /* coords of Nagios icon */
+int nagios_icon_y=0;
+
+extern hostextinfo *hostextinfo_list;
+extern hoststatus *hoststatus_list;
+
+extern time_t program_start;
+
+layer *layer_list=NULL;
+int exclude_layers=TRUE;
+int all_layers=FALSE;
+
+
+
+
+
+int main(int argc, char **argv){
+	int result;
+
+	/* 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);
+		if(create_type==CREATE_HTML)
+			cgi_config_file_error(get_cgi_config_location());
+		document_footer();
+		return ERROR;
+	        }
+
+	/* defaults from CGI config file */
+	layout_method=default_statusmap_layout_method;
+
+	/* get the arguments passed in the URL */
+	process_cgivars();
+
+	/* read the main configuration file */
+	result=read_main_config_file(main_config_file);
+	if(result==ERROR){
+		document_header(FALSE);
+		if(create_type==CREATE_HTML)
+			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);
+		if(create_type==CREATE_HTML)
+			object_data_error();
+		document_footer();
+		return ERROR;
+                }
+
+	/* read all status data */
+	result=read_all_status_data(get_cgi_config_location(),READ_ALL_STATUS_DATA);
+	if(result==ERROR){
+		document_header(FALSE);
+		if(create_type==CREATE_HTML)
+			status_data_error();
+		document_footer();
+		free_memory();
+		return ERROR;
+                }
+
+
+	document_header(TRUE);
+
+	/* get authentication information */
+	get_authentication_information(&current_authdata);
+
+	/* display the network map... */
+	display_map();
+
+	document_footer();
+
+	/* free all allocated memory */
+	free_memory();
+	free_layer_list();
+
+	return OK;
+        }
+
+
+
+void document_header(int use_stylesheet){
+	char date_time[MAX_DATETIME_LENGTH];
+	time_t current_time;
+	time_t expire_time;
+
+	if(create_type==CREATE_HTML){
+		printf("Cache-Control: no-store\r\n");
+		printf("Pragma: no-cache\r\n");
+		printf("Refresh: %d\r\n",refresh_rate);
+
+		time(&current_time);
+		get_time_string(&current_time,date_time,sizeof(date_time),HTTP_DATE_TIME);
+		printf("Last-Modified: %s\r\n",date_time);
+
+		expire_time=0L;
+		get_time_string(&expire_time,date_time,sizeof(date_time),HTTP_DATE_TIME);
+		printf("Expires: %s\r\n",date_time);
+
+		printf("Content-Type: text/html\r\n\r\n");
+
+		if(embedded==TRUE)
+			return;
+
+		printf("<html>\n");
+		printf("<head>\n");
+		printf("<title>\n");
+		printf("Network Map\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,STATUSMAP_CSS);
+		        }
+
+		/* write JavaScript code for popup window */
+		write_popup_code();
+
+		printf("</head>\n");
+		
+		printf("<body CLASS='statusmap' name='mappage' id='mappage'>\n");
+
+		/* include user SSI header */
+		include_ssi_files(STATUSMAP_CGI,SSI_HEADER);
+
+		printf("<div id=\"popup\" style=\"position:absolute; z-index:1; visibility: hidden\"></div>\n");
+	        }
+
+	else{
+		printf("Cache-Control: no-store\r\n");
+		printf("Pragma: no-cache\r\n");
+
+		time(&current_time);
+		get_time_string(&current_time,date_time,sizeof(date_time),HTTP_DATE_TIME);
+		printf("Last-Modified: %s\r\n",date_time);
+
+		expire_time=(time_t)0L;
+		get_time_string(&expire_time,date_time,sizeof(date_time),HTTP_DATE_TIME);
+		printf("Expires: %s\r\n",date_time);
+
+		printf("Content-Type: image/png\r\n\r\n");
+	        }
+
+	return;
+        }
+
+
+void document_footer(void){
+
+	if(embedded==TRUE)
+		return;
+
+	if(create_type==CREATE_HTML){
+
+		/* include user SSI footer */
+		include_ssi_files(STATUSMAP_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="all";
+			else
+				strcpy(host_name,variables[x]);
+
+			if(!strcmp(host_name,"all"))
+				show_all_hosts=TRUE;
+			else
+				show_all_hosts=FALSE;
+		        }
+
+		/* we found the image creation option */
+		else if(!strcmp(variables[x],"createimage")){
+			create_type=CREATE_IMAGE;
+		        }
+
+		/* 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 canvas origin */
+		else if(!strcmp(variables[x],"canvas_x")){
+			x++;
+			if(variables[x]==NULL){
+				error=TRUE;
+				break;
+			        }
+			canvas_x=atoi(variables[x]);
+			user_supplied_canvas=TRUE;
+		        }
+		else if(!strcmp(variables[x],"canvas_y")){
+			x++;
+			if(variables[x]==NULL){
+				error=TRUE;
+				break;
+			        }
+			canvas_y=atoi(variables[x]);
+			user_supplied_canvas=TRUE;
+		        }
+
+		/* we found the canvas size */
+		else if(!strcmp(variables[x],"canvas_width")){
+			x++;
+			if(variables[x]==NULL){
+				error=TRUE;
+				break;
+			        }
+			canvas_width=atoi(variables[x]);
+			user_supplied_canvas=TRUE;
+		        }
+		else if(!strcmp(variables[x],"canvas_height")){
+			x++;
+			if(variables[x]==NULL){
+				error=TRUE;
+				break;
+			        }
+			canvas_height=atoi(variables[x]);
+			user_supplied_canvas=TRUE;
+		        }
+		else if(!strcmp(variables[x],"proximity_width")){
+			x++;
+			if(variables[x]==NULL){
+				error=TRUE;
+				break;
+			        }
+			proximity_width=atoi(variables[x]);
+			if(proximity_width<0)
+				proximity_width=DEFAULT_PROXIMITY_WIDTH;
+		        }
+		else if(!strcmp(variables[x],"proximity_height")){
+			x++;
+			if(variables[x]==NULL){
+				error=TRUE;
+				break;
+			        }
+			proximity_height=atoi(variables[x]);
+			if(proximity_height<0)
+				proximity_height=DEFAULT_PROXIMITY_HEIGHT;
+		        }
+
+		/* we found the scaling factor */
+		else if(!strcmp(variables[x],"scaling_factor")){
+			x++;
+			if(variables[x]==NULL){
+				error=TRUE;
+				break;
+			        }
+			user_scaling_factor=strtod(variables[x],NULL);
+			if(user_scaling_factor>0.0)
+				user_supplied_scaling=TRUE;
+		        }
+
+		/* we found the max image size */
+		else if(!strcmp(variables[x],"max_width")){
+			x++;
+			if(variables[x]==NULL){
+				error=TRUE;
+				break;
+			        }
+			max_image_width=atoi(variables[x]);
+		        }
+		else if(!strcmp(variables[x],"max_height")){
+			x++;
+			if(variables[x]==NULL){
+				error=TRUE;
+				break;
+			        }
+			max_image_height=atoi(variables[x]);
+		        }
+
+		/* we found the layout method option */
+		else if(!strcmp(variables[x],"layout")){
+			x++;
+			if(variables[x]==NULL){
+				error=TRUE;
+				break;
+			        }
+			layout_method=atoi(variables[x]);
+		        }
+
+		/* we found the no links argument*/
+		else if(!strcmp(variables[x],"nolinks"))
+			use_links=FALSE;
+
+		/* we found the no text argument*/
+		else if(!strcmp(variables[x],"notext"))
+			use_text=FALSE;
+
+		/* we found the no highlights argument*/
+		else if(!strcmp(variables[x],"nohighlights"))
+			use_highlights=FALSE;
+
+		/* we found the no popups argument*/
+		else if(!strcmp(variables[x],"nopopups"))
+			display_popups=FALSE;
+
+		/* we found the layer inclusion/exclusion argument */
+		else if(!strcmp(variables[x],"layermode")){
+			x++;
+			if(variables[x]==NULL){
+				error=TRUE;
+				break;
+			        }
+
+			if(!strcmp(variables[x],"include"))
+				exclude_layers=FALSE;
+			else
+				exclude_layers=TRUE;
+		        }
+
+		/* we found the layer argument */
+		else if(!strcmp(variables[x],"layer")){
+			x++;
+			if(variables[x]==NULL){
+				error=TRUE;
+				break;
+			        }
+
+			add_layer(variables[x]);
+		        }
+	        }
+
+	/* free memory allocated to the CGI variables */
+	free_cgivars(variables);
+
+	return error;
+        }
+
+
+
+/* top of page */
+void display_page_header(void){
+	char temp_buffer[MAX_INPUT_BUFFER];
+	int zoom;
+	int zoom_width, zoom_height;
+	int zoom_width_granularity=0;
+	int zoom_height_granularity=0;
+	int current_zoom_granularity=0;
+	hostgroup *temp_hostgroup;
+	layer *temp_layer;
+	int found=0;
+
+
+	if(create_type!=CREATE_HTML)
+		return;
+
+	if(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>\n");
+
+		if(show_all_hosts==TRUE)
+			snprintf(temp_buffer,sizeof(temp_buffer)-1,"Network Map For All Hosts");
+		else
+			snprintf(temp_buffer,sizeof(temp_buffer)-1,"Network Map For Host <I>%s</I>",host_name);
+		temp_buffer[sizeof(temp_buffer)-1]='\x0';
+		display_info_table(temp_buffer,TRUE,&current_authdata);
+
+		printf("<TABLE BORDER=1 CELLPADDING=0 CELLSPACING=0 CLASS='linkBox'>\n");
+		printf("<TR><TD CLASS='linkBox'>\n");
+
+		if(show_all_hosts==FALSE){
+			printf("<a href='%s?host=all&max_width=%d&max_height=%d'>View Status Map For All Hosts</a><BR>",STATUSMAP_CGI,max_image_width,max_image_height);
+			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=all'>View Status Detail For All Hosts</a><BR>\n",STATUS_CGI);
+		printf("<a href='%s?hostgroup=all'>View Status Overview For All Hosts</a>\n",STATUS_CGI);
+
+		printf("</TD></TR>\n");
+		printf("</TABLE>\n");
+
+		printf("</td>\n");
+
+
+
+		/* center column of top row */
+		printf("<td align=center valign=center>\n");
+
+		/* print image size and scaling info */
+#ifdef DEBUG
+		printf("<p><div align=center><font size=-1>\n");
+		printf("[ Raw Image Size: %d x %d pixels | Scaling Factor: %1.2lf | Scaled Image Size: %d x %d pixels ]",canvas_width,canvas_height,scaling_factor,(int)(canvas_width*scaling_factor),(int)(canvas_height*scaling_factor));
+		printf("</font></div></p>\n");
+
+		printf("<p><div align=center><font size=-1>\n");
+		printf("[ Canvas_x: %d | Canvas_y: %d | Canvas_width: %d | Canvas_height: %d ]",canvas_x,canvas_y,canvas_width,canvas_height);
+		printf("</font></div></p>\n");
+#endif
+
+		/* zoom links */
+		if(user_supplied_canvas==FALSE && strcmp(host_name,"all") && display_header==TRUE){
+			
+			printf("<p><div align=center>\n");
+
+			zoom_width_granularity=((total_image_width-MINIMUM_PROXIMITY_WIDTH)/11);
+			if(zoom_width_granularity==0)
+				zoom_width_granularity=1;
+			zoom_height_granularity=((total_image_height-MINIMUM_PROXIMITY_HEIGHT)/11);
+
+			if(proximity_width<=0)
+				current_zoom_granularity=0;
+			else
+				current_zoom_granularity=(total_image_width-proximity_width)/zoom_width_granularity;
+			if(current_zoom_granularity>10)
+				current_zoom_granularity=10;
+
+			printf("<table border=0 cellpadding=0 cellspacing=2>\n");
+			printf("<tr>\n");
+			printf("<td valign=center class='zoomTitle'>Zoom Out&nbsp;&nbsp;</td>\n");
+
+			for(zoom=0;zoom<=10;zoom++){
+
+				zoom_width=total_image_width-(zoom*zoom_width_granularity);
+				zoom_height=total_image_height-(zoom*zoom_height_granularity);
+
+				printf("<td valign=center><a href='%s?host=%s&layout=%d&max_width=%d&max_height=%d&proximity_width=%d&proximity_height=%d%s%s",STATUSMAP_CGI,url_encode(host_name),layout_method,max_image_width,max_image_height,zoom_width,zoom_height,(display_header==TRUE)?"":"&noheader",(display_popups==FALSE)?"&nopopups":"");
+				if(user_supplied_scaling==TRUE)
+					printf("&scaling_factor=%2.1f",user_scaling_factor);
+				print_layer_url(TRUE);
+				printf("'>");
+				printf("<img src='%s%s' border=0 alt='%d' title='%d'></a></td>\n",url_images_path,(current_zoom_granularity==zoom)?ZOOM2_ICON:ZOOM1_ICON,zoom,zoom);
+		                }
+
+			printf("<td valign=center class='zoomTitle'>&nbsp;&nbsp;Zoom In</td>\n");
+			printf("</tr>\n");
+			printf("</table>\n");
+
+			printf("</div></p>\n");
+	                }
+
+		printf("</td>\n");
+
+
+
+		/* right hand column of top row */
+		printf("<td align=right valign=top>\n");
+
+		printf("<table border=0 CLASS='optBox'>\n");
+		printf("<tr><td valign=top>\n");
+		printf("<form method=\"POST\" action=\"%s\">\n",STATUSMAP_CGI);
+		printf("<input type='hidden' name='host' value='%s'>\n",host_name);
+		printf("<input type='hidden' name='layout' value='%d'>\n",layout_method);
+
+		printf("</td><td valign=top>\n");
+
+		printf("<table border=0>\n");
+
+		printf("<tr><td CLASS='optBoxItem'>\n");
+		printf("Layout Method:<br>\n");
+		printf("<select name='layout'>\n");
+#ifndef DUMMY_INSTALL
+		printf("<option value=%d %s>User-supplied coords\n",LAYOUT_USER_SUPPLIED,(layout_method==LAYOUT_USER_SUPPLIED)?"selected":"");
+#endif
+		printf("<option value=%d %s>Depth layers\n",LAYOUT_SUBLAYERS,(layout_method==LAYOUT_SUBLAYERS)?"selected":"");
+		printf("<option value=%d %s>Collapsed tree\n",LAYOUT_COLLAPSED_TREE,(layout_method==LAYOUT_COLLAPSED_TREE)?"selected":"");
+		printf("<option value=%d %s>Balanced tree\n",LAYOUT_BALANCED_TREE,(layout_method==LAYOUT_BALANCED_TREE)?"selected":"");
+		printf("<option value=%d %s>Circular\n",LAYOUT_CIRCULAR,(layout_method==LAYOUT_CIRCULAR)?"selected":"");
+		printf("<option value=%d %s>Circular (Marked Up)\n",LAYOUT_CIRCULAR_MARKUP,(layout_method==LAYOUT_CIRCULAR_MARKUP)?"selected":"");
+		printf("<option value=%d %s>Circular (Balloon)\n",LAYOUT_CIRCULAR_BALLOON,(layout_method==LAYOUT_CIRCULAR_BALLOON)?"selected":"");
+		printf("</select>\n");
+		printf("</td>\n");
+		printf("<td CLASS='optBoxItem'>\n");
+		printf("Scaling factor:<br>\n");
+		printf("<input type='text' name='scaling_factor' maxlength='5' size='4' value='%2.1f'>\n",(user_supplied_scaling==TRUE)?user_scaling_factor:0.0);
+		printf("</td></tr>\n");
+
+		/*
+		printf("<tr><td CLASS='optBoxItem'>\n");
+		printf("Max image width:<br>\n");
+		printf("<input type='text' name='max_width' maxlength='5' size='4' value='%d'>\n",max_image_width);
+		printf("</td>\n");
+		printf("<td CLASS='optBoxItem'>\n");
+		printf("Max image height:<br>\n");
+		printf("<input type='text' name='max_height' maxlength='5' size='4' value='%d'>\n",max_image_height);
+		printf("</td></tr>\n");
+
+		printf("<tr><td CLASS='optBoxItem'>\n");
+		printf("Proximity width:<br>\n");
+		printf("<input type='text' name='proximity_width' maxlength='5' size='4' value='%d'>\n",proximity_width);
+		printf("</td>\n");
+		printf("<td CLASS='optBoxItem'>\n");
+		printf("Proximity height:<br>\n");
+		printf("<input type='text' name='proximity_height' maxlength='5' size='4' value='%d'>\n",proximity_height);
+		printf("</td></tr>\n");
+		*/
+
+		printf("<input type='hidden' name='max_width' value='%d'>\n",max_image_width);
+		printf("<input type='hidden' name='max_height' value='%d'>\n",max_image_height);
+		printf("<input type='hidden' name='proximity_width' value='%d'>\n",proximity_width);
+		printf("<input type='hidden' name='proximity_height' value='%d'>\n",proximity_height);
+
+		printf("<tr><td CLASS='optBoxItem'>Drawing Layers:<br>\n");
+		printf("<select multiple name='layer' size='4'>\n");
+		for(temp_hostgroup=hostgroup_list;temp_hostgroup!=NULL;temp_hostgroup=temp_hostgroup->next){
+			if(is_authorized_for_hostgroup(temp_hostgroup,&current_authdata)==FALSE)
+				continue;
+			found=0;
+			for(temp_layer=layer_list;temp_layer!=NULL;temp_layer=temp_layer->next){
+				if(!strcmp(temp_layer->layer_name,temp_hostgroup->group_name)){
+					found=1;
+					break;
+				        }
+			        }
+			printf("<option value='%s' %s>%s\n",temp_hostgroup->group_name,(found==1)?"SELECTED":"",temp_hostgroup->alias);
+		        }
+		printf("</select>\n");
+		printf("</td><td CLASS='optBoxItem' valign=top>Layer mode:<br>");
+		printf("<input type='radio' name='layermode' value='include' %s>Include<br>\n",(exclude_layers==FALSE)?"CHECKED":"");
+		printf("<input type='radio' name='layermode' value='exclude' %s>Exclude\n",(exclude_layers==TRUE)?"CHECKED":"");
+		printf("</td></tr>\n");
+
+		printf("<tr><td CLASS='optBoxItem'>\n");
+		printf("Suppress popups:<br>\n");
+		printf("<input type='checkbox' name='nopopups' %s>\n",(display_popups==FALSE)?"CHECKED":"");
+		printf("</td><td CLASS='optBoxItem'>\n");
+		printf("<input type='submit' value='Update'>\n");
+		printf("</td></tr>\n");
+
+		/* display context-sensitive help */
+		printf("<tr><td></td><td align=right valign=bottom>\n");
+		display_context_help(CONTEXTHELP_MAP);
+		printf("</td></tr>\n");
+
+		printf("</table>\n");
+
+		printf("</form>\n");
+		printf("</td></tr>\n");
+		printf("</table>\n");
+
+		printf("</td>\n");
+	
+		/* end of top table */
+		printf("</tr>\n");
+		printf("</table>\n");
+	        }
+
+
+	return;
+        }
+
+
+
+/* top-level map generation... */
+void display_map(void){
+
+	load_background_image();
+	calculate_host_coords();
+	calculate_total_image_bounds();
+	calculate_canvas_bounds();
+	calculate_scaling_factor();
+	find_eligible_hosts();
+
+	/* display page header */
+	display_page_header();
+
+	initialize_graphics();
+	draw_background_image();
+	draw_background_extras();
+	draw_host_links();
+
+	if(create_type==CREATE_HTML)
+		printf("<map name='statusmap'>\n");
+
+	draw_hosts();
+
+	if(create_type==CREATE_HTML)
+		printf("</map>\n");
+
+	write_graphics();
+	cleanup_graphics();
+
+
+	/* write the URL location for the image we just generated - the web browser will come and get it... */
+	if(create_type==CREATE_HTML){
+		printf("<P><DIV ALIGN=center>\n");
+		printf("<img src='%s?host=%s&createimage",STATUSMAP_CGI,url_encode(host_name));
+		printf("&canvas_x=%d&canvas_y=%d&canvas_width=%d&canvas_height=%d&max_width=%d&max_height=%d&layout=%d%s%s%s",canvas_x,canvas_y,canvas_width,canvas_height,max_image_width,max_image_height,layout_method,(use_links==FALSE)?"&nolinks":"",(use_text==FALSE)?"&notext":"",(use_highlights==FALSE)?"&nohighlights":"");
+		print_layer_url(TRUE);
+		printf("' width=%d height=%d border=0 name='statusimage' useMap='#statusmap'>\n",(int)(canvas_width*scaling_factor),(int)(canvas_height*scaling_factor));
+		printf("</DIV></P>\n");
+	        }
+	
+	return;
+        }
+
+
+
+/******************************************************************/
+/********************* CALCULATION FUNCTIONS **********************/
+/******************************************************************/
+
+/* calculates host drawing coordinates */
+void calculate_host_coords(void){
+	hostextinfo *temp_hostextinfo;
+	host *this_host;
+	host *temp_host;
+	int child_hosts=0;
+	int parent_hosts=0;
+	int max_layer_width=1;
+	int current_child_host=0;
+	int current_parent_host=0;
+	int center_x=0;
+	int offset_x=DEFAULT_NODE_WIDTH/2;
+	int offset_y=DEFAULT_NODE_WIDTH/2;
+	int current_layer=0;
+	int layer_members=0;
+	int current_layer_member=0;
+	int max_drawing_width=0;
+  
+
+	/******************************/
+	/***** MANUAL LAYOUT MODE *****/
+	/******************************/
+
+	/* user-supplied coords */
+	if(layout_method==LAYOUT_USER_SUPPLIED){
+
+		/* see which hosts we should draw and calculate drawing coords */
+		for(temp_hostextinfo=hostextinfo_list;temp_hostextinfo!=NULL;temp_hostextinfo=temp_hostextinfo->next){
+			
+			if(temp_hostextinfo->have_2d_coords==TRUE)
+				temp_hostextinfo->should_be_drawn=TRUE;
+			else
+				temp_hostextinfo->should_be_drawn=FALSE;
+		        }
+
+		return;
+	        }
+
+
+	/*****************************/
+	/***** AUTO-LAYOUT MODES *****/
+	/*****************************/
+
+	/* add empty extended host info entries for all hosts that don't have any */
+	for(temp_host=host_list;temp_host!=NULL;temp_host=temp_host->next){
+
+		/* find the corresponding hostextinfo definition */
+		temp_hostextinfo=find_hostextinfo(temp_host->name);
+
+		/* none was found, so add a blank one */
+		if(temp_hostextinfo==NULL)
+			add_hostextinfo(temp_host->name,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,0,0.0,0.0,0.0,0,0);
+	        }
+
+
+	/***** DEPTH LAYER MODE *****/
+	if(layout_method==LAYOUT_SUBLAYERS){
+
+		/* find the "main" host we're displaying */
+		if(show_all_hosts==TRUE)
+			this_host=NULL;
+		else
+			this_host=find_host(host_name);
+
+		/* find total number of immediate parents/children for this host */
+		child_hosts=number_of_immediate_child_hosts(this_host);
+		parent_hosts=number_of_immediate_parent_hosts(this_host);
+
+		if(child_hosts==0 && parent_hosts==0)
+			max_layer_width=1;
+		else
+			max_layer_width=(child_hosts>parent_hosts)?child_hosts:parent_hosts;
+
+		/* calculate center x coord */
+		center_x=(((DEFAULT_NODE_WIDTH*max_layer_width)+(DEFAULT_NODE_HSPACING*(max_layer_width-1)))/2)+offset_x;
+
+		/* coords for Nagios icon if necessary */
+		if(this_host==NULL || this_host->parent_hosts==NULL){
+			nagios_icon_x=center_x;
+			nagios_icon_y=offset_y;
+			draw_nagios_icon=TRUE;
+		        }
+
+		/* do we need to draw a link to parent(s)? */
+		if(this_host!=NULL && is_host_immediate_child_of_host(NULL,this_host)==FALSE){
+			draw_parent_links=TRUE;
+			offset_y+=DEFAULT_NODE_HEIGHT+DEFAULT_NODE_VSPACING;
+		        }
+
+		/* see which hosts we should draw and calculate drawing coords */
+		for(temp_hostextinfo=hostextinfo_list;temp_hostextinfo!=NULL;temp_hostextinfo=temp_hostextinfo->next){
+
+			/* find the host that matches this entry */
+			temp_host=find_host(temp_hostextinfo->host_name);
+
+			if(temp_host==NULL)
+				continue;
+			
+			/* this is an immediate parent of the "main" host we're drawing */
+			else if(is_host_immediate_parent_of_host(this_host,temp_host)==TRUE){
+				temp_hostextinfo->should_be_drawn=TRUE;
+				temp_hostextinfo->have_2d_coords=TRUE;
+				temp_hostextinfo->x_2d=center_x-(((parent_hosts*DEFAULT_NODE_WIDTH)+((parent_hosts-1)*DEFAULT_NODE_HSPACING))/2)+(current_parent_host*(DEFAULT_NODE_WIDTH+DEFAULT_NODE_HSPACING))+(DEFAULT_NODE_WIDTH/2);
+				temp_hostextinfo->y_2d=offset_y;
+				current_parent_host++;
+			        }
+			
+			/* this is the "main" host we're drawing */
+			else if(this_host==temp_host){
+				temp_hostextinfo->should_be_drawn=TRUE;
+				temp_hostextinfo->have_2d_coords=TRUE;
+				temp_hostextinfo->x_2d=center_x;
+				temp_hostextinfo->y_2d=DEFAULT_NODE_HEIGHT+DEFAULT_NODE_VSPACING+offset_y;
+			        }
+
+			/* this is an immediate child of the "main" host we're drawing */
+			else if(is_host_immediate_child_of_host(this_host,temp_host)==TRUE){
+				temp_hostextinfo->should_be_drawn=TRUE;
+				temp_hostextinfo->have_2d_coords=TRUE;
+				temp_hostextinfo->x_2d=center_x-(((child_hosts*DEFAULT_NODE_WIDTH)+((child_hosts-1)*DEFAULT_NODE_HSPACING))/2)+(current_child_host*(DEFAULT_NODE_WIDTH+DEFAULT_NODE_HSPACING))+(DEFAULT_NODE_WIDTH/2);
+				if(this_host==NULL)
+					temp_hostextinfo->y_2d=(DEFAULT_NODE_HEIGHT+DEFAULT_NODE_VSPACING)+offset_y;
+				else
+					temp_hostextinfo->y_2d=((DEFAULT_NODE_HEIGHT+DEFAULT_NODE_VSPACING)*2)+offset_y;
+				current_child_host++;
+				if(number_of_immediate_child_hosts(temp_host)>0){
+					bottom_margin=DEFAULT_NODE_HEIGHT+DEFAULT_NODE_VSPACING;
+					draw_child_links=TRUE;
+				        }
+			        }
+
+			/* else do not draw this host */
+			else{
+				temp_hostextinfo->should_be_drawn=FALSE;
+				temp_hostextinfo->have_2d_coords=FALSE;
+			        }
+		        }
+	        }
+
+
+
+	/***** COLLAPSED TREE MODE *****/
+	else if(layout_method==LAYOUT_COLLAPSED_TREE){
+
+		/* find the "main" host we're displaying  - DO NOT USE THIS (THIS IS THE OLD METHOD) */
+		/*
+		if(show_all_hosts==TRUE)
+			this_host=NULL;
+		else
+			this_host=find_host(host_name);
+		*/
+
+		/* always use NULL as the "main" host, screen coords/dimensions are adjusted automatically */
+		this_host=NULL;
+
+		/* find total number of immediate parents for this host */
+		parent_hosts=number_of_immediate_parent_hosts(this_host);
+
+		/* find the max layer width we have... */
+		max_layer_width=max_child_host_layer_members(this_host);
+		if(parent_hosts>max_layer_width)
+			max_layer_width=parent_hosts;
+
+		/* calculate center x coord */
+		center_x=(((DEFAULT_NODE_WIDTH*max_layer_width)+(DEFAULT_NODE_HSPACING*(max_layer_width-1)))/2)+offset_x;
+
+		/* coords for Nagios icon if necessary */
+		if(this_host==NULL || this_host->parent_hosts==NULL){
+			nagios_icon_x=center_x;
+			nagios_icon_y=offset_y;
+			draw_nagios_icon=TRUE;
+		        }
+
+		/* do we need to draw a link to parent(s)? */
+		if(this_host!=NULL && is_host_immediate_child_of_host(NULL,this_host)==FALSE){
+			draw_parent_links=TRUE;
+			offset_y+=DEFAULT_NODE_HEIGHT+DEFAULT_NODE_VSPACING;
+		        }
+
+		/* see which hosts we should draw and calculate drawing coords */
+		for(temp_hostextinfo=hostextinfo_list;temp_hostextinfo!=NULL;temp_hostextinfo=temp_hostextinfo->next){
+
+			/* find the host that matches this entry */
+			temp_host=find_host(temp_hostextinfo->host_name);
+
+			if(temp_host==NULL)
+				continue;
+			
+			/* this is an immediate parent of the "main" host we're drawing */
+			else if(is_host_immediate_parent_of_host(this_host,temp_host)==TRUE){
+				temp_hostextinfo->should_be_drawn=TRUE;
+				temp_hostextinfo->have_2d_coords=TRUE;
+				temp_hostextinfo->x_2d=center_x-(((parent_hosts*DEFAULT_NODE_WIDTH)+((parent_hosts-1)*DEFAULT_NODE_HSPACING))/2)+(current_parent_host*(DEFAULT_NODE_WIDTH+DEFAULT_NODE_HSPACING))+(DEFAULT_NODE_WIDTH/2);
+				temp_hostextinfo->y_2d=offset_y;
+				current_parent_host++;
+			        }
+			
+			/* this is the "main" host we're drawing */
+			else if(this_host==temp_host){
+				temp_hostextinfo->should_be_drawn=TRUE;
+				temp_hostextinfo->have_2d_coords=TRUE;
+				temp_hostextinfo->x_2d=center_x;
+				temp_hostextinfo->y_2d=DEFAULT_NODE_HEIGHT+DEFAULT_NODE_VSPACING+offset_y;
+			        }
+
+			/* else do not draw this host (we might if its a child - see below, but assume no for now) */
+			else{
+				temp_hostextinfo->should_be_drawn=FALSE;
+				temp_hostextinfo->have_2d_coords=FALSE;
+			        }
+		        }
+
+
+		/* TODO: REORDER CHILD LAYER MEMBERS SO THAT WE MINIMIZE LINK CROSSOVERS FROM PARENT HOSTS */
+
+		/* draw hosts in child "layers" */
+		for(current_layer=1;;current_layer++){
+			
+			/* how many members in this layer? */
+			layer_members=number_of_host_layer_members(this_host,current_layer);
+
+			if(layer_members==0)
+				break;
+
+			current_layer_member=0;
+
+			/* see which hosts are members of this layer and calculate drawing coords */
+			for(temp_hostextinfo=hostextinfo_list;temp_hostextinfo!=NULL;temp_hostextinfo=temp_hostextinfo->next){
+
+				/* find the host that matches this entry */
+				temp_host=find_host(temp_hostextinfo->host_name);
+
+				if(temp_host==NULL)
+					continue;
+
+				/* is this host a member of the current child layer? */
+				if(host_child_depth_separation(this_host,temp_host)==current_layer){
+					temp_hostextinfo->should_be_drawn=TRUE;
+					temp_hostextinfo->have_2d_coords=TRUE;
+					temp_hostextinfo->x_2d=center_x-(((layer_members*DEFAULT_NODE_WIDTH)+((layer_members-1)*DEFAULT_NODE_HSPACING))/2)+(current_layer_member*(DEFAULT_NODE_WIDTH+DEFAULT_NODE_HSPACING))+(DEFAULT_NODE_WIDTH/2);
+					if(this_host==NULL)
+						temp_hostextinfo->y_2d=((DEFAULT_NODE_HEIGHT+DEFAULT_NODE_VSPACING)*current_layer)+offset_y;
+					else
+						temp_hostextinfo->y_2d=((DEFAULT_NODE_HEIGHT+DEFAULT_NODE_VSPACING)*(current_layer+1))+offset_y;
+					current_layer_member++;
+				        }
+			        }
+		        }
+
+	        }
+
+
+	/***** "BALANCED" TREE MODE *****/
+	else if(layout_method==LAYOUT_BALANCED_TREE){
+
+		/* find the "main" host we're displaying  - DO NOT USE THIS (THIS IS THE OLD METHOD) */
+		/*
+		if(show_all_hosts==TRUE)
+			this_host=NULL;
+		else
+			this_host=find_host(host_name);
+		*/
+		
+		/* always use NULL as the "main" host, screen coords/dimensions are adjusted automatically */
+		this_host=NULL;
+
+		/* find total number of immediate parents for this host */
+		parent_hosts=number_of_immediate_parent_hosts(this_host);
+
+		/* find the max drawing width we have... */
+		max_drawing_width=max_child_host_drawing_width(this_host);
+		if(parent_hosts>max_drawing_width)
+			max_drawing_width=parent_hosts;
+
+		/* calculate center x coord */
+		center_x=(((DEFAULT_NODE_WIDTH*max_drawing_width)+(DEFAULT_NODE_HSPACING*(max_drawing_width-1)))/2)+offset_x;
+
+		/* coords for Nagios icon if necessary */
+		if(this_host==NULL || this_host->parent_hosts==NULL){
+			nagios_icon_x=center_x;
+			nagios_icon_y=offset_y;
+			draw_nagios_icon=TRUE;
+		        }
+
+		/* do we need to draw a link to parent(s)? */
+		if(this_host!=NULL && is_host_immediate_child_of_host(NULL,this_host)==FALSE){
+			draw_parent_links=TRUE;
+			offset_y+=DEFAULT_NODE_HEIGHT+DEFAULT_NODE_VSPACING;
+		        }
+
+		/* see which hosts we should draw and calculate drawing coords */
+		for(temp_hostextinfo=hostextinfo_list;temp_hostextinfo!=NULL;temp_hostextinfo=temp_hostextinfo->next){
+
+			/* find the host that matches this entry */
+			temp_host=find_host(temp_hostextinfo->host_name);
+
+			if(temp_host==NULL)
+				continue;
+			
+			/* this is an immediate parent of the "main" host we're drawing */
+			else if(is_host_immediate_parent_of_host(this_host,temp_host)==TRUE){
+				temp_hostextinfo->should_be_drawn=TRUE;
+				temp_hostextinfo->have_2d_coords=TRUE;
+				temp_hostextinfo->x_2d=center_x-(((parent_hosts*DEFAULT_NODE_WIDTH)+((parent_hosts-1)*DEFAULT_NODE_HSPACING))/2)+(current_parent_host*(DEFAULT_NODE_WIDTH+DEFAULT_NODE_HSPACING))+(DEFAULT_NODE_WIDTH/2);
+				temp_hostextinfo->y_2d=offset_y;
+				current_parent_host++;
+			        }
+			
+			/* this is the "main" host we're drawing */
+			else if(this_host==temp_host){
+				temp_hostextinfo->should_be_drawn=TRUE;
+				temp_hostextinfo->have_2d_coords=TRUE;
+				temp_hostextinfo->x_2d=center_x;
+				temp_hostextinfo->y_2d=DEFAULT_NODE_HEIGHT+DEFAULT_NODE_VSPACING+offset_y;
+			        }
+
+			/* else do not draw this host (we might if its a child - see below, but assume no for now) */
+			else{
+				temp_hostextinfo->should_be_drawn=FALSE;
+				temp_hostextinfo->have_2d_coords=FALSE;
+			        }
+		        }
+
+		/* draw all children hosts */
+		calculate_balanced_tree_coords(this_host,center_x,DEFAULT_NODE_HEIGHT+DEFAULT_NODE_VSPACING+offset_y);
+
+	        }
+
+
+	/***** CIRCULAR LAYOUT MODE *****/
+	else if(layout_method==LAYOUT_CIRCULAR || layout_method==LAYOUT_CIRCULAR_MARKUP || layout_method==LAYOUT_CIRCULAR_BALLOON){
+
+		/* draw process icon */
+		nagios_icon_x=0;
+		nagios_icon_y=0;
+		draw_nagios_icon=TRUE;
+
+		/* calculate coordinates for all hosts */
+		calculate_circular_coords();
+	        }
+
+	return;
+        }
+
+
+
+/* calculates max possible image dimensions */
+void calculate_total_image_bounds(void){
+	hostextinfo *temp_hostextinfo;
+
+	total_image_width=0;
+	total_image_height=0;
+
+	/* check all extended host information entries... */
+	for(temp_hostextinfo=hostextinfo_list;temp_hostextinfo!=NULL;temp_hostextinfo=temp_hostextinfo->next){
+
+		/* only check entries that have 2-D coords specified */
+		if(temp_hostextinfo->have_2d_coords==FALSE)
+			continue;
+
+		/* skip hosts we shouldn't be drawing */
+		if(temp_hostextinfo->should_be_drawn==FALSE)
+			continue;
+		
+		if(temp_hostextinfo->x_2d>total_image_width)
+			total_image_width=temp_hostextinfo->x_2d;
+		if(temp_hostextinfo->y_2d>total_image_height)
+			total_image_height=temp_hostextinfo->y_2d;
+
+		coordinates_were_specified=TRUE;
+	        }
+
+	/* add some space for icon size and overlapping text... */
+	if(coordinates_were_specified==TRUE){
+
+		total_image_width+=(DEFAULT_NODE_WIDTH*2);
+		total_image_height+=DEFAULT_NODE_HEIGHT;
+
+		/* add space for bottom margin if necessary */
+		total_image_height+=bottom_margin;
+	        }
+
+	/* image size should be at least as large as dimensions of background image */
+	if(total_image_width<background_image_width)
+		total_image_width=background_image_width;
+	if(total_image_height<background_image_height)
+		total_image_height=background_image_height;
+
+	/* we didn't find any hosts that had user-supplied coordinates, so we're going to display a warning */
+	if(coordinates_were_specified==FALSE){
+		coordinates_were_specified=FALSE;
+		total_image_width=COORDS_WARNING_WIDTH;
+		total_image_height=COORDS_WARNING_HEIGHT;
+	        }
+
+	return;
+        }
+
+
+/* calculates canvas coordinates/dimensions */
+void calculate_canvas_bounds(void){
+
+	if(user_supplied_canvas==FALSE && strcmp(host_name,"all"))
+		calculate_canvas_bounds_from_host(host_name);
+
+	/* calculate canvas origin (based on total image bounds) */
+	if(canvas_x<=0 || canvas_width>total_image_width)
+		canvas_x=0;
+	if(canvas_y<=0 || canvas_height>total_image_height)
+		canvas_y=0;
+
+	/* calculate canvas dimensions */
+	if(canvas_height<=0)
+		canvas_height=(total_image_height-canvas_y);
+	if(canvas_width<=0)
+		canvas_width=(total_image_width-canvas_x);
+
+	if(canvas_x+canvas_width>total_image_width)
+		canvas_width=total_image_width-canvas_x;
+	if(canvas_y+canvas_height>total_image_height)
+		canvas_height=total_image_height-canvas_y;
+
+	return;
+        }
+
+
+/* calculates canvas coordinates/dimensions around a particular host */
+void calculate_canvas_bounds_from_host(char *host_name){
+	hostextinfo *temp_hostextinfo;
+	int zoom_width;
+	int zoom_height;
+
+	/* find the extended host info */
+	temp_hostextinfo=find_hostextinfo(host_name);
+	if(temp_hostextinfo==NULL)
+		return;
+
+	/* make sure we have 2-D coords */
+	if(temp_hostextinfo->have_2d_coords==FALSE)
+		return;
+	
+	if(max_image_width>0 && proximity_width>max_image_width)
+		zoom_width=max_image_width;
+	else
+		zoom_width=proximity_width;
+	if(max_image_height>0 && proximity_height>max_image_height)
+		zoom_height=max_image_height;
+	else
+		zoom_height=proximity_height;
+
+	canvas_width=zoom_width;
+	if(canvas_width>=total_image_width)
+		canvas_x=0;
+	else
+		canvas_x=(temp_hostextinfo->x_2d-(zoom_width/2));
+
+	canvas_height=zoom_height;
+	if(canvas_height>=total_image_height)
+		canvas_y=0;
+	else
+		canvas_y=(temp_hostextinfo->y_2d-(zoom_height/2));
+
+
+	return;
+        }
+
+
+/* calculates scaling factor used in image generation */
+void calculate_scaling_factor(void){
+	double x_scaling=1.0;
+	double y_scaling=1.0;
+
+	/* calculate horizontal scaling factor */
+	if(max_image_width<=0 || canvas_width<=max_image_width)
+		x_scaling=1.0;
+	else
+		x_scaling=(double)((double)max_image_width/(double)canvas_width);
+
+	/* calculate vertical scaling factor */
+	if(max_image_height<=0 || canvas_height<=max_image_height)
+		y_scaling=1.0;
+	else
+		y_scaling=(double)((double)max_image_height/(double)canvas_height);
+
+	/* calculate general scaling factor to use */
+	if(x_scaling<y_scaling)
+		scaling_factor=x_scaling;
+	else
+		scaling_factor=y_scaling;
+
+	/*** USER-SUPPLIED SCALING FACTOR ***/
+	if(user_supplied_scaling==TRUE)
+		scaling_factor=user_scaling_factor;
+
+	return;
+        }
+
+
+/* finds hosts that can be drawn in the canvas area */
+void find_eligible_hosts(void){
+	hostextinfo *temp_hostextinfo;
+	int total_eligible_hosts=0;
+	host *temp_host;
+
+	/* check all extended host information entries... */
+	for(temp_hostextinfo=hostextinfo_list;temp_hostextinfo!=NULL;temp_hostextinfo=temp_hostextinfo->next){
+
+		/* find the host */
+		temp_host=find_host(temp_hostextinfo->host_name);
+
+		if(temp_host==NULL)
+			temp_hostextinfo->should_be_drawn=FALSE;
+
+		/* only include hosts that have 2-D coords supplied */
+		else if(temp_hostextinfo->have_2d_coords==FALSE)
+			temp_hostextinfo->should_be_drawn=FALSE;
+
+		/* make sure coords are all positive */
+		else if(temp_hostextinfo->x_2d<0 || temp_hostextinfo->y_2d<0)
+			temp_hostextinfo->should_be_drawn=FALSE;
+
+		/* make sure x coordinates fall within canvas bounds */
+		else if(temp_hostextinfo->x_2d<(canvas_x-DEFAULT_NODE_WIDTH) || temp_hostextinfo->x_2d>(canvas_x+canvas_width))
+			temp_hostextinfo->should_be_drawn=FALSE;
+
+		/* make sure y coordinates fall within canvas bounds */
+		else if(temp_hostextinfo->y_2d<(canvas_y-DEFAULT_NODE_HEIGHT) || temp_hostextinfo->y_2d>(canvas_y+canvas_height))
+			temp_hostextinfo->should_be_drawn=FALSE;
+
+		/* see if the user is authorized to view the host */
+		else if(is_authorized_for_host(temp_host,&current_authdata)==FALSE)
+			temp_hostextinfo->should_be_drawn=FALSE;
+
+		/* all checks passed, so we can draw the host! */
+		else{
+			temp_hostextinfo->should_be_drawn=TRUE;
+			total_eligible_hosts++;
+		        }
+	        }
+
+	return;
+        }
+
+
+
+/******************************************************************/
+/*********************** DRAWING FUNCTIONS ************************/
+/******************************************************************/
+
+
+/* loads background image from file */
+void load_background_image(void){
+	char temp_buffer[MAX_INPUT_BUFFER];
+
+	/* bail out if we shouldn't be drawing a background image */
+	if(layout_method!=LAYOUT_USER_SUPPLIED || statusmap_background_image==NULL)
+		return;
+
+	snprintf(temp_buffer,sizeof(temp_buffer)-1,"%s%s",physical_images_path,statusmap_background_image);
+	temp_buffer[sizeof(temp_buffer)-1]='\x0';
+
+	/* read the background image into memory */
+	background_image=load_image_from_file(temp_buffer);
+
+	/* grab background image dimensions for calculating total image width later */
+	if(background_image!=NULL){
+		background_image_width=background_image->sx;
+		background_image_height=background_image->sy;
+	        }
+
+	/* if we are just creating the html, we don't need the image anymore */
+	if(create_type==CREATE_HTML && background_image!=NULL)
+		gdImageDestroy(background_image);
+
+	return;
+	}
+
+
+/* draws background image on drawing canvas */
+void draw_background_image(void){
+
+	/* bail out if we shouldn't be drawing a background image */
+	if(create_type==CREATE_HTML || layout_method!=LAYOUT_USER_SUPPLIED || statusmap_background_image==NULL)
+		return;
+
+	/* bail out if we don't have an image */
+	if(background_image==NULL)
+		return;
+
+	/* copy the background image to the canvas */
+	gdImageCopy(map_image,background_image,0,0,canvas_x,canvas_y,canvas_width,canvas_height);
+
+	/* free memory for background image, as we don't need it anymore */
+	gdImageDestroy(background_image);
+
+	return;
+        }
+
+
+
+/* draws background "extras" */
+void draw_background_extras(void){
+
+	/* bail out if we shouldn't be here */
+	if(create_type==CREATE_HTML)
+		return;
+
+	/* circular layout stuff... */
+	if(layout_method==LAYOUT_CIRCULAR_MARKUP){
+
+		/* draw colored sections... */
+		draw_circular_markup();
+	        }
+
+	return;
+        }
+
+
+/* draws host links */
+void draw_host_links(void){
+	hostextinfo *temp_hostextinfo;
+	hostextinfo *temp_parent_hostextinfo;
+	host *this_host;
+	host *main_host;
+	host *parent_host;
+	hostsmember *temp_hostsmember;
+	int status_color=color_black;
+	hoststatus *this_hoststatus;
+	hoststatus *parent_hoststatus;
+	int child_in_layer_list=FALSE;
+	int parent_in_layer_list=FALSE;
+	int dotted_line=FALSE;
+	int x=0;
+	int y=0;
+
+	if(create_type==CREATE_HTML)
+		return;
+
+	if(use_links==FALSE)
+		return;
+
+	/* find the "main" host we're drawing */
+	main_host=find_host(host_name);
+	if(show_all_hosts==TRUE)
+		main_host=NULL;
+
+	/* check all extended host information entries... */
+	for(temp_hostextinfo=hostextinfo_list;temp_hostextinfo!=NULL;temp_hostextinfo=temp_hostextinfo->next){
+
+		/* find the config entry for this host */
+		this_host=find_host(temp_hostextinfo->host_name);
+		if(this_host==NULL)
+			continue;
+
+		/* only draw link if user is authorized to view this host */
+		if(is_authorized_for_host(this_host,&current_authdata)==FALSE)
+			continue;
+
+		/* this is a "root" host, so draw link to Nagios process icon if using auto-layout mode */
+		if(this_host->parent_hosts==NULL && layout_method!=LAYOUT_USER_SUPPLIED && draw_nagios_icon==TRUE){
+
+			x=temp_hostextinfo->x_2d+(DEFAULT_NODE_WIDTH/2)-canvas_x;
+			y=temp_hostextinfo->y_2d+(DEFAULT_NODE_WIDTH/2)-canvas_y;
+
+			draw_line(x,y,nagios_icon_x+(DEFAULT_NODE_WIDTH/2)-canvas_x,nagios_icon_y+(DEFAULT_NODE_WIDTH/2)-canvas_y,color_black);
+		        }
+
+		/* this is a child of the main host we're drawing in auto-layout mode... */
+		if(layout_method!=LAYOUT_USER_SUPPLIED && draw_child_links==TRUE && number_of_immediate_child_hosts(this_host)>0 && is_host_immediate_child_of_host(main_host,this_host)==TRUE){
+			/* determine color to use when drawing links to children  */
+			this_hoststatus=find_hoststatus(temp_hostextinfo->host_name);
+			if(this_hoststatus!=NULL){
+				if(this_hoststatus->status==HOST_DOWN || this_hoststatus->status==HOST_UNREACHABLE)
+					status_color=color_red;
+				else
+					status_color=color_black;
+		                }
+			else
+				status_color=color_black;
+
+			x=temp_hostextinfo->x_2d+(DEFAULT_NODE_WIDTH/2)-canvas_x;
+			y=(temp_hostextinfo->y_2d+(DEFAULT_NODE_WIDTH)/2)-canvas_y;
+
+			draw_dashed_line(x,y,x,y+DEFAULT_NODE_HEIGHT+DEFAULT_NODE_VSPACING,status_color);
+
+			/* draw arrow tips */
+			draw_line(x,y+DEFAULT_NODE_HEIGHT+DEFAULT_NODE_VSPACING,x-5,y+DEFAULT_NODE_HEIGHT+DEFAULT_NODE_VSPACING-5,color_black);
+			draw_line(x,y+DEFAULT_NODE_HEIGHT+DEFAULT_NODE_VSPACING,x+5,y+DEFAULT_NODE_HEIGHT+DEFAULT_NODE_VSPACING-5,color_black);
+		        }
+
+		/* this is a parent of the main host we're drawing in auto-layout mode... */
+		if(layout_method!=LAYOUT_USER_SUPPLIED && draw_parent_links==TRUE && is_host_immediate_child_of_host(this_host,main_host)==TRUE){
+
+			x=temp_hostextinfo->x_2d+(DEFAULT_NODE_WIDTH/2)-canvas_x;
+			y=temp_hostextinfo->y_2d+(DEFAULT_NODE_WIDTH/2)-canvas_y;
+
+			draw_dashed_line(x,y,x,y-DEFAULT_NODE_HEIGHT-DEFAULT_NODE_VSPACING,color_black);
+
+			/* draw arrow tips */
+			draw_line(x,y-DEFAULT_NODE_HEIGHT-DEFAULT_NODE_VSPACING,x-5,y-DEFAULT_NODE_HEIGHT-DEFAULT_NODE_VSPACING+5,color_black);
+			draw_line(x,y-DEFAULT_NODE_HEIGHT-DEFAULT_NODE_VSPACING,x+5,y-DEFAULT_NODE_HEIGHT-DEFAULT_NODE_VSPACING+5,color_black);
+		        }
+
+		/* draw links to all parent hosts */
+		for(temp_hostsmember=this_host->parent_hosts;temp_hostsmember!=NULL;temp_hostsmember=temp_hostsmember->next){
+
+			/* find extended info entry for this parent host */
+			temp_parent_hostextinfo=find_hostextinfo(temp_hostsmember->host_name);
+			if(temp_parent_hostextinfo==NULL)
+				continue;
+
+			/* don't draw the link if we don't have the coords */
+			if(temp_parent_hostextinfo->have_2d_coords==FALSE || temp_hostextinfo->have_2d_coords==FALSE)
+				continue;
+
+			/* find the parent host config entry */
+			parent_host=find_host(temp_parent_hostextinfo->host_name);
+			if(parent_host==NULL)
+				continue;
+
+			/* only draw link if user is authorized for this parent host */
+			if(is_authorized_for_host(parent_host,&current_authdata)==FALSE)
+				continue;
+
+			/* are the hosts in the layer list? */
+			child_in_layer_list=is_host_in_layer_list(this_host);
+			parent_in_layer_list=is_host_in_layer_list(parent_host);
+
+			/* use dotted or solid line? */
+			/* either the child or parent should not be drawn, so use a dotted line */
+			if((child_in_layer_list==TRUE && parent_in_layer_list==FALSE) || (child_in_layer_list==FALSE && parent_in_layer_list==TRUE))
+				dotted_line=TRUE;
+			/* both hosts should not be drawn, so use a dotted line */
+			else if((child_in_layer_list==FALSE && parent_in_layer_list==FALSE && exclude_layers==FALSE) || (child_in_layer_list==TRUE && parent_in_layer_list==TRUE && exclude_layers==TRUE))
+				dotted_line=TRUE;
+			/* both hosts should be drawn, so use a solid line */
+			else
+				dotted_line=FALSE;
+
+			/* determine color to use when drawing links to parent host */
+			parent_hoststatus=find_hoststatus(temp_parent_hostextinfo->host_name);
+			if(parent_hoststatus!=NULL){
+				if(parent_hoststatus->status==HOST_DOWN || parent_hoststatus->status==HOST_UNREACHABLE)
+					status_color=color_red;
+				else
+					status_color=color_black;
+		                }
+			else
+				status_color=color_black;
+
+			/* draw the link */
+			if(dotted_line==TRUE)
+				draw_dotted_line((temp_hostextinfo->x_2d+(DEFAULT_NODE_WIDTH/2))-canvas_x,(temp_hostextinfo->y_2d+(DEFAULT_NODE_WIDTH)/2)-canvas_y,(temp_parent_hostextinfo->x_2d+(DEFAULT_NODE_WIDTH/2))-canvas_x,(temp_parent_hostextinfo->y_2d+(DEFAULT_NODE_WIDTH/2))-canvas_y,status_color);
+			else
+				draw_line((temp_hostextinfo->x_2d+(DEFAULT_NODE_WIDTH/2))-canvas_x,(temp_hostextinfo->y_2d+(DEFAULT_NODE_WIDTH)/2)-canvas_y,(temp_parent_hostextinfo->x_2d+(DEFAULT_NODE_WIDTH/2))-canvas_x,(temp_parent_hostextinfo->y_2d+(DEFAULT_NODE_WIDTH/2))-canvas_y,status_color);
+		        }
+
+	        }
+
+	return;
+        }
+
+
+
+/* draws hosts */
+void draw_hosts(void){
+	hostextinfo *temp_hostextinfo;
+	host *temp_host;
+	int x1, x2;
+	int y1, y2;
+	int has_image=FALSE;
+	char image_input_file[MAX_INPUT_BUFFER];
+	int current_radius=0;
+	int status_color=color_black;
+	hoststatus *temp_hoststatus;
+	int in_layer_list=FALSE;
+	int average_host_services;
+	int host_services;
+	double host_services_ratio;
+	int outer_radius;
+	int inner_radius;
+	int time_color=0;
+	time_t current_time;
+	int translated_x;
+	int translated_y;
+
+	
+	/* user didn't supply any coordinates for hosts, so display a warning */
+	if(coordinates_were_specified==FALSE){
+
+		if(create_type==CREATE_IMAGE){
+			draw_text("You have not supplied any host drawing coordinates, so you cannot use this layout method.",(COORDS_WARNING_WIDTH/2),30,color_black);
+			draw_text("Read the FAQs for more information on specifying drawing coordinates or select a different layout method.",(COORDS_WARNING_WIDTH/2),45,color_black);
+		        }
+
+		return;
+	        }
+
+	/* draw Nagios process icon if using auto-layout mode */
+	if(layout_method!=LAYOUT_USER_SUPPLIED && draw_nagios_icon==TRUE){
+
+		/* get coords of bounding box */
+		x1=nagios_icon_x-canvas_x;
+		x2=x1+DEFAULT_NODE_WIDTH;
+		y1=nagios_icon_y-canvas_y;
+		y2=y1+DEFAULT_NODE_HEIGHT;
+
+		/* get the name of the image file to open for the logo */
+		snprintf(image_input_file,sizeof(image_input_file)-1,"%s%s",physical_logo_images_path,NAGIOS_GD2_ICON);
+		image_input_file[sizeof(image_input_file)-1]='\x0';
+
+		/* read in the image from file... */
+		logo_image=load_image_from_file(image_input_file);
+
+	        /* copy the logo image to the canvas image... */
+		if(logo_image!=NULL){
+			gdImageCopy(map_image,logo_image,x1,y1,0,0,logo_image->sx,logo_image->sy);
+			gdImageDestroy(logo_image);
+                        }
+
+		/* if we don't have an image, draw a bounding box */
+		else{
+			draw_line(x1,y1,x1,y1+DEFAULT_NODE_WIDTH,color_black);
+			draw_line(x1,y1+DEFAULT_NODE_WIDTH,x2,y1+DEFAULT_NODE_WIDTH,color_black);
+			draw_line(x2,y1+DEFAULT_NODE_WIDTH,x2,y1,color_black);
+			draw_line(x2,y1,x1,y1,color_black);
+	                }
+
+		if(create_type==CREATE_IMAGE)
+			draw_text("Nagios Process",x1+(DEFAULT_NODE_WIDTH/2),y1+DEFAULT_NODE_HEIGHT,color_black);
+	        }
+
+	/* calculate average services per host */
+	average_host_services=4;
+
+	/* draw all hosts... */
+	for(temp_hostextinfo=hostextinfo_list;temp_hostextinfo!=NULL;temp_hostextinfo=temp_hostextinfo->next){
+		
+		/* skip hosts that should not be drawn */
+		if(temp_hostextinfo->should_be_drawn==FALSE)
+			continue;
+
+		/* find the host */
+		temp_host=find_host(temp_hostextinfo->host_name);
+
+		/* is this host in the layer inclusion/exclusion list? */
+		in_layer_list=is_host_in_layer_list(temp_host);
+		if((in_layer_list==TRUE && exclude_layers==TRUE) || (in_layer_list==FALSE && exclude_layers==FALSE))
+			continue;
+
+		/* get coords of host bounding box */
+		x1=temp_hostextinfo->x_2d-canvas_x;
+		x2=x1+DEFAULT_NODE_WIDTH;
+		y1=temp_hostextinfo->y_2d-canvas_y;
+		y2=y1+DEFAULT_NODE_HEIGHT;
+
+		if(create_type==CREATE_IMAGE){
+
+
+			temp_hoststatus=find_hoststatus(temp_hostextinfo->host_name);
+			if(temp_hoststatus!=NULL){
+				if(temp_hoststatus->status==HOST_DOWN)
+					status_color=color_red;
+				else if(temp_hoststatus->status==HOST_UNREACHABLE)
+					status_color=color_red;
+				else if(temp_hoststatus->status==HOST_UP)
+					status_color=color_green;
+				else if(temp_hoststatus->status==HOST_PENDING)
+					status_color=color_grey;
+			        }
+			else
+				status_color=color_black;
+
+
+			/* use balloons instead of icons... */
+			if(layout_method==LAYOUT_CIRCULAR_BALLOON){
+
+				/* get the number of services associated with the host */
+				host_services=number_of_host_services(temp_host);
+
+				if(average_host_services==0)
+					host_services_ratio=0.0;
+				else
+					host_services_ratio=(double)((double)host_services/(double)average_host_services);
+
+				/* calculate size of node */
+				if(host_services_ratio>=2.0)
+					outer_radius=DEFAULT_NODE_WIDTH;
+				else if(host_services_ratio>=1.5)
+					outer_radius=DEFAULT_NODE_WIDTH*0.8;
+				else if(host_services_ratio>=1.0)
+					outer_radius=DEFAULT_NODE_WIDTH*0.6;
+				else if(host_services_ratio>=0.5)
+					outer_radius=DEFAULT_NODE_WIDTH*0.4;
+				else
+					outer_radius=DEFAULT_NODE_WIDTH*0.2;
+
+				/* calculate width of border */
+				if(temp_hoststatus==NULL)
+					inner_radius=outer_radius;
+				else if((temp_hoststatus->status==HOST_DOWN || temp_hoststatus->status==HOST_UNREACHABLE) && temp_hoststatus->problem_has_been_acknowledged==FALSE)
+					inner_radius=outer_radius-3;
+				else
+					inner_radius=outer_radius;
+
+				/* fill node with color based on how long its been in this state... */
+				gdImageArc(map_image,x1+(DEFAULT_NODE_WIDTH/2),y1+(DEFAULT_NODE_WIDTH/2),outer_radius,outer_radius,0,360,color_blue);
+
+				/* determine fill color */
+				time(&current_time);
+				if(temp_hoststatus==NULL)
+					time_color=color_white;
+				else if(current_time-temp_hoststatus->last_state_change<=900)
+					time_color=color_orange;
+				else if(current_time-temp_hoststatus->last_state_change<=3600)
+					time_color=color_yellow;
+				else
+					time_color=color_white;
+
+				/* fill node with appropriate time color */
+				/* the fill function only works with coordinates that are in bounds of the actual image */
+				translated_x=x1+(DEFAULT_NODE_WIDTH/2);
+				translated_y=y1+(DEFAULT_NODE_WIDTH/2);
+				if(translated_x>0 && translated_y>0 && translated_x<canvas_width && translated_y<canvas_height)
+					gdImageFillToBorder(map_image,translated_x,translated_y,color_blue,time_color);
+
+				/* border of node should reflect current state */
+				for(current_radius=outer_radius;current_radius>=inner_radius;current_radius--)
+					gdImageArc(map_image,x1+(DEFAULT_NODE_WIDTH/2),y1+(DEFAULT_NODE_WIDTH/2),current_radius,current_radius,0,360,status_color);
+
+				/* draw circles around the selected host (if there is one) */
+				if(!strcmp(host_name,temp_hostextinfo->host_name) && use_highlights==TRUE){
+					for(current_radius=DEFAULT_NODE_WIDTH*2;current_radius>0;current_radius-=10)
+						gdImageArc(map_image,x1+(DEFAULT_NODE_WIDTH/2),y1+(DEFAULT_NODE_WIDTH/2),current_radius,current_radius,0,360,status_color);
+			                }
+			        }
+
+
+			/* normal method is to use icons for hosts... */
+			else{
+
+				/* draw a target around root hosts (hosts with no parents) */
+				if(temp_host!=NULL && use_highlights==TRUE){
+					if(temp_host->parent_hosts==NULL){
+						gdImageArc(map_image,x1+(DEFAULT_NODE_WIDTH/2),y1+(DEFAULT_NODE_WIDTH/2),(DEFAULT_NODE_WIDTH*2),(DEFAULT_NODE_WIDTH*2),0,360,status_color);
+						draw_line(x1-(DEFAULT_NODE_WIDTH/2),y1+(DEFAULT_NODE_WIDTH/2),x1+(DEFAULT_NODE_WIDTH*3/2),y1+(DEFAULT_NODE_WIDTH/2),status_color);
+						draw_line(x1+(DEFAULT_NODE_WIDTH/2),y1-(DEFAULT_NODE_WIDTH/2),x1+(DEFAULT_NODE_WIDTH/2),y1+(DEFAULT_NODE_WIDTH*3/2),status_color);
+				                }
+			                }
+
+				/* draw circles around the selected host (if there is one) */
+				if(!strcmp(host_name,temp_hostextinfo->host_name) && use_highlights==TRUE){
+					for(current_radius=DEFAULT_NODE_WIDTH*2;current_radius>0;current_radius-=10)
+						gdImageArc(map_image,x1+(DEFAULT_NODE_WIDTH/2),y1+(DEFAULT_NODE_WIDTH/2),current_radius,current_radius,0,360,status_color);
+			                }
+
+
+				if(temp_hostextinfo->statusmap_image!=NULL)
+					has_image=TRUE;
+				else
+					has_image=FALSE;
+				
+				/* load the logo associated with this host */
+				if(has_image==TRUE){
+
+				        /* get the name of the image file to open for the logo */
+					snprintf(image_input_file,sizeof(image_input_file)-1,"%s%s",physical_logo_images_path,temp_hostextinfo->statusmap_image);
+					image_input_file[sizeof(image_input_file)-1]='\x0';
+
+				        /* read in the logo image from file... */
+					logo_image=load_image_from_file(image_input_file);
+
+			                /* copy the logo image to the canvas image... */
+					if(logo_image!=NULL){
+						gdImageCopy(map_image,logo_image,x1,y1,0,0,logo_image->sx,logo_image->sy);
+						gdImageDestroy(logo_image);
+		                                }
+					else
+						has_image=FALSE;
+			                }
+
+				/* if the host doesn't have an image associated with it (or the user doesn't have rights to see this host), use the unknown image */
+				if(has_image==FALSE){
+
+					if(unknown_logo_image!=NULL)
+						gdImageCopy(map_image,unknown_logo_image,x1,y1,0,0,unknown_logo_image->sx,unknown_logo_image->sy);
+
+					else{
+
+						/* last ditch effort - draw a host bounding box */
+						draw_line(x1,y1,x1,y1+DEFAULT_NODE_WIDTH,color_black);
+						draw_line(x1,y1+DEFAULT_NODE_WIDTH,x2,y1+DEFAULT_NODE_WIDTH,color_black);
+						draw_line(x2,y1+DEFAULT_NODE_WIDTH,x2,y1,color_black);
+						draw_line(x2,y1,x1,y1,color_black);
+				                }
+		                        }
+			        }
+
+
+			/* draw host name, status, etc. */
+			draw_host_text(temp_hostextinfo->host_name,x1+(DEFAULT_NODE_WIDTH/2),y1+DEFAULT_NODE_HEIGHT);
+		        }
+
+		/* we're creating HTML image map... */
+		else{
+			printf("<AREA shape='rect' ");
+
+			/* coordinates */
+			printf("coords='%d,%d,%d,%d' ",(int)(x1*scaling_factor),(int)(y1*scaling_factor),(int)((x1+DEFAULT_NODE_WIDTH)*scaling_factor),(int)((y1+DEFAULT_NODE_HEIGHT)*scaling_factor));
+
+			/* URL */
+			if(!strcmp(host_name,temp_hostextinfo->host_name))
+				printf("href='%s?host=%s' ",STATUS_CGI,url_encode(temp_hostextinfo->host_name));
+			else{
+				printf("href='%s?host=%s&layout=%d&max_width=%d&max_height=%d&proximity_width=%d&proximity_height=%d%s%s%s%s%s",STATUSMAP_CGI,url_encode(temp_hostextinfo->host_name),layout_method,max_image_width,max_image_height,proximity_width,proximity_height,(display_header==TRUE)?"":"&noheader",(use_links==FALSE)?"&nolinks":"",(use_text==FALSE)?"&notext":"",(use_highlights==FALSE)?"&nohighlights":"",(display_popups==FALSE)?"&nopopups":"");
+				if(user_supplied_scaling==TRUE)
+					printf("&scaling_factor=%2.1f",user_scaling_factor);
+				print_layer_url(TRUE);
+				printf("' ");
+			        }
+
+			/* popup text */
+			if(display_popups==TRUE){
+
+				printf("onMouseOver='showPopup(\"");
+				write_host_popup_text(find_host(temp_hostextinfo->host_name));
+				printf("\",event)' onMouseOut='hidePopup()'");
+			        }
+
+			printf(">\n");
+		        }
+
+	        }
+
+	return;
+        }
+
+
+/* draws text */
+void draw_text(char *buffer,int x,int y,int text_color){
+	int string_width=0;
+	int string_height=0;
+
+	/* write the string to the generated image... */
+	string_height=gdFontSmall->h;
+	string_width=gdFontSmall->w*strlen(buffer);
+	if(layout_method!=LAYOUT_CIRCULAR_MARKUP)
+		gdImageFilledRectangle(map_image,x-(string_width/2)-2,y-(2*string_height),x+(string_width/2)+2,y-string_height,color_white);
+	gdImageString(map_image,gdFontSmall,x-(string_width/2),y-(2*string_height),(unsigned char *)buffer,text_color);
+
+	return;
+        }
+
+
+/* draws host text */
+void draw_host_text(char *name,int x,int y){
+	hoststatus *temp_hoststatus;
+	int status_color=color_black;
+	char temp_buffer[MAX_INPUT_BUFFER];
+
+	if(use_text==FALSE)
+		return;
+
+	strncpy(temp_buffer,name,sizeof(temp_buffer)-1);
+	temp_buffer[sizeof(temp_buffer)-1]='\x0';
+
+	/* write the host status string to the generated image... */
+	draw_text(temp_buffer,x,y,color_black);
+
+	/* find the status entry for this host */
+	temp_hoststatus=find_hoststatus(name);
+
+	/* get the status of the host (pending, up, down, or unreachable) */
+	if(temp_hoststatus!=NULL){
+
+		/* draw the status string */
+		if(temp_hoststatus->status==HOST_DOWN){
+			strncpy(temp_buffer,"Down",sizeof(temp_buffer));
+			status_color=color_red;
+                        }
+		else if(temp_hoststatus->status==HOST_UNREACHABLE){
+			strncpy(temp_buffer,"Unreachable",sizeof(temp_buffer));
+			status_color=color_red;
+                        }
+		else if(temp_hoststatus->status==HOST_UP){
+			strncpy(temp_buffer,"Up",sizeof(temp_buffer));
+			status_color=color_green;
+                        }
+		else if(temp_hoststatus->status==HOST_PENDING){
+			strncpy(temp_buffer,"Pending",sizeof(temp_buffer));
+			status_color=color_grey;
+                        }
+		else{
+			strncpy(temp_buffer,"Unknown",sizeof(temp_buffer));
+			status_color=color_orange;
+	                }
+
+		temp_buffer[sizeof(temp_buffer)-1]='\x0';
+
+		/* write the host status string to the generated image... */
+		draw_text(temp_buffer,x,y+gdFontSmall->h,status_color);
+                }
+
+	return;
+        }
+
+
+/* writes popup text for a specific host */
+void write_host_popup_text(host *hst){
+	hostextinfo *temp_hostextinfo;
+	hoststatus *temp_status;
+	hostsmember *temp_hostsmember;
+	int service_totals;
+	char date_time[48];
+	time_t current_time;
+	time_t t;
+	char state_duration[48];
+	int days;
+	int hours;
+	int minutes;
+	int seconds;
+
+	if(hst==NULL){
+		printf("Host data not found");
+		return;
+	        }
+
+	/* find the status entry for this host */
+	temp_status=find_hoststatus(hst->name);
+	if(temp_status==NULL){
+		printf("Host status information not found");
+		return;
+	        }
+
+	/* strip nasty stuff from plugin output */
+	sanitize_plugin_output(temp_status->plugin_output);
+
+	printf("<table border=0 cellpadding=0 cellspacing=5>");
+
+	temp_hostextinfo=find_hostextinfo(hst->name);
+	if(temp_hostextinfo!=NULL){
+		printf("<tr><td><img src=%s%s border=0 width=40 height=40></td>",url_logo_images_path,(temp_hostextinfo->icon_image==NULL)?UNKNOWN_ICON_IMAGE:temp_hostextinfo->icon_image);
+		printf("<td class=\\\"popupText\\\"><i>%s</i></td></tr>",(temp_hostextinfo->icon_image_alt==NULL)?"":html_encode(temp_hostextinfo->icon_image_alt));
+	        }
+
+	printf("<tr><td class=\\\"popupText\\\">Name:</td><td class=\\\"popupText\\\"><b>%s</b></td></tr>",html_encode(hst->name));
+	printf("<tr><td class=\\\"popupText\\\">Alias:</td><td class=\\\"popupText\\\"><b>%s</b></td></tr>",html_encode(hst->alias));
+	printf("<tr><td class=\\\"popupText\\\">Address:</td><td class=\\\"popupText\\\"><b>%s</b></td></tr>",html_encode(hst->address));
+	printf("<tr><td class=\\\"popupText\\\">State:</td><td class=\\\"popupText\\\"><b>");
+
+	/* get the status of the host (pending, up, down, or unreachable) */
+	if(temp_status->status==HOST_DOWN){
+		printf("<font color=red>Down");
+		if(temp_status->problem_has_been_acknowledged==TRUE)
+			printf(" (Acknowledged)");
+		printf("</font>");
+	        }
+
+	else if(temp_status->status==HOST_UNREACHABLE){
+		printf("<font color=red>Unreachable");
+		if(temp_status->problem_has_been_acknowledged==TRUE)
+			printf(" (Acknowledged)");
+		printf("</font>");
+	        }
+
+	else if(temp_status->status==HOST_UP)
+		printf("<font color=green>Up</font>");
+
+	else if(temp_status->status==HOST_PENDING)
+		printf("Pending");
+
+	printf("</b></td></tr>");
+	printf("<tr><td class=\\\"popupText\\\">Status Information:</td><td class=\\\"popupText\\\"><b>%s</b></td></tr>",(temp_status->plugin_output==NULL)?"":temp_status->plugin_output);
+
+	current_time=time(NULL);
+	if(temp_status->last_state_change==(time_t)0)
+		t=current_time-program_start;
+	else
+		t=current_time-temp_status->last_state_change;
+	get_time_breakdown((unsigned long)t,&days,&hours,&minutes,&seconds);
+	snprintf(state_duration,sizeof(state_duration)-1,"%2dd %2dh %2dm %2ds%s",days,hours,minutes,seconds,(temp_status->last_state_change==(time_t)0)?"+":"");
+	state_duration[sizeof(state_duration)-1]='\x0';
+	printf("<tr><td class=\\\"popupText\\\">State Duration:</td><td class=\\\"popupText\\\"><b>%s</b></td></tr>",state_duration);
+
+	get_time_string(&temp_status->last_check,date_time,(int)sizeof(date_time),SHORT_DATE_TIME);
+	printf("<tr><td class=\\\"popupText\\\">Last Status Check:</td><td class=\\\"popupText\\\"><b>%s</b></td></tr>",(temp_status->last_check==(time_t)0)?"N/A":date_time);
+	get_time_string(&temp_status->last_state_change,date_time,(int)sizeof(date_time),SHORT_DATE_TIME);
+	printf("<tr><td class=\\\"popupText\\\">Last State Change:</td><td class=\\\"popupText\\\"><b>%s</b></td></tr>",(temp_status->last_state_change==(time_t)0)?"N/A":date_time);
+
+	printf("<tr><td class=\\\"popupText\\\">Parent Host(s):</td><td class=\\\"popupText\\\"><b>");
+	if(hst->parent_hosts==NULL)
+		printf("None (This is a root host)");
+	else{
+		for(temp_hostsmember=hst->parent_hosts;temp_hostsmember!=NULL;temp_hostsmember=temp_hostsmember->next)
+			printf("%s%s",(temp_hostsmember==hst->parent_hosts)?"":", ",html_encode(temp_hostsmember->host_name));
+	        }
+	printf("</b></td></tr>");
+
+	printf("<tr><td class=\\\"popupText\\\">Immediate Child Hosts:</td><td class=\\\"popupText\\\"><b>");
+	printf("%d",number_of_immediate_child_hosts(hst));
+	printf("</b></td></tr>");
+
+	printf("</table>");
+
+	printf("<br><b><u>Services:</u></b><br>");
+
+	service_totals=get_servicestatus_count(hst->name,SERVICE_OK);
+	if(service_totals>0)
+		printf("- <font color=green>%d ok</font><br>",service_totals);
+	service_totals=get_servicestatus_count(hst->name,SERVICE_CRITICAL);
+	if(service_totals>0)
+		printf("- <font color=red>%d critical</font><br>",service_totals);
+	service_totals=get_servicestatus_count(hst->name,SERVICE_WARNING);
+	if(service_totals>0)
+		printf("- <font color=orange>%d warning</font><br>",service_totals);
+	service_totals=get_servicestatus_count(hst->name,SERVICE_UNKNOWN);
+	if(service_totals>0)
+		printf("- <font color=orange>%d unknown</font><br>",service_totals);
+	service_totals=get_servicestatus_count(hst->name,SERVICE_PENDING);
+	if(service_totals>0)
+		printf("- %d pending<br>",service_totals);
+
+	return;
+        }
+
+
+
+/* draws a solid line */
+void draw_line(int x1,int y1,int x2,int y2,int color){
+
+	if(create_type==CREATE_HTML)
+		return;
+
+	gdImageLine(map_image,x1,y1,x2,y2,color);
+
+	return;
+	}
+
+
+/* draws a dotted line */
+void draw_dotted_line(int x1,int y1,int x2,int y2,int color){
+	int styleDotted[12];
+
+	styleDotted[0]=color;
+	styleDotted[1]=gdTransparent;
+	styleDotted[2]=gdTransparent;
+	styleDotted[3]=gdTransparent;
+	styleDotted[4]=gdTransparent;
+	styleDotted[5]=gdTransparent;
+	styleDotted[6]=color;
+	styleDotted[7]=gdTransparent;
+	styleDotted[8]=gdTransparent;
+	styleDotted[9]=gdTransparent;
+	styleDotted[10]=gdTransparent;
+	styleDotted[11]=gdTransparent;
+
+	/* sets current style to a dashed line */
+	gdImageSetStyle(map_image,styleDotted,12);
+
+	/* draws a line (dotted) */
+	gdImageLine(map_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[12];
+
+	styleDashed[0]=color;
+	styleDashed[1]=color;
+	styleDashed[2]=color;
+	styleDashed[3]=color;
+	styleDashed[4]=gdTransparent;
+	styleDashed[5]=gdTransparent;
+	styleDashed[6]=color;
+	styleDashed[7]=color;
+	styleDashed[8]=color;
+	styleDashed[9]=color;
+	styleDashed[10]=gdTransparent;
+	styleDashed[11]=gdTransparent;
+
+	/* sets current style to a dashed line */
+	gdImageSetStyle(map_image,styleDashed,12);
+
+	/* draws a line (dashed) */
+	gdImageLine(map_image,x1,y1,x2,y2,gdStyled);
+
+	return;
+	}
+
+
+
+/******************************************************************/
+/*********************** GRAPHICS FUNCTIONS ***********************/
+/******************************************************************/
+
+/* initialize graphics */
+int initialize_graphics(void){
+	char image_input_file[MAX_INPUT_BUFFER];
+
+	if(create_type==CREATE_HTML)
+		return ERROR;
+
+	/* allocate buffer for storing image */
+	map_image=gdImageCreate(canvas_width,canvas_height);
+	if(map_image==NULL)
+		return ERROR;
+
+	/* allocate colors used for drawing */
+	color_white=gdImageColorAllocate(map_image,255,255,255);
+	color_black=gdImageColorAllocate(map_image,0,0,0);
+	color_grey=gdImageColorAllocate(map_image,128,128,128);
+	color_lightgrey=gdImageColorAllocate(map_image,210,210,210);
+	color_red=gdImageColorAllocate(map_image,255,0,0);
+	color_lightred=gdImageColorAllocate(map_image,215,175,175);
+	color_green=gdImageColorAllocate(map_image,0,175,0);
+	color_lightgreen=gdImageColorAllocate(map_image,210,255,215);
+	color_blue=gdImageColorAllocate(map_image,0,0,255);
+	color_yellow=gdImageColorAllocate(map_image,255,255,0);
+	color_orange=gdImageColorAllocate(map_image,255,100,25);
+
+	/* set transparency index */
+	gdImageColorTransparent(map_image,color_white);
+
+	/* make sure the graphic is interlaced */
+	gdImageInterlace(map_image,1);
+
+	/* get the path where we will be reading logo images from (GD2 format)... */
+	snprintf(physical_logo_images_path,sizeof(physical_logo_images_path)-1,"%slogos/",physical_images_path);
+	physical_logo_images_path[sizeof(physical_logo_images_path)-1]='\x0';
+
+	/* load the unknown icon to use for hosts that don't have pretty images associated with them... */
+	snprintf(image_input_file,sizeof(image_input_file)-1,"%s%s",physical_logo_images_path,UNKNOWN_GD2_ICON);
+	image_input_file[sizeof(image_input_file)-1]='\x0';
+	unknown_logo_image=load_image_from_file(image_input_file);
+
+	return OK;
+        }
+
+
+
+/* loads a graphic image (GD2, JPG or PNG) from file into memory */
+gdImagePtr load_image_from_file(char *filename){
+	FILE *fp;
+	gdImagePtr im=NULL;
+	char *ext;
+
+	/* make sure we were passed a file name */
+	if(filename==NULL)
+		return NULL;
+
+	/* find the file extension */
+	if((ext=rindex(filename,'.'))==NULL)
+		return NULL;
+
+	/* open the file for reading (binary mode) */
+	fp=fopen(filename,"rb");
+	if(fp==NULL)
+		return NULL;
+
+	/* attempt to read files in various formats */
+	if(!strcasecmp(ext,".png"))
+		im=gdImageCreateFromPng(fp);
+	else if(!strcasecmp(ext,".jpg") || !strcasecmp(ext,".jpeg"))
+		im=gdImageCreateFromJpeg(fp);
+	else if(!strcasecmp(ext,".xbm"))
+		im=gdImageCreateFromXbm(fp);
+	else if(!strcasecmp(ext,".gd2"))
+		im=gdImageCreateFromGd2(fp);
+	else if(!strcasecmp(ext,".gd"))
+		im=gdImageCreateFromGd(fp);
+
+	/* fall back to GD2 image format */
+	else
+		im=gdImageCreateFromGd2(fp);
+
+	/* close the file */
+	fclose(fp);
+
+	return im;
+        }
+
+
+
+/* draw graphics */
+void write_graphics(void){
+	FILE *image_output_file=NULL;
+
+	if(create_type==CREATE_HTML)
+		return;
+
+	/* use STDOUT for writing the image data... */
+	image_output_file=stdout;
+
+	/* write the image out in PNG format */
+	gdImagePng(map_image,image_output_file);
+
+	/* or we could write the image out in JPG format... */
+	/*gdImageJpeg(map_image,image_output_file,99);*/
+
+	return;
+        }
+
+
+/* cleanup graphics resources */
+void cleanup_graphics(void){
+
+	if(create_type==CREATE_HTML)
+		return;
+
+	/* free memory allocated to image */
+	gdImageDestroy(map_image);
+
+	return;
+        }
+
+
+
+
+/******************************************************************/
+/************************* MISC FUNCTIONS *************************/
+/******************************************************************/
+
+
+/* write JavaScript code an layer for popup window */
+void write_popup_code(void){
+	char *border_color="#000000";
+	char *background_color="#ffffcc";
+	int border=1;
+	int padding=3;
+	int x_offset=3;
+	int y_offset=3;
+
+	printf("<SCRIPT LANGUAGE='JavaScript'>\n");
+	printf("<!--\n");
+	printf("// JavaScript popup based on code originally found at http://www.helpmaster.com/htmlhelp/javascript/popjbpopup.htm\n");
+	printf("function showPopup(text, eventObj){\n");
+	printf("if(!document.all && document.getElementById)\n");
+	printf("{ document.all=document.getElementsByTagName(\"*\")}\n");
+	printf("ieLayer = 'document.all[\\'popup\\']';\n");
+	printf("nnLayer = 'document.layers[\\'popup\\']';\n");
+	printf("moLayer = 'document.getElementById(\\'popup\\')';\n");
+
+	printf("if(!(document.all||document.layers||document.documentElement)) return;\n");
+
+	printf("if(document.all) { document.popup=eval(ieLayer); }\n");
+	printf("else {\n");
+	printf("  if (document.documentElement) document.popup=eval(moLayer);\n");
+	printf("  else document.popup=eval(nnLayer);\n");
+	printf("}\n");
+
+	printf("var table = \"\";\n");
+
+	printf("if (document.all||document.documentElement){\n");
+	printf("table += \"<table bgcolor='%s' border=%d cellpadding=%d cellspacing=0>\";\n",background_color,border,padding);
+	printf("table += \"<tr><td>\";\n");
+	printf("table += \"<table cellspacing=0 cellpadding=%d>\";\n",padding);
+	printf("table += \"<tr><td bgcolor='%s' class='popupText'>\" + text + \"</td></tr>\";\n",background_color);
+	printf("table += \"</table></td></tr></table>\"\n");
+	printf("document.popup.innerHTML = table;\n");
+	printf("document.popup.style.left = document.body.scrollLeft + %d;\n",x_offset);
+	printf("document.popup.style.top = document.body.scrollTop + %d;\n",y_offset);
+	/*
+	printf("document.popup.style.left = (document.all ? eventObj.x : eventObj.layerX) + %d;\n",x_offset);
+	printf("document.popup.style.top  = (document.all ? eventObj.y : eventObj.layerY) + %d;\n",y_offset);
+	*/
+
+	printf("document.popup.style.visibility = \"visible\";\n");
+	printf("} \n");
+ 
+
+	printf("else{\n");
+	printf("table += \"<table cellpadding=%d border=%d cellspacing=0 bordercolor='%s'>\";\n",padding,border,border_color);
+	printf("table += \"<tr><td bgcolor='%s' class='popupText'>\" + text + \"</td></tr></table>\";\n",background_color);
+	printf("document.popup.document.open();\n");
+	printf("document.popup.document.write(table);\n");
+	printf("document.popup.document.close();\n");
+
+	/* set x coordinate */
+	printf("document.popup.left = eventObj.layerX + %d;\n",x_offset);
+	
+	/* make sure we don't overlap the right side of the screen */
+	printf("if(document.popup.left + document.popup.document.width + %d > window.innerWidth) document.popup.left = window.innerWidth - document.popup.document.width - %d - 16;\n",x_offset,x_offset);
+		
+	/* set y coordinate */
+	printf("document.popup.top  = eventObj.layerY + %d;\n",y_offset);
+	
+	/* make sure we don't overlap the bottom edge of the screen */
+	printf("if(document.popup.top + document.popup.document.height + %d > window.innerHeight) document.popup.top = window.innerHeight - document.popup.document.height - %d - 16;\n",y_offset,y_offset);
+		
+	/* make the popup visible */
+	printf("document.popup.visibility = \"visible\";\n");
+	printf("}\n");
+	printf("}\n");
+
+	printf("function hidePopup(){ \n");
+	printf("if (!(document.all || document.layers || document.documentElement)) return;\n");
+	printf("if (document.popup == null){ }\n");
+	printf("else if (document.all||document.documentElement) document.popup.style.visibility = \"hidden\";\n");
+	printf("else document.popup.visibility = \"hidden\";\n");
+	printf("document.popup = null;\n");
+	printf("}\n");
+	printf("//-->\n");
+
+	printf("</SCRIPT>\n");
+
+	return;
+        }
+
+
+
+/* adds a layer to the list in memory */
+int add_layer(char *group_name){
+	layer *new_layer;
+
+	if(group_name==NULL)
+		return ERROR;
+
+	/* allocate memory for a new layer */
+	new_layer=(layer *)malloc(sizeof(layer));
+	if(new_layer==NULL)
+		return ERROR;
+
+	new_layer->layer_name=(char *)malloc(strlen(group_name)+1);
+	if(new_layer->layer_name==NULL){
+		free(new_layer);
+		return ERROR;
+	        }
+
+	strcpy(new_layer->layer_name,group_name);
+
+	/* add new layer to head of layer list */
+	new_layer->next=layer_list;
+	layer_list=new_layer;
+
+	return OK;
+        }
+
+
+
+/* frees memory allocated to the layer list */
+void free_layer_list(void){
+	layer *this_layer;
+	layer *next_layer;
+
+	return;
+
+	for(this_layer=layer_list;layer_list!=NULL;this_layer=next_layer){
+		next_layer=this_layer->next;
+		free(this_layer->layer_name);
+		free(this_layer);
+	        }
+
+	return;
+        }
+
+
+/* checks to see if a host is in the layer list */
+int is_host_in_layer_list(host *hst){
+	hostgroup *temp_hostgroup;
+	layer *temp_layer;
+
+	if(hst==NULL)
+		return FALSE;
+
+	/* check each layer... */
+	for(temp_layer=layer_list;temp_layer!=NULL;temp_layer=temp_layer->next){
+
+		/* find the hostgroup */
+		temp_hostgroup=find_hostgroup(temp_layer->layer_name);
+		if(temp_hostgroup==NULL)
+			continue;
+		
+		/* is the requested host a member of the hostgroup/layer? */
+		if(is_host_member_of_hostgroup(temp_hostgroup,hst)==TRUE)
+			return TRUE;
+	        }
+
+	return FALSE;
+        }
+
+
+/* print layer url info */
+void print_layer_url(int get_method){
+	layer *temp_layer;
+
+	for(temp_layer=layer_list;temp_layer!=NULL;temp_layer=temp_layer->next){
+		if(get_method==TRUE)
+			printf("&layer=%s",temp_layer->layer_name);
+		else
+			printf("<input type='hidden' name='layer' value='%s'>\n",temp_layer->layer_name);
+	        }
+
+	if(get_method==TRUE)
+		printf("&layermode=%s",(exclude_layers==TRUE)?"exclude":"include");
+	else
+		printf("<input type='hidden' name='layermode' value='%s'>\n",(exclude_layers==TRUE)?"exclude":"include");
+
+	return;
+        }
+	
+
+
+
+/******************************************************************/
+/************************ UTILITY FUNCTIONS ***********************/
+/******************************************************************/
+
+/* calculates how many "layers" separate parent and child - used by collapsed tree layout method */
+int host_child_depth_separation(host *parent, host *child){
+	int this_depth=0;
+	int min_depth=0;
+	int have_min_depth=FALSE;
+	host *temp_host;
+
+	if(child==NULL)
+		return -1;
+
+	if(parent==child)
+		return 0;
+
+	if(is_host_immediate_child_of_host(parent,child)==TRUE)
+		return 1;
+
+	for(temp_host=host_list;temp_host!=NULL;temp_host=temp_host->next){
+
+		if(is_host_immediate_child_of_host(parent,temp_host)==TRUE){
+
+			this_depth=host_child_depth_separation(temp_host,child);
+
+			if(this_depth>=0 && (have_min_depth==FALSE || (have_min_depth==TRUE && (this_depth<min_depth)))){
+				have_min_depth=TRUE;
+				min_depth=this_depth;
+			        }
+		        }
+	        }
+
+	if(have_min_depth==FALSE)
+		return -1;
+	else
+		return min_depth+1;
+        }
+
+
+
+/* calculates how many hosts reside on a specific "layer" - used by collapsed tree layout method */
+int number_of_host_layer_members(host *parent, int layer){
+	int current_layer;
+	int layer_members=0;
+	host *temp_host;
+
+	for(temp_host=host_list;temp_host!=NULL;temp_host=temp_host->next){
+
+		current_layer=host_child_depth_separation(parent,temp_host);
+
+		if(current_layer==layer)
+			layer_members++;
+	        }
+
+	return layer_members;
+        }
+
+
+
+/* calculate max number of members on all "layers" beneath and including parent host - used by collapsed tree layout method */
+int max_child_host_layer_members(host *parent){
+	int current_layer;
+	int max_members=1;
+	int current_members=0;
+
+	for(current_layer=1;;current_layer++){
+
+		current_members=number_of_host_layer_members(parent,current_layer);
+
+		if(current_members<=0)
+			break;
+
+		if(current_members>max_members)
+			max_members=current_members;
+	        }
+
+	return max_members;
+        }
+
+
+
+/* calculate max drawing width for host and children - used by balanced tree layout method */
+int max_child_host_drawing_width(host *parent){
+	host *temp_host;
+	int child_width=0;
+
+
+	for(temp_host=host_list;temp_host!=NULL;temp_host=temp_host->next){
+		
+		if(is_host_immediate_child_of_host(parent,temp_host)==TRUE)
+			child_width+=max_child_host_drawing_width(temp_host);
+	        }
+
+	/* no children, so set width to 1 for this host */
+	if(child_width==0)
+		return 1;
+
+	else
+		return child_width;
+        }
+
+
+
+/* calculates number of services associated with a particular service */
+int number_of_host_services(host *hst){
+	service *temp_service;
+	int total_services=0;
+
+	if(hst==NULL)
+		return 0;
+
+	/* check all the services */
+	for(temp_service=service_list;temp_service!=NULL;temp_service=temp_service->next){
+		if(!strcmp(temp_service->host_name,hst->name))
+			total_services++;
+	        }
+
+	return total_services;
+        }
+	
+
+
+/******************************************************************/
+/***************** COORDINATE CALCULATION FUNCTIONS ***************/
+/******************************************************************/
+
+/* calculates coords of a host's children - used by balanced tree layout method */
+void calculate_balanced_tree_coords(host *parent, int x, int y){
+	int parent_drawing_width;
+	int start_drawing_x;
+	int current_drawing_x;
+	int this_drawing_width;
+	host *temp_host;
+	hostextinfo *temp_hostextinfo;
+
+	/* calculate total drawing width of parent host */
+	parent_drawing_width=max_child_host_drawing_width(parent);
+
+	/* calculate starting x coord */
+	start_drawing_x=x-(((DEFAULT_NODE_WIDTH*parent_drawing_width)+(DEFAULT_NODE_HSPACING*(parent_drawing_width-1)))/2);
+	current_drawing_x=start_drawing_x;
+
+
+	/* calculate coords for children */
+	for(temp_host=host_list;temp_host!=NULL;temp_host=temp_host->next){
+
+		temp_hostextinfo=find_hostextinfo(temp_host->name);
+		if(temp_hostextinfo==NULL)
+			continue;
+
+		if(is_host_immediate_child_of_host(parent,temp_host)==TRUE){
+
+			/* get drawing width of child host */
+			this_drawing_width=max_child_host_drawing_width(temp_host);
+
+			temp_hostextinfo->x_2d=current_drawing_x+(((DEFAULT_NODE_WIDTH*this_drawing_width)+(DEFAULT_NODE_HSPACING*(this_drawing_width-1)))/2);
+			temp_hostextinfo->y_2d=y+DEFAULT_NODE_HEIGHT+DEFAULT_NODE_VSPACING;
+			temp_hostextinfo->have_2d_coords=TRUE;
+			temp_hostextinfo->should_be_drawn=TRUE;
+			
+			current_drawing_x+=(this_drawing_width*DEFAULT_NODE_WIDTH)+((this_drawing_width-1)*DEFAULT_NODE_HSPACING)+DEFAULT_NODE_HSPACING;
+
+			/* recurse into child host ... */
+			calculate_balanced_tree_coords(temp_host,temp_hostextinfo->x_2d,temp_hostextinfo->y_2d);
+		        }
+
+	        }
+
+	return;
+        }
+
+
+/* calculate coords of all hosts in circular layout method */
+void calculate_circular_coords(void){
+	int min_x=0;
+	int min_y=0;
+	int have_min_x=FALSE;
+	int have_min_y=FALSE;
+	hostextinfo *temp_hostextinfo;
+
+	/* calculate all host coords, starting with first layer */
+	calculate_circular_layer_coords(NULL,0.0,360.0,1,CIRCULAR_DRAWING_RADIUS);
+
+	/* adjust all calculated coords so none are negative in x or y axis... */
+
+	/* calculate min x, y coords */
+	for(temp_hostextinfo=hostextinfo_list;temp_hostextinfo!=NULL;temp_hostextinfo=temp_hostextinfo->next){
+		if(have_min_x==FALSE || temp_hostextinfo->x_2d<min_x){
+			have_min_x=TRUE;
+			min_x=temp_hostextinfo->x_2d;
+		        }
+		if(have_min_y==FALSE || temp_hostextinfo->y_2d<min_y){
+			have_min_y=TRUE;
+			min_y=temp_hostextinfo->y_2d;
+		        }
+	        }
+	
+	/* offset all drawing coords by the min x,y coords we found */
+	for(temp_hostextinfo=hostextinfo_list;temp_hostextinfo!=NULL;temp_hostextinfo=temp_hostextinfo->next){
+		if(min_x<0)
+			temp_hostextinfo->x_2d-=min_x;
+		if(min_y<0)
+			temp_hostextinfo->y_2d-=min_y;
+	        }
+
+	if(min_x<0)
+		nagios_icon_x-=min_x;
+	if(min_y<0)
+		nagios_icon_y-=min_y;
+
+	for(temp_hostextinfo=hostextinfo_list;temp_hostextinfo!=NULL;temp_hostextinfo=temp_hostextinfo->next){
+		temp_hostextinfo->x_2d+=(DEFAULT_NODE_WIDTH/2);
+		temp_hostextinfo->y_2d+=(DEFAULT_NODE_HEIGHT/2);
+	        }
+	nagios_icon_x+=(DEFAULT_NODE_WIDTH/2);
+	nagios_icon_y+=(DEFAULT_NODE_HEIGHT/2);
+
+	return;
+        }
+	
+
+/* calculates coords of all hosts in a particular "layer" in circular layout method */
+void calculate_circular_layer_coords(host *parent, double start_angle, double useable_angle, int layer, int radius){
+	int parent_drawing_width=0;
+	int this_drawing_width=0;
+	int immediate_children=0;
+	double current_drawing_angle=0.0;
+	double this_drawing_angle=0.0;
+	double available_angle=0.0;
+	double clipped_available_angle=0.0;
+	double average_child_angle=0.0;
+	double x_coord=0.0;
+	double y_coord=0.0;
+	host *temp_host;
+	hostextinfo *temp_hostextinfo;
+
+
+	/* get the total number of immediate children to this host */
+	immediate_children=number_of_immediate_child_hosts(parent);
+
+	/* bail out if we're done */
+	if(immediate_children==0)
+		return;
+
+	/* calculate total drawing "width" of parent host */
+	parent_drawing_width=max_child_host_drawing_width(parent);
+
+	/* calculate average angle given to each child host */
+	average_child_angle=(double)(useable_angle/(double)immediate_children);
+
+	/* calculate initial drawing angle */
+	current_drawing_angle=start_angle;
+
+
+	/* calculate coords for children */
+	for(temp_host=host_list;temp_host!=NULL;temp_host=temp_host->next){
+
+		temp_hostextinfo=find_hostextinfo(temp_host->name);
+		if(temp_hostextinfo==NULL)
+			continue;
+
+		if(is_host_immediate_child_of_host(parent,temp_host)==TRUE){
+
+			/* get drawing width of child host */
+			this_drawing_width=max_child_host_drawing_width(temp_host);
+
+			/* calculate angle this host gets for drawing */
+			available_angle=useable_angle*((double)this_drawing_width/(double)parent_drawing_width);
+
+			/* clip available angle if necessary */
+			/* this isn't really necessary, but helps keep things looking a bit more sane with less potential connection crossover */
+			clipped_available_angle=360.0/layer;
+			if(available_angle<clipped_available_angle)
+				clipped_available_angle=available_angle;
+
+			/* calculate the exact angle at which we should draw this child */
+			this_drawing_angle=current_drawing_angle+(available_angle/2.0);
+
+			/* compensate for angle overflow */
+			while(this_drawing_angle>=360.0)
+				this_drawing_angle-=360.0;
+			while(this_drawing_angle<0.0)
+				this_drawing_angle+=360.0;
+
+			/* calculate drawing coords of this host using good ol' geometry... */
+			x_coord=-(sin(-this_drawing_angle*(M_PI/180.0))*radius);
+			y_coord=-(sin((90+this_drawing_angle)*(M_PI/180.0))*radius);
+
+			temp_hostextinfo->x_2d=(int)x_coord;
+			temp_hostextinfo->y_2d=(int)y_coord;
+			temp_hostextinfo->have_2d_coords=TRUE;
+			temp_hostextinfo->should_be_drawn=TRUE;
+
+			/* recurse into child host ... */
+			calculate_circular_layer_coords(temp_host,current_drawing_angle+((available_angle-clipped_available_angle)/2),clipped_available_angle,layer+1,radius+CIRCULAR_DRAWING_RADIUS);
+
+			/* increment current drawing angle */
+			current_drawing_angle+=available_angle;
+		        }
+	        }
+
+	return;
+        }
+
+
+
+/* draws background "extras" for all hosts in circular markup layout */
+void draw_circular_markup(void){
+
+	/* calculate all host sections, starting with first layer */
+	draw_circular_layer_markup(NULL,0.0,360.0,1,CIRCULAR_DRAWING_RADIUS);
+
+	return;
+        }
+
+
+/* draws background "extras" for all hosts in a particular "layer" in circular markup layout */
+void draw_circular_layer_markup(host *parent, double start_angle, double useable_angle, int layer, int radius){
+	int parent_drawing_width=0;
+	int this_drawing_width=0;
+	int immediate_children=0;
+	double current_drawing_angle=0.0;
+	double available_angle=0.0;
+	double clipped_available_angle=0.0;
+	double average_child_angle=0.0;
+	double x_coord[4]={0.0,0.0,0.0,0.0};
+	double y_coord[4]={0.0,0.0,0.0,0.0};
+	host *temp_host;
+	hoststatus *temp_hoststatus;
+	hostextinfo *temp_hostextinfo;
+	int x_offset=0;
+	int y_offset=0;
+	int center_x=0;
+	int center_y=0;
+	int bgcolor=0;
+	double arc_start_angle=0.0;
+	double arc_end_angle=0.0;
+	int translated_x=0;
+	int translated_y=0;
+
+	/* get the total number of immediate children to this host */
+	immediate_children=number_of_immediate_child_hosts(parent);
+
+	/* bail out if we're done */
+	if(immediate_children==0)
+		return;
+
+	/* calculate total drawing "width" of parent host */
+	parent_drawing_width=max_child_host_drawing_width(parent);
+
+	/* calculate average angle given to each child host */
+	average_child_angle=(double)(useable_angle/(double)immediate_children);
+
+	/* calculate initial drawing angle */
+	current_drawing_angle=start_angle;
+
+	/* calculate coords for children */
+	for(temp_host=host_list;temp_host!=NULL;temp_host=temp_host->next){
+
+		temp_hostextinfo=find_hostextinfo(temp_host->name);
+		if(temp_hostextinfo==NULL)
+			continue;
+
+		if(is_host_immediate_child_of_host(parent,temp_host)==TRUE){
+
+			/* get drawing width of child host */
+			this_drawing_width=max_child_host_drawing_width(temp_host);
+
+			/* calculate angle this host gets for drawing */
+			available_angle=useable_angle*((double)this_drawing_width/(double)parent_drawing_width);
+
+			/* clip available angle if necessary */
+			/* this isn't really necessary, but helps keep things looking a bit more sane with less potential connection crossover */
+			clipped_available_angle=360.0/layer;
+			if(available_angle<clipped_available_angle)
+				clipped_available_angle=available_angle;
+
+			/* calculate drawing coords of "leftmost" divider using good ol' geometry... */
+			x_coord[0]=-(sin(-current_drawing_angle*(M_PI/180.0))*(radius-(CIRCULAR_DRAWING_RADIUS/2)));
+			y_coord[0]=-(sin((90+current_drawing_angle)*(M_PI/180.0))*(radius-(CIRCULAR_DRAWING_RADIUS/2)));
+			x_coord[1]=-(sin(-current_drawing_angle*(M_PI/180.0))*(radius+(CIRCULAR_DRAWING_RADIUS/2)));
+			y_coord[1]=-(sin((90+current_drawing_angle)*(M_PI/180.0))*(radius+(CIRCULAR_DRAWING_RADIUS/2)));
+
+			/* calculate drawing coords of "rightmost" divider using good ol' geometry... */
+			x_coord[2]=-(sin((-(current_drawing_angle+available_angle))*(M_PI/180.0))*(radius-(CIRCULAR_DRAWING_RADIUS/2)));
+			y_coord[2]=-(sin((90+current_drawing_angle+available_angle)*(M_PI/180.0))*(radius-(CIRCULAR_DRAWING_RADIUS/2)));
+			x_coord[3]=-(sin((-(current_drawing_angle+available_angle))*(M_PI/180.0))*(radius+(CIRCULAR_DRAWING_RADIUS/2)));
+			y_coord[3]=-(sin((90+current_drawing_angle+available_angle)*(M_PI/180.0))*(radius+(CIRCULAR_DRAWING_RADIUS/2)));
+
+
+			x_offset=nagios_icon_x+(DEFAULT_NODE_WIDTH/2)-canvas_x;
+			y_offset=nagios_icon_y+(DEFAULT_NODE_HEIGHT/2)-canvas_y;
+
+			/* draw "slice" dividers */
+			if(immediate_children>1 || layer>1){
+
+				/* draw "leftmost" divider */
+				gdImageLine(map_image,(int)x_coord[0]+x_offset,(int)y_coord[0]+y_offset,(int)x_coord[1]+x_offset,(int)y_coord[1]+y_offset,color_lightgrey);
+
+				/* draw "rightmost" divider */
+				gdImageLine(map_image,(int)x_coord[2]+x_offset,(int)y_coord[2]+y_offset,(int)x_coord[3]+x_offset,(int)y_coord[3]+y_offset,color_lightgrey);
+			        }
+
+			/* determine arc drawing angles */
+			arc_start_angle=current_drawing_angle-90.0;
+			while(arc_start_angle<0.0)
+				arc_start_angle+=360.0;
+			arc_end_angle=arc_start_angle+available_angle;
+
+			/* draw inner arc */
+			gdImageArc(map_image,x_offset,y_offset,(radius-(CIRCULAR_DRAWING_RADIUS/2))*2,(radius-(CIRCULAR_DRAWING_RADIUS/2))*2,floor(arc_start_angle),ceil(arc_end_angle),color_lightgrey);
+
+			/* draw outer arc */
+			gdImageArc(map_image,x_offset,y_offset,(radius+(CIRCULAR_DRAWING_RADIUS/2))*2,(radius+(CIRCULAR_DRAWING_RADIUS/2))*2,floor(arc_start_angle),ceil(arc_end_angle),color_lightgrey);
+
+
+			/* determine center of "slice" and fill with appropriate color */
+			center_x=-(sin(-(current_drawing_angle+(available_angle/2.0))*(M_PI/180.0))*(radius));
+			center_y=-(sin((90+current_drawing_angle+(available_angle/2.0))*(M_PI/180.0))*(radius));
+			translated_x=center_x+x_offset;
+			translated_y=center_y+y_offset;
+
+			/* determine background color */
+			temp_hoststatus=find_hoststatus(temp_host->name);
+			if(temp_hoststatus==NULL)
+				bgcolor=color_lightgrey;
+			else if(temp_hoststatus->status==HOST_DOWN || temp_hoststatus->status==HOST_UNREACHABLE)
+				bgcolor=color_lightred;
+			else
+				bgcolor=color_lightgreen;
+
+			/* fill slice with background color */
+			/* the fill function only works with coordinates that are in bounds of the actual image */
+			if(translated_x>0 && translated_y>0 && translated_x<canvas_width && translated_y<canvas_height)
+				gdImageFillToBorder(map_image,translated_x,translated_y,color_lightgrey,bgcolor);
+
+			/* recurse into child host ... */
+			draw_circular_layer_markup(temp_host,current_drawing_angle+((available_angle-clipped_available_angle)/2),clipped_available_angle,layer+1,radius+CIRCULAR_DRAWING_RADIUS);
+
+			/* increment current drawing angle */
+			current_drawing_angle+=available_angle;
+		        }
+	        }
+
+	return;
+        }
+
diff -urNad nagios2-2.6~/cgi/statuswml.c nagios2-2.6/cgi/statuswml.c
--- nagios2-2.6~/cgi/statuswml.c	2006-03-22 17:45:26.000000000 +0000
+++ nagios2-2.6/cgi/statuswml.c	2008-05-26 16:07:18.000000000 +0000
@@ -616,7 +616,7 @@
 	printf("<card id='card1' title='Status Overview'>\n");
 	printf("<p align='center' mode='nowrap'>\n");
 
-	printf("<b><anchor title='Status Overview'>Status Overview<go href='%s' method='post'><postfield name='hostgroup' value='%s'/><postfield name='style' value='summary'/></go></anchor></b><br/><br/>\n",STATUSWML_CGI,hostgroup_name);
+	printf("<b><anchor title='Status Overview'>Status Overview<go href='%s' method='post'><postfield name='hostgroup' value='%s'/><postfield name='style' value='summary'/></go></anchor></b><br/><br/>\n",STATUSWML_CGI,url_encode(hostgroup_name));
 
 	/* check all hostgroups */
 	for(temp_hostgroup=hostgroup_list;temp_hostgroup!=NULL;temp_hostgroup=temp_hostgroup->next){
@@ -699,7 +699,7 @@
 	printf("<card id='card1' title='Status Summary'>\n");
 	printf("<p align='center' mode='nowrap'>\n");
 
-	printf("<b><anchor title='Status Summary'>Status Summary<go href='%s' method='post'><postfield name='hostgroup' value='%s'/><postfield name='style' value='overview'/></go></anchor></b><br/><br/>\n",STATUSWML_CGI,hostgroup_name);
+	printf("<b><anchor title='Status Summary'>Status Summary<go href='%s' method='post'><postfield name='hostgroup' value='%s'/><postfield name='style' value='overview'/></go></anchor></b><br/><br/>\n",STATUSWML_CGI,url_encode(hostgroup_name));
 
 	/* check all hostgroups */
 	for(temp_hostgroup=hostgroup_list;temp_hostgroup!=NULL;temp_hostgroup=temp_hostgroup->next){
@@ -921,7 +921,7 @@
 
 	printf("</table>\n");
 	printf("<br/>\n");
-	printf("<b><anchor title='View Services'>View Services<go href='%s' method='post'><postfield name='host' value='%s'/><postfield name='style' value='servicedetail'/></go></anchor></b>\n",STATUSWML_CGI,host_name);
+	printf("<b><anchor title='View Services'>View Services<go href='%s' method='post'><postfield name='host' value='%s'/><postfield name='style' value='servicedetail'/></go></anchor></b>\n",STATUSWML_CGI,url_encode(host_name));
 	printf("<b><anchor title='Host Commands'>Host Commands<go href='#card2'/></anchor></b>\n");
 	printf("</p>\n");
 
@@ -940,23 +940,23 @@
 		printf("<b><anchor title='Acknowledge Problem'>Acknowledge Problem<go href='#card3'/></anchor></b>\n");
 
 	if(temp_hoststatus->checks_enabled==FALSE)
-		printf("<b><anchor title='Enable Host Checks'>Enable Host Checks<go href='%s' method='post'><postfield name='host' value='%s'/><postfield name='cmd_typ' value='%d'/><postfield name='cmd_mod' value='%d'/><postfield name='content' value='wml'/></go></anchor></b><br/>\n",COMMAND_CGI,host_name,CMD_ENABLE_HOST_CHECK,CMDMODE_COMMIT);
+		printf("<b><anchor title='Enable Host Checks'>Enable Host Checks<go href='%s' method='post'><postfield name='host' value='%s'/><postfield name='cmd_typ' value='%d'/><postfield name='cmd_mod' value='%d'/><postfield name='content' value='wml'/></go></anchor></b><br/>\n",COMMAND_CGI,url_encode(host_name),CMD_ENABLE_HOST_CHECK,CMDMODE_COMMIT);
 	else
-		printf("<b><anchor title='Disable Host Checks'>Disable Host Checks<go href='%s' method='post'><postfield name='host' value='%s'/><postfield name='cmd_typ' value='%d'/><postfield name='cmd_mod' value='%d'/><postfield name='content' value='wml'/></go></anchor></b><br/>\n",COMMAND_CGI,host_name,CMD_DISABLE_HOST_CHECK,CMDMODE_COMMIT);
+		printf("<b><anchor title='Disable Host Checks'>Disable Host Checks<go href='%s' method='post'><postfield name='host' value='%s'/><postfield name='cmd_typ' value='%d'/><postfield name='cmd_mod' value='%d'/><postfield name='content' value='wml'/></go></anchor></b><br/>\n",COMMAND_CGI,url_encode(host_name),CMD_DISABLE_HOST_CHECK,CMDMODE_COMMIT);
 
 	if(temp_hoststatus->notifications_enabled==FALSE)
-		printf("<b><anchor title='Enable Host Notifications'>Enable Host Notifications<go href='%s' method='post'><postfield name='host' value='%s'/><postfield name='cmd_typ' value='%d'/><postfield name='cmd_mod' value='%d'/><postfield name='content' value='wml'/></go></anchor></b><br/>\n",COMMAND_CGI,host_name,CMD_ENABLE_HOST_NOTIFICATIONS,CMDMODE_COMMIT);
+		printf("<b><anchor title='Enable Host Notifications'>Enable Host Notifications<go href='%s' method='post'><postfield name='host' value='%s'/><postfield name='cmd_typ' value='%d'/><postfield name='cmd_mod' value='%d'/><postfield name='content' value='wml'/></go></anchor></b><br/>\n",COMMAND_CGI,url_encode(host_name),CMD_ENABLE_HOST_NOTIFICATIONS,CMDMODE_COMMIT);
 	else
-		printf("<b><anchor title='Disable Host Notifications'>Disable Host Notifications<go href='%s' method='post'><postfield name='host' value='%s'/><postfield name='cmd_typ' value='%d'/><postfield name='cmd_mod' value='%d'/><postfield name='content' value='wml'/></go></anchor></b><br/>\n",COMMAND_CGI,host_name,CMD_DISABLE_HOST_NOTIFICATIONS,CMDMODE_COMMIT);
+		printf("<b><anchor title='Disable Host Notifications'>Disable Host Notifications<go href='%s' method='post'><postfield name='host' value='%s'/><postfield name='cmd_typ' value='%d'/><postfield name='cmd_mod' value='%d'/><postfield name='content' value='wml'/></go></anchor></b><br/>\n",COMMAND_CGI,url_encode(host_name),CMD_DISABLE_HOST_NOTIFICATIONS,CMDMODE_COMMIT);
 
 
-	printf("<b><anchor title='Enable All Service Checks'>Enable All Service Checks<go href='%s' method='post'><postfield name='host' value='%s'/><postfield name='cmd_typ' value='%d'/><postfield name='cmd_mod' value='%d'/><postfield name='content' value='wml'/></go></anchor></b><br/>\n",COMMAND_CGI,host_name,CMD_ENABLE_HOST_SVC_CHECKS,CMDMODE_COMMIT);
+	printf("<b><anchor title='Enable All Service Checks'>Enable All Service Checks<go href='%s' method='post'><postfield name='host' value='%s'/><postfield name='cmd_typ' value='%d'/><postfield name='cmd_mod' value='%d'/><postfield name='content' value='wml'/></go></anchor></b><br/>\n",COMMAND_CGI,url_encode(host_name),CMD_ENABLE_HOST_SVC_CHECKS,CMDMODE_COMMIT);
 
-	printf("<b><anchor title='Disable All Service Checks'>Disable All Service Checks<go href='%s' method='post'><postfield name='host' value='%s'/><postfield name='cmd_typ' value='%d'/><postfield name='cmd_mod' value='%d'/><postfield name='content' value='wml'/></go></anchor></b><br/>\n",COMMAND_CGI,host_name,CMD_DISABLE_HOST_SVC_CHECKS,CMDMODE_COMMIT);
+	printf("<b><anchor title='Disable All Service Checks'>Disable All Service Checks<go href='%s' method='post'><postfield name='host' value='%s'/><postfield name='cmd_typ' value='%d'/><postfield name='cmd_mod' value='%d'/><postfield name='content' value='wml'/></go></anchor></b><br/>\n",COMMAND_CGI,url_encode(host_name),CMD_DISABLE_HOST_SVC_CHECKS,CMDMODE_COMMIT);
 
-	printf("<b><anchor title='Enable All Service Notifications'>Enable All Service Notifications<go href='%s' method='post'><postfield name='host' value='%s'/><postfield name='cmd_typ' value='%d'/><postfield name='cmd_mod' value='%d'/><postfield name='content' value='wml'/></go></anchor></b><br/>\n",COMMAND_CGI,host_name,CMD_ENABLE_HOST_SVC_NOTIFICATIONS,CMDMODE_COMMIT);
+	printf("<b><anchor title='Enable All Service Notifications'>Enable All Service Notifications<go href='%s' method='post'><postfield name='host' value='%s'/><postfield name='cmd_typ' value='%d'/><postfield name='cmd_mod' value='%d'/><postfield name='content' value='wml'/></go></anchor></b><br/>\n",COMMAND_CGI,url_encode(host_name),CMD_ENABLE_HOST_SVC_NOTIFICATIONS,CMDMODE_COMMIT);
 
-	printf("<b><anchor title='Disable All Service Notifications'>Disable All Service Notifications<go href='%s' method='post'><postfield name='host' value='%s'/><postfield name='cmd_typ' value='%d'/><postfield name='cmd_mod' value='%d'/><postfield name='content' value='wml'/></go></anchor></b><br/>\n",COMMAND_CGI,host_name,CMD_DISABLE_HOST_SVC_NOTIFICATIONS,CMDMODE_COMMIT);
+	printf("<b><anchor title='Disable All Service Notifications'>Disable All Service Notifications<go href='%s' method='post'><postfield name='host' value='%s'/><postfield name='cmd_typ' value='%d'/><postfield name='cmd_mod' value='%d'/><postfield name='content' value='wml'/></go></anchor></b><br/>\n",COMMAND_CGI,url_encode(host_name),CMD_DISABLE_HOST_SVC_NOTIFICATIONS,CMDMODE_COMMIT);
 
 	printf("</p>\n");
 
@@ -976,7 +976,7 @@
 	printf("<input name='comment'/>\n");
 
 	printf("<do type='accept'>\n");
-	printf("<go href='%s' method='post'><postfield name='host' value='%s'/><postfield name='com_author' value='$(name)'/><postfield name='com_data' value='$(comment)'/><postfield name='persistent' value=''/><postfield name='send_notification' value=''/><postfield name='cmd_typ' value='%d'/><postfield name='cmd_mod' value='%d'/><postfield name='content' value='wml'/></go>\n",COMMAND_CGI,host_name,CMD_ACKNOWLEDGE_HOST_PROBLEM,CMDMODE_COMMIT);
+	printf("<go href='%s' method='post'><postfield name='host' value='%s'/><postfield name='com_author' value='$(name)'/><postfield name='com_data' value='$(comment)'/><postfield name='persistent' value=''/><postfield name='send_notification' value=''/><postfield name='cmd_typ' value='%d'/><postfield name='cmd_mod' value='%d'/><postfield name='content' value='wml'/></go>\n",COMMAND_CGI,url_encode(host_name),CMD_ACKNOWLEDGE_HOST_PROBLEM,CMDMODE_COMMIT);
 	printf("</do>\n");
 
 	printf("</p>\n");
@@ -996,7 +996,7 @@
 	/**** MAIN SCREEN (CARD 1) ****/
 	printf("<card id='card1' title='Host Services'>\n");
 	printf("<p align='center' mode='nowrap'>\n");
-	printf("<b>Host <anchor title='%s'>'%s'<go href='%s' method='post'><postfield name='host' value='%s'/></go></anchor> Services</b><br/>\n",host_name,host_name,STATUSWML_CGI,host_name);
+	printf("<b>Host <anchor title='%s'>'%s'<go href='%s' method='post'><postfield name='host' value='%s'/></go></anchor> Services</b><br/>\n",url_encode(host_name),host_name,STATUSWML_CGI,url_encode(host_name));
 
 	printf("<table columns='2' align='LL'>\n");
 
@@ -1137,7 +1137,7 @@
 
 	printf("</table>\n");
 	printf("<br/>\n");
-	printf("<b><anchor title='View Host'>View Host<go href='%s' method='post'><postfield name='host' value='%s'/></go></anchor></b>\n",STATUSWML_CGI,host_name);
+	printf("<b><anchor title='View Host'>View Host<go href='%s' method='post'><postfield name='host' value='%s'/></go></anchor></b>\n",STATUSWML_CGI,url_encode(host_name));
 	printf("<b><anchor title='Service Commands'>Svc. Commands<go href='#card2'/></anchor></b>\n");
 	printf("</p>\n");
 
@@ -1153,16 +1153,16 @@
 		printf("<b><anchor title='Acknowledge Problem'>Acknowledge Problem<go href='#card3'/></anchor></b>\n");
 
 	if(temp_servicestatus->checks_enabled==FALSE)
-		printf("<b><anchor title='Enable Checks'>Enable Checks<go href='%s' method='post'><postfield name='host' value='%s'/><postfield name='service' value='%s'/><postfield name='cmd_typ' value='%d'/><postfield name='cmd_mod' value='%d'/><postfield name='content' value='wml'/></go></anchor></b><br/>\n",COMMAND_CGI,host_name,service_desc,CMD_ENABLE_SVC_CHECK,CMDMODE_COMMIT);
+		printf("<b><anchor title='Enable Checks'>Enable Checks<go href='%s' method='post'><postfield name='host' value='%s'/><postfield name='service' value='%s'/><postfield name='cmd_typ' value='%d'/><postfield name='cmd_mod' value='%d'/><postfield name='content' value='wml'/></go></anchor></b><br/>\n",COMMAND_CGI,url_encode(host_name),url_encode(service_desc),CMD_ENABLE_SVC_CHECK,CMDMODE_COMMIT);
 	else{
-		printf("<b><anchor title='Disable Checks'>Disable Checks<go href='%s' method='post'><postfield name='host' value='%s'/><postfield name='service' value='%s'/><postfield name='cmd_typ' value='%d'/><postfield name='cmd_mod' value='%d'/><postfield name='content' value='wml'/></go></anchor></b><br/>\n",COMMAND_CGI,host_name,service_desc,CMD_DISABLE_SVC_CHECK,CMDMODE_COMMIT);
-		printf("<b><anchor title='Schedule Immediate Check'>Schedule Immediate Check<go href='%s' method='post'><postfield name='host' value='%s'/><postfield name='service' value='%s'/><postfield name='cmd_typ' value='%d'/><postfield name='cmd_mod' value='%d'/><postfield name='content' value='wml'/></go></anchor></b><br/>\n",COMMAND_CGI,host_name,service_desc,CMD_SCHEDULE_SVC_CHECK,CMDMODE_COMMIT);
+		printf("<b><anchor title='Disable Checks'>Disable Checks<go href='%s' method='post'><postfield name='host' value='%s'/><postfield name='service' value='%s'/><postfield name='cmd_typ' value='%d'/><postfield name='cmd_mod' value='%d'/><postfield name='content' value='wml'/></go></anchor></b><br/>\n",COMMAND_CGI,url_encode(host_name),url_encode(service_desc),CMD_DISABLE_SVC_CHECK,CMDMODE_COMMIT);
+		printf("<b><anchor title='Schedule Immediate Check'>Schedule Immediate Check<go href='%s' method='post'><postfield name='host' value='%s'/><postfield name='service' value='%s'/><postfield name='cmd_typ' value='%d'/><postfield name='cmd_mod' value='%d'/><postfield name='content' value='wml'/></go></anchor></b><br/>\n",COMMAND_CGI,url_encode(host_name),url_encode(service_desc),CMD_SCHEDULE_SVC_CHECK,CMDMODE_COMMIT);
 	        }
 
 	if(temp_servicestatus->notifications_enabled==FALSE)
-		printf("<b><anchor title='Enable Notifications'>Enable Notifications<go href='%s' method='post'><postfield name='host' value='%s'/><postfield name='service' value='%s'/><postfield name='cmd_typ' value='%d'/><postfield name='cmd_mod' value='%d'/><postfield name='content' value='wml'/></go></anchor></b><br/>\n",COMMAND_CGI,host_name,service_desc,CMD_ENABLE_SVC_NOTIFICATIONS,CMDMODE_COMMIT);
+		printf("<b><anchor title='Enable Notifications'>Enable Notifications<go href='%s' method='post'><postfield name='host' value='%s'/><postfield name='service' value='%s'/><postfield name='cmd_typ' value='%d'/><postfield name='cmd_mod' value='%d'/><postfield name='content' value='wml'/></go></anchor></b><br/>\n",COMMAND_CGI,url_encode(host_name),url_encode(service_desc),CMD_ENABLE_SVC_NOTIFICATIONS,CMDMODE_COMMIT);
 	else
-		printf("<b><anchor title='Disable Notifications'>Disable Notifications<go href='%s' method='post'><postfield name='host' value='%s'/><postfield name='service' value='%s'/><postfield name='cmd_typ' value='%d'/><postfield name='cmd_mod' value='%d'/><postfield name='content' value='wml'/></go></anchor></b><br/>\n",COMMAND_CGI,host_name,service_desc,CMD_DISABLE_SVC_NOTIFICATIONS,CMDMODE_COMMIT);
+		printf("<b><anchor title='Disable Notifications'>Disable Notifications<go href='%s' method='post'><postfield name='host' value='%s'/><postfield name='service' value='%s'/><postfield name='cmd_typ' value='%d'/><postfield name='cmd_mod' value='%d'/><postfield name='content' value='wml'/></go></anchor></b><br/>\n",COMMAND_CGI,url_encode(host_name),url_encode(service_desc),CMD_DISABLE_SVC_NOTIFICATIONS,CMDMODE_COMMIT);
 
 	printf("</p>\n");
 
@@ -1182,7 +1182,7 @@
 	printf("<input name='comment'/>\n");
 
 	printf("<do type='accept'>\n");
-	printf("<go href='%s' method='post'><postfield name='host' value='%s'/><postfield name='service' value='%s'/><postfield name='com_author' value='$(name)'/><postfield name='com_data' value='$(comment)'/><postfield name='persistent' value=''/><postfield name='send_notification' value=''/><postfield name='cmd_typ' value='%d'/><postfield name='cmd_mod' value='%d'/><postfield name='content' value='wml'/></go>\n",COMMAND_CGI,host_name,service_desc,CMD_ACKNOWLEDGE_SVC_PROBLEM,CMDMODE_COMMIT);
+	printf("<go href='%s' method='post'><postfield name='host' value='%s'/><postfield name='service' value='%s'/><postfield name='com_author' value='$(name)'/><postfield name='com_data' value='$(comment)'/><postfield name='persistent' value=''/><postfield name='send_notification' value=''/><postfield name='cmd_typ' value='%d'/><postfield name='cmd_mod' value='%d'/><postfield name='content' value='wml'/></go>\n",COMMAND_CGI,url_encode(host_name),url_encode(service_desc),CMD_ACKNOWLEDGE_SVC_PROBLEM,CMDMODE_COMMIT);
 	printf("</do>\n");
 
 	printf("</p>\n");
diff -urNad nagios2-2.6~/cgi/statuswml.c.orig nagios2-2.6/cgi/statuswml.c.orig
--- nagios2-2.6~/cgi/statuswml.c.orig	1970-01-01 00:00:00.000000000 +0000
+++ nagios2-2.6/cgi/statuswml.c.orig	2006-03-22 17:45:26.000000000 +0000
@@ -0,0 +1,1486 @@
+/**************************************************************************
+ *
+ * STATUSWML.C -  Nagios Status CGI for WAP-enabled devices
+ *
+ * Copyright (c) 2001-2006 Ethan Galstad (nagios at nagios.org)
+ * Last Modified: 03-22-2006
+ *
+ * License:
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *************************************************************************/
+
+#include "../include/config.h"
+#include "../include/common.h"
+#include "../include/objects.h"
+#include "../include/statusdata.h"
+
+#include "../include/cgiutils.h"
+#include "../include/getcgi.h"
+#include "../include/cgiauth.h"
+
+extern time_t          program_start;
+
+extern char main_config_file[MAX_FILENAME_LENGTH];
+
+extern host *host_list;
+extern hostgroup *hostgroup_list;
+extern service *service_list;
+extern hoststatus *hoststatus_list;
+extern servicestatus *servicestatus_list;
+
+extern int      enable_notifications;
+extern int      execute_service_checks;
+extern int      nagios_process_state;
+
+extern char     *ping_syntax;
+
+#define DISPLAY_HOST		        0
+#define DISPLAY_SERVICE                 1
+#define DISPLAY_HOSTGROUP               2
+#define DISPLAY_INDEX                   3
+#define DISPLAY_PING                    4
+#define DISPLAY_TRACEROUTE              5
+#define DISPLAY_QUICKSTATS              6
+#define DISPLAY_PROCESS                 7
+#define DISPLAY_ALL_PROBLEMS            8
+#define DISPLAY_UNHANDLED_PROBLEMS      9
+
+#define DISPLAY_HOSTGROUP_SUMMARY       0
+#define DISPLAY_HOSTGROUP_OVERVIEW      1
+
+#define DISPLAY_HOST_SUMMARY            0
+#define DISPLAY_HOST_SERVICES           1
+
+void document_header(void);
+void document_footer(void);
+int process_cgivars(void);
+
+int display_type=DISPLAY_INDEX;
+int hostgroup_style=DISPLAY_HOSTGROUP_SUMMARY;
+int host_style=DISPLAY_HOST_SUMMARY;
+
+void display_index(void);
+void display_host(void);
+void display_host_services(void);
+void display_service(void);
+void display_hostgroup_summary(void);
+void display_hostgroup_overview(void);
+void display_ping(void);
+void display_traceroute(void);
+void display_quick_stats(void);
+void display_process(void);
+void display_problems(void);
+
+char *host_name="";
+char *hostgroup_name="";
+char *service_desc="";
+char *ping_address="";
+char *traceroute_address="";
+
+int show_all_hostgroups=TRUE;
+
+
+authdata current_authdata;
+
+
+
+int main(void){
+	int result=OK;
+	
+	/* get the arguments passed in the URL */
+	process_cgivars();
+
+	/* reset internal variables */
+	reset_cgi_vars();
+
+	document_header();
+
+	/* read the CGI configuration file */
+	result=read_cgi_config_file(get_cgi_config_location());
+	if(result==ERROR){
+		printf("<P>Error: Could not open CGI configuration file '%s' for reading!</P>\n",get_cgi_config_location());
+		document_footer();
+		return ERROR;
+	        }
+
+	/* read the main configuration file */
+	result=read_main_config_file(main_config_file);
+	if(result==ERROR){
+		printf("<P>Error: Could not open main configuration file '%s' for reading!</P>\n",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){
+		printf("<P>Error: Could not read some or all object configuration data!</P>\n");
+		document_footer();
+		return ERROR;
+                }
+
+	/* read all status data */
+	result=read_all_status_data(get_cgi_config_location(),READ_ALL_STATUS_DATA);
+	if(result==ERROR){
+		printf("<P>Error: Could not read host and service status information!</P>\n");
+		document_footer();
+		free_memory();
+		return ERROR;
+                }
+
+	/* get authentication information */
+	get_authentication_information(&current_authdata);
+
+	/* decide what to display to the user */
+	if(display_type==DISPLAY_HOST && host_style==DISPLAY_HOST_SERVICES)
+		display_host_services();
+	else if(display_type==DISPLAY_HOST)
+		display_host();
+	else if(display_type==DISPLAY_SERVICE)
+		display_service();
+	else if(display_type==DISPLAY_HOSTGROUP && hostgroup_style==DISPLAY_HOSTGROUP_OVERVIEW)
+		display_hostgroup_overview();
+	else if(display_type==DISPLAY_HOSTGROUP && hostgroup_style==DISPLAY_HOSTGROUP_SUMMARY)
+		display_hostgroup_summary();
+	else if(display_type==DISPLAY_PING)
+		display_ping();
+	else if(display_type==DISPLAY_TRACEROUTE)
+		display_traceroute();
+	else if(display_type==DISPLAY_QUICKSTATS)
+		display_quick_stats();
+	else if(display_type==DISPLAY_PROCESS)
+		display_process();
+	else if(display_type==DISPLAY_ALL_PROBLEMS || display_type==DISPLAY_UNHANDLED_PROBLEMS)
+		display_problems();
+	else
+		display_index();
+
+	document_footer();
+
+	/* free all allocated memory */
+	free_memory();
+
+	return OK;
+        }
+
+
+void document_header(void){
+	char date_time[MAX_DATETIME_LENGTH];
+	time_t expire_time;
+	time_t current_time;
+
+	time(&current_time);
+
+	printf("Cache-Control: no-store\r\n");
+	printf("Pragma: no-cache\r\n");
+
+	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/vnd.wap.wml\r\n\r\n");
+
+	printf("<?xml version=\"1.0\"?>\n");
+	printf("<!DOCTYPE wml PUBLIC \"-//WAPFORUM//DTD WML 1.1//EN\" \"http://www.wapforum.org/DTD/wml_1.1.xml\">\n");
+
+	printf("<wml>\n");
+	
+	printf("<head>\n");
+	printf("<meta forua=\"true\" http-equiv=\"Cache-Control\" content=\"max-age=0\"/>\n");
+	printf("</head>\n");
+
+	return;
+        }
+
+
+void document_footer(void){
+
+	printf("</wml>\n");
+
+	return;
+        }
+
+
+int process_cgivars(void){
+	char **variables;
+	int error=FALSE;
+	int x;
+
+	variables=getcgivars();
+
+	for(x=0;variables[x]!=NULL;x++){
+
+		/* we found the hostgroup argument */
+		if(!strcmp(variables[x],"hostgroup")){
+			display_type=DISPLAY_HOSTGROUP;
+			x++;
+			if(variables[x]==NULL){
+				error=TRUE;
+				break;
+			        }
+
+			hostgroup_name=(char *)malloc(strlen(variables[x])+1);
+			if(hostgroup_name==NULL)
+				hostgroup_name="";
+			else
+				strcpy(hostgroup_name,variables[x]);
+
+			if(!strcmp(hostgroup_name,"all"))
+				show_all_hostgroups=TRUE;
+			else
+				show_all_hostgroups=FALSE;
+		        }
+
+		/* we found the host argument */
+		else if(!strcmp(variables[x],"host")){
+			display_type=DISPLAY_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]);
+		        }
+
+		/* we found the service argument */
+		else if(!strcmp(variables[x],"service")){
+			display_type=DISPLAY_SERVICE;
+			x++;
+			if(variables[x]==NULL){
+				error=TRUE;
+				break;
+			        }
+
+			service_desc=(char *)malloc(strlen(variables[x])+1);
+			if(service_desc==NULL)
+				service_desc="";
+			else
+				strcpy(service_desc,variables[x]);
+		        }
+
+
+		/* we found the hostgroup style argument */
+		else if(!strcmp(variables[x],"style")){
+			x++;
+			if(variables[x]==NULL){
+				error=TRUE;
+				break;
+			        }
+
+			if(!strcmp(variables[x],"overview"))
+				hostgroup_style=DISPLAY_HOSTGROUP_OVERVIEW;
+			else if(!strcmp(variables[x],"summary"))
+				hostgroup_style=DISPLAY_HOSTGROUP_SUMMARY;
+			else if(!strcmp(variables[x],"servicedetail"))
+				host_style=DISPLAY_HOST_SERVICES;
+			else if(!strcmp(variables[x],"processinfo"))
+				display_type=DISPLAY_PROCESS;
+			else if(!strcmp(variables[x],"aprobs"))
+				display_type=DISPLAY_ALL_PROBLEMS;
+			else if(!strcmp(variables[x],"uprobs"))
+				display_type=DISPLAY_UNHANDLED_PROBLEMS;
+			else
+				display_type=DISPLAY_QUICKSTATS;
+		        }		        
+
+		/* we found the ping argument */
+		else if(!strcmp(variables[x],"ping")){
+			display_type=DISPLAY_PING;
+			x++;
+			if(variables[x]==NULL){
+				error=TRUE;
+				break;
+			        }
+
+			ping_address=(char *)malloc(strlen(variables[x])+1);
+			if(ping_address==NULL)
+				ping_address="";
+			else
+				strcpy(ping_address,variables[x]);
+		        }
+
+		/* we found the traceroute argument */
+		else if(!strcmp(variables[x],"traceroute")){
+			display_type=DISPLAY_TRACEROUTE;
+			x++;
+			if(variables[x]==NULL){
+				error=TRUE;
+				break;
+			        }
+
+			traceroute_address=(char *)malloc(strlen(variables[x])+1);
+			if(traceroute_address==NULL)
+				traceroute_address="";
+			else
+				strcpy(traceroute_address,variables[x]);
+		        }
+
+	        }
+
+	/* free memory allocated to the CGI variables */
+	free_cgivars(variables);
+
+	return error;
+        }
+
+
+
+/* main intro screen */
+void display_index(void){
+
+
+	/**** MAIN MENU SCREEN (CARD 1) ****/
+	printf("<card id='card1' title='Nagios WAP Interface'>\n");
+	printf("<p align='center' mode='nowrap'>\n");
+
+	printf("<b>Nagios</b><br/><b>WAP Interface</b><br/>\n");
+
+	printf("<b><anchor title='Quick Stats'>Quick Stats<go href='%s'><postfield name='style' value='quickstats'/></go></anchor></b><br/>\n",STATUSWML_CGI);
+
+	printf("<b><anchor title='Status Summary'>Status Summary<go href='%s'><postfield name='hostgroup' value='all'/><postfield name='style' value='summary'/></go></anchor></b><br/>\n",STATUSWML_CGI);
+
+	printf("<b><anchor title='Status Overview'>Status Overview<go href='%s'><postfield name='hostgroup' value='all'/><postfield name='style' value='overview'/></go></anchor></b><br/>\n",STATUSWML_CGI);
+
+	printf("<b><anchor title='All Problems'>All Problems<go href='%s'><postfield name='style' value='aprobs'/></go></anchor></b><br/>\n",STATUSWML_CGI);
+
+	printf("<b><anchor title='Unhandled Problems'>Unhandled Problems<go href='%s'><postfield name='style' value='uprobs'/></go></anchor></b><br/>\n",STATUSWML_CGI);
+
+	printf("<b><anchor title='Process Info'>Process Info<go href='%s'><postfield name='style' value='processinfo'/></go></anchor></b><br/>\n",STATUSWML_CGI);
+
+	printf("<b><anchor title='Network Tools'>Tools<go href='#card2'/></anchor></b><br/>\n");
+
+	printf("<b><anchor title='About'>About<go href='#card3'/></anchor></b><br/>\n");
+
+	printf("</p>\n");
+	printf("</card>\n");
+
+
+	/**** TOOLS SCREEN (CARD 2) ****/
+	printf("<card id='card2' title='Network Tools'>\n");
+	printf("<p align='center' mode='nowrap'>\n");
+
+	printf("<b>Network Tools:</b><br/>\n");
+
+	printf("<b><anchor title='Ping Host'>Ping<go href='%s'><postfield name='ping' value=''/></go></anchor></b><br/>\n",STATUSWML_CGI);
+	printf("<b><anchor title='Traceroute'>Traceroute<go href='%s'><postfield name='traceroute' value=''/></go></anchor></b><br/>\n",STATUSWML_CGI);
+	printf("<b><anchor title='View Host'>View Host<go href='#card4'/></anchor></b><br/>\n");
+	printf("<b><anchor title='View Hostgroup'>View Hostgroup<go href='#card5'/></anchor></b><br/>\n");
+
+	printf("</p>\n");
+	printf("</card>\n");
+
+
+	/**** ABOUT SCREEN (CARD 3) ****/
+	printf("<card id='card3' title='About'>\n");
+	printf("<p align='center' mode='nowrap'>\n");
+	printf("<b>About</b><br/>\n");
+	printf("</p>\n");
+
+	printf("<p align='center' mode='wrap'>\n");
+	printf("<b>Nagios %s</b><br/><b>WAP Interface</b><br/>\n",PROGRAM_VERSION);
+	printf("Copyright (C) 2001 Ethan Galstad<br/>\n");
+	printf("nagios at nagios.org<br/><br/>\n");
+	printf("License: <b>GPL</b><br/><br/>\n");
+	printf("Based in part on features found in AskAround's Wireless Network Tools<br/>\n");
+	printf("<b>www.askaround.com</b><br/>\n");
+	printf("</p>\n");
+
+	printf("</card>\n");
+
+
+
+	/**** VIEW HOST SCREEN (CARD 4) ****/
+	printf("<card id='card4' title='View Host'>\n");
+	printf("<p align='center' mode='nowrap'>\n");
+	printf("<b>View Host</b><br/>\n");
+	printf("</p>\n");
+
+	printf("<p align='center' mode='wrap'>\n");
+	printf("<b>Host Name:</b><br/>\n");
+	printf("<input name='hname'/>\n");
+	printf("<do type='accept'>\n");
+	printf("<go href='%s' method='post'><postfield name='host' value='$(hname)'/></go>\n",STATUSWML_CGI);
+	printf("</do>\n");
+	printf("</p>\n");
+
+	printf("</card>\n");
+
+
+
+	/**** VIEW HOSTGROUP SCREEN (CARD 5) ****/
+	printf("<card id='card5' title='View Hostgroup'>\n");
+	printf("<p align='center' mode='nowrap'>\n");
+	printf("<b>View Hostgroup</b><br/>\n");
+	printf("</p>\n");
+
+	printf("<p align='center' mode='wrap'>\n");
+	printf("<b>Hostgroup Name:</b><br/>\n");
+	printf("<input name='gname'/>\n");
+	printf("<do type='accept'>\n");
+	printf("<go href='%s' method='post'><postfield name='hostgroup' value='$(gname)'/><postfield name='style' value='overview'/></go>\n",STATUSWML_CGI);
+	printf("</do>\n");
+	printf("</p>\n");
+
+	printf("</card>\n");
+
+
+	return;
+        }
+
+
+/* displays process info */
+void display_process(void){
+
+
+	/**** MAIN SCREEN (CARD 1) ****/
+	printf("<card id='card1' title='Process Info'>\n");
+	printf("<p align='center' mode='nowrap'>\n");
+	printf("<b>Process Info</b><br/><br/>\n");
+
+	/* check authorization */
+	if(is_authorized_for_system_information(&current_authdata)==FALSE){
+
+		printf("<b>Error: Not authorized for process info!</b>\n");
+		printf("</p>\n");
+		printf("</card>\n");
+		return;
+	        }
+
+	if(nagios_process_state==STATE_OK)
+		printf("Nagios process is running<br/>\n");
+	else
+		printf("<b>Nagios process may not be running</b><br/>\n");
+
+	if(enable_notifications==TRUE)
+		printf("Notifications are enabled<br/>\n");
+	else
+		printf("<b>Notifications are disabled</b><br/>\n");
+
+	if(execute_service_checks==TRUE)
+		printf("Check execution is enabled<br/>\n");
+	else
+		printf("<b>Check execution is disabled</b><br/>\n");
+
+	printf("<br/>\n");
+	printf("<b><anchor title='Process Commands'>Process Commands<go href='#card2'/></anchor></b>\n");
+	printf("</p>\n");
+
+	printf("</card>\n");
+
+
+	/**** COMMANDS SCREEN (CARD 2) ****/
+	printf("<card id='card2' title='Process Commands'>\n");
+	printf("<p align='center' mode='nowrap'>\n");
+	printf("<b>Process Commands</b><br/>\n");
+
+	if(enable_notifications==FALSE)
+		printf("<b><anchor title='Enable Notifications'>Enable Notifications<go href='%s' method='post'><postfield name='cmd_typ' value='%d'/><postfield name='cmd_mod' value='%d'/><postfield name='content' value='wml'/></go></anchor></b><br/>\n",COMMAND_CGI,CMD_ENABLE_NOTIFICATIONS,CMDMODE_COMMIT);
+	else
+		printf("<b><anchor title='Disable Notifications'>Disable Notifications<go href='%s' method='post'><postfield name='cmd_typ' value='%d'/><postfield name='cmd_mod' value='%d'/><postfield name='content' value='wml'/></go></anchor></b><br/>\n",COMMAND_CGI,CMD_DISABLE_NOTIFICATIONS,CMDMODE_COMMIT);
+
+	if(execute_service_checks==FALSE)
+		printf("<b><anchor title='Enable Check Execution'>Enable Check Execution<go href='%s' method='post'><postfield name='cmd_typ' value='%d'/><postfield name='cmd_mod' value='%d'/><postfield name='content' value='wml'/></go></anchor></b><br/>\n",COMMAND_CGI,CMD_START_EXECUTING_SVC_CHECKS,CMDMODE_COMMIT);
+	else
+		printf("<b><anchor title='Disable Check Execution'>Disable Check Execution<go href='%s' method='post'><postfield name='cmd_typ' value='%d'/><postfield name='cmd_mod' value='%d'/><postfield name='content' value='wml'/></go></anchor></b><br/>\n",COMMAND_CGI,CMD_STOP_EXECUTING_SVC_CHECKS,CMDMODE_COMMIT);
+
+	printf("</p>\n");
+
+	printf("</card>\n");
+
+
+	return;
+        }
+
+
+
+/* displays quick stats */
+void display_quick_stats(void){
+	host *temp_host;
+	hoststatus *temp_hoststatus;
+	service *temp_service;
+	servicestatus *temp_servicestatus;
+	int hosts_unreachable=0;
+	int hosts_down=0;
+	int hosts_up=0;
+	int hosts_pending=0;
+	int services_critical=0;
+	int services_unknown=0;
+	int services_warning=0;
+	int services_ok=0;
+	int services_pending=0;
+
+
+	/**** MAIN SCREEN (CARD 1) ****/
+	printf("<card id='card1' title='Quick Stats'>\n");
+	printf("<p align='center' mode='nowrap'>\n");
+	printf("<b>Quick Stats</b><br/>\n");
+	printf("</p>\n");
+
+	/* check all hosts */
+	for(temp_host=host_list;temp_host!=NULL;temp_host=temp_host->next){
+
+		if(is_authorized_for_host(temp_host,&current_authdata)==FALSE)
+			continue;
+
+		temp_hoststatus=find_hoststatus(temp_host->name);
+		if(temp_hoststatus==NULL)
+			continue;
+
+		if(temp_hoststatus->status==HOST_UNREACHABLE)
+			hosts_unreachable++;
+		else if(temp_hoststatus->status==HOST_DOWN)
+			hosts_down++;
+		else if(temp_hoststatus->status==HOST_PENDING)
+			hosts_pending++;
+		else
+			hosts_up++;
+	        }
+
+	/* check all services */
+	for(temp_service=service_list;temp_service!=NULL;temp_service=temp_service->next){
+
+		if(is_authorized_for_service(temp_service,&current_authdata)==FALSE)
+			continue;
+
+		temp_servicestatus=find_servicestatus(temp_service->host_name,temp_service->description);
+		if(temp_servicestatus==NULL)
+			continue;
+
+		if(temp_servicestatus->status==SERVICE_CRITICAL)
+			services_critical++;
+		else if(temp_servicestatus->status==SERVICE_UNKNOWN)
+			services_unknown++;
+		else if(temp_servicestatus->status==SERVICE_WARNING)
+			services_warning++;
+		else if(temp_servicestatus->status==SERVICE_PENDING)
+			services_pending++;
+		else
+			services_ok++;
+	        }
+
+	printf("<p align='left' mode='nowrap'>\n");
+
+	printf("<b>Host Totals</b>:<br/>\n");
+	printf("%d UP<br/>\n",hosts_up);
+	printf("%d DOWN<br/>\n",hosts_down);
+	printf("%d UNREACHABLE<br/>\n",hosts_unreachable);
+	printf("%d PENDING<br/>\n",hosts_pending);
+
+	printf("<br/>\n");
+	
+	printf("<b>Service Totals:</b><br/>\n");
+	printf("%d OK<br/>\n",services_ok);
+	printf("%d WARNING<br/>\n",services_warning);
+	printf("%d UNKNOWN<br/>\n",services_unknown);
+	printf("%d CRITICAL<br/>\n",services_critical);
+	printf("%d PENDING<br/>\n",services_pending);
+	
+	printf("</p>\n");
+
+	printf("</card>\n");
+
+	return;
+        }
+
+
+
+/* displays hostgroup status overview */
+void display_hostgroup_overview(void){
+	hostgroup *temp_hostgroup;
+	hostgroupmember *temp_member;
+	host *temp_host;
+	hoststatus *temp_hoststatus;
+
+	
+	/**** MAIN SCREEN (CARD 1) ****/
+	printf("<card id='card1' title='Status Overview'>\n");
+	printf("<p align='center' mode='nowrap'>\n");
+
+	printf("<b><anchor title='Status Overview'>Status Overview<go href='%s' method='post'><postfield name='hostgroup' value='%s'/><postfield name='style' value='summary'/></go></anchor></b><br/><br/>\n",STATUSWML_CGI,hostgroup_name);
+
+	/* check all hostgroups */
+	for(temp_hostgroup=hostgroup_list;temp_hostgroup!=NULL;temp_hostgroup=temp_hostgroup->next){
+
+		if(show_all_hostgroups==FALSE && strcmp(temp_hostgroup->group_name,hostgroup_name))
+			continue;
+
+		if(is_authorized_for_hostgroup(temp_hostgroup,&current_authdata)==FALSE)
+			continue;
+
+		printf("<b>%s</b>\n",temp_hostgroup->alias);
+
+		printf("<table columns='2' align='LL'>\n");
+
+		/* check all hosts in this hostgroup */
+		for(temp_member=temp_hostgroup->members;temp_member!=NULL;temp_member=temp_member->next){
+
+			temp_host=find_host(temp_member->host_name);
+			if(temp_host==NULL)
+				continue;
+
+			if(is_host_member_of_hostgroup(temp_hostgroup,temp_host)==FALSE)
+				continue;
+
+			temp_hoststatus=find_hoststatus(temp_host->name);
+			if(temp_hoststatus==NULL)
+				continue;
+
+			printf("<tr><td><anchor title='%s'>",temp_host->name);
+			if(temp_hoststatus->status==HOST_UP)
+				printf("UP");
+			else if(temp_hoststatus->status==HOST_PENDING)
+				printf("PND");
+			else if(temp_hoststatus->status==HOST_DOWN)
+				printf("DWN");
+			else if(temp_hoststatus->status==HOST_UNREACHABLE)
+				printf("UNR");
+			else
+				printf("???");
+			printf("<go href='%s' method='post'><postfield name='host' value='%s'/></go></anchor></td>",STATUSWML_CGI,temp_host->name);
+			printf("<td>%s</td></tr>\n",temp_host->name);
+		        }
+
+		printf("</table>\n");
+
+		printf("<br/>\n");
+	        }
+
+	if(show_all_hostgroups==FALSE)
+		printf("<b><anchor title='View All Hostgroups'>View All Hostgroups<go href='%s' method='post'><postfield name='hostgroup' value='all'/><postfield name='style' value='overview'/></go></anchor></b>\n",STATUSWML_CGI);
+
+	printf("</p>\n");
+	printf("</card>\n");
+
+	return;
+        }
+
+
+/* displays hostgroup status summary */
+void display_hostgroup_summary(void){
+	hostgroup *temp_hostgroup;
+	hostgroupmember *temp_member;
+	host *temp_host;
+	hoststatus *temp_hoststatus;
+	service *temp_service;
+	servicestatus *temp_servicestatus;
+	int hosts_unreachable=0;
+	int hosts_down=0;
+	int hosts_up=0;
+	int hosts_pending=0;
+	int services_critical=0;
+	int services_unknown=0;
+	int services_warning=0;
+	int services_ok=0;
+	int services_pending=0;
+	int found=0;
+
+
+	/**** MAIN SCREEN (CARD 1) ****/
+	printf("<card id='card1' title='Status Summary'>\n");
+	printf("<p align='center' mode='nowrap'>\n");
+
+	printf("<b><anchor title='Status Summary'>Status Summary<go href='%s' method='post'><postfield name='hostgroup' value='%s'/><postfield name='style' value='overview'/></go></anchor></b><br/><br/>\n",STATUSWML_CGI,hostgroup_name);
+
+	/* check all hostgroups */
+	for(temp_hostgroup=hostgroup_list;temp_hostgroup!=NULL;temp_hostgroup=temp_hostgroup->next){
+
+		if(show_all_hostgroups==FALSE && strcmp(temp_hostgroup->group_name,hostgroup_name))
+			continue;
+
+		if(is_authorized_for_hostgroup(temp_hostgroup,&current_authdata)==FALSE)
+			continue;
+
+		printf("<b><anchor title='%s'>%s<go href='%s' method='post'><postfield name='hostgroup' value='%s'/><postfield name='style' value='overview'/></go></anchor></b>\n",temp_hostgroup->group_name,temp_hostgroup->alias,STATUSWML_CGI,temp_hostgroup->group_name);
+
+		printf("<table columns='2' align='LL'>\n");
+
+		hosts_up=0;
+		hosts_pending=0;
+		hosts_down=0;
+		hosts_unreachable=0;
+
+		services_ok=0;
+		services_pending=0;
+		services_warning=0;
+		services_unknown=0;
+		services_critical=0;
+
+		/* check all hosts in this hostgroup */
+		for(temp_member=temp_hostgroup->members;temp_member!=NULL;temp_member=temp_member->next){
+
+			temp_host=find_host(temp_member->host_name);
+			if(temp_host==NULL)
+				continue;
+
+			if(is_host_member_of_hostgroup(temp_hostgroup,temp_host)==FALSE)
+				continue;
+
+			temp_hoststatus=find_hoststatus(temp_host->name);
+			if(temp_hoststatus==NULL)
+				continue;
+
+			if(temp_hoststatus->status==HOST_UNREACHABLE)
+				hosts_unreachable++;
+			else if(temp_hoststatus->status==HOST_DOWN)
+				hosts_down++;
+			else if(temp_hoststatus->status==HOST_PENDING)
+				hosts_pending++;
+			else
+				hosts_up++;
+
+			/* check all services on this host */
+			for(temp_service=service_list;temp_service!=NULL;temp_service=temp_service->next){
+
+				if(strcmp(temp_service->host_name,temp_host->name))
+					continue;
+
+				if(is_authorized_for_service(temp_service,&current_authdata)==FALSE)
+					continue;
+
+				temp_servicestatus=find_servicestatus(temp_service->host_name,temp_service->description);
+				if(temp_servicestatus==NULL)
+					continue;
+
+				if(temp_servicestatus->status==SERVICE_CRITICAL)
+					services_critical++;
+				else if(temp_servicestatus->status==SERVICE_UNKNOWN)
+					services_unknown++;
+				else if(temp_servicestatus->status==SERVICE_WARNING)
+					services_warning++;
+				else if(temp_servicestatus->status==SERVICE_PENDING)
+					services_pending++;
+				else
+					services_ok++;
+			        }
+		        }
+
+		printf("<tr><td>Hosts:</td><td>");
+		found=0;
+		if(hosts_unreachable>0){
+			printf("%d UNR",hosts_unreachable);
+			found=1;
+		        }
+		if(hosts_down>0){
+			printf("%s%d DWN",(found==1)?", ":"",hosts_down);
+			found=1;
+		        }
+		if(hosts_pending>0){
+			printf("%s%d PND",(found==1)?", ":"",hosts_pending);
+			found=1;
+		        }
+		printf("%s%d UP",(found==1)?", ":"",hosts_up);
+		printf("</td></tr>\n");
+		printf("<tr><td>Services:</td><td>");
+		found=0;
+		if(services_critical>0){
+			printf("%d CRI",services_critical);
+			found=1;
+		        }
+		if(services_warning>0){
+			printf("%s%d WRN",(found==1)?", ":"",services_warning);
+			found=1;
+		        }
+		if(services_unknown>0){
+			printf("%s%d UNK",(found==1)?", ":"",services_unknown);
+			found=1;
+		        }
+		if(services_pending>0){
+			printf("%s%d PND",(found==1)?", ":"",services_pending);
+			found=1;
+		        }
+		printf("%s%d OK",(found==1)?", ":"",services_ok);
+		printf("</td></tr>\n");
+
+		printf("</table>\n");
+
+		printf("<br/>\n");
+	        }
+
+	if(show_all_hostgroups==FALSE)
+		printf("<b><anchor title='View All Hostgroups'>View All Hostgroups<go href='%s' method='post'><postfield name='hostgroup' value='all'/><postfield name='style' value='summary'/></go></anchor></b>\n",STATUSWML_CGI);
+	
+	printf("</p>\n");
+
+	printf("</card>\n");
+
+	return;
+        } 
+
+
+
+/* displays host status */
+void display_host(void){
+	host *temp_host;
+	hoststatus *temp_hoststatus;
+	char last_check[MAX_DATETIME_LENGTH];
+	int days;
+	int hours;
+	int minutes;
+	int seconds;
+	time_t current_time;
+	time_t t;
+	char state_duration[48];
+	int found;
+
+	/**** MAIN SCREEN (CARD 1) ****/
+	printf("<card id='card1' title='Host Status'>\n");
+	printf("<p align='center' mode='nowrap'>\n");
+	printf("<b>Host '%s'</b><br/>\n",host_name);
+
+	/* find the host */
+	temp_host=find_host(host_name);
+	temp_hoststatus=find_hoststatus(host_name);
+	if(temp_host==NULL || temp_hoststatus==NULL){
+
+		printf("<b>Error: Could not find host!</b>\n");
+		printf("</p>\n");
+		printf("</card>\n");
+		return;
+	        }
+
+	/* check authorization */
+	if(is_authorized_for_host(temp_host,&current_authdata)==FALSE){
+
+		printf("<b>Error: Not authorized for host!</b>\n");
+		printf("</p>\n");
+		printf("</card>\n");
+		return;
+	        }
+
+
+	printf("<table columns='2' align='LL'>\n");
+
+	printf("<tr><td>Status:</td><td>");
+	if(temp_hoststatus->status==HOST_UP)
+		printf("UP");
+	else if(temp_hoststatus->status==HOST_PENDING)
+		printf("PENDING");
+	else if(temp_hoststatus->status==HOST_DOWN)
+		printf("DOWN");
+	else if(temp_hoststatus->status==HOST_UNREACHABLE)
+		printf("UNREACHABLE");
+	else
+		printf("?");
+	printf("</td></tr>\n");
+
+	printf("<tr><td>Info:</td><td>%s</td></tr>\n",temp_hoststatus->plugin_output);
+
+	get_time_string(&temp_hoststatus->last_check,last_check,sizeof(last_check)-1,SHORT_DATE_TIME);
+	printf("<tr><td>Last Check:</td><td>%s</td></tr>\n",last_check);
+
+	current_time=time(NULL);
+	if(temp_hoststatus->last_state_change==(time_t)0)
+		t=current_time-program_start;
+	else
+		t=current_time-temp_hoststatus->last_state_change;
+	get_time_breakdown((unsigned long)t,&days,&hours,&minutes,&seconds);
+	snprintf(state_duration,sizeof(state_duration)-1,"%2dd %2dh %2dm %2ds%s",days,hours,minutes,seconds,(temp_hoststatus->last_state_change==(time_t)0)?"+":"");
+	printf("<tr><td>Duration:</td><td>%s</td></tr>\n",state_duration);
+
+	printf("<tr><td>Properties:</td><td>");
+	found=0;
+	if(temp_hoststatus->checks_enabled==FALSE){
+		printf("%sChecks disabled",(found==1)?", ":"");
+		found=1;
+	        }
+	if(temp_hoststatus->notifications_enabled==FALSE){
+		printf("%sNotifications disabled",(found==1)?", ":"");
+		found=1;
+	        }
+	if(temp_hoststatus->problem_has_been_acknowledged==TRUE){
+		printf("%sProblem acknowledged",(found==1)?", ":"");
+		found=1;
+	        }
+	if(temp_hoststatus->scheduled_downtime_depth>0){
+		printf("%sIn scheduled downtime",(found==1)?", ":"");
+		found=1;
+	        }
+	if(found==0)
+		printf("N/A");
+	printf("</td></tr>\n");
+
+	printf("</table>\n");
+	printf("<br/>\n");
+	printf("<b><anchor title='View Services'>View Services<go href='%s' method='post'><postfield name='host' value='%s'/><postfield name='style' value='servicedetail'/></go></anchor></b>\n",STATUSWML_CGI,host_name);
+	printf("<b><anchor title='Host Commands'>Host Commands<go href='#card2'/></anchor></b>\n");
+	printf("</p>\n");
+
+	printf("</card>\n");
+
+
+	/**** COMMANDS SCREEN (CARD 2) ****/
+	printf("<card id='card2' title='Host Commands'>\n");
+	printf("<p align='center' mode='nowrap'>\n");
+	printf("<b>Host Commands</b><br/>\n");
+
+	printf("<b><anchor title='Ping Host'>Ping Host<go href='%s' method='post'><postfield name='ping' value='%s'/></go></anchor></b>\n",STATUSWML_CGI,temp_host->address);
+	printf("<b><anchor title='Traceroute'>Traceroute<go href='%s' method='post'><postfield name='traceroute' value='%s'/></go></anchor></b>\n",STATUSWML_CGI,temp_host->address);
+
+	if(temp_hoststatus->status!=HOST_UP && temp_hoststatus->status!=HOST_PENDING)
+		printf("<b><anchor title='Acknowledge Problem'>Acknowledge Problem<go href='#card3'/></anchor></b>\n");
+
+	if(temp_hoststatus->checks_enabled==FALSE)
+		printf("<b><anchor title='Enable Host Checks'>Enable Host Checks<go href='%s' method='post'><postfield name='host' value='%s'/><postfield name='cmd_typ' value='%d'/><postfield name='cmd_mod' value='%d'/><postfield name='content' value='wml'/></go></anchor></b><br/>\n",COMMAND_CGI,host_name,CMD_ENABLE_HOST_CHECK,CMDMODE_COMMIT);
+	else
+		printf("<b><anchor title='Disable Host Checks'>Disable Host Checks<go href='%s' method='post'><postfield name='host' value='%s'/><postfield name='cmd_typ' value='%d'/><postfield name='cmd_mod' value='%d'/><postfield name='content' value='wml'/></go></anchor></b><br/>\n",COMMAND_CGI,host_name,CMD_DISABLE_HOST_CHECK,CMDMODE_COMMIT);
+
+	if(temp_hoststatus->notifications_enabled==FALSE)
+		printf("<b><anchor title='Enable Host Notifications'>Enable Host Notifications<go href='%s' method='post'><postfield name='host' value='%s'/><postfield name='cmd_typ' value='%d'/><postfield name='cmd_mod' value='%d'/><postfield name='content' value='wml'/></go></anchor></b><br/>\n",COMMAND_CGI,host_name,CMD_ENABLE_HOST_NOTIFICATIONS,CMDMODE_COMMIT);
+	else
+		printf("<b><anchor title='Disable Host Notifications'>Disable Host Notifications<go href='%s' method='post'><postfield name='host' value='%s'/><postfield name='cmd_typ' value='%d'/><postfield name='cmd_mod' value='%d'/><postfield name='content' value='wml'/></go></anchor></b><br/>\n",COMMAND_CGI,host_name,CMD_DISABLE_HOST_NOTIFICATIONS,CMDMODE_COMMIT);
+
+
+	printf("<b><anchor title='Enable All Service Checks'>Enable All Service Checks<go href='%s' method='post'><postfield name='host' value='%s'/><postfield name='cmd_typ' value='%d'/><postfield name='cmd_mod' value='%d'/><postfield name='content' value='wml'/></go></anchor></b><br/>\n",COMMAND_CGI,host_name,CMD_ENABLE_HOST_SVC_CHECKS,CMDMODE_COMMIT);
+
+	printf("<b><anchor title='Disable All Service Checks'>Disable All Service Checks<go href='%s' method='post'><postfield name='host' value='%s'/><postfield name='cmd_typ' value='%d'/><postfield name='cmd_mod' value='%d'/><postfield name='content' value='wml'/></go></anchor></b><br/>\n",COMMAND_CGI,host_name,CMD_DISABLE_HOST_SVC_CHECKS,CMDMODE_COMMIT);
+
+	printf("<b><anchor title='Enable All Service Notifications'>Enable All Service Notifications<go href='%s' method='post'><postfield name='host' value='%s'/><postfield name='cmd_typ' value='%d'/><postfield name='cmd_mod' value='%d'/><postfield name='content' value='wml'/></go></anchor></b><br/>\n",COMMAND_CGI,host_name,CMD_ENABLE_HOST_SVC_NOTIFICATIONS,CMDMODE_COMMIT);
+
+	printf("<b><anchor title='Disable All Service Notifications'>Disable All Service Notifications<go href='%s' method='post'><postfield name='host' value='%s'/><postfield name='cmd_typ' value='%d'/><postfield name='cmd_mod' value='%d'/><postfield name='content' value='wml'/></go></anchor></b><br/>\n",COMMAND_CGI,host_name,CMD_DISABLE_HOST_SVC_NOTIFICATIONS,CMDMODE_COMMIT);
+
+	printf("</p>\n");
+
+	printf("</card>\n");
+
+
+	/**** ACKNOWLEDGEMENT SCREEN (CARD 3) ****/
+	printf("<card id='card3' title='Acknowledge Problem'>\n");
+	printf("<p align='center' mode='nowrap'>\n");
+	printf("<b>Acknowledge Problem</b><br/>\n");
+	printf("</p>\n");
+
+	printf("<p align='center' mode='wrap'>\n");
+	printf("<b>Your Name:</b><br/>\n");
+	printf("<input name='name'/><br/>\n");
+	printf("<b>Comment:</b><br/>\n");
+	printf("<input name='comment'/>\n");
+
+	printf("<do type='accept'>\n");
+	printf("<go href='%s' method='post'><postfield name='host' value='%s'/><postfield name='com_author' value='$(name)'/><postfield name='com_data' value='$(comment)'/><postfield name='persistent' value=''/><postfield name='send_notification' value=''/><postfield name='cmd_typ' value='%d'/><postfield name='cmd_mod' value='%d'/><postfield name='content' value='wml'/></go>\n",COMMAND_CGI,host_name,CMD_ACKNOWLEDGE_HOST_PROBLEM,CMDMODE_COMMIT);
+	printf("</do>\n");
+
+	printf("</p>\n");
+
+	printf("</card>\n");
+
+	return;
+        }
+
+
+
+/* displays services on a host */
+void display_host_services(void){
+	service *temp_service;
+	servicestatus *temp_servicestatus;
+
+	/**** MAIN SCREEN (CARD 1) ****/
+	printf("<card id='card1' title='Host Services'>\n");
+	printf("<p align='center' mode='nowrap'>\n");
+	printf("<b>Host <anchor title='%s'>'%s'<go href='%s' method='post'><postfield name='host' value='%s'/></go></anchor> Services</b><br/>\n",host_name,host_name,STATUSWML_CGI,host_name);
+
+	printf("<table columns='2' align='LL'>\n");
+
+	/* check all services */
+	for(temp_service=service_list;temp_service!=NULL;temp_service=temp_service->next){
+
+		if(strcmp(temp_service->host_name,host_name))
+			continue;
+
+		if(is_authorized_for_service(temp_service,&current_authdata)==FALSE)
+			continue;
+
+		temp_servicestatus=find_servicestatus(temp_service->host_name,temp_service->description);
+		if(temp_servicestatus==NULL)
+			continue;
+
+		printf("<tr><td><anchor title='%s'>",temp_service->description);
+		if(temp_servicestatus->status==SERVICE_OK)
+			printf("OK");
+		else if(temp_servicestatus->status==SERVICE_PENDING)
+			printf("PND");
+		else if(temp_servicestatus->status==SERVICE_WARNING)
+			printf("WRN");
+		else if(temp_servicestatus->status==SERVICE_UNKNOWN)
+			printf("UNK");
+		else if(temp_servicestatus->status==SERVICE_CRITICAL)
+			printf("CRI");
+		else
+			printf("???");
+
+		printf("<go href='%s' method='post'><postfield name='host' value='%s'/><postfield name='service' value='%s'/></go></anchor></td>",STATUSWML_CGI,temp_service->host_name,temp_service->description);
+		printf("<td>%s</td></tr>\n",temp_service->description);
+	        }
+
+	printf("</table>\n");
+
+	printf("</p>\n");
+
+	printf("</card>\n");
+
+	return;
+        }
+
+
+
+/* displays service status */
+void display_service(void){
+	service *temp_service;
+	servicestatus *temp_servicestatus;
+	char last_check[MAX_DATETIME_LENGTH];
+	int days;
+	int hours;
+	int minutes;
+	int seconds;
+	time_t current_time;
+	time_t t;
+	char state_duration[48];
+	int found;
+
+	/**** MAIN SCREEN (CARD 1) ****/
+	printf("<card id='card1' title='Service Status'>\n");
+	printf("<p align='center' mode='nowrap'>\n");
+	printf("<b>Service '%s' on host '%s'</b><br/>\n",service_desc,host_name);
+
+	/* find the service */
+	temp_service=find_service(host_name,service_desc);
+	temp_servicestatus=find_servicestatus(host_name,service_desc);
+	if(temp_service==NULL || temp_servicestatus==NULL){
+
+		printf("<b>Error: Could not find service!</b>\n");
+		printf("</p>\n");
+		printf("</card>\n");
+		return;
+	        }
+
+	/* check authorization */
+	if(is_authorized_for_service(temp_service,&current_authdata)==FALSE){
+
+		printf("<b>Error: Not authorized for service!</b>\n");
+		printf("</p>\n");
+		printf("</card>\n");
+		return;
+	        }
+
+
+	printf("<table columns='2' align='LL'>\n");
+
+	printf("<tr><td>Status:</td><td>");
+	if(temp_servicestatus->status==SERVICE_OK)
+		printf("OK");
+	else if(temp_servicestatus->status==SERVICE_PENDING)
+		printf("PENDING");
+	else if(temp_servicestatus->status==SERVICE_WARNING)
+		printf("WARNING");
+	else if(temp_servicestatus->status==SERVICE_UNKNOWN)
+		printf("UNKNOWN");
+	else if(temp_servicestatus->status==SERVICE_CRITICAL)
+		printf("CRITICAL");
+	else
+		printf("?");
+	printf("</td></tr>\n");
+
+	printf("<tr><td>Info:</td><td>%s</td></tr>\n",temp_servicestatus->plugin_output);
+
+	get_time_string(&temp_servicestatus->last_check,last_check,sizeof(last_check)-1,SHORT_DATE_TIME);
+	printf("<tr><td>Last Check:</td><td>%s</td></tr>\n",last_check);
+
+	current_time=time(NULL);
+	if(temp_servicestatus->last_state_change==(time_t)0)
+		t=current_time-program_start;
+	else
+		t=current_time-temp_servicestatus->last_state_change;
+	get_time_breakdown((unsigned long)t,&days,&hours,&minutes,&seconds);
+	snprintf(state_duration,sizeof(state_duration)-1,"%2dd %2dh %2dm %2ds%s",days,hours,minutes,seconds,(temp_servicestatus->last_state_change==(time_t)0)?"+":"");
+	printf("<tr><td>Duration:</td><td>%s</td></tr>\n",state_duration);
+
+	printf("<tr><td>Properties:</td><td>");
+	found=0;
+	if(temp_servicestatus->checks_enabled==FALSE){
+		printf("%sChecks disabled",(found==1)?", ":"");
+		found=1;
+	        }
+	if(temp_servicestatus->notifications_enabled==FALSE){
+		printf("%sNotifications disabled",(found==1)?", ":"");
+		found=1;
+	        }
+	if(temp_servicestatus->problem_has_been_acknowledged==TRUE){
+		printf("%sProblem acknowledged",(found==1)?", ":"");
+		found=1;
+	        }
+	if(temp_servicestatus->scheduled_downtime_depth>0){
+		printf("%sIn scheduled downtime",(found==1)?", ":"");
+		found=1;
+	        }
+	if(found==0)
+		printf("N/A");
+	printf("</td></tr>\n");
+
+	printf("</table>\n");
+	printf("<br/>\n");
+	printf("<b><anchor title='View Host'>View Host<go href='%s' method='post'><postfield name='host' value='%s'/></go></anchor></b>\n",STATUSWML_CGI,host_name);
+	printf("<b><anchor title='Service Commands'>Svc. Commands<go href='#card2'/></anchor></b>\n");
+	printf("</p>\n");
+
+	printf("</card>\n");
+
+
+	/**** COMMANDS SCREEN (CARD 2) ****/
+	printf("<card id='card2' title='Service Commands'>\n");
+	printf("<p align='center' mode='nowrap'>\n");
+	printf("<b>Service Commands</b><br/>\n");
+
+	if(temp_servicestatus->status!=SERVICE_OK && temp_servicestatus->status!=SERVICE_PENDING)
+		printf("<b><anchor title='Acknowledge Problem'>Acknowledge Problem<go href='#card3'/></anchor></b>\n");
+
+	if(temp_servicestatus->checks_enabled==FALSE)
+		printf("<b><anchor title='Enable Checks'>Enable Checks<go href='%s' method='post'><postfield name='host' value='%s'/><postfield name='service' value='%s'/><postfield name='cmd_typ' value='%d'/><postfield name='cmd_mod' value='%d'/><postfield name='content' value='wml'/></go></anchor></b><br/>\n",COMMAND_CGI,host_name,service_desc,CMD_ENABLE_SVC_CHECK,CMDMODE_COMMIT);
+	else{
+		printf("<b><anchor title='Disable Checks'>Disable Checks<go href='%s' method='post'><postfield name='host' value='%s'/><postfield name='service' value='%s'/><postfield name='cmd_typ' value='%d'/><postfield name='cmd_mod' value='%d'/><postfield name='content' value='wml'/></go></anchor></b><br/>\n",COMMAND_CGI,host_name,service_desc,CMD_DISABLE_SVC_CHECK,CMDMODE_COMMIT);
+		printf("<b><anchor title='Schedule Immediate Check'>Schedule Immediate Check<go href='%s' method='post'><postfield name='host' value='%s'/><postfield name='service' value='%s'/><postfield name='cmd_typ' value='%d'/><postfield name='cmd_mod' value='%d'/><postfield name='content' value='wml'/></go></anchor></b><br/>\n",COMMAND_CGI,host_name,service_desc,CMD_SCHEDULE_SVC_CHECK,CMDMODE_COMMIT);
+	        }
+
+	if(temp_servicestatus->notifications_enabled==FALSE)
+		printf("<b><anchor title='Enable Notifications'>Enable Notifications<go href='%s' method='post'><postfield name='host' value='%s'/><postfield name='service' value='%s'/><postfield name='cmd_typ' value='%d'/><postfield name='cmd_mod' value='%d'/><postfield name='content' value='wml'/></go></anchor></b><br/>\n",COMMAND_CGI,host_name,service_desc,CMD_ENABLE_SVC_NOTIFICATIONS,CMDMODE_COMMIT);
+	else
+		printf("<b><anchor title='Disable Notifications'>Disable Notifications<go href='%s' method='post'><postfield name='host' value='%s'/><postfield name='service' value='%s'/><postfield name='cmd_typ' value='%d'/><postfield name='cmd_mod' value='%d'/><postfield name='content' value='wml'/></go></anchor></b><br/>\n",COMMAND_CGI,host_name,service_desc,CMD_DISABLE_SVC_NOTIFICATIONS,CMDMODE_COMMIT);
+
+	printf("</p>\n");
+
+	printf("</card>\n");
+
+
+	/**** ACKNOWLEDGEMENT SCREEN (CARD 3) ****/
+	printf("<card id='card3' title='Acknowledge Problem'>\n");
+	printf("<p align='center' mode='nowrap'>\n");
+	printf("<b>Acknowledge Problem</b><br/>\n");
+	printf("</p>\n");
+
+	printf("<p align='center' mode='wrap'>\n");
+	printf("<b>Your Name:</b><br/>\n");
+	printf("<input name='name'/><br/>\n");
+	printf("<b>Comment:</b><br/>\n");
+	printf("<input name='comment'/>\n");
+
+	printf("<do type='accept'>\n");
+	printf("<go href='%s' method='post'><postfield name='host' value='%s'/><postfield name='service' value='%s'/><postfield name='com_author' value='$(name)'/><postfield name='com_data' value='$(comment)'/><postfield name='persistent' value=''/><postfield name='send_notification' value=''/><postfield name='cmd_typ' value='%d'/><postfield name='cmd_mod' value='%d'/><postfield name='content' value='wml'/></go>\n",COMMAND_CGI,host_name,service_desc,CMD_ACKNOWLEDGE_SVC_PROBLEM,CMDMODE_COMMIT);
+	printf("</do>\n");
+
+	printf("</p>\n");
+
+	printf("</card>\n");
+
+	return;
+        }
+
+
+/* displays ping results */
+void display_ping(void){
+	char input_buffer[MAX_INPUT_BUFFER];
+	char buffer[MAX_INPUT_BUFFER];
+	char *temp_ptr;
+	FILE *fp;
+	int odd=0;
+	int in_macro=FALSE;
+
+	/**** MAIN SCREEN (CARD 1) ****/
+	printf("<card id='card1' title='Ping'>\n");
+
+	if(!strcmp(ping_address,"")){
+
+		printf("<p align='center' mode='nowrap'>\n");
+		printf("<b>Ping Host</b><br/>\n");
+		printf("</p>\n");
+
+		printf("<p align='center' mode='wrap'>\n");
+		printf("<b>Host Name/Address:</b><br/>\n");
+		printf("<input name='address'/>\n");
+		printf("<do type='accept'>\n");
+		printf("<go href='%s'><postfield name='ping' value='$(address)'/></go>\n",STATUSWML_CGI);
+		printf("</do>\n");
+		printf("</p>\n");
+	        }
+
+	else{
+
+		printf("<p align='center' mode='nowrap'>\n");
+		printf("<b>Results For Ping Of %s:</b><br/>\n",ping_address);
+		printf("</p>\n");
+
+		printf("<p mode='nowrap'>\n");
+
+		if(ping_syntax==NULL)
+			printf("ping_syntax in CGI config file is NULL!\n");
+	
+		else{
+
+			/* process macros in the ping syntax */
+			strcpy(buffer,"");
+			strncpy(input_buffer,ping_syntax,sizeof(input_buffer)-1);
+			input_buffer[strlen(ping_syntax)-1]='\x0';
+			for(temp_ptr=my_strtok(input_buffer,"$");temp_ptr!=NULL;temp_ptr=my_strtok(NULL,"$")){
+
+				if(in_macro==FALSE){
+					if(strlen(buffer)+strlen(temp_ptr)<sizeof(buffer)-1){
+						strncat(buffer,temp_ptr,sizeof(buffer)-strlen(buffer)-1);
+						buffer[sizeof(buffer)-1]='\x0';
+					        }
+					in_macro=TRUE;
+				        }
+				else{
+
+					if(strlen(buffer)+strlen(temp_ptr) < sizeof(buffer)-1){
+
+						if(!strcmp(temp_ptr,"HOSTADDRESS"))
+							strncat(buffer,ping_address,sizeof(buffer)-strlen(buffer)-1);
+					        }
+
+					in_macro=FALSE;
+				        }
+			        }
+
+			/* run the ping command */
+			fp=popen(buffer,"r");
+			if(fp){
+				while(1){
+					fgets(buffer,sizeof(buffer)-1,fp);
+					if(feof(fp))
+						break;
+
+					strip(buffer);
+
+					if(odd){
+						odd=0;
+						printf("%s<br/>\n",buffer);
+			                        }
+					else{
+						odd=1;
+						printf("<b>%s</b><br/>\n",buffer);
+			                        }
+		                        }
+	                        }
+			else
+				printf("Error executing ping!\n");
+
+			pclose(fp);
+		        }
+
+		printf("</p>\n");
+	        }
+
+	printf("</card>\n");
+
+	return;
+        }
+
+
+/* displays traceroute results */
+void display_traceroute(void){
+	char buffer[MAX_INPUT_BUFFER];
+	FILE *fp;
+	int odd=0;
+
+	/**** MAIN SCREEN (CARD 1) ****/
+	printf("<card id='card1' title='Traceroute'>\n");
+
+	if(!strcmp(traceroute_address,"")){
+
+		printf("<p align='center' mode='nowrap'>\n");
+		printf("<b>Traceroute</b><br/>\n");
+		printf("</p>\n");
+
+		printf("<p align='center' mode='wrap'>\n");
+		printf("<b>Host Name/Address:</b><br/>\n");
+		printf("<input name='address'/>\n");
+		printf("<do type='accept'>\n");
+		printf("<go href='%s'><postfield name='traceroute' value='$(address)'/></go>\n",STATUSWML_CGI);
+		printf("</do>\n");
+		printf("</p>\n");
+	        }
+
+	else{
+
+		printf("<p align='center' mode='nowrap'>\n");
+		printf("<b>Results For Traceroute To %s:</b><br/>\n",traceroute_address);
+		printf("</p>\n");
+
+		printf("<p mode='nowrap'>\n");
+	
+		snprintf(buffer,sizeof(buffer)-1,"%s %s",TRACEROUTE_COMMAND,traceroute_address);
+		buffer[sizeof(buffer)-1]='\x0';
+
+		fp=popen(buffer,"r");
+		if(fp){
+			while(1){
+				fgets(buffer,sizeof(buffer)-1,fp);
+				if(feof(fp))
+					break;
+
+				strip(buffer);
+
+				if(odd){
+					odd=0;
+					printf("%s<br/>\n",buffer);
+			                }
+				else{
+					odd=1;
+					printf("<b>%s</b><br/>\n",buffer);
+			                }
+		               }
+	                }
+		else
+			printf("Error executing traceroute!\n");
+
+		pclose(fp);
+
+		printf("</p>\n");
+	        }
+
+	printf("</card>\n");
+
+	return;
+        }
+
+
+
+/* displays problems */
+void display_problems(void){
+	host *temp_host;
+	service *temp_service;
+	hoststatus *temp_hoststatus;
+	int total_host_problems=0;
+	servicestatus *temp_servicestatus;
+	int total_service_problems=0;
+
+	/**** MAIN SCREEN (CARD 1) ****/
+	printf("<card id='card1' title='%s Problems'>\n",(display_type==DISPLAY_ALL_PROBLEMS)?"All":"Unhandled");
+	printf("<p align='center' mode='nowrap'>\n");
+	printf("<b>%s Problems</b><br/><br/>\n",(display_type==DISPLAY_ALL_PROBLEMS)?"All":"Unhandled");
+
+	printf("<b>Host Problems:</b>\n");
+
+	printf("<table columns='2' align='LL'>\n");
+
+	/* check all hosts */
+	for(temp_hoststatus=hoststatus_list;temp_hoststatus!=NULL;temp_hoststatus=temp_hoststatus->next){
+
+		temp_host=find_host(temp_hoststatus->host_name);
+		if(temp_host==NULL)
+			continue;
+
+		if(is_authorized_for_host(temp_host,&current_authdata)==FALSE)
+			continue;
+
+		if(temp_hoststatus->status==HOST_UP || temp_hoststatus->status==HOST_PENDING)
+			continue;
+
+		if(display_type==DISPLAY_UNHANDLED_PROBLEMS){
+			if(temp_hoststatus->problem_has_been_acknowledged==TRUE)
+				continue;
+			if(temp_hoststatus->notifications_enabled==FALSE)
+				continue;
+			if(temp_hoststatus->scheduled_downtime_depth>0)
+				continue;
+		        }
+
+		total_host_problems++;
+
+		printf("<tr><td><anchor title='%s'>",temp_host->name);
+		if(temp_hoststatus->status==HOST_DOWN)
+			printf("DWN");
+		else if(temp_hoststatus->status==HOST_UNREACHABLE)
+			printf("UNR");
+		else
+			printf("???");
+		printf("<go href='%s' method='post'><postfield name='host' value='%s'/></go></anchor></td>",STATUSWML_CGI,temp_host->name);
+		printf("<td>%s</td></tr>\n",temp_host->name);
+	        }
+
+	if(total_host_problems==0)
+		printf("<tr><td>No problems</td></tr>\n");
+
+	printf("</table>\n");
+
+	printf("<br/>\n");
+
+
+	printf("<b>Svc Problems:</b>\n");
+
+	printf("<table columns='2' align='LL'>\n");
+
+	/* check all services */
+	for(temp_servicestatus=servicestatus_list;temp_servicestatus!=NULL;temp_servicestatus=temp_servicestatus->next){
+		
+		temp_service=find_service(temp_servicestatus->host_name,temp_servicestatus->description);
+		if(temp_service==NULL)
+			continue;
+
+		if(is_authorized_for_service(temp_service,&current_authdata)==FALSE)
+			continue;
+
+		if(temp_servicestatus->status==SERVICE_OK || temp_servicestatus->status==SERVICE_PENDING)
+			continue;
+
+		if(display_type==DISPLAY_UNHANDLED_PROBLEMS){
+			if(temp_servicestatus->problem_has_been_acknowledged==TRUE)
+				continue;
+			if(temp_servicestatus->notifications_enabled==FALSE)
+				continue;
+			if(temp_servicestatus->scheduled_downtime_depth>0)
+				continue;
+			if((temp_hoststatus=find_hoststatus(temp_service->host_name))){
+				if(temp_hoststatus->scheduled_downtime_depth>0)
+					continue;
+				if(temp_hoststatus->problem_has_been_acknowledged==TRUE)
+					continue;
+				}
+		        }
+
+		total_service_problems++;
+
+		printf("<tr><td><anchor title='%s'>",temp_servicestatus->description);
+		if(temp_servicestatus->status==SERVICE_CRITICAL)
+			printf("CRI");
+		else if(temp_servicestatus->status==SERVICE_WARNING)
+			printf("WRN");
+		else if(temp_servicestatus->status==SERVICE_UNKNOWN)
+			printf("UNK");
+		else
+			printf("???");
+		printf("<go href='%s' method='post'><postfield name='host' value='%s'/><postfield name='service' value='%s'/></go></anchor></td>",STATUSWML_CGI,temp_service->host_name,temp_service->description);
+		printf("<td>%s/%s</td></tr>\n",temp_service->host_name,temp_service->description);
+	        }
+
+	if(total_service_problems==0)
+		printf("<tr><td>No problems</td></tr>\n");
+
+	printf("</table>\n");
+
+	printf("</p>\n");
+
+	printf("</card>\n");
+
+	return;
+        }
+
+
+
diff -urNad nagios2-2.6~/cgi/statuswml.c.rej nagios2-2.6/cgi/statuswml.c.rej
--- nagios2-2.6~/cgi/statuswml.c.rej	1970-01-01 00:00:00.000000000 +0000
+++ nagios2-2.6/cgi/statuswml.c.rej	2008-05-26 16:01:40.000000000 +0000
@@ -0,0 +1,22 @@
+@@ -1153,16 +1153,16 @@ void display_service(void){
+ 		printf("<b><anchor title='Acknowledge Problem'>Acknowledge Problem<go href='#card3'/></anchor></b>\n");
+ 
+ 	if(temp_servicestatus->checks_enabled==FALSE)
+-		printf("<b><anchor title='Enable Checks'>Enable Checks<go href='%s' method='post'><postfield name='host' value='%s'/><postfield name='service' value='%s'/><postfield name='cmd_typ' value='%d'/><postfield name='cmd_mod' value='%d'/><postfield name='content' value='wml'/></go></anchor></b><br/>\n",COMMAND_CGI,host_name,service_desc,CMD_ENABLE_SVC_CHECK,CMDMODE_COMMIT);
++		printf("<b><anchor title='Enable Checks'>Enable Checks<go href='%s' method='post'><postfield name='host' value='%s'/><postfield name='service' value='%s'/><postfield name='cmd_typ' value='%d'/><postfield name='cmd_mod' value='%d'/><postfield name='content' value='wml'/></go></anchor></b><br/>\n",COMMAND_CGI,url_encode(host_name),url_encode(service_desc),CMD_ENABLE_SVC_CHECK,CMDMODE_COMMIT);
+ 	else{
+-		printf("<b><anchor title='Disable Checks'>Disable Checks<go href='%s' method='post'><postfield name='host' value='%s'/><postfield name='service' value='%s'/><postfield name='cmd_typ' value='%d'/><postfield name='cmd_mod' value='%d'/><postfield name='content' value='wml'/></go></anchor></b><br/>\n",COMMAND_CGI,host_name,service_desc,CMD_DISABLE_SVC_CHECK,CMDMODE_COMMIT);
+-		printf("<b><anchor title='Schedule Immediate Check'>Schedule Immediate Check<go href='%s' method='post'><postfield name='host' value='%s'/><postfield name='service' value='%s'/><postfield name='start_time' value='%lu'/><postfield name='cmd_typ' value='%d'/><postfield name='cmd_mod' value='%d'/><postfield name='content' value='wml'/></go></anchor></b><br/>\n",COMMAND_CGI,host_name,service_desc,(unsigned long)current_time,CMD_SCHEDULE_SVC_CHECK,CMDMODE_COMMIT);
++		printf("<b><anchor title='Disable Checks'>Disable Checks<go href='%s' method='post'><postfield name='host' value='%s'/><postfield name='service' value='%s'/><postfield name='cmd_typ' value='%d'/><postfield name='cmd_mod' value='%d'/><postfield name='content' value='wml'/></go></anchor></b><br/>\n",COMMAND_CGI,url_encode(host_name),url_encode(service_desc),CMD_DISABLE_SVC_CHECK,CMDMODE_COMMIT);
++		printf("<b><anchor title='Schedule Immediate Check'>Schedule Immediate Check<go href='%s' method='post'><postfield name='host' value='%s'/><postfield name='service' value='%s'/><postfield name='start_time' value='%lu'/><postfield name='cmd_typ' value='%d'/><postfield name='cmd_mod' value='%d'/><postfield name='content' value='wml'/></go></anchor></b><br/>\n",COMMAND_CGI,url_encode(host_name),url_encode(service_desc),(unsigned long)current_time,CMD_SCHEDULE_SVC_CHECK,CMDMODE_COMMIT);
+ 	        }
+ 
+ 	if(temp_servicestatus->notifications_enabled==FALSE)
+-		printf("<b><anchor title='Enable Notifications'>Enable Notifications<go href='%s' method='post'><postfield name='host' value='%s'/><postfield name='service' value='%s'/><postfield name='cmd_typ' value='%d'/><postfield name='cmd_mod' value='%d'/><postfield name='content' value='wml'/></go></anchor></b><br/>\n",COMMAND_CGI,host_name,service_desc,CMD_ENABLE_SVC_NOTIFICATIONS,CMDMODE_COMMIT);
++		printf("<b><anchor title='Enable Notifications'>Enable Notifications<go href='%s' method='post'><postfield name='host' value='%s'/><postfield name='service' value='%s'/><postfield name='cmd_typ' value='%d'/><postfield name='cmd_mod' value='%d'/><postfield name='content' value='wml'/></go></anchor></b><br/>\n",COMMAND_CGI,url_encode(host_name),url_encode(service_desc),CMD_ENABLE_SVC_NOTIFICATIONS,CMDMODE_COMMIT);
+ 	else
+-		printf("<b><anchor title='Disable Notifications'>Disable Notifications<go href='%s' method='post'><postfield name='host' value='%s'/><postfield name='service' value='%s'/><postfield name='cmd_typ' value='%d'/><postfield name='cmd_mod' value='%d'/><postfield name='content' value='wml'/></go></anchor></b><br/>\n",COMMAND_CGI,host_name,service_desc,CMD_DISABLE_SVC_NOTIFICATIONS,CMDMODE_COMMIT);
++		printf("<b><anchor title='Disable Notifications'>Disable Notifications<go href='%s' method='post'><postfield name='host' value='%s'/><postfield name='service' value='%s'/><postfield name='cmd_typ' value='%d'/><postfield name='cmd_mod' value='%d'/><postfield name='content' value='wml'/></go></anchor></b><br/>\n",COMMAND_CGI,url_encode(host_name),url_encode(service_desc),CMD_DISABLE_SVC_NOTIFICATIONS,CMDMODE_COMMIT);
+ 
+ 	printf("</p>\n");
+ 
diff -urNad nagios2-2.6~/cgi/trends.c nagios2-2.6/cgi/trends.c
--- nagios2-2.6~/cgi/trends.c	2006-03-21 21:31:47.000000000 +0000
+++ nagios2-2.6/cgi/trends.c	2008-05-26 16:01:40.000000000 +0000
@@ -451,9 +451,9 @@
 				printf("<input type='hidden' name='nomap' value=''>\n");
 			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);
+			printf("<input type='hidden' name='host' value='%s'>\n",url_encode(host_name));
 			if(display_type==DISPLAY_SERVICE_TRENDS)
-				printf("<input type='hidden' name='service' value='%s'>\n",svc_description);
+				printf("<input type='hidden' name='service' value='%s'>\n",url_encode(svc_description));
 
 			printf("<input type='hidden' name='assumeinitialstates' value='%s'>\n",(assume_initial_states==TRUE)?"yes":"no");
 			printf("<input type='hidden' name='assumestateretention' value='%s'>\n",(assume_state_retention==TRUE)?"yes":"no");
@@ -897,9 +897,9 @@
 
 			printf("<TABLE BORDER=0 CELLPADDING=5>\n");
 			printf("<form method=\"GET\" action=\"%s\">\n",TRENDS_CGI);
-			printf("<input type='hidden' name='host' value='%s'>\n",host_name);
+			printf("<input type='hidden' name='host' value='%s'>\n",url_encode(host_name));
 			if(display_type==DISPLAY_SERVICE_TRENDS)
-				printf("<input type='hidden' name='service' value='%s'>\n",svc_description);
+				printf("<input type='hidden' name='service' value='%s'>\n",url_encode(svc_description));
 
 			printf("<tr><td class='reportSelectSubTitle' align=right>Report period:</td>\n");
 			printf("<td class='reportSelectItem'>\n");


More information about the Pkg-nagios-devel mailing list