Patch: allowing circular parent/child definitions

Peter Westlake peter.westlake at pobox.com
Wed Mar 21 17:52:46 CET 2007


Here's the patch I promised to allow cyclic networks, where host A is
the parent of B and B is the parent of A. It was originally developed
against 2.7, then checked against 3.0a1.

Please let me know if having cycles in the network topology breaks any
third-party tools, and I'll see if I can provide patches for them too.

Peter.

diff -r -U 3 --minimal nagios-3.0a1/base/checks.c develop/nagios-3.0a1/base/checks.c
--- nagios-3.0a1/base/checks.c	2007-03-01 18:19:15.000000000 +0000
+++ develop/nagios-3.0a1/base/checks.c	2007-03-21 10:45:08.000000000 +0000
@@ -1844,6 +1844,7 @@
 	/* reset latency, since on-demand checks have none */
 	hst->latency=0.0;
 
+        unmark_all_hosts(CHECKED_HOSTS_SET);
 	/* check route to the host (propagate problems and recoveries both up and down the tree) */
 	result=check_host(hst,PROPAGATE_TO_PARENT_HOSTS | PROPAGATE_TO_CHILD_HOSTS,check_options);
 
@@ -1997,6 +1998,10 @@
 	printf("check_host() start\n");
 #endif
 
+        if (host_is_marked(hst, CHECKED_HOSTS_SET)) {
+		return hst->current_state;
+        }
+        mark_host(hst, CHECKED_HOSTS_SET);
 	/* ADDED 06/20/2006 EG */
 	/* bail out if signal encountered */
 	if(sigrestart==TRUE || sigshutdown==TRUE)
@@ -2179,9 +2184,9 @@
 					/* check the parent host, assume its up if we can't find it, use the parent host's "old" status if we shouldn't propagate */
 					if(parent_host==NULL)
 						parent_result=HOST_UP;
-					else if(propagation_options & PROPAGATE_TO_PARENT_HOSTS)
-						parent_result=check_host(parent_host,PROPAGATE_TO_PARENT_HOSTS,check_options);
-					else
+					else if(propagation_options & PROPAGATE_TO_PARENT_HOSTS) {
+                                                parent_result=check_host(parent_host,PROPAGATE_TO_PARENT_HOSTS,check_options);
+					} else
 						parent_result=parent_host->current_state;
 
 					/* if this parent host was up, the route is okay */
diff -r -U 3 --minimal nagios-3.0a1/base/config.c develop/nagios-3.0a1/base/config.c
--- nagios-3.0a1/base/config.c	2007-02-16 19:04:11.000000000 +0000
+++ develop/nagios-3.0a1/base/config.c	2007-03-21 13:46:16.000000000 +0000
@@ -3164,38 +3164,6 @@
 
 
 	/********************************************/
-	/* check for circular paths between hosts   */
-	/********************************************/
-	if(verify_config==TRUE)
-		printf("Checking for circular paths between hosts...\n");
-
-	/* check routes between all hosts */
-	found=FALSE;
-	result=OK;
-	for(temp_host=host_list;temp_host!=NULL;temp_host=temp_host->next){
-
-		/* clear checked flag for all hosts */
-		for(temp_host2=host_list;temp_host2!=NULL;temp_host2=temp_host2->next)
-			temp_host2->circular_path_checked=FALSE;
-
-		found=check_for_circular_host_path(temp_host,temp_host);
-		if(found==TRUE){
-			asprintf(&temp_buffer,"Error: There is a circular parent/child path that exists for host '%s'!",temp_host->name);
-			write_to_logs_and_console(temp_buffer,NSLOG_VERIFICATION_ERROR,TRUE);
-			my_free((void **)&temp_buffer);
-			result=ERROR;
-		        }
-	        }
-	if(result==ERROR)
-		errors++;
-
-#ifdef DEBUG1
-	printf("\tCompleted circular path checks\n");
-#endif
-
-
-
-	/********************************************/
 	/* check for circular dependencies         */
 	/********************************************/
 	if(verify_config==TRUE)
diff -r -U 3 --minimal nagios-3.0a1/cgi/outages.c develop/nagios-3.0a1/cgi/outages.c
--- nagios-3.0a1/cgi/outages.c	2006-03-21 21:38:10.000000000 +0000
+++ develop/nagios-3.0a1/cgi/outages.c	2007-03-21 10:45:11.683849000 +0000
@@ -571,13 +571,16 @@
 
 
 /* calculates network outage effect of a particular host being down or unreachable */
-void calculate_outage_effect_of_host(host *hst, int *affected_hosts, int *affected_services){
+static void calculate_outage_effect_of_host_rec(host *hst, int *affected_hosts, int *affected_services){
 	int total_child_hosts_affected=0;
 	int total_child_services_affected=0;
 	int temp_child_hosts_affected=0;
 	int temp_child_services_affected=0;
 	host *temp_host;
 
+        if (host_is_marked(hst, CALC_OUTAGE_SET))
+                return;
+        mark_host(hst, CALC_OUTAGE_SET);
 
 	/* find all child hosts of this host */
 	for(temp_host=host_list;temp_host!=NULL;temp_host=temp_host->next){
@@ -587,7 +590,7 @@
 			continue;
 
 		/* calculate the outage effect of the child */
-		calculate_outage_effect_of_host(temp_host,&temp_child_hosts_affected,&temp_child_services_affected);
+		calculate_outage_effect_of_host_rec(temp_host,&temp_child_hosts_affected,&temp_child_services_affected);
 
 		/* keep a running total of outage effects */
 		total_child_hosts_affected+=temp_child_hosts_affected;
@@ -601,6 +604,11 @@
         }
 
 
+void calculate_outage_effect_of_host(host *hst, int *affected_hosts, int *affected_services){
+        unmark_all_hosts(CALC_OUTAGE_SET);
+        calculate_outage_effect_of_host_rec(hst, affected_hosts, affected_services);
+        unmark_all_hosts(CALC_OUTAGE_SET);
+}
 
 /* tests whether or not a host is "blocked" by upstream parents (host is already assumed to be down or unreachable) */
 int is_route_to_host_blocked(host *hst){
diff -r -U 3 --minimal nagios-3.0a1/cgi/statusmap.c develop/nagios-3.0a1/cgi/statusmap.c
--- nagios-3.0a1/cgi/statusmap.c	2006-03-21 21:38:10.000000000 +0000
+++ develop/nagios-3.0a1/cgi/statusmap.c	2007-03-21 13:49:42.000000000 +0000
@@ -278,6 +278,7 @@
 		return ERROR;
                 }
 
+        assign_host_depths();
 
 	document_header(TRUE);
 
@@ -898,7 +899,7 @@
 			this_host=find_host(host_name);
 
 		/* find total number of immediate parents/children for this host */
-		child_hosts=number_of_immediate_child_hosts(this_host);
+		child_hosts=number_of_immediate_child_hosts_not_parents(this_host);
 		parent_hosts=number_of_immediate_parent_hosts(this_host);
 
 		if(child_hosts==0 && parent_hosts==0)
@@ -2394,40 +2395,17 @@
 
 /* calculates how many "layers" separate parent and child - used by collapsed tree layout method */
 int host_child_depth_separation(host *parent, host *child){
-	int this_depth=0;
-	int min_depth=0;
-	int have_min_depth=FALSE;
-	host *temp_host;
-
 	if(child==NULL)
 		return -1;
 
 	if(parent==child)
 		return 0;
 
-	if(is_host_immediate_child_of_host(parent,child)==TRUE)
-		return 1;
-
-	for(temp_host=host_list;temp_host!=NULL;temp_host=temp_host->next){
-
-		if(is_host_immediate_child_of_host(parent,temp_host)==TRUE){
-
-			this_depth=host_child_depth_separation(temp_host,child);
-
-			if(this_depth>=0 && (have_min_depth==FALSE || (have_min_depth==TRUE && (this_depth<min_depth)))){
-				have_min_depth=TRUE;
-				min_depth=this_depth;
-			        }
-		        }
-	        }
-
-	if(have_min_depth==FALSE)
-		return -1;
-	else
-		return min_depth+1;
-        }
-
+        if (parent==NULL)
+                return child->depth;
 
+        return child->depth - parent->depth;
+}
 
 /* calculates how many hosts reside on a specific "layer" - used by collapsed tree layout method */
 int number_of_host_layer_members(host *parent, int layer){
@@ -2471,16 +2449,18 @@
 
 
 /* calculate max drawing width for host and children - used by balanced tree layout method */
-int max_child_host_drawing_width(host *parent){
+static int max_child_host_drawing_width_rec(host *parent){
 	host *temp_host;
 	int child_width=0;
 
 
 	for(temp_host=host_list;temp_host!=NULL;temp_host=temp_host->next){
-		
-		if(is_host_immediate_child_of_host(parent,temp_host)==TRUE)
-			child_width+=max_child_host_drawing_width(temp_host);
-	        }
+                if(is_host_immediate_child_of_host(parent,temp_host)==TRUE)
+                        if (!host_is_marked(temp_host, DRAWING_WIDTH_SET)) {
+                                mark_host(temp_host, DRAWING_WIDTH_SET);
+                                child_width+=max_child_host_drawing_width_rec(temp_host);
+                        }
+        }
 
 	/* no children, so set width to 1 for this host */
 	if(child_width==0)
@@ -2490,7 +2470,14 @@
 		return child_width;
         }
 
+int max_child_host_drawing_width(host *parent){
+        int child_width;
 
+        unmark_all_hosts(DRAWING_WIDTH_SET);
+        child_width = max_child_host_drawing_width_rec(parent);
+        unmark_all_hosts(DRAWING_WIDTH_SET);
+        return child_width;
+}
 
 /* calculates number of services associated with a particular service */
 int number_of_host_services(host *hst){
@@ -2516,13 +2503,17 @@
 /******************************************************************/
 
 /* calculates coords of a host's children - used by balanced tree layout method */
-void calculate_balanced_tree_coords(host *parent, int x, int y){
+static void calculate_balanced_tree_coords_rec(host *parent, int x, int y){
 	int parent_drawing_width;
 	int start_drawing_x;
 	int current_drawing_x;
 	int this_drawing_width;
 	host *temp_host;
 
+        if (host_is_marked(parent, CALC_BALANCED_SET))
+                return;
+        mark_host(parent, CALC_BALANCED_SET);
+
 	/* calculate total drawing width of parent host */
 	parent_drawing_width=max_child_host_drawing_width(parent);
 
@@ -2547,7 +2538,7 @@
 			current_drawing_x+=(this_drawing_width*DEFAULT_NODE_WIDTH)+((this_drawing_width-1)*DEFAULT_NODE_HSPACING)+DEFAULT_NODE_HSPACING;
 
 			/* recurse into child host ... */
-			calculate_balanced_tree_coords(temp_host,temp_host->x_2d,temp_host->y_2d);
+			calculate_balanced_tree_coords_rec(temp_host,temp_host->x_2d,temp_host->y_2d);
 		        }
 
 	        }
@@ -2555,6 +2546,11 @@
 	return;
         }
 
+void calculate_balanced_tree_coords(host *parent, int x, int y){
+        unmark_all_hosts(CALC_BALANCED_SET);
+        calculate_balanced_tree_coords_rec(parent, x, y);
+        unmark_all_hosts(CALC_BALANCED_SET);
+}
 
 /* calculate coords of all hosts in circular layout method */
 void calculate_circular_coords(void){
@@ -2606,7 +2602,7 @@
 	
 
 /* calculates coords of all hosts in a particular "layer" in circular layout method */
-void calculate_circular_layer_coords(host *parent, double start_angle, double useable_angle, int layer, int radius){
+static void calculate_circular_layer_coords_rec(host *parent, double start_angle, double useable_angle, int layer, int radius){
 	int parent_drawing_width=0;
 	int this_drawing_width=0;
 	int immediate_children=0;
@@ -2619,6 +2615,9 @@
 	double y_coord=0.0;
 	host *temp_host;
 
+        if (host_is_marked(parent, LAYER_COORDS_SET))
+                return;
+        mark_host(parent, LAYER_COORDS_SET);
 
 	/* get the total number of immediate children to this host */
 	immediate_children=number_of_immediate_child_hosts(parent);
@@ -2673,7 +2672,7 @@
 			temp_host->should_be_drawn=TRUE;
 
 			/* recurse into child host ... */
-			calculate_circular_layer_coords(temp_host,current_drawing_angle+((available_angle-clipped_available_angle)/2),clipped_available_angle,layer+1,radius+CIRCULAR_DRAWING_RADIUS);
+			calculate_circular_layer_coords_rec(temp_host,current_drawing_angle+((available_angle-clipped_available_angle)/2),clipped_available_angle,layer+1,radius+CIRCULAR_DRAWING_RADIUS);
 
 			/* increment current drawing angle */
 			current_drawing_angle+=available_angle;
@@ -2684,10 +2683,16 @@
         }
 
 
+void calculate_circular_layer_coords(host *parent, double start_angle, double useable_angle, int layer, int radius){
+        unmark_all_hosts(LAYER_COORDS_SET);
+        calculate_circular_layer_coords_rec(parent, start_angle, useable_angle, layer, radius);
+        unmark_all_hosts(LAYER_COORDS_SET);
+}
 
 /* draws background "extras" for all hosts in circular markup layout */
 void draw_circular_markup(void){
 
+        unmark_all_hosts(DRAW_CIRCULAR_SET);
 	/* calculate all host sections, starting with first layer */
 	draw_circular_layer_markup(NULL,0.0,360.0,1,CIRCULAR_DRAWING_RADIUS);
 
@@ -2718,6 +2723,10 @@
 	int translated_x=0;
 	int translated_y=0;
 
+        if (host_is_marked(parent, DRAW_CIRCULAR_SET))
+                return;
+        mark_host(parent, DRAW_CIRCULAR_SET);
+
 	/* get the total number of immediate children to this host */
 	immediate_children=number_of_immediate_child_hosts(parent);
 
diff -r -U 3 --minimal nagios-3.0a1/cgi/statuswrl.c develop/nagios-3.0a1/cgi/statuswrl.c
--- nagios-3.0a1/cgi/statuswrl.c	2006-03-27 21:53:55.000000000 +0100
+++ develop/nagios-3.0a1/cgi/statuswrl.c	2007-03-21 13:51:40.000000000 +0000
@@ -466,17 +466,18 @@
 	return max_members;
         }
 
-
-
 /* calculate max drawing width for host and children - used by balanced tree layout method */
-int max_child_host_drawing_width(host *parent){
+int max_child_host_drawing_width_rec(host *parent){
 	host *temp_host;
 	int child_width=0;
 
 	for(temp_host=host_list;temp_host!=NULL;temp_host=temp_host->next){
 		if(is_host_immediate_child_of_host(parent,temp_host)==TRUE)
-			child_width+=max_child_host_drawing_width(temp_host);
-	        }
+                        if (!host_is_marked(temp_host, DRAWING_WIDTH_SET)) {
+                                mark_host(temp_host, DRAWING_WIDTH_SET);
+                                child_width+=max_child_host_drawing_width_rec(temp_host);
+                        }
+                }
 
 	/* no children, so set width to 1 for this host */
 	if(child_width==0)
@@ -485,6 +486,15 @@
 	else
 		return child_width;
         }
+
+int max_child_host_drawing_width(host *parent){
+        int child_width;
+
+        unmark_all_hosts(DRAWING_WIDTH_SET);
+        child_width = max_child_host_drawing_width_rec(parent);
+        unmark_all_hosts(DRAWING_WIDTH_SET);
+        return child_width;
+}
 	
 
 
@@ -1171,13 +1181,17 @@
 /******************************************************************/
 
 /* calculates coords of a host's children - used by balanced tree layout method */
-void calculate_balanced_tree_coords(host *parent, int x, int y){
+static void calculate_balanced_tree_coords_rec(host *parent, int x, int y){
 	int parent_drawing_width;
 	int start_drawing_x;
 	int current_drawing_x;
 	int this_drawing_width;
 	host *temp_host;
 
+        if (host_is_marked(parent, CALC_BALANCED_SET))
+                return;
+        mark_host(parent, CALC_BALANCED_SET);
+
 	/* calculate total drawing width of parent host */
 	parent_drawing_width=max_child_host_drawing_width(parent);
 
@@ -1202,7 +1216,7 @@
 			current_drawing_x+=(this_drawing_width*DEFAULT_NODE_WIDTH)+((this_drawing_width-1)*DEFAULT_NODE_HSPACING)+DEFAULT_NODE_HSPACING;
 
 			/* recurse into child host ... */
-			calculate_balanced_tree_coords(temp_host,temp_host->x_3d,temp_host->y_3d);
+			calculate_balanced_tree_coords_rec(temp_host,temp_host->x_3d,temp_host->y_3d);
 		        }
 
 	        }
@@ -1210,6 +1224,11 @@
 	return;
         }
 
+void calculate_balanced_tree_coords(host *parent, int x, int y){
+        unmark_all_hosts(CALC_BALANCED_SET);
+        calculate_balanced_tree_coords_rec(parent, x, y);
+        unmark_all_hosts(CALC_BALANCED_SET);
+}
 
 /* calculate coords of all hosts in circular layout method */
 void calculate_circular_coords(void){
@@ -1222,7 +1241,7 @@
 	
 
 /* calculates coords of all hosts in a particular "layer" in circular layout method */
-void calculate_circular_layer_coords(host *parent, double start_angle, double useable_angle, int layer, int radius){
+static void calculate_circular_layer_coords_rec(host *parent, double start_angle, double useable_angle, int layer, int radius){
 	int parent_drawing_width=0;
 	int this_drawing_width=0;
 	int immediate_children=0;
@@ -1235,6 +1254,9 @@
 	double y_coord=0.0;
 	host *temp_host;
 
+        if (host_is_marked(parent, LAYER_COORDS_SET))
+                return;
+        mark_host(parent, LAYER_COORDS_SET);
 
 	/* get the total number of immediate children to this host */
 	immediate_children=number_of_immediate_child_hosts(parent);
@@ -1289,7 +1311,7 @@
 			temp_host->should_be_drawn=TRUE;
 
 			/* recurse into child host ... */
-			calculate_circular_layer_coords(temp_host,current_drawing_angle+((available_angle-clipped_available_angle)/2),clipped_available_angle,layer+1,radius+CIRCULAR_DRAWING_RADIUS);
+			calculate_circular_layer_coords_rec(temp_host,current_drawing_angle+((available_angle-clipped_available_angle)/2),clipped_available_angle,layer+1,radius+CIRCULAR_DRAWING_RADIUS);
 
 			/* increment current drawing angle */
 			current_drawing_angle+=available_angle;
@@ -1299,4 +1321,8 @@
 	return;
         }
 
-
+void calculate_circular_layer_coords(host *parent, double start_angle, double useable_angle, int layer, int radius){
+        unmark_all_hosts(LAYER_COORDS_SET);
+        calculate_circular_layer_coords_rec(parent, start_angle, useable_angle, layer, radius);
+        unmark_all_hosts(LAYER_COORDS_SET);
+}
diff -r -U 3 --minimal nagios-3.0a1/cgi/tac.c develop/nagios-3.0a1/cgi/tac.c
--- nagios-3.0a1/cgi/tac.c	2006-08-22 17:19:07.000000000 +0100
+++ develop/nagios-3.0a1/cgi/tac.c	2007-03-21 10:45:11.734901000 +0000
@@ -820,11 +820,14 @@
 
 
 /* calculates network outage effect of a particular host being down or unreachable */
-void calculate_outage_effect_of_host(host *hst, int *affected_hosts){
+static void calculate_outage_effect_of_host_rec(host *hst, int *affected_hosts){
 	int total_child_hosts_affected=0;
 	int temp_child_hosts_affected=0;
 	host *temp_host;
 
+        if (host_is_marked(hst, CALC_OUTAGE_SET))
+                return;
+        mark_host(hst, CALC_OUTAGE_SET);
 
 	/* find all child hosts of this host */
 	for(temp_host=host_list;temp_host!=NULL;temp_host=temp_host->next){
@@ -834,7 +837,7 @@
 			continue;
 
 		/* calculate the outage effect of the child */
-		calculate_outage_effect_of_host(temp_host,&temp_child_hosts_affected);
+		calculate_outage_effect_of_host_rec(temp_host,&temp_child_hosts_affected);
 
 		/* keep a running total of outage effects */
 		total_child_hosts_affected+=temp_child_hosts_affected;
@@ -845,6 +848,11 @@
 	return;
         }
 
+void calculate_outage_effect_of_host(host *hst, int *affected_hosts){
+        unmark_all_hosts(CALC_OUTAGE_SET);
+        calculate_outage_effect_of_host_rec(hst, affected_hosts);
+        unmark_all_hosts(CALC_OUTAGE_SET);
+}
 
 
 /* tests whether or not a host is "blocked" by upstream parents (host is already assumed to be down or unreachable) */
diff -r -U 3 --minimal nagios-3.0a1/common/objects.c develop/nagios-3.0a1/common/objects.c
--- nagios-3.0a1/common/objects.c	2007-02-04 20:17:58.000000000 +0000
+++ develop/nagios-3.0a1/common/objects.c	2007-03-21 10:45:10.000000000 +0000
@@ -3584,6 +3584,67 @@
 
 
 
+/************************************/
+/***** Graph traversal routines *****/
+/************************************/
+
+void unmark_all_hosts(int set){
+        host *temp_host;
+
+       	for(temp_host=host_list;temp_host!=NULL;temp_host=temp_host->next){
+                temp_host->visited &= ~set;
+        }
+}
+
+void mark_host(host *hst, int set){
+        if (hst != NULL)
+                hst->visited |= set;
+}
+
+int host_is_marked(host *hst, int set){
+        return hst != NULL && (hst->visited & set);
+}
+
+static int assign_host_depth_rec(host *hst){
+        hostsmember *temp_hostsmember;
+        int min_depth_found = FALSE;
+
+        if (host_is_marked(hst, DEPTH_VISITING_SET))
+                return host_is_marked(hst, MIN_DEPTH_FOUND_SET);
+
+        mark_host(hst, DEPTH_VISITING_SET);
+        if (hst->parent_hosts == NULL) {
+                mark_host(hst, MIN_DEPTH_FOUND_SET);
+                min_depth_found = TRUE;
+                hst->depth = 1;
+        } else {
+                hst->depth = -1;
+                for(temp_hostsmember=hst->parent_hosts;temp_hostsmember!=NULL;temp_hostsmember=temp_hostsmember->next) {
+                        host *temp_host = find_host(temp_hostsmember->host_name);
+                        min_depth_found = assign_host_depth_rec(temp_host);
+                        if (min_depth_found && (hst->depth == -1 || temp_host->depth + 1 < hst->depth))
+                                hst->depth = temp_host->depth + 1;
+                }
+                if (min_depth_found)
+                        mark_host(hst, MIN_DEPTH_FOUND_SET);
+                else
+                        hst->depth = 1;
+
+        }
+        return min_depth_found;
+}
+
+void assign_host_depths(void){
+        host *temp_host;
+        int min_depth = 0;
+
+        unmark_all_hosts(DEPTH_VISITING_SET|MIN_DEPTH_FOUND_SET);
+
+       	for(temp_host=host_list;temp_host!=NULL;temp_host=temp_host->next){
+                assign_host_depth_rec(temp_host);
+        }
+}
+
 /******************************************************************/
 /********************* OBJECT QUERY FUNCTIONS *********************/
 /******************************************************************/
@@ -3672,6 +3733,20 @@
 	}
 
 
+/* returns a count of the immediate children for a given host */
+int number_of_immediate_child_hosts_not_parents(host *hst){
+	int children=0;
+	host *temp_host;
+
+	for(temp_host=host_list;temp_host!=NULL;temp_host=temp_host->next){
+		if(is_host_immediate_child_of_host(hst,temp_host)==TRUE && is_host_immediate_parent_of_host(hst,temp_host)==FALSE)
+			children++;
+		}
+
+	return children;
+	}
+
+
 /* returns a count of the total children for a given host */
 int number_of_total_child_hosts(host *hst){
 	int children=0;
diff -r -U 3 --minimal nagios-3.0a1/include/objects.h develop/nagios-3.0a1/include/objects.h
--- nagios-3.0a1/include/objects.h	2007-03-06 13:19:37.000000000 +0000
+++ develop/nagios-3.0a1/include/objects.h	2007-03-21 10:45:11.830996000 +0000
@@ -65,7 +65,17 @@
 #define HOSTESCALATION_HASHSLOTS               1024
 #define SERVICEESCALATION_HASHSLOTS            1024
 
+/****************** SET IDENTIFIERS *******************/
 
+#define CHECKED_HOSTS_SET   (1<<0)
+#define DEPTH_VISITING_SET  (1<<1)
+#define MIN_DEPTH_FOUND_SET (1<<2)
+#define LAYER_MEMBERS_SET   (1<<3)
+#define LAYER_COORDS_SET    (1<<4)
+#define DRAWING_WIDTH_SET   (1<<5)
+#define DRAW_CIRCULAR_SET   (1<<6)
+#define CALC_BALANCED_SET   (1<<7)
+#define CALC_OUTAGE_SET     (1<<8)
 
 /****************** DATA STRUCTURES *******************/
 
@@ -354,6 +364,8 @@
 	timeperiod *notification_period_ptr;
 	objectlist *hostgroups_ptr;
 #endif
+        int     visited;
+        int     depth;
 	struct  host_struct *next;
 	struct  host_struct *nexthash;
         };
@@ -629,6 +641,8 @@
 /**** Top-level input functions ****/
 int read_object_config_data(char *,int,int,int);        /* reads all external configuration data of specific types */
 
+void assign_host_depths(void);
+
 /**** Object Creation Functions ****/
 contact *add_contact(char *,char *,char *,char *,char **,char *,char *,int,int,int,int,int,int,int,int,int,int,int,int,int,int,int,int);	/* adds a contact definition */
 commandsmember *add_service_notification_command_to_contact(contact *,char *);				/* adds a service notification command to a contact definition */
@@ -737,6 +751,7 @@
 int is_host_immediate_parent_of_host(host *,host *);		        /* tests whether or not a host is an immediate parent of another host */
 
 int number_of_immediate_child_hosts(host *);		                /* counts the number of immediate child hosts for a particular host */
+int number_of_immediate_child_hosts_not_parents(host *);	        /* counts the number of immediate child hosts for a particular host that are not also its parents */
 int number_of_total_child_hosts(host *);				/* counts the number of total child hosts for a particular host */
 int number_of_immediate_parent_hosts(host *);				/* counts the number of immediate parents hosts for a particular host */
 int number_of_total_parent_hosts(host *);				/* counts the number of total parents hosts for a particular host */
@@ -751,6 +766,11 @@
 /**** Object Cleanup Functions ****/
 int free_object_data(void);                             /* frees all allocated memory for the object definitions */
 
+/**** set membership functions ****/
+extern void unmark_all_hosts(int set);
+extern void mark_host(host *hst, int set);
+extern int host_is_marked(host *hst, int set);
+
 #ifdef __cplusplus
   }
 #endif


-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV




More information about the Developers mailing list