Large scale network monitoring limits with nagios

michael at optusnet.com.au michael at optusnet.com.au
Fri Mar 12 13:25:15 CET 2004


Noah Leaman <noah at mac.com> writes:
> Hopes it's o.k. cross posting to both groups on this matter...
> 
> Using the concept of one service per up/down trap for each network
> interface, I tested a little by creating a very simple set of nagios
> configs, but with about 8000 PASSIVE service checks and no active
> service checks. of course there was no problem in terms of scheduling
> issues, but the CGIs all crawled to a snails pace. In my setup (nagios
> 1.2, Dual G4 first-gen xServe) it takes about 30 secs to display the
> Status Summary page.

Yes, this is what I'd expect. The problem is that nagios out of the
box has some terrible code in it. In particular, there's a lot of
places (including the display cgi's) that use O(n^2) algorithms.

Some of the time the problem is hidden; Upper level code will 
do "foreach (list) { action }" where 'action' calls a function
also does a linear search of the same list. oops.

Other times the problem is obvious: Code that adds elements
to the end of a singly linked list. By doing a linear
search from the beginning. For each item added. For 12,000
items. oops.

In our local version we create hash tables, and pre/post-sort lists to
work around the worst of the problems.

If you dig through the list archives you'll see the patches that
were sent in to fix it for 1.1.

That still leaves the other big problem with the passive service
checks. Believe it or not, sending a passive result makes nagios
fork()!! The parent process reads the check result, fork()s and then
resends the result again to the parent. Rather wild stuff. :)
Even better is that the child process has to wait around
for the parent to handle the send.

This is normally masked because the main event loop simply
doesn't check the named pipe very frequently, so normally
your external scripts will blow up with massive queues
waiting for nagios to read the pipe.

Nagios out of the box is simply not ready for reasonable
scale yet.

Michael.

Ps. Ok. I saved you some effort. I dug up the local patches:
(Note: I didn't write these)

* Check the named pipe frequently.
* Don't fork() too often when handling passive check results.
* Use hash tables and sorted lists to get rid of most of the
   O(n^2) places.
* Sleep only for a short time in the main loop.
* allow check for auth-smtp.
* fix a few bugs.
* introduces depedancy on glib.





diff -ru nagios-1.1-virgin/base/Makefile.in nagios-1.1/base/Makefile.in
--- nagios-1.1-virgin/base/Makefile.in	Thu Jul 10 08:30:10 2003
+++ nagios-1.1/base/Makefile.in	Tue Oct  7 13:03:51 2003
@@ -10,9 +10,9 @@
 SRC_XDATA=../xdata
 
 CC=@CC@
-CFLAGS=@CFLAGS@ @DEFS@ -DNSCORE
+CFLAGS=@CFLAGS@ @DEFS@ -DNSCORE `pkg-config glib --cflags`
 #CFLAGS=-O3 -Wall -Wshadow -Wpointer-arith -Wcast-qual -Wcast-align -Wstrict-prototypes -Wmissing-prototypes -Wnested-externs -DHAVE_CONFIG_H -DNSCORE
-LDFLAGS=@LDFLAGS@ @LIBS@
+LDFLAGS=@LDFLAGS@ @LIBS@ `pkg-config glib --libs`
 
 prefix=@prefix@
 exec_prefix=@exec_prefix@
diff -ru nagios-1.1-virgin/cgi/Makefile.in nagios-1.1/cgi/Makefile.in
--- nagios-1.1-virgin/cgi/Makefile.in	Thu Jul 10 08:30:10 2003
+++ nagios-1.1/cgi/Makefile.in	Tue Oct  7 13:03:51 2003
@@ -25,9 +25,9 @@
 
 CP=@CP@
 CC=@CC@
-CFLAGS=@CFLAGS@ @DEFS@ -DNSCGI
+CFLAGS=@CFLAGS@ @DEFS@ -DNSCGI `pkg-config glib --cflags`
 #CFLAGS=-O3 -Wall -Wshadow -Wpointer-arith -Wcast-qual -Wcast-align -Wstrict-prototypes -Wmissing-prototypes -Wnested-externs -DHAVE_CONFIG_H -DNSCGI
-LDFLAGS=@LDFLAGS@ @LIBS@
+LDFLAGS=@LDFLAGS@ @LIBS@ `pkg-config glib --libs`
 
 CGIS=avail.cgi cmd.cgi config.cgi extinfo.cgi history.cgi notifications.cgi outages.cgi showlog.cgi status.cgi statuswml.cgi summary.cgi tac.cgi $(CGIEXTRAS)
 
diff -ru nagios-1.1-virgin/common/common.h nagios-1.1/common/common.h
--- nagios-1.1-virgin/common/common.h	Thu Jul 10 08:30:10 2003
+++ nagios-1.1/common/common.h	Tue Oct  7 13:03:51 2003
@@ -208,8 +208,12 @@
 #define	OK				0
 #define ERROR				-2	/* value was changed from -1 so as to not interfere with STATUS_UNKNOWN plugin result */
 
+#ifndef TRUE
 #define TRUE				1
+#endif
+#ifndef FALSE
 #define FALSE				0
+#endif
 
 
 /****************** HOST CONFIG FILE READING OPTIONS ********************/
diff -ru nagios-1.1-virgin/common/config.h.in nagios-1.1/common/config.h.in
--- nagios-1.1-virgin/common/config.h.in	Thu Jul 10 08:30:10 2003
+++ nagios-1.1/common/config.h.in	Tue Oct  7 13:03:51 2003
@@ -214,3 +214,7 @@
 #include <dirent.h>
 #endif
 
+#define HAVE_GLIB_H 1
+#ifdef HAVE_GLIB_H
+#include <glib.h>
+#endif
diff -ru nagios-1.1-virgin/common/objects.c nagios-1.1/common/objects.c
--- nagios-1.1-virgin/common/objects.c	Thu Jul 10 08:30:10 2003
+++ nagios-1.1/common/objects.c	Tue Oct  7 13:03:51 2003
@@ -59,7 +59,10 @@
 servicedependency       *servicedependency_list=NULL;
 hostdependency          *hostdependency_list=NULL;
 hostescalation          *hostescalation_list=NULL;
+GTree			*service_tree = NULL;
+GHashTable	*host_hash = NULL;
 
+int service_list_add(char *key, service *v, void *data);
 
 
 /******************************************************************/
@@ -99,6 +102,8 @@
 	printf("read_object_config_data() end\n");
 #endif
 
+        g_tree_traverse(service_tree, (GTraverseFunc)service_list_add, G_IN_ORDER, NULL);
+
 	return result;
         }
 
@@ -107,6 +112,13 @@
 /**************** OBJECT ADDITION FUNCTIONS ***********************/
 /******************************************************************/
 
+int service_list_add(char *key, service *v, void *data)
+{
+        v->next = service_list;
+        service_list = v;
+        return 0;
+}
+                                                                                                                                                       
 
 
 /* add a new timeperiod to the list in memory */
@@ -747,6 +759,16 @@
 	printf("\tNotification Interval:    %d\n",new_host->notification_interval);
 	printf("\tNotification Time Period: %s\n",new_host->notification_period);
 #endif
+
+#ifdef HAVE_GLIB_H
+	/* Cache host in hash table */
+	if (!host_hash)
+		host_hash = g_hash_table_new(g_str_hash, g_str_equal);
+
+	if (host_hash)
+		g_hash_table_insert(host_hash, new_host->name, new_host);
+#endif
+
 #ifdef DEBUG0
 	printf("add_host() end\n");
 #endif
@@ -2173,40 +2195,7 @@
 	strcpy(new_service->perf_data,"");
 
 #endif
-	/* add new service to service list, sorted by host name then service description */
-	last_service=service_list;
-	for(temp_service=service_list;temp_service!=NULL;temp_service=temp_service->next){
-
-		if(strcmp(new_service->host_name,temp_service->host_name)<0){
-			new_service->next=temp_service;
-			if(temp_service==service_list)
-				service_list=new_service;
-			else
-				last_service->next=new_service;
-			break;
-		        }
-
-		else if(strcmp(new_service->host_name,temp_service->host_name)==0 && strcmp(new_service->description,temp_service->description)<0){
-			new_service->next=temp_service;
-			if(temp_service==service_list)
-				service_list=new_service;
-			else
-				last_service->next=new_service;
-			break;
-		        }
 
-		else
-			last_service=temp_service;
-	        }
-	if(service_list==NULL){
-		new_service->next=NULL;
-		service_list=new_service;
-	        }
-	else if(temp_service==NULL){
-		new_service->next=NULL;
-		last_service->next=new_service;
-	        }
-		
 #ifdef DEBUG1
 	printf("\tHost:                     %s\n",new_service->host_name);
 	printf("\tDescription:              %s\n",new_service->description);
@@ -2222,6 +2211,19 @@
 	printf("\tEvent Handler:            %s\n",(new_service->event_handler==NULL)?"N/A":new_service->event_handler);
 #endif
 
+#ifdef HAVE_GLIB_H
+	/* Cache service in tree */
+	if (!service_tree)
+		service_tree = g_tree_new((GCompareFunc)strcmp);
+
+	if (service_tree)
+	{
+		char *key = calloc(strlen(new_service->host_name) + strlen(new_service->description) + 2, 1);
+		sprintf(key, "%s-%s", new_service->host_name, new_service->description);
+		g_tree_insert(service_tree, key, new_service);
+	}
+#endif
+
 #ifdef DEBUG0
 	printf("add_service() end\n");
 #endif
@@ -3226,6 +3228,13 @@
 	if(name==NULL)
 		return NULL;
 
+#ifdef HAVE_GLIB_H
+	/* Lookup host in the hash */
+	if (host_hash)
+		return (host *)g_hash_table_lookup(host_hash, name);
+#endif
+
+
 	if(hst==NULL)
 		temp_host=host_list;
 	else
@@ -3500,6 +3509,18 @@
 	if(host_name==NULL || svc_desc==NULL)
 		return NULL;
 
+#ifdef HAVE_GLIB_H
+	/* Lookup service in the tree */
+	if (service_tree)
+	{
+		char *key = calloc(strlen(host_name) + strlen(svc_desc) + 2, 1);
+		sprintf(key, "%s-%s", host_name, svc_desc);
+		temp_service = (service *)g_tree_lookup(service_tree, key);
+		free(key);
+		return temp_service;
+	}
+#endif
+
 	if(svcptr==NULL)
 		temp_service=service_list;
 	else
diff -ru nagios-1.1-virgin/common/statusdata.c nagios-1.1/common/statusdata.c
--- nagios-1.1-virgin/common/statusdata.c	Thu Jul 10 08:30:10 2003
+++ nagios-1.1/common/statusdata.c	Tue Oct  7 13:04:12 2003
@@ -51,6 +51,7 @@
 #ifdef NSCGI
 hoststatus      *hoststatus_list=NULL;
 servicestatus   *servicestatus_list=NULL;
+GTree 		*servicestatus_tree=NULL;
 
 time_t program_start;
 int daemon_mode;
@@ -320,6 +321,7 @@
 /******************************************************************/
 
 
+int servicestatus_list_add(servicestatus *key, void *v, void *data);
 /* reads in all status data */
 int read_status_data(char *config_file,int options){
 	int result=OK;
@@ -332,6 +334,7 @@
 	result=xsddb_read_status_data(config_file,options);
 #endif
 
+	g_tree_traverse(servicestatus_tree, (GTraverseFunc)servicestatus_list_add, G_IN_ORDER, NULL);
 	return result;
         }
 
@@ -341,6 +344,12 @@
 /********************** ADDITION FUNCTIONS ************************/
 /******************************************************************/
 
+int servicestatus_list_add(servicestatus *key, void *v, void *data)
+{
+	key->next = servicestatus_list;
+	servicestatus_list = key;
+	return 0;
+}
 
 /* sets program status variables */
 int add_program_status(time_t _program_start, int _nagios_pid, int _daemon_mode, time_t _last_command_check, time_t _last_log_rotation, int _enable_notifications,int _execute_service_checks,int _accept_passive_service_checks,int _enable_event_handlers,int _obsess_over_services, int _enable_flap_detection, int _enable_failure_prediction, int _process_performance_data){
@@ -534,6 +543,16 @@
 	return OK;
         }
 
+int servicestatus_cmp(servicestatus *a, servicestatus *b)
+{
+	int c;
+
+	c = strcmp(b->host_name, a->host_name);
+	if (c)
+		return c;
+
+	return strcmp(b->description, a->description);
+}
 
 /* adds a service status entry to the list in memory */
 int add_service_status(char *host_name,char *svc_description,char *status_string,time_t last_update,int current_attempt,int max_attempts,int state_type,time_t last_check,time_t next_check,int check_type,int checks_enabled,int accept_passive_checks,int event_handler_enabled,time_t last_state_change,int problem_has_been_acknowledged,char *last_hard_state_string,unsigned long time_ok,unsigned long time_warning,unsigned long time_unknown,unsigned long time_critical,time_t last_notification,int current_notification_number,int notifications_enabled, int latency, int execution_time, int flap_detection_enabled, int is_flapping, double percent_state_change, int scheduled_downtime_depth, int failure_prediction_enabled, int process_performance_data, int obsess_over_service, char *plugin_output){
@@ -543,6 +562,8 @@
 	int status;
 	int last_hard_state;
 
+	if (!servicestatus_tree)
+		servicestatus_tree = g_tree_new( (GCompareFunc) servicestatus_cmp);
 
 	/* make sure we have what we need */
 	if(host_name==NULL)
@@ -724,41 +745,7 @@
 	/* scheduled downtime depth */
 	new_svcstatus->scheduled_downtime_depth=scheduled_downtime_depth;
 
-
-	/* add new service status to list, sorted by host name then description */
-	last_svcstatus=servicestatus_list;
-	for(temp_svcstatus=servicestatus_list;temp_svcstatus!=NULL;temp_svcstatus=temp_svcstatus->next){
-
-		if(strcmp(new_svcstatus->host_name,temp_svcstatus->host_name)<0){
-			new_svcstatus->next=temp_svcstatus;
-			if(temp_svcstatus==servicestatus_list)
-				servicestatus_list=new_svcstatus;
-			else
-				last_svcstatus->next=new_svcstatus;
-			break;
-		        }
-
-		else if(strcmp(new_svcstatus->host_name,temp_svcstatus->host_name)==0 && strcmp(new_svcstatus->description,temp_svcstatus->description)<0){
-			new_svcstatus->next=temp_svcstatus;
-			if(temp_svcstatus==servicestatus_list)
-				servicestatus_list=new_svcstatus;
-			else
-				last_svcstatus->next=new_svcstatus;
-			break;
-		        }
-
-		else
-			last_svcstatus=temp_svcstatus;
-	        }
-	if(servicestatus_list==NULL){
-		new_svcstatus->next=NULL;
-		servicestatus_list=new_svcstatus;
-	        }
-	else if(temp_svcstatus==NULL){
-		new_svcstatus->next=NULL;
-		last_svcstatus->next=new_svcstatus;
-	        }
-
+	g_tree_insert(servicestatus_tree, new_svcstatus, new_svcstatus);
 
 	return OK;
         }
diff -ru nagios-1.1-virgin/contrib/Makefile.in nagios-1.1/contrib/Makefile.in
--- nagios-1.1-virgin/contrib/Makefile.in	Thu Jul 10 08:30:10 2003
+++ nagios-1.1/contrib/Makefile.in	Tue Oct  7 13:03:51 2003
@@ -5,8 +5,8 @@
 ###############################
 
 CC=@CC@
-CFLAGS=@CFLAGS@ @DEFS@
-LDFLAGS=@LDFLAGS@ @LIBS@
+CFLAGS=@CFLAGS@ @DEFS@ `pkg-config glib --cflags`
+LDFLAGS=@LDFLAGS@ @LIBS@ `pkg-config glib --libs`
 
 # Source code directories
 SRC_COMMON=../common
diff -ru nagios-1.1-virgin/html/Makefile.in nagios-1.1/html/Makefile.in
--- nagios-1.1-virgin/html/Makefile.in	Thu Jul 10 08:30:10 2003
+++ nagios-1.1/html/Makefile.in	Tue Oct  7 13:03:51 2003
@@ -1,6 +1,6 @@
 CC=@CC@
-CFLAGS=@CFLAGS@ @DEFS@
-LDFLAGS=@LDFLAGS@ @LIBS@
+CFLAGS=@CFLAGS@ @DEFS@ `pkg-config glib --cflags`
+LDFLAGS=@LDFLAGS@ @LIBS@ `pkg-config glib --libs`
 
 prefix=@prefix@
 exec_prefix=@exec_prefix@
diff -ru nagios-1.1-virgin/cgi/status.c nagios-1.1/cgi/status.c
--- nagios-1.1-virgin/cgi/status.c	Thu Jul 10 08:30:10 2003
+++ nagios-1.1/cgi/status.c	Tue Oct  7 12:29:00 2003
@@ -1151,6 +1151,7 @@
 	printf("<TH CLASS='status'>Attempt <A HREF='%s&sorttype=%d&sortoption=%d'><IMG SRC='%s%s' BORDER=0 ALT='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)'></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("<TH CLASS='status'>Ack</TH>\n");
 	printf("</TR>\n");
 
 
@@ -1499,6 +1500,15 @@
 			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 </TD>\n",status_bg_class,temp_status->information);
+			if (temp_status->status==SERVICE_OK)
+			{
+				printf("<TD CLASS='status%s'> </TD>\n",status_bg_class);
+			}
+			else
+			{
+				printf("<TD CLASS='status%s'><A HREF='%s?cmd_typ=34&host=%s", status_bg_class, COMMAND_CGI, url_encode(temp_status->host_name));
+				printf("&service=%s'>Ack</A></TD>\n", url_encode(temp_status->description));
+			}
 
 			printf("</TR>\n");
 
diff -u -b -B -r1.1.1.1 Makefile.in
--- base/Makefile.in	23 Jun 2003 01:56:10 -0000	1.1.1.1
+++ base/Makefile.in	29 Jul 2003 08:22:54 -0000
@@ -10,9 +10,9 @@
 SRC_XDATA=../xdata
 
 CC=@CC@
-CFLAGS=@CFLAGS@ @DEFS@ -DNSCORE
+CFLAGS=@CFLAGS@ @DEFS@ -DNSCORE `glib-config --cflags`
 #CFLAGS=-O3 -Wall -Wshadow -Wpointer-arith -Wcast-qual -Wcast-align -Wstrict-prototypes -Wmissing-prototypes -Wnested-externs -DHAVE_CONFIG_H -DNSCORE
-LDFLAGS=@LDFLAGS@ @LIBS@
+LDFLAGS=@LDFLAGS@ @LIBS@ `glib-config --libs`
 
 prefix=@prefix@
 exec_prefix=@exec_prefix@
diff -u -b -B -r1.1.1.1 Makefile.in
--- cgi/Makefile.in	23 Jun 2003 01:56:10 -0000	1.1.1.1
+++ cgi/Makefile.in	29 Jul 2003 08:22:54 -0000
@@ -25,9 +25,9 @@
 
 CP=@CP@
 CC=@CC@
-CFLAGS=@CFLAGS@ @DEFS@ -DNSCGI
+CFLAGS=@CFLAGS@ @DEFS@ -DNSCGI `glib-config --cflags`
 #CFLAGS=-O3 -Wall -Wshadow -Wpointer-arith -Wcast-qual -Wcast-align -Wstrict-prototypes -Wmissing-prototypes -Wnested-externs -DHAVE_CONFIG_H -DNSCGI
-LDFLAGS=@LDFLAGS@ @LIBS@
+LDFLAGS=@LDFLAGS@ @LIBS@ `glib-config --libs`
 
 CGIS=avail.cgi cmd.cgi config.cgi extinfo.cgi history.cgi notifications.cgi outages.cgi showlog.cgi status.cgi statuswml.cgi summary.cgi tac.cgi $(CGIEXTRAS)
 
diff -u -b -B -r1.1.1.2 common.h
--- common/common.h	23 Jun 2003 01:57:24 -0000	1.1.1.2
+++ common/common.h	29 Jul 2003 08:22:54 -0000
@@ -208,8 +208,12 @@
 #define	OK				0
 #define ERROR				-2	/* value was changed from -1 so as to not interfere with STATUS_UNKNOWN plugin result */
 
+#ifndef TRUE
 #define TRUE				1
+#endif
+#ifndef FALSE
 #define FALSE				0
+#endif
 
 
 /****************** HOST CONFIG FILE READING OPTIONS ********************/
diff -u -b -B -r1.1.1.1 config.h.in
--- common/config.h.in	23 Jun 2003 01:56:10 -0000	1.1.1.1
+++ common/config.h.in	29 Jul 2003 08:22:54 -0000
@@ -214,3 +214,7 @@
 #include <dirent.h>
 #endif
 
+#define HAVE_GLIB_H 1
+#ifdef HAVE_GLIB_H
+#include <glib.h>
+#endif
diff -u -b -B -r1.1.1.1 objects.c
--- common/objects.c	23 Jun 2003 01:56:10 -0000	1.1.1.1
+++ common/objects.c	29 Jul 2003 08:22:54 -0000
@@ -59,6 +59,7 @@
 servicedependency       *servicedependency_list=NULL;
 hostdependency          *hostdependency_list=NULL;
 hostescalation          *hostescalation_list=NULL;
+GHashTable	*service_hash = NULL;
 
 
 
@@ -2222,6 +2223,19 @@
 	printf("\tEvent Handler:            %s\n",(new_service->event_handler==NULL)?"N/A":new_service->event_handler);
 #endif
 
+#ifdef HAVE_GLIB_H
+	/* Cache service in hash table */
+	if (!service_hash)
+		service_hash = g_hash_table_new(g_str_hash, g_str_equal);
+
+	if (service_hash)
+	{
+		char *key = calloc(strlen(new_service->host_name) + strlen(new_service->description) + 2, 1);
+		sprintf(key, "%s-%s", new_service->host_name, new_service->description);
+		g_hash_table_insert(service_hash, key, new_service);
+	}
+#endif
+
 #ifdef DEBUG0
 	printf("add_service() end\n");
 #endif
@@ -3500,6 +3514,18 @@
 	if(host_name==NULL || svc_desc==NULL)
 		return NULL;
 
+#ifdef HAVE_GLIB_H
+	/* Lookup service in the hash */
+	if (service_hash)
+	{
+		char *key = calloc(strlen(host_name) + strlen(svc_desc) + 2, 1);
+		sprintf(key, "%s-%s", host_name, svc_desc);
+		temp_service = (service *)g_hash_table_lookup(service_hash, key);
+		free(key);
+		return temp_service;
+	}
+#endif
+
 	if(svcptr==NULL)
 		temp_service=service_list;
 	else
diff -u -b -B -r1.1.1.2 Makefile.in
--- contrib/Makefile.in	23 Jun 2003 01:57:24 -0000	1.1.1.2
+++ contrib/Makefile.in	29 Jul 2003 08:22:54 -0000
@@ -5,8 +5,8 @@
 ###############################
 
 CC=@CC@
-CFLAGS=@CFLAGS@ @DEFS@
-LDFLAGS=@LDFLAGS@ @LIBS@
+CFLAGS=@CFLAGS@ @DEFS@ `glib-config --cflags`
+LDFLAGS=@LDFLAGS@ @LIBS@ `glib-config --libs`
 
 # Source code directories
 SRC_COMMON=../common
diff -u -b -B -r1.1.1.1 Makefile.in
--- html/Makefile.in	23 Jun 2003 01:56:10 -0000	1.1.1.1
+++ html/Makefile.in	29 Jul 2003 08:22:54 -0000
@@ -1,6 +1,6 @@
 CC=@CC@
-CFLAGS=@CFLAGS@ @DEFS@
-LDFLAGS=@LDFLAGS@ @LIBS@
+CFLAGS=@CFLAGS@ @DEFS@ `glib-config --cflags`
+LDFLAGS=@LDFLAGS@ @LIBS@ `glib-config --libs`
 
 prefix=@prefix@
 exec_prefix=@exec_prefix@
diff -ru nagios-1.1-virgin/cgi/status.c nagios-1.1/cgi/status.c
--- nagios-1.1-virgin/cgi/status.c	Thu Jul 10 08:30:10 2003
+++ nagios-1.1/cgi/status.c	Wed Nov 26 18:01:16 2003
@@ -1293,9 +1293,15 @@
 				strncpy(status,"CRITICAL",sizeof(status));
 				status_class="CRITICAL";
 				if(temp_status->problem_has_been_acknowledged==TRUE)
+				{
 					status_bg_class="BGCRITICALACK";
+					status_class="BGCRITICALACK";
+				}
 				else if(temp_status->scheduled_downtime_depth>0)
+				{
 					status_bg_class="BGCRITICALSCHED";
+					status_class="BGCRITICALSCHED";
+				}
 				else
 					status_bg_class="BGCRITICAL";
 		                }
diff -ur nagios-1.1-virgin/base/nagios.c nagios-1.1/base/nagios.c
--- nagios-1.1-virgin/base/nagios.c	Thu Jul 10 08:30:10 2003
+++ nagios-1.1/base/nagios.c	Thu Jul 10 08:32:20 2003
@@ -51,6 +51,8 @@
 #include <getopt.h>
 #endif
 
+#include <time.h>
+
 /******** BEGIN EMBEDDED PERL INTERPRETER DECLARATIONS ********/
 
 #ifdef EMBEDDEDPERL 
@@ -1497,6 +1499,8 @@
 		printf("Current/Max Outstanding Checks: %d/%d\n",currently_running_service_checks,max_parallel_service_checks);
 #endif
 
+		check_for_external_commands();
+
 		/* handle high priority events */
 		if(event_list_high!=NULL && (current_time>=event_list_high->run_time)){
 
@@ -1594,8 +1598,13 @@
 			        }
 
 			/* wait a second so we don't hog the CPU... */
-			else
-				sleep((unsigned int)sleep_time);
+			else {
+				struct timespec t;
+				t.tv_sec = 0;
+				t.tv_nsec = 1000 * 1000 * 50;
+				nanosleep(&t, NULL);
+				//check_for_external_commands();
+				}
 		        }
 
 		/* we don't have anything to do at this moment in time */
@@ -1606,7 +1615,12 @@
 				check_for_external_commands();
 
 			/* wait a second so we don't hog the CPU... */
-			sleep((unsigned int)sleep_time);
+
+			{ struct timespec t;
+			t.tv_sec = 0;
+			t.tv_nsec = 1000 * 1000 * 50;
+			nanosleep(&t, NULL); }
+
 		        }
 	        }
 
--- commands.c.old	Sat Aug  2 14:13:23 2003
+++ nagios-1.1/base/commands.c	Sat Aug  2 14:13:53 2003
@@ -347,8 +347,19 @@
 
 
 	/**** PROCESS ALL PASSIVE CHECK RESULTS AT ONE TIME ****/
-	if(passive_check_result_list!=NULL)
-		process_passive_service_checks();
+        {
+                static unsigned int last_checked = 0;
+                unsigned int t;
+                                                                                                                       
+                        /* Don't process more frequently than once every 5 seconds. */
+                        /* This does a fork!!! */
+                time(&t);
+                if(passive_check_result_list!=NULL && ((t - last_checked) > 5) ) {
+                        process_passive_service_checks();
+                        last_checked = t;
+                }
+        }
+
 
 
 #ifdef DEBUG0
--- commands.c.old	Sat Aug  2 15:37:31 2003
+++ nagios-1.1/base/commands.c	Sat Aug  2 15:44:36 2003
@@ -63,7 +63,7 @@
 
 extern FILE     *command_file_fp;
 
-passive_check_result    *passive_check_result_list;
+passive_check_result    *passive_check_result_list = NULL;
 
 int             flush_pending_commands=FALSE;
 
@@ -96,9 +96,6 @@
 	/* update the status log with new program information */
 	update_program_status(FALSE);
 
-	/* reset passive check result list pointer */
-	passive_check_result_list=NULL;
-
 	/* reset flush flag */
 	flush_pending_commands=FALSE;
 
@@ -1279,13 +1276,9 @@
 
 	new_pcr->next=NULL;
 
-	/* add the passive check result to the end of the list in memory */
-	if(passive_check_result_list==NULL)
-		passive_check_result_list=new_pcr;
-	else{
-		for(temp_pcr=passive_check_result_list;temp_pcr->next!=NULL;temp_pcr=temp_pcr->next);
-		temp_pcr->next=new_pcr;
-	        }
+	/* add the passive check result to the head of the list in memory */
+	new_pcr->next = passive_check_result_list;
+	passive_check_result_list = new_pcr;
 
 #ifdef DEBUG0
 	printf("cmd_process_service_check_result() end\n");
@@ -2845,6 +2838,17 @@
 
 		/* the grandchild process should submit the service check result... */
 		if(pid==0){
+			passive_check_result *t, *t1;
+			/* Reverse passive list to correct the reverse that happened in collection. */
+
+			t = passive_check_result_list;
+			passive_check_result_list = NULL;
+			while (t) {
+				t1 = t->next;
+				t->next = passive_check_result_list;
+				passive_check_result_list = t;
+				t = t1;
+			}
 
 			/* write all service checks to the IPC pipe for later processing by the grandparent */
 			for(temp_pcr=passive_check_result_list;temp_pcr!=NULL;temp_pcr=temp_pcr->next){
Index: base/checks.c
===================================================================
RCS file: /home/cvs/repos/nagios_source/base/checks.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 checks.c
--- base/checks.c	23 Jun 2003 01:56:10 -0000	1.1.1.1
+++ base/checks.c	7 Dec 2003 21:15:43 -0000
@@ -522,6 +522,7 @@
 	time_t current_time;
 	int first_check=FALSE;
 	int state_was_logged=FALSE;
+	int output_changed = FALSE;
 	char old_plugin_output[MAX_PLUGINOUTPUT_LENGTH]="";
 	char temp_plugin_output[MAX_PLUGINOUTPUT_LENGTH]="";
 	char *temp_ptr;
@@ -617,6 +618,7 @@
 		dependency_result=DEPENDENCIES_OK;
 		first_check=FALSE;
 		state_was_logged=FALSE;
+		output_changed=FALSE;
 		strcpy(old_plugin_output,"");
 		strcpy(temp_plugin_output,"");
 
@@ -705,6 +707,9 @@
 			/* grab the return code */
 			temp_service->current_state=queued_svc_msg.return_code;
 		        }
+		
+		if (strcmp(old_plugin_output,temp_service->plugin_output))
+			output_changed = TRUE;
 
 		/* get the host that this service runs on */
 		temp_host=find_host(temp_service->host_name,NULL);
@@ -835,7 +840,7 @@
 				state_was_logged=TRUE;
 
 				/* notify contacts about the service recovery */
-				service_notification(temp_service,NULL);
+				service_notification(temp_service,NULL,output_changed);
 
 				/* run the service event handler to handle the hard state change */
 				handle_service_event(temp_service,HARD_STATE);
@@ -1064,7 +1069,7 @@
 					check_pending_flex_service_downtime(temp_service);
 
 				/* (re)send notifications out about this service problem if the host is up (and was at last check also) and the dependencies were okay... */
-				service_notification(temp_service,NULL);
+				service_notification(temp_service,NULL,output_changed);
 
 				/* run the service event handler if we changed state from the last hard state or if this service is flagged as being volatile */
 				if(hard_state_change==TRUE || temp_service->is_volatile==TRUE)
@@ -1103,7 +1108,6 @@
 
 		/* if we're stalking this state type and state was not already logged AND the plugin output changed since last check, log it now.. */
 		if(temp_service->state_type==HARD_STATE && state_change==FALSE && state_was_logged==FALSE && strcmp(old_plugin_output,temp_service->plugin_output)){
-
 			if((temp_service->current_state==STATE_OK && temp_service->stalk_on_ok==TRUE))
 				log_service_event(temp_service,HARD_STATE);
 			
Index: base/commands.c
===================================================================
RCS file: /home/cvs/repos/nagios_source/base/commands.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 commands.c
--- base/commands.c	23 Jun 2003 01:56:10 -0000	1.1.1.1
+++ base/commands.c	7 Dec 2003 21:15:43 -0000
@@ -2277,7 +2277,7 @@
 
 	/* send out an acknowledgement notification */
 	if(notify==TRUE)
-		service_notification(svc,ack_data);
+		service_notification(svc,ack_data,0);
 
 	/* set the acknowledgement flag */
 	svc->problem_has_been_acknowledged=TRUE;
Index: base/flapping.c
===================================================================
RCS file: /home/cvs/repos/nagios_source/base/flapping.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 flapping.c
--- base/flapping.c	23 Jun 2003 01:56:10 -0000	1.1.1.1
+++ base/flapping.c	7 Dec 2003 21:15:43 -0000
@@ -321,7 +321,7 @@
 
 	/* should we send a recovery notification? */
 	if(svc->check_flapping_recovery_notification==TRUE && svc->current_state==STATE_OK)
-		service_notification(svc,NULL);
+		service_notification(svc,NULL,0);
 
 	/* clear the recovery notification flag */
 	svc->check_flapping_recovery_notification=FALSE;
Index: base/nagios.h.in
===================================================================
RCS file: /home/cvs/repos/nagios_source/base/nagios.h.in,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 nagios.h.in
--- base/nagios.h.in	23 Jun 2003 01:56:10 -0000	1.1.1.1
+++ base/nagios.h.in	7 Dec 2003 21:15:44 -0000
@@ -367,10 +367,10 @@
 
 
 /**** Notification Functions ****/
-int check_service_notification_viability(service *,char *);		/* checks viability of notifying all contacts about a service */
+int check_service_notification_viability(service *,char *,int);		/* checks viability of notifying all contacts about a service */
 int is_valid_escalation_for_service_notification(service *,serviceescalation *);	/* checks if an escalation entry is valid for a particular service notification */
 int should_service_notification_be_escalated(service *);		/* checks if a service notification should be escalated */
-int service_notification(service *,char *);                        	/* notify all contacts about a service (problem or recovery) */
+int service_notification(service *,char *,int);                        	/* notify all contacts about a service (problem or recovery) */
 int check_contact_service_notification_viability(contact *, service *);	/* checks viability of notifying a contact about a service */ 
 int notify_contact_of_service(contact *,service *,char *);        	/* notify a single contact about a service */
 int check_host_notification_viability(host *,int,char *);		/* checks viability of notifying all contacts about a host */
Index: base/notifications.c
===================================================================
RCS file: /home/cvs/repos/nagios_source/base/notifications.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 notifications.c
--- base/notifications.c	23 Jun 2003 01:56:10 -0000	1.1.1.1
+++ base/notifications.c	7 Dec 2003 21:15:44 -0000
@@ -58,7 +58,7 @@
 
 
 /* notify contacts about a service problem or recovery */
-int service_notification(service *svc, char *ack_data){
+int service_notification(service *svc, char *ack_data, int output_changed) {
 	host *temp_host;
 	notification *temp_notification;
 	time_t current_time;
@@ -87,7 +87,7 @@
 	        }
 
 	/* check the viability of sending out a service notification */
-	if(check_service_notification_viability(svc,ack_data)==ERROR){
+	if(check_service_notification_viability(svc,ack_data,output_changed)==ERROR){
 #ifdef DEBUG4
 		printf("\tSending out a notification for this service is not viable at this time.\n");
 #endif
@@ -200,7 +200,7 @@
 
 
 /* checks the viability of sending out a service alert (top level filters) */
-int check_service_notification_viability(service *svc, char *ack_data){
+int check_service_notification_viability(service *svc, char *ack_data, int output_changed){
 	host *temp_host;
 	time_t current_time;
 	time_t timeperiod_start;
@@ -371,7 +371,12 @@
 	        }
 
 	/* don't notify if we haven't waited long enough since the last time (and the service is not marked as being volatile) */
-	if((current_time < svc->next_notification) && svc->is_volatile==FALSE){
+	if((current_time < svc->next_notification) && svc->is_volatile==FALSE &&
+		(!output_changed ||
+		 (svc->current_state==STATE_OK && !svc->stalk_on_ok) ||
+		 (svc->current_state==STATE_WARNING && !svc->stalk_on_warning) ||
+		 (svc->current_state==STATE_UNKNOWN && !svc->stalk_on_unknown) || 
+		 (svc->current_state==STATE_CRITICAL && !svc->stalk_on_critical) )){
 #ifdef DEBUG4
 		printf("\tWe haven't waited long enough to re-notify contacts about this service!\n");
 		printf("\tNext valid notification time: %s",ctime(&svc->next_notification));
? cgi/Makefile
? cgi/authall.patch
? cgi/avail.cgi
? cgi/cgiutils.h
? cgi/cmd.cgi
? cgi/config.cgi
? cgi/extinfo.cgi
? cgi/histogram.cgi
? cgi/history.cgi
? cgi/notifications.cgi
? cgi/outages.cgi
? cgi/showlog.cgi
? cgi/status.cgi
? cgi/statusmap.cgi
? cgi/statuswml.cgi
? cgi/statuswrl.cgi
? cgi/summary.cgi
? cgi/tac.cgi
? cgi/trends.cgi
Index: cgi/auth.c
===================================================================
RCS file: /home/cvs/repos/nagios_source/cgi/auth.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 auth.c
--- cgi/auth.c	23 Jun 2003 01:56:10 -0000	1.1.1.1
+++ cgi/auth.c	25 Feb 2004 00:35:29 -0000
@@ -198,9 +198,6 @@
 int is_authorized_for_host(host *hst, authdata *authinfo){
 	contact *temp_contact;
 
-	if(hst==NULL)
-		return FALSE;
-
 	/* if we're not using authentication, fake it */
 	if(use_authentication==FALSE)
 		return TRUE;
@@ -213,6 +210,9 @@
 	if(is_authorized_for_all_hosts(authinfo)==TRUE)
 		return TRUE;
 
+	if(hst==NULL)
+		return FALSE;
+
 	/* find the contact */
 	temp_contact=find_contact(authinfo->username,NULL);
 
@@ -252,9 +252,6 @@
 	host *temp_host;
 	contact *temp_contact;
 
-	if(svc==NULL)
-		return FALSE;
-
 	/* if we're not using authentication, fake it */
 	if(use_authentication==FALSE)
 		return TRUE;
@@ -266,6 +263,9 @@
 	/* if this user is authorized for all services, they are for this one... */
 	if(is_authorized_for_all_services(authinfo)==TRUE)
 		return TRUE;
+
+	if(svc==NULL)
+		return FALSE;
 
 	/* find the host */
 	temp_host=find_host(svc->host_name,NULL);
diff -ruN nagios-plugins-1.3.0.orig/plugins/check_smtp.c nagios-plugins-1.3.0/plugins/check_smtp.c
--- nagios-plugins-1.3.0.orig/plugins/check_smtp.c	2003-02-15 23:48:46.000000000 +1100
+++ nagios-plugins-1.3.0/plugins/check_smtp.c	2003-08-12 15:00:07.000000000 +1000
@@ -69,12 +69,77 @@
 char *server_address = NULL;
 char *server_expect = NULL;
 char *from_arg = " ";
+char *authtype = NULL;
+char *authuser = NULL;
+char *authpass = NULL;
 int warning_time = 0;
 int check_warning_time = FALSE;
 int critical_time = 0;
 int check_critical_time = FALSE;
 int verbose = FALSE;
 
+/* encode64 routine from http://www.experts-exchange.com/Programming/Programming_Languages/C/Q_20245582.html */
+
+#define BUFOVER             (-2)
+#define CHAR64(c)           (((c) < 0 || (c) > 127) ? -1 : index_64[(c)])
+static char     basis_64[] =
+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????";
+static char     index_64[128] = {
+  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63,
+  52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1,
+  -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+  15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,
+  -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
+  41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1
+};
+
+static int
+encode64(const char *_in, unsigned inlen, char *_out, unsigned outmax, unsigned *outlen)
+{
+
+  const unsigned char *in = (const unsigned char *) _in;
+  unsigned char  *out = (unsigned char *) _out;
+  unsigned char   oval;
+  char           *blah;
+  unsigned        olen;
+
+  olen = (inlen + 2) / 3 * 4;
+  if (outlen)
+      *outlen = olen;
+  if (outmax < olen)
+      return BUFOVER;
+
+  blah = (char *) out;
+  while (inlen >= 3)
+  {
+/* user provided max buffer size; make sure we don't go over it */
+      *out++ = basis_64[in[0] >> 2];
+      *out++ = basis_64[((in[0] << 4) & 0x30) | (in[1] >> 4)];
+      *out++ = basis_64[((in[1] << 2) & 0x3c) | (in[2] >> 6)];
+      *out++ = basis_64[in[2] & 0x3f];
+      in += 3;
+      inlen -= 3;
+  }
+  if (inlen > 0)
+  {
+/* user provided max buffer size; make sure we don't go over it */
+      *out++ = basis_64[in[0] >> 2];
+      oval = (in[0] << 4) & 0x30;
+      if (inlen > 1)
+          oval |= in[1] >> 4;
+      *out++ = basis_64[oval];
+      *out++ = (inlen < 2) ? '=' : basis_64[(in[1] << 2) & 0x3c];
+      *out++ = '=';
+  }
+
+  if (olen < outmax)
+      *out = '\0';
+
+  return OK;
+}
+
 int
 main (int argc, char **argv)
 {
@@ -83,6 +148,7 @@
 	char buffer[MAX_INPUT_BUFFER] = "";
 	char *from_str = NULL;
 	char *helocmd = NULL;
+	char *error_msg = NULL;
 
 	if (process_arguments (argc, argv) != OK)
 		usage ("Invalid command arguments supplied\n");
@@ -124,41 +190,134 @@
 		if (result == -1) {
 			printf ("recv() failed\n");
 			result = STATE_WARNING;
+		} else
+			result = STATE_OK;
+		
+		/* make sure we find the response we are looking for */
+		if (result == STATE_OK && !strstr (buffer, server_expect)) {
+			if (server_port == SMTP_PORT)
+				printf ("Invalid SMTP response received from host\n");
+			else
+				printf ("Invalid SMTP response received from host on port %d\n",
+								server_port);
+			result = STATE_WARNING;
 		}
-
-		else {
-
-			/* make sure we find the response we are looking for */
-			if (!strstr (buffer, server_expect)) {
-				if (server_port == SMTP_PORT)
-					printf ("Invalid SMTP response received from host\n");
-				else
-					printf ("Invalid SMTP response received from host on port %d\n",
-									server_port);
-				result = STATE_WARNING;
+		
+		if (result == STATE_OK && authtype != NULL) {
+			if (strcmp (authtype, "LOGIN") == 0) {
+				char abuf[MAX_INPUT_BUFFER];
+				unsigned alen;
+				int ret;
+				do {
+					if (authuser == NULL) {
+						result = STATE_CRITICAL;
+						error_msg = "no authuser specified";
+						break;
+					}
+					if (authpass == NULL) {
+						result = STATE_CRITICAL;
+						error_msg = "no authpass specified";
+						break;
+					}
+					send(sd, "AUTH LOGIN\r\n", strlen("AUTH LOGIN\r\n"), 0);
+					if (verbose == TRUE) {
+						printf ("sent AUTH LOGIN\n");
+					}
+					if ((ret = recv(sd, buffer, MAX_INPUT_BUFFER-1, 0)) == -1) {
+						result = STATE_CRITICAL;
+						error_msg = "recv() failed after AUTH LOGIN";
+						break;
+					}
+					buffer[ret] = 0;
+					if (verbose == TRUE) {
+						printf ("received %s\n", buffer);
+					}
+					if (strncmp (buffer, "334", 3) != 0) {
+						result = STATE_CRITICAL;
+						error_msg = "invalid response received after AUTH LOGIN";
+						break;
+					}
+					if (encode64 (authuser, strlen(authuser), abuf, MAX_INPUT_BUFFER, &alen) != OK) {
+						result = STATE_CRITICAL;
+						error_msg = "failed to base64-encode authuser";
+						break;
+					}
+					strcat (abuf, "\r\n");
+					send(sd, abuf, strlen(abuf), 0);
+					if (verbose == TRUE) {
+						printf ("sent %s\n", abuf);
+					}
+					if ((ret = recv(sd, buffer, MAX_INPUT_BUFFER-1, 0)) == -1) {
+						result = STATE_CRITICAL;
+						error_msg = "recv() failed after sending authuser";
+						break;
+					}
+					buffer[ret] = 0;
+					if (verbose == TRUE) {
+						printf ("received %s\n", buffer);
+					}
+					if (strncmp (buffer, "334", 3) != 0) {
+						result = STATE_CRITICAL;
+						error_msg = "invalid response received after authuser";
+						break;
+					}
+					if (encode64 (authpass, strlen(authpass), abuf, MAX_INPUT_BUFFER, &alen) != OK) {
+						result = STATE_CRITICAL;
+						error_msg = "failed to base64-encode authpass";
+						break;
+					}
+					strcat (abuf, "\r\n");
+					send(sd, abuf, strlen(abuf), 0);
+					if (verbose == TRUE) {
+						printf ("sent %s\n", abuf);
+					}
+					if ((ret = recv(sd, buffer, MAX_INPUT_BUFFER-1, 0)) == -1) {
+						result = STATE_CRITICAL;
+						error_msg = "recv() failed after sending authpass";
+						break;
+					}
+					buffer[ret] = 0;
+					if (verbose == TRUE) {
+						printf ("received %s\n", buffer);
+					}
+					if (strncmp (buffer, "235", 3) != 0) {
+						result = STATE_CRITICAL;
+						error_msg = "invalid response received after authpass";
+						break;
+					}
+					break;
+				} while (0);
+			} else {
+				result = STATE_CRITICAL;
+				error_msg = "only authtype LOGIN is supported";
 			}
+		}
+		
+		time (&end_time);
 
-			else {
-
-				time (&end_time);
-
-				result = STATE_OK;
-
-				if (check_critical_time == TRUE
-						&& (end_time - start_time) > critical_time) result =
-						STATE_CRITICAL;
-				else if (check_warning_time == TRUE
-								 && (end_time - start_time) > warning_time) result =
-						STATE_WARNING;
-
-				if (verbose == TRUE)
-					printf ("SMTP %s - %d sec. response time, %s\n",
-									state_text (result), (int) (end_time - start_time), buffer);
-				else
-					printf ("SMTP %s - %d second response time\n", state_text (result),
-									(int) (end_time - start_time));
+		if (check_critical_time == TRUE
+				&& (end_time - start_time) > critical_time) result =
+				STATE_CRITICAL;
+		else if (check_warning_time == TRUE
+						 && (end_time - start_time) > warning_time) result =
+				STATE_WARNING;
+
+		if (verbose == TRUE)
+			if (error_msg == NULL) {
+				printf ("SMTP %s - %d sec. response time, %s\n",
+		        		state_text (result), (int) (end_time - start_time), buffer);
+			} else {
+				printf ("SMTP %s - %s, %d sec. response time, %s\n",
+		        		state_text (result), error_msg, (int) (end_time - start_time), buffer);
+			}
+		else
+			if (error_msg == NULL) {
+				printf ("SMTP %s - %d second response time\n",
+		        		state_text (result), (int) (end_time - start_time));
+			} else {
+				printf ("SMTP %s - %s, %d second response time\n",
+		        		state_text (result), error_msg, (int) (end_time - start_time));
 			}
-		}
 
 		/* close the connection */
 
@@ -211,6 +370,9 @@
 		{"warning", required_argument, 0, 'w'},
 		{"port", required_argument, 0, 'p'},
 		{"from", required_argument, 0, 'f'},
+		{"authtype", required_argument, 0, 'A'},
+		{"authuser", required_argument, 0, 'U'},
+		{"authpass", required_argument, 0, 'P'},
 		{"verbose", no_argument, 0, 'v'},
 		{"version", no_argument, 0, 'V'},
 		{"help", no_argument, 0, 'h'},
@@ -233,10 +395,10 @@
 	while (1) {
 #ifdef HAVE_GETOPT_H
 		c =
-			getopt_long (argc, argv, "+hVvt:p:f:e:c:w:H:", long_options,
+			getopt_long (argc, argv, "+hVvt:p:f:e:c:w:H:A:U:P:", long_options,
 									 &option_index);
 #else
-		c = getopt (argc, argv, "+?hVvt:p:f:e:c:w:H:");
+		c = getopt (argc, argv, "+?hVvt:p:f:e:c:w:H:A:U:P:");
 #endif
 		if (c == -1 || c == EOF)
 			break;
@@ -261,6 +423,15 @@
 		case 'f':									/* from argument */
 			from_arg = optarg;
 			break;
+		case 'A':
+			authtype = optarg;
+			break;
+		case 'U':
+			authuser = optarg;
+			break;
+		case 'P':
+			authpass = optarg;
+			break;
 		case 'e':									/* server expect string on 220  */
 			server_expect = optarg;
 			break;
@@ -355,6 +526,12 @@
 		 "   String to expect in first line of server response (default: %s)\n"
 		 " -f, --from=STRING\n"
 		 "   from address to include in MAIL command (default NULL, Exchange2000 requires one)\n"
+		 " -A, --authtype=STRING\n"
+		 "   SMTP AUTH type to check (default none, only LOGIN supported)\n"
+		 " -U, --authuser=STRING\n"
+		 "   SMTP AUTH username\n"
+		 " -P, --authpass=STRING\n"
+		 "   SMTP AUTH password\n"
 		 " -w, --warning=INTEGER\n"
 		 "   Seconds necessary to result in a warning status\n"
 		 " -c, --critical=INTEGER\n"
@@ -379,7 +556,7 @@
 print_usage (void)
 {
 	printf
-		("Usage: %s -H host [-e expect] [-p port] [-f from addr] [-w warn] [-c crit] [-t timeout] [-v]\n"
+		("Usage: %s -H host [-e expect] [-p port] [-f from addr] [-A authtype -U authuser -P authpass] [-w warn] [-c crit] [-t timeout] [-v]\n"
 		 "       %s --help\n"
 		 "       %s --version\n", progname, progname, progname);
 }
--- /tmp/nagios-plugins-1.3.0/plugins/check_time.c	2003-02-15 23:48:46.000000000 +1100
+++ nagios-plugins-1.3.0/plugins/check_time.c	2003-06-06 10:43:32.000000000 +1000
@@ -61,7 +61,7 @@
 int check_critical_diff = FALSE;
 int server_port = TIME_PORT;
 char *server_address = NULL;
-
+int use_udp = FALSE;
 
 int process_arguments (int, char **);
 void print_usage (void);
@@ -85,7 +85,13 @@
 	time (&start_time);
 
 	/* try to connect to the host at the given port number */
-	if (my_tcp_connect (server_address, server_port, &sd) != STATE_OK) {
+	if (use_udp) {
+		result = my_udp_connect (server_address, server_port, &sd);
+	} else {
+		result = my_tcp_connect (server_address, server_port, &sd);
+	}
+
+	if (result != STATE_OK) {
 		if (check_critical_time == TRUE)
 			result = STATE_CRITICAL;
 		else if (check_warning_time == TRUE)
@@ -94,7 +100,21 @@
 			result = STATE_UNKNOWN;
 		terminate (result,
 		           "TIME UNKNOWN - could not connect to server %s, port %d\n",
-		           server_address, server_port);
+	        	   server_address, server_port);
+	}
+
+	if (use_udp) {
+		if (send (sd, "", 0, 0) < 0) {
+			if (check_critical_time == TRUE)
+				result = STATE_CRITICAL;
+			else if (check_warning_time == TRUE)
+				result = STATE_WARNING;
+			else
+				result = STATE_UNKNOWN;
+			terminate (result,
+			           "TIME UNKNOWN - could not send UDP request to server %s, port %d\n",
+	        		   server_address, server_port);
+		}
 	}
 
 	/* watch for the connection string */
@@ -170,6 +190,7 @@
 		{"timeout", required_argument, 0, 't'},
 		{"version", no_argument, 0, 'V'},
 		{"help", no_argument, 0, 'h'},
+		{"udp", no_argument, 0, 'u'},
 		{0, 0, 0, 0}
 	};
 #endif
@@ -193,10 +214,10 @@
 	while (1) {
 #ifdef HAVE_GETOPT_H
 		c =
-			getopt_long (argc, argv, "hVH:w:c:W:C:p:t:", long_options,
+			getopt_long (argc, argv, "hVH:w:c:W:C:p:t:u", long_options,
 									 &option_index);
 #else
-		c = getopt (argc, argv, "hVH:w:c:W:C:p:t:");
+		c = getopt (argc, argv, "hVH:w:c:W:C:p:t:u");
 #endif
 
 		if (c == -1 || c == EOF)
@@ -275,6 +296,9 @@
 				usage ("Timeout interval must be a nonnegative integer\n");
 			socket_timeout = atoi (optarg);
 			break;
+		case 'u':
+		/* udp */
+			use_udp = TRUE;
 		}
 	}
 
@@ -338,6 +362,8 @@
 		 "    Seconds before connection times out (default: %d)\n"
 		 " -p, --port=INTEGER\n"
 		 "    Port number (default: %d)\n"
+		 " -u, --udp\n"
+		 "    Use UDP to connect, not TCP\n"
 		 " -h, --help\n"
 		 "    Print detailed help screen\n"
 		 " -V, --version\n"
--- nagios-plugins-1.3.0/plugins/check_udp.c	2003-02-19 09:24:35.000000000 +1100
+++ nagios-plugins-r1_3_0-200306050007/plugins/check_udp.c	2003-03-07 17:40:33.000000000 +1100
@@ -6,7 +6,7 @@
 * License: GPL
 * Copyright (c) 1999 Ethan Galstad (nagios at nagios.org)
 *
-* Last Modified: $Date: 2003/02/18 22:24:35 $
+* Last Modified: $Date: 2003/03/07 06:40:33 $
 *
 * Command line: CHECK_UDP <host_address> [-p port] [-s send] [-e expect] \
 *			   [-wt warn_time] [-ct crit_time] [-to to_sec]
@@ -173,7 +173,7 @@
 			print_help ();
 			exit (STATE_OK);
 		case 'V':									/* version */
-			print_revision (progname, "$Revision: 1.4 $");
+			print_revision (progname, "$Revision: 1.4.2.1 $");
 			exit (STATE_OK);
 		case 'v':									/* verbose mode */
 			verbose = TRUE;
@@ -220,9 +220,9 @@
 			usage ("Invalid host name/address\n");
 		server_address = argv[c++];
 	}
-	else {
+
+	if (server_address == NULL)
 		usage ("Host name was not supplied\n");
-	}
 
 	return c;
 }
@@ -246,7 +246,7 @@
 void
 print_help (void)
 {
-	print_revision (progname, "$Revision: 1.4 $");
+	print_revision (progname, "$Revision: 1.4.2.1 $");
 	printf
 		("Copyright (c) 1999 Ethan Galstad (nagios at nagios.org)\n\n"
 		 "This plugin tests an UDP connection with the specified host.\n\n");


-------------------------------------------------------
This SF.Net email is sponsored by: IBM Linux Tutorials
Free Linux tutorial presented by Daniel Robbins, President and CEO of
GenToo technologies. Learn everything from fundamentals to system
administration.http://ads.osdn.com/?ad_id=1470&alloc_id=3638&op=click




More information about the Users mailing list