[Nagios-devel] Large scale network monitoring limits with nagios

Fredrik Wänglund fredrik.wanglund at mobeon.com
Fri Mar 12 14:34:35 CET 2004


I think there was an discussion on this sorting-topc some month ago. I 
thought that resulted in some pathes that changed the code to hash-based 
sorting...
Anyone know where those patches are?

/FredrikW


michael at optusnet.com.au wrote:

> 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
> _______________________________________________
> Nagios-devel mailing list
> Nagios-devel at lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/nagios-devel



-------------------------------------------------------
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
_______________________________________________
Nagios-users mailing list
Nagios-users at lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/nagios-users
::: Please include Nagios version, plugin version (-v) and OS when reporting any issue. 
::: Messages without supporting info will risk being sent to /dev/null





More information about the Users mailing list